From cb0eec606774ab5e07e50c045b1301f3c2f425dd Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 5 Nov 2024 17:01:59 +0100 Subject: [PATCH 001/150] Created SparseMatrix module --- src/cdomains/vectorMatrix.ml | 153 +++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index a3712274ab..5a4b7b644f 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -609,3 +609,156 @@ module ArrayMatrix: AbstractMatrix = let map2i_with f m v = timing_wrap "map2i_with" (map2i_with f m) v end + + +(** Sparse matrix implementation. + It provides a normalization function to reduce a matrix into reduced row echelon form. + Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) +module SparseMatrix: AbstractMatrix = + functor (A: RatOps) (V: AbstractVector) -> + struct + include ConvenienceOps(A) + module V = V(A) + + (*Array of arrays implementation. One array per row containing tuple of column index and value*) + type t = (int * A.t) array array [@@deriving eq, ord, hash] + + let show x = + failwith "TODO" + + let empty () = + Array.make_matrix 0 0 (0, A.zero) + + let num_rows m = + failwith "TODO" + + let is_empty m = + num_rows m = 0 + + let num_cols m = + failwith "TODO" + + let copy m = + failwith "TODO" + + let copy m = + failwith "TODO" + + let add_empty_columns m cols = + failwith "TODO" + + let add_empty_columns m cols = + timing_wrap "add_empty_cols" (add_empty_columns m) cols + + let append_row m row = + failwith "TODO" + + let get_row m n = + failwith "TODO" + + let remove_row m n = + failwith "TODO" + + let get_col m n = + failwith "TODO" + + let get_col m n = + timing_wrap "get_col" (get_col m) n + + let set_col_with m new_col n = + failwith "TODO" + + let set_col_with m new_col n = timing_wrap "set_col" (set_col_with m new_col) n + + let set_col m new_col n = + failwith "TODO" + + let append_matrices m1 m2 = + failwith "TODO" + + let equal m1 m2 = timing_wrap "equal" (equal m1) m2 + + let reduce_col_with m j = + failwith "TODO" + + let reduce_col_with m j = timing_wrap "reduce_col_with" (reduce_col_with m) j + let reduce_col m j = + failwith "TODO" + + let del_col m j = + failwith "TODO" + + let del_cols m cols = + failwith "TODO" + + let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols + + let map2i f m v = + failwith "TODO" + + let remove_zero_rows m = + failwith "TODO" + + let rref_with m = + failwith "TODO" + + let rref_with m = timing_wrap "rref_with" rref_with m + + let init_with_vec v = + failwith "TODO" + + + let reduce_col_with_vec m j v = + failwith "TODO" + + let get_pivot_positions m = + failwith "TODO" + + let rref_vec m pivot_positions v = + failwith "TODO" + + + let rref_vec_with m v = + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) + (*m must be in rref form and contain the same num of cols as v*) + (*If m is empty then v is simply normalized and returned*) + failwith "TODO" + + let rref_vec_with m v = timing_wrap "rref_vec_with" (rref_vec_with m) v + + let rref_matrix_with m1 m2 = + (*Similar to rref_vec_with but takes two matrices instead.*) + (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) + failwith "TODO" + + let rref_matrix_with m1 m2 = timing_wrap "rref_matrix_with" (rref_matrix_with m1) m2 + + let normalize_with m = + failwith "TODO" + + let normalize_with m = timing_wrap "normalize_with" normalize_with m + + let normalize m = + failwith "TODO" + + let is_covered_by m1 m2 = + failwith "TODO" + + let is_covered_by m1 m2 = timing_wrap "is_covered_by" (is_covered_by m1) m2 + + let find_opt f m = + failwith "TODO" + + let map2 f m v = + failwith "TODO" + + let map2_with f m v = + failwith "TODO" + + let map2_with f m v = timing_wrap "map2_with" (map2_with f m) v + + let map2i_with f m v = + failwith "TODO" + + let map2i_with f m v = timing_wrap "map2i_with" (map2i_with f m) v + end \ No newline at end of file From 69cc72f53cb1cc9c41a6c6a42af066d4e25d7373 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 7 Nov 2024 19:36:57 +0100 Subject: [PATCH 002/150] changed type to lists --- src/cdomains/vectorMatrix.ml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 5a4b7b644f..12be213e5c 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -621,13 +621,16 @@ module SparseMatrix: AbstractMatrix = module V = V(A) (*Array of arrays implementation. One array per row containing tuple of column index and value*) - type t = (int * A.t) array array [@@deriving eq, ord, hash] + type t = { + entries : (int * A.t) array array; + column_count : int + } [@@deriving eq, ord, hash] let show x = failwith "TODO" let empty () = - Array.make_matrix 0 0 (0, A.zero) + failwith "TODO" let num_rows m = failwith "TODO" From 1b5f531b7690d909bd39ea7e3ceb2f66330ca868 Mon Sep 17 00:00:00 2001 From: Kevin Date: Thu, 7 Nov 2024 21:52:03 +0100 Subject: [PATCH 003/150] SparseMatrix list and get_col --- src/cdomains/vectorMatrix.ml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 12be213e5c..62a7b7a67b 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -622,7 +622,7 @@ module SparseMatrix: AbstractMatrix = (*Array of arrays implementation. One array per row containing tuple of column index and value*) type t = { - entries : (int * A.t) array array; + entries : (int * A.t) list list; column_count : int } [@@deriving eq, ord, hash] @@ -630,16 +630,16 @@ module SparseMatrix: AbstractMatrix = failwith "TODO" let empty () = - failwith "TODO" + {entries = []; column_count = 0} let num_rows m = - failwith "TODO" + List.length m.entries let is_empty m = num_rows m = 0 let num_cols m = - failwith "TODO" + m.column_count let copy m = failwith "TODO" @@ -654,7 +654,7 @@ module SparseMatrix: AbstractMatrix = timing_wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - failwith "TODO" + failwith "TODO" let get_row m n = failwith "TODO" @@ -663,7 +663,15 @@ module SparseMatrix: AbstractMatrix = failwith "TODO" let get_col m n = - failwith "TODO" + (* Uses the fact that row is sorted to return Zero when index n is exceeded *) + let rec get_col_from_row row = + match row with + | [] -> A.zero + | (col_idx, value)::_ when col_idx = n -> value + | (col_idx, _)::_ when col_idx > n -> A.zero + | _::cs -> get_col_from_row cs + in + V.of_list @@ List.map (fun row -> get_col_from_row row ) m.entries let get_col m n = timing_wrap "get_col" (get_col m) n @@ -720,7 +728,7 @@ module SparseMatrix: AbstractMatrix = let rref_vec m pivot_positions v = failwith "TODO" - + let rref_vec_with m v = (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) (*m must be in rref form and contain the same num of cols as v*) From b1c877aa69d04d0bc9cd66bb991bb21cd7cf8c7b Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 8 Nov 2024 18:57:36 +0100 Subject: [PATCH 004/150] Implement del_col and del_cols for SparseMatrix --- src/cdomains/vectorMatrix.ml | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 62a7b7a67b..71672ab30f 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -697,10 +697,35 @@ module SparseMatrix: AbstractMatrix = failwith "TODO" let del_col m j = - failwith "TODO" - + if is_empty m then m else + let del_col_from_row row = + List.filter_map (fun (col_idx, value) -> + if col_idx = j then + None + else if col_idx > j then + Some (col_idx - 1, value) + else + Some (col_idx, value) + ) row + in + let new_entries = List.map (fun row -> del_col_from_row row) m.entries in + {entries = new_entries; column_count = m.column_count - 1} + + (* TODO: Might be more efficient to check for each entry how much to reduce their index and not by recursively calling del_col *) let del_cols m cols = - failwith "TODO" + let cols = Array.to_list cols in (* TODO: Get away from Arrays *) + let to_delete_count = List.length cols in + if to_delete_count = 0 || is_empty m then m + else + if num_cols m = to_delete_count then empty () else + let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification)*) + let rec del_cols_aux m cols deleted_col_count = + match cols with + | [] -> m + | col_idx::cs -> + let m' = del_col m (col_idx - deleted_col_count) in (* Taking already deleted cols into account because of new index *) + del_cols_aux m' cs (deleted_col_count + 1) + in del_cols_aux m sorted_cols 0 let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols From bfbd373d8c00cfdf3b1e904cdb36d99aa877da91 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Sun, 10 Nov 2024 13:59:34 +0100 Subject: [PATCH 005/150] added row functions and conversions between vectors and sparse lists --- src/cdomains/vectorMatrix.ml | 40 +++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 71672ab30f..700e32c148 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -114,6 +114,11 @@ sig val of_array: num array -> t val copy: t -> t + + val of_sparse_list: (int * num) list -> int -> t + + val to_sparse_list: t -> (int * num) list + end (** Some functions inside have the suffix _with, which means that the function has side effects. *) @@ -272,6 +277,20 @@ module ArrayVector: AbstractVector = let copy v = Array.copy v let mapi_with f v = Array.iteri (fun i x -> v.(i) <- f i x) v + + let of_sparse_list ls col_count = + let vec = Array.make col_count A.zero in + List.iter (fun (idx, value) -> vec.(idx) <- value) ls; + vec + + let to_sparse_list v = + let rec aux idx acc = + if idx < 0 then acc + else + let value = v.(idx) in + let acc = if value <> A.zero then (idx, value):: acc else acc in + aux (idx - 1) acc + in aux (length v - 1) [] end open Batteries.Array @@ -620,14 +639,14 @@ module SparseMatrix: AbstractMatrix = include ConvenienceOps(A) module V = V(A) - (*Array of arrays implementation. One array per row containing tuple of column index and value*) + (* Array of arrays implementation. One array per row containing tuple of column index and value *) type t = { entries : (int * A.t) list list; column_count : int } [@@deriving eq, ord, hash] let show x = - failwith "TODO" + List.fold_left (^) " " (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) let empty () = {entries = []; column_count = 0} @@ -642,10 +661,10 @@ module SparseMatrix: AbstractMatrix = m.column_count let copy m = - failwith "TODO" + {entries = m.entries; column_count = m.column_count} (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) let copy m = - failwith "TODO" + timing_wrap "copy" (copy) m let add_empty_columns m cols = failwith "TODO" @@ -654,13 +673,20 @@ module SparseMatrix: AbstractMatrix = timing_wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - failwith "TODO" + {entries = m.entries @ [V.to_sparse_list row]; column_count = m.column_count} let get_row m n = - failwith "TODO" + V.of_sparse_list (List.nth m.entries n) m.column_count let remove_row m n = - failwith "TODO" + let rec aux idx entries = match idx, entries with + | i, x :: xs when i = n -> xs + | _, x :: xs -> x :: aux (idx + 1) xs + | _, _ -> failwith "trying to remove out of bounds row" + in + let new_entries = aux 0 m.entries in + let new_col_count = if new_entries = [] then 0 else m.column_count in + {entries = new_entries; column_count = new_col_count} let get_col m n = (* Uses the fact that row is sorted to return Zero when index n is exceeded *) From d0124f9a0c9d91f80babfa02ef6fd14ceab69b15 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Mon, 11 Nov 2024 16:53:58 +0100 Subject: [PATCH 006/150] add_empty_columns untested --- src/cdomains/vectorMatrix.ml | 45 ++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 62a7b7a67b..68dcecab50 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -637,20 +637,57 @@ module SparseMatrix: AbstractMatrix = let is_empty m = num_rows m = 0 + (*This should be different if the implimentation is sound*) + (*m.column_count = 0*) let num_cols m = m.column_count let copy m = - failwith "TODO" + {entries = m.entries; column_count = m.column_count} let copy m = failwith "TODO" - let add_empty_columns m cols = - failwith "TODO" + let add_empty_columns m (cols : int enumerable) = + let colsL = Array.to_list(cols) in + let emptyT = A.zero in + let rec list_of_all_before_index idx cols = + (*This should return two arrays + all the idices before idx and all those after, but I'm not sure if inclusive or not + e.g. list_of_all_before_index 3 [1,2,3,4] = ([1,2], [3,4]) or = ([1,2,3], [4]) + right now its of the first form! + *) + match cols with + | x::xs -> + if x < idx + then + let (h,t) = list_of_all_before_index idx xs in + (x::h, t) + else ([],x::xs) + | [] -> ([],[]) + in + (*This could easily be abstracted into the above functions, but its nice to have + it here for readability and debugging*) + let rec make_empty_entries_for_idxs idxs = + match idxs with + | x::xs -> (x, emptyT)::(make_empty_entries_for_idxs xs) + | [] -> [] + in + let rec add_column_element r cols = + match r with + | (idx, _)::xs -> + let (bef,aft) = list_of_all_before_index idx cols in + (make_empty_entries_for_idxs bef)@(add_column_element xs aft) + | [] -> [] + in + let rec add_empty_columns_on_list m cols = + match m with + | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) + | [] -> [] + in {entries = add_empty_columns_on_list m.entries colsL; column_count = m.column_count + Array.length cols} - let add_empty_columns m cols = + let add_empty_columns m (cols : int enumerable) = timing_wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = From d78945919ae14da99f0c3030ac20451d8d3e92d8 Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 12 Nov 2024 16:58:16 +0100 Subject: [PATCH 007/150] Implement set_col for SparseMatrix --- src/cdomains/vectorMatrix.ml | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index a33a08018c..cef4ba83b5 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -656,8 +656,8 @@ module SparseMatrix: AbstractMatrix = let is_empty m = num_rows m = 0 - (*This should be different if the implimentation is sound*) - (*m.column_count = 0*) + (*This should be different if the implimentation is sound*) + (*m.column_count = 0*) let num_cols m = m.column_count @@ -680,14 +680,14 @@ module SparseMatrix: AbstractMatrix = match cols with | x::xs -> if x < idx - then - let (h,t) = list_of_all_before_index idx xs in - (x::h, t) - else ([],x::xs) + then + let (h,t) = list_of_all_before_index idx xs in + (x::h, t) + else ([],x::xs) | [] -> ([],[]) in (*This could easily be abstracted into the above functions, but its nice to have - it here for readability and debugging*) + it here for readability and debugging*) let rec make_empty_entries_for_idxs idxs = match idxs with | x::xs -> (x, emptyT)::(make_empty_entries_for_idxs xs) @@ -745,7 +745,18 @@ module SparseMatrix: AbstractMatrix = let set_col_with m new_col n = timing_wrap "set_col" (set_col_with m new_col) n let set_col m new_col n = - failwith "TODO" + let rec set_col_in_row row value = + match row with + | [] -> if value =: A.zero then [] else [(n, value)] + | (col_idx, v)::cs when col_idx > n -> if value =: A.zero then (col_idx, v)::cs else (n, value)::(col_idx, v)::cs + | (col_idx, v)::cs when col_idx = n -> if value =: A.zero then cs else (n, value)::cs + | (col_idx, v)::cs -> (col_idx, v)::(set_col_in_row cs value) + in + let new_entries = List.mapi (fun row_idx row -> + let value = V.nth new_col row_idx in + set_col_in_row row value + ) m.entries in + {entries = new_entries; column_count = m.column_count} let append_matrices m1 m2 = failwith "TODO" From 8c23838bb90fe3cdffd2e117813234259aa57d0e Mon Sep 17 00:00:00 2001 From: Kevin Date: Tue, 12 Nov 2024 17:52:34 +0100 Subject: [PATCH 008/150] Add functions without side effects to ArrayVector and Vector interface --- src/cdomains/vectorMatrix.ml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index cef4ba83b5..90ba4f044b 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -83,6 +83,8 @@ sig val map_with: (num -> num) -> t -> unit + val map: (num -> num) -> t -> t + val compare_length_with: t -> int -> int val of_list: num list -> t @@ -99,6 +101,8 @@ sig val rev_with: t -> unit + val rev: t -> t + val map2i: (int -> num -> num -> num) -> t -> t -> t val map2i_with: (int -> num -> num -> num) -> t -> t -> unit @@ -107,6 +111,8 @@ sig val mapi_with: (int -> num -> num) -> t -> unit + val mapi: (int -> num -> num) -> t -> t + val find2i: (num -> num -> bool) -> t -> t -> int val to_array: t -> num array @@ -180,6 +186,8 @@ sig val map2_with: (vec -> num -> vec) -> t -> vec -> unit + val map2: (vec -> num -> vec) -> t -> vec -> t + val map2i: (int -> vec-> num -> vec) -> t -> vec -> t val map2i_with: (int -> vec -> num -> vec) -> t -> vec -> unit @@ -270,14 +278,26 @@ module ArrayVector: AbstractVector = let rev_with v = Array.rev_in_place v + let rev v = Array.rev v + let map_with f v = Array.modify f v + let map f v = Array.map f v + let map2_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f x y) v1 v2 + let map2 f v1 v2 = + let copy_v1 = copy v1 in + map2_with f copy_v1 v2; copy_v1 + let copy v = Array.copy v let mapi_with f v = Array.iteri (fun i x -> v.(i) <- f i x) v + let mapi f v = + let copy = copy v in + mapi_with f copy; copy + let of_sparse_list ls col_count = let vec = Array.make col_count A.zero in List.iter (fun (idx, value) -> vec.(idx) <- value) ls; From fd73a7ca1960ce7b140159d356be15ae67452f20 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 12 Nov 2024 18:32:24 +0100 Subject: [PATCH 009/150] Removed some _with functions from the AffineEqualityDomain --- .../apron/affineEqualityDomain.apron.ml | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 06268130b2..aa64b7f741 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -29,7 +29,7 @@ struct m else ( Array.modifyi (+) ch.dim; - let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col_with y x; y) m ch.dim else m in + let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col y x) m ch.dim else m in remove_zero_rows @@ del_cols m' ch.dim) let dim_remove ch m ~del = VectorMatrix.timing_wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del @@ -59,7 +59,7 @@ struct let open Apron.Texpr1 in let exception NotLinear in let zero_vec = Vector.zero_vec @@ Environment.size t.env + 1 in - let neg v = Vector.map_with Mpqf.neg v; v in + let neg v = Vector.map Mpqf.neg v in let is_const_vec v = Vector.compare_length_with (Vector.filteri (fun i x -> (*Inefficient*) Vector.compare_length_with v (i + 1) > 0 && x <>: Mpqf.zero) v) 1 = 0 in @@ -75,13 +75,13 @@ struct Vector.set_val zero_vec ((Vector.length zero_vec) - 1) (of_union x) | Var x -> let zero_vec_cp = Vector.copy zero_vec in - let entry_only v = Vector.set_val_with v (Environment.dim_of_var t.env x) Mpqf.one; v in + let entry_only v = Vector.set_val v (Environment.dim_of_var t.env x) Mpqf.one in begin match t.d with | Some m -> let row = Matrix.find_opt (fun r -> Vector.nth r (Environment.dim_of_var t.env x) =: Mpqf.one) m in begin match row with | Some v when is_const_vec v -> - Vector.set_val_with zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)); zero_vec_cp + Vector.set_val zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)) | _ -> entry_only zero_vec_cp end | None -> entry_only zero_vec_cp end @@ -91,17 +91,17 @@ struct | Binop (Add, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in - Vector.map2_with (+:) v1 v2; v1 + Vector.map2 (+:) v1 v2 | Binop (Sub, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in - Vector.map2_with (+:) v1 (neg @@ v2); v1 + Vector.map2 (+:) v1 (neg @@ v2) | Binop (Mul, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in begin match to_constant_opt v1, to_constant_opt v2 with - | _, Some c -> Vector.apply_with_c_with ( *:) c v1; v1 - | Some c, _ -> Vector.apply_with_c_with ( *:) c v2; v2 + | _, Some c -> Vector.apply_with_c ( *:) c v1 + | Some c, _ -> Vector.apply_with_c ( *:) c v2 | _, _ -> raise NotLinear end | Binop _ -> raise NotLinear @@ -294,18 +294,17 @@ struct (a, b, max) else ( - Vector.rev_with col_a; - Vector.rev_with col_b; + let col_a = Vector.rev col_a in + let col_b = Vector.rev col_b in let i = Vector.find2i (<>:) col_a col_b in let (x, y) = Vector.nth col_a i, Vector.nth col_b i in let r, diff = Vector.length col_a - (i + 1), x -: y in let a_r, b_r = Matrix.get_row a r, Matrix.get_row b r in - Vector.map2_with (-:) col_a col_b; - Vector.rev_with col_a; + let col_a = Vector.map2 (-:) col_a col_b in + let col_a = Vector.rev col_a in let multiply_by_t m t = - Matrix.map2i_with (fun i' x c -> if i' <= max then (let beta = c /: diff in - Vector.map2_with (fun u j -> u -: (beta *: j)) x t); x) m col_a; - m + Matrix.map2i (fun i' x c -> if i' <= max then (let beta = c /: diff in Vector.map2 (fun u j -> u -: (beta *: j)) x t) else x) m col_a; + in Matrix.remove_row (multiply_by_t a a_r) r, Matrix.remove_row (multiply_by_t b b_r) r, (max - 1) ) From 11e7dcd71733d891e55605150a503d82547ad0d9 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 12 Nov 2024 19:07:36 +0100 Subject: [PATCH 010/150] sparseVector stumb --- src/cdomains/vectorMatrix.ml | 139 +++++++++++++++++++++++++++++++++-- 1 file changed, 133 insertions(+), 6 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 90ba4f044b..3da2707fe2 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -650,6 +650,138 @@ module ArrayMatrix: AbstractMatrix = end + module SparseVector: AbstractVector = + functor (A: RatOps) -> + struct + include ConvenienceOps (A) + + type t = { + entries: (int * A.t) list ; + len: int + }[@@deriving eq, ord, hash] + + let show v = + failwith "TODO" + + let keep_vals v n = + let rec keep_vals_vec v n = + match v with + | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) + | [] -> [] + in + if n >= v.len then v else (*could be left out but maybe performance??*) + {entries = keep_vals_vec v.entries n; len=n} + + let remove_val v n = + let dec_idx v = + List.map (fun (a,b) -> (a-1, b)) v + in + let rec remove_val_vec v n = + match v with + | x::xs -> + if fst x = n then dec_idx xs else + if fst x > n then dec_idx (x::xs) else + x::(remove_val_vec xs n) + | [] -> [] + in + if n >= v.len then v else (*could be left out but maybe performance??*) + {entries = remove_val_vec v.entries n; len = v.len - 1} + + let set_val v n m = + failwith "TODO" + + let set_val_with v n m = + failwith "TODO" + + let insert_val n m t = + failwith "TODO" + + let apply_with_c f m v = + failwith "TODO" + + let apply_with_c_with f m v = + failwith "TODO" + + let zero_vec n = + failwith "TODO" + + let nth v n = + failwith "TODO" + + let length v = + failwith "TODO" + + let map2 f v v' = + failwith "TODO" + + let map2_with f v v' = + failwith "TODO" + + let findi f v = + failwith "TODO" + + let map f v = + failwith "TODO" + + let map_with f v = + failwith "TODO" + + let compare_length_with v n = + failwith "TODO" + + let of_list l = + failwith "TODO" + + let to_list v = + failwith "TODO" + + let filteri f v = + failwith "TODO" + + let append v v' = + failwith "TODO" + + let exists f v = + failwith "TODO" + + let rev v = + failwith "TODO" + + let rev_with v = + failwith "TODO" + + let map2i f v v' = + failwith "TODO" + + let map2i_with f v v' = + failwith "TODO" + + let mapi f v = + failwith "TODO" + + let mapi_with f v = + failwith "TODO" + + let find2i f v v' = + failwith "TODO" + + let to_array v = + failwith "TODO" + + let of_array a = + failwith "TODO" + + let copy v = v + + let of_sparse_list ls col_count = + failwith "TODO" + + let to_sparse_list v = + failwith "TODO" + + end + + (** Sparse matrix implementation. It provides a normalization function to reduce a matrix into reduced row echelon form. Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) @@ -689,14 +821,9 @@ module SparseMatrix: AbstractMatrix = timing_wrap "copy" (copy) m let add_empty_columns m (cols : int enumerable) = - let colsL = Array.to_list(cols) in + let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in let emptyT = A.zero in let rec list_of_all_before_index idx cols = - (*This should return two arrays - all the idices before idx and all those after, but I'm not sure if inclusive or not - e.g. list_of_all_before_index 3 [1,2,3,4] = ([1,2], [3,4]) or = ([1,2,3], [4]) - right now its of the first form! - *) match cols with | x::xs -> if x < idx From d3b4072a38eedff421ebee33793f84ba132da113 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 14 Nov 2024 16:18:40 +0100 Subject: [PATCH 011/150] Extracted operations --- src/cdomains/affineEquality/convenienceOps.ml | 18 +++++ src/cdomains/affineEquality/ratOps.ml | 18 +++++ .../apron/affineEqualityDomain.apron.ml | 2 + .../apron/linearTwoVarEqualityDomain.apron.ml | 2 + src/cdomains/vectorMatrix.ml | 65 +++++-------------- 5 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 src/cdomains/affineEquality/convenienceOps.ml create mode 100644 src/cdomains/affineEquality/ratOps.ml diff --git a/src/cdomains/affineEquality/convenienceOps.ml b/src/cdomains/affineEquality/convenienceOps.ml new file mode 100644 index 0000000000..39aeeeb5e8 --- /dev/null +++ b/src/cdomains/affineEquality/convenienceOps.ml @@ -0,0 +1,18 @@ +open RatOps + +(** It provides more readable infix operators for the functions of RatOps. + It is designed to be included by modules that make use of RatOps's functions. *) +module ConvenienceOps (A: RatOps) = +struct + let ( *: ) = A.mul + let (+:) = A.add + let (-:) = A.sub + let (/:) = A.div + let (=:) x y = A.equal x y + let (<>:) x y = not (A.equal x y) + let (<:) x y = A.compare x y < 0 + let (>:) x y = A.compare x y > 0 + let (<=:) x y = A.compare x y <= 0 + let (>=:) x y = A.compare x y >= 0 + let of_int x = A.of_int x +end diff --git a/src/cdomains/affineEquality/ratOps.ml b/src/cdomains/affineEquality/ratOps.ml new file mode 100644 index 0000000000..c8d8017693 --- /dev/null +++ b/src/cdomains/affineEquality/ratOps.ml @@ -0,0 +1,18 @@ +(** Abstracts the functions of the Mpqf module for rationals from Apron that implements multi-precision rationals. + One could later exchange "Mpqf" with a different module that provides the functions specified by this interface. *) +module type RatOps = +sig + type t [@@deriving eq, ord, hash] + val add : t -> t -> t + val sub : t -> t -> t + val mul : t -> t -> t + val div : t -> t -> t + val neg : t -> t + val abs : t -> t + val to_string: t -> string + val of_int: int -> t + val zero: t + val one: t + val get_den: t -> Z.t + val get_num: t -> Z.t +end \ No newline at end of file diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 06268130b2..5850568e5b 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -10,7 +10,9 @@ open GoblintCil open Pretty module M = Messages open GobApron + open VectorMatrix +open ConvenienceOps module Mpqf = SharedFunctions.Mpqf diff --git a/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml b/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml index c1ca3661a5..62118a9134 100644 --- a/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml +++ b/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml @@ -12,7 +12,9 @@ open GoblintCil open Pretty module M = Messages open GobApron + open VectorMatrix +open ConvenienceOps module Mpqf = SharedFunctions.Mpqf diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 3da2707fe2..b1fa41fb5e 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -4,47 +4,14 @@ open Batteries module Array = Batteries.Array module M = Messages +open RatOps +open ConvenienceOps + (* let timing_wrap = Timing.wrap *) (* Disable timing of VectorMatrix and AffineEqualityDomain. This is cleaner than a timing functor because the timed functions also call each other. *) let timing_wrap _ f x = f x -(** Abstracts the functions of the Mpqf module for rationals from Apron that implements multi-precision rationals. - One could later exchange "Mpqf" with a different module that provides the functions specified by this interface. *) -module type RatOps = -sig - type t [@@deriving eq, ord, hash] - val add : t -> t -> t - val sub : t -> t -> t - val mul : t -> t -> t - val div : t -> t -> t - val neg : t -> t - val abs : t -> t - val to_string: t -> string - val of_int: int -> t - val zero: t - val one: t - val get_den: t -> Z.t - val get_num: t -> Z.t -end - -(** It provides more readable infix operators for the functions of RatOps. - It is designed to be included by modules that make use of RatOps's functions. *) -module ConvenienceOps (A: RatOps) = -struct - let ( *: ) = A.mul - let (+:) = A.add - let (-:) = A.sub - let (/:) = A.div - let (=:) x y = A.equal x y - let (<>:) x y = not (A.equal x y) - let (<:) x y = A.compare x y < 0 - let (>:) x y = A.compare x y > 0 - let (<=:) x y = A.compare x y <= 0 - let (>=:) x y = A.compare x y >= 0 - let of_int x = A.of_int x -end - (** High-level abstraction of a vector. *) module type Vector = sig @@ -650,11 +617,11 @@ module ArrayMatrix: AbstractMatrix = end - module SparseVector: AbstractVector = +module SparseVector: AbstractVector = functor (A: RatOps) -> struct include ConvenienceOps (A) - + type t = { entries: (int * A.t) list ; len: int @@ -662,15 +629,15 @@ module ArrayMatrix: AbstractMatrix = let show v = failwith "TODO" - + let keep_vals v n = let rec keep_vals_vec v n = - match v with - | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) - | [] -> [] + match v with + | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) + | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = keep_vals_vec v.entries n; len=n} + {entries = keep_vals_vec v.entries n; len=n} let remove_val v n = let dec_idx v = @@ -681,15 +648,15 @@ module ArrayMatrix: AbstractMatrix = | x::xs -> if fst x = n then dec_idx xs else if fst x > n then dec_idx (x::xs) else - x::(remove_val_vec xs n) + x::(remove_val_vec xs n) | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_val_vec v.entries n; len = v.len - 1} + {entries = remove_val_vec v.entries n; len = v.len - 1} let set_val v n m = failwith "TODO" - + let set_val_with v n m = failwith "TODO" @@ -710,7 +677,7 @@ module ArrayMatrix: AbstractMatrix = let length v = failwith "TODO" - + let map2 f v v' = failwith "TODO" @@ -742,7 +709,7 @@ module ArrayMatrix: AbstractMatrix = failwith "TODO" let exists f v = - failwith "TODO" + failwith "TODO" let rev v = failwith "TODO" @@ -770,7 +737,7 @@ module ArrayMatrix: AbstractMatrix = let of_array a = failwith "TODO" - + let copy v = v let of_sparse_list ls col_count = From 7141f97d9858188a51956de721e02520806dddcd Mon Sep 17 00:00:00 2001 From: Kevin Date: Thu, 14 Nov 2024 18:28:06 +0100 Subject: [PATCH 012/150] Implement normalize SparseMatrix --- src/cdomains/vectorMatrix.ml | 81 ++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 17 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 3da2707fe2..2c89f7fcd1 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -475,19 +475,19 @@ module ArrayMatrix: AbstractMatrix = for i = 0 to num_rows-1 do let exception Found in try ( - for j = i to num_cols -2 do + for j = i to num_cols -2 do (* Find pivot *) for k = i to num_rows -1 do if m.(k).(j) <>: A.zero then ( if k <> i then swap_rows k i; let piv = m.(i).(j) in - Array.iteri(fun j' x -> m.(i).(j') <- x /: piv) m.(i); - for l = 0 to num_rows-1 do + Array.iteri(fun j' x -> m.(i).(j') <- x /: piv) m.(i); (* Normalize pivot *) + for l = 0 to num_rows-1 do (* Subtract from each row *) if l <> i && m.(l).(j) <>: A.zero then ( let is_only_zero = ref true in let m_lj = m.(l).(j) in for k = 0 to num_cols - 2 do - m.(l).(k) <- m.(l).(k) -: m.(i).(k) *: m_lj /: m.(i).(j); + m.(l).(k) <- m.(l).(k) -: m.(i).(k) *: m_lj /: m.(i).(j); (* Subtraction *) if m.(l).(k) <>: A.zero then is_only_zero := false; done; let k_end = num_cols - 1 in @@ -650,11 +650,11 @@ module ArrayMatrix: AbstractMatrix = end - module SparseVector: AbstractVector = +module SparseVector: AbstractVector = functor (A: RatOps) -> struct include ConvenienceOps (A) - + type t = { entries: (int * A.t) list ; len: int @@ -662,15 +662,15 @@ module ArrayMatrix: AbstractMatrix = let show v = failwith "TODO" - + let keep_vals v n = let rec keep_vals_vec v n = - match v with - | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) - | [] -> [] + match v with + | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) + | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = keep_vals_vec v.entries n; len=n} + {entries = keep_vals_vec v.entries n; len=n} let remove_val v n = let dec_idx v = @@ -681,15 +681,15 @@ module ArrayMatrix: AbstractMatrix = | x::xs -> if fst x = n then dec_idx xs else if fst x > n then dec_idx (x::xs) else - x::(remove_val_vec xs n) + x::(remove_val_vec xs n) | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_val_vec v.entries n; len = v.len - 1} + {entries = remove_val_vec v.entries n; len = v.len - 1} let set_val v n m = failwith "TODO" - + let set_val_with v n m = failwith "TODO" @@ -710,7 +710,7 @@ module ArrayMatrix: AbstractMatrix = let length v = failwith "TODO" - + let map2 f v v' = failwith "TODO" @@ -742,7 +742,7 @@ module ArrayMatrix: AbstractMatrix = failwith "TODO" let exists f v = - failwith "TODO" + failwith "TODO" let rev v = failwith "TODO" @@ -770,7 +770,7 @@ module ArrayMatrix: AbstractMatrix = let of_array a = failwith "TODO" - + let copy v = v let of_sparse_list ls col_count = @@ -996,6 +996,53 @@ module SparseMatrix: AbstractMatrix = let normalize_with m = timing_wrap "normalize_with" normalize_with m let normalize m = + let entries = m.entries in + let col_count = m.column_count in + let swap_rows m r1_idx r2_idx = + List.mapi (fun i row -> + if i = r1_idx then List.nth m r2_idx + else if i = r2_idx then List.nth m r1_idx + else row + ) entries + in + let sub_rows row pivot_row : (int * A.t) list = + failwith "TODO" + in + let div_row row pivot = + List.map (fun (idx, value) -> (idx, value /: pivot)) row + in + let dec_mat_2D m = + m + in + let rec find_pivot_in_col m row_idx col_idx = + match m with + | ((idx, value)::_)::xs -> if idx = col_idx then Some (row_idx, value) else find_pivot_in_col xs (row_idx + 1) col_idx + | ([])::xs -> find_pivot_in_col xs (row_idx + 1) col_idx + | [] -> None + in + (* let rec find_pivot m col_idx row_idx = + if col_idx >= col_count then None else + match find_pivot_in_col m col_idx row_idx with + | Some (row_idx, value) -> Some (row_idx, value) + | None -> find_pivot m (col_idx + 1) row_idx + in *) + let rec main_loop m m' row_idx col_idx : (int * A.t) list list = + match find_pivot_in_col m' row_idx col_idx with + | None -> ( + if col_idx = (col_count - 1) + then m + else main_loop m m' row_idx (col_idx + 1) + ) + | Some (piv_row_idx, piv_val) -> ( + let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in + let m = List.map (fun row -> div_row row piv_val) m in + let piv_row = (List.nth m row_idx) in + let m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) m in + let m' = dec_mat_2D m in + failwith "TODO" + ) + + in failwith "TODO" let is_covered_by m1 m2 = From 7c2cb083bdb2b6eae2ac206d12c99bdc44b485f9 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 12 Nov 2024 19:07:36 +0100 Subject: [PATCH 013/150] sparseVector stumb --- src/cdomains/vectorMatrix.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 2c89f7fcd1..d71f29e926 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -672,6 +672,7 @@ module SparseVector: AbstractVector = if n >= v.len then v else (*could be left out but maybe performance??*) {entries = keep_vals_vec v.entries n; len=n} + let remove_val v n = let dec_idx v = List.map (fun (a,b) -> (a-1, b)) v @@ -681,15 +682,15 @@ module SparseVector: AbstractVector = | x::xs -> if fst x = n then dec_idx xs else if fst x > n then dec_idx (x::xs) else - x::(remove_val_vec xs n) + x::(remove_val_vec xs n) | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_val_vec v.entries n; len = v.len - 1} + {entries = remove_val_vec v.entries n; len = v.len - 1} let set_val v n m = failwith "TODO" - + let set_val_with v n m = failwith "TODO" @@ -711,7 +712,7 @@ module SparseVector: AbstractVector = let length v = failwith "TODO" - let map2 f v v' = + let map2 f v v' = failwith "TODO" let map2_with f v v' = From 37d1bc0ccc11316a6658795da6515f9a9503aa08 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 12 Nov 2024 18:32:24 +0100 Subject: [PATCH 014/150] Removed some _with functions from the AffineEqualityDomain --- .../apron/affineEqualityDomain.apron.ml | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 06268130b2..aa64b7f741 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -29,7 +29,7 @@ struct m else ( Array.modifyi (+) ch.dim; - let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col_with y x; y) m ch.dim else m in + let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col y x) m ch.dim else m in remove_zero_rows @@ del_cols m' ch.dim) let dim_remove ch m ~del = VectorMatrix.timing_wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del @@ -59,7 +59,7 @@ struct let open Apron.Texpr1 in let exception NotLinear in let zero_vec = Vector.zero_vec @@ Environment.size t.env + 1 in - let neg v = Vector.map_with Mpqf.neg v; v in + let neg v = Vector.map Mpqf.neg v in let is_const_vec v = Vector.compare_length_with (Vector.filteri (fun i x -> (*Inefficient*) Vector.compare_length_with v (i + 1) > 0 && x <>: Mpqf.zero) v) 1 = 0 in @@ -75,13 +75,13 @@ struct Vector.set_val zero_vec ((Vector.length zero_vec) - 1) (of_union x) | Var x -> let zero_vec_cp = Vector.copy zero_vec in - let entry_only v = Vector.set_val_with v (Environment.dim_of_var t.env x) Mpqf.one; v in + let entry_only v = Vector.set_val v (Environment.dim_of_var t.env x) Mpqf.one in begin match t.d with | Some m -> let row = Matrix.find_opt (fun r -> Vector.nth r (Environment.dim_of_var t.env x) =: Mpqf.one) m in begin match row with | Some v when is_const_vec v -> - Vector.set_val_with zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)); zero_vec_cp + Vector.set_val zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)) | _ -> entry_only zero_vec_cp end | None -> entry_only zero_vec_cp end @@ -91,17 +91,17 @@ struct | Binop (Add, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in - Vector.map2_with (+:) v1 v2; v1 + Vector.map2 (+:) v1 v2 | Binop (Sub, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in - Vector.map2_with (+:) v1 (neg @@ v2); v1 + Vector.map2 (+:) v1 (neg @@ v2) | Binop (Mul, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in begin match to_constant_opt v1, to_constant_opt v2 with - | _, Some c -> Vector.apply_with_c_with ( *:) c v1; v1 - | Some c, _ -> Vector.apply_with_c_with ( *:) c v2; v2 + | _, Some c -> Vector.apply_with_c ( *:) c v1 + | Some c, _ -> Vector.apply_with_c ( *:) c v2 | _, _ -> raise NotLinear end | Binop _ -> raise NotLinear @@ -294,18 +294,17 @@ struct (a, b, max) else ( - Vector.rev_with col_a; - Vector.rev_with col_b; + let col_a = Vector.rev col_a in + let col_b = Vector.rev col_b in let i = Vector.find2i (<>:) col_a col_b in let (x, y) = Vector.nth col_a i, Vector.nth col_b i in let r, diff = Vector.length col_a - (i + 1), x -: y in let a_r, b_r = Matrix.get_row a r, Matrix.get_row b r in - Vector.map2_with (-:) col_a col_b; - Vector.rev_with col_a; + let col_a = Vector.map2 (-:) col_a col_b in + let col_a = Vector.rev col_a in let multiply_by_t m t = - Matrix.map2i_with (fun i' x c -> if i' <= max then (let beta = c /: diff in - Vector.map2_with (fun u j -> u -: (beta *: j)) x t); x) m col_a; - m + Matrix.map2i (fun i' x c -> if i' <= max then (let beta = c /: diff in Vector.map2 (fun u j -> u -: (beta *: j)) x t) else x) m col_a; + in Matrix.remove_row (multiply_by_t a a_r) r, Matrix.remove_row (multiply_by_t b b_r) r, (max - 1) ) From 3e159ad5ee2ba7269d90a9b401496c2c1fdf2d13 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 14 Nov 2024 18:28:56 +0100 Subject: [PATCH 015/150] Some Vector Functions --- src/cdomains/vectorMatrix.ml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index d71f29e926..b1aff09538 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -689,8 +689,16 @@ module SparseVector: AbstractVector = {entries = remove_val_vec v.entries n; len = v.len - 1} let set_val v n m = - failwith "TODO" - + let rec set_val_vec v n m = + match v with + | x::xs -> if fst x = n then (n, m)::xs else + if fst x < n then x::(set_val_vec xs n m) + else v + | [] -> [] + in + if n >= v.len then failwith "Out of bounds" else + {entries=set_val_vec v.entries n m; len=v.len} + let set_val_with v n m = failwith "TODO" From 9acc346a2483b5a350afaae27d19beab9a862333 Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 15 Nov 2024 15:08:11 +0100 Subject: [PATCH 016/150] Implement some more SparseMatrix functions --- src/cdomains/vectorMatrix.ml | 58 ++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index b1aff09538..bd981b05ae 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -896,7 +896,7 @@ module SparseMatrix: AbstractMatrix = timing_wrap "get_col" (get_col m) n let set_col_with m new_col n = - failwith "TODO" + failwith "Do not use!" let set_col_with m new_col n = timing_wrap "set_col" (set_col_with m new_col) n @@ -915,12 +915,13 @@ module SparseMatrix: AbstractMatrix = {entries = new_entries; column_count = m.column_count} let append_matrices m1 m2 = - failwith "TODO" + let new_entries = List.append m1.entries m2.entries in + {entries = new_entries; column_count = m1.column_count} let equal m1 m2 = timing_wrap "equal" (equal m1) m2 let reduce_col_with m j = - failwith "TODO" + failwith "Do not use!" let reduce_col_with m j = timing_wrap "reduce_col_with" (reduce_col_with m) j let reduce_col m j = @@ -960,13 +961,26 @@ module SparseMatrix: AbstractMatrix = let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols let map2i f m v = - failwith "TODO" + let f' index row num = V.to_sparse_list @@ f index (V.of_sparse_list row m.column_count) num in + (* TODO: Do we need to consider different lengths here? + let vector_length = List.length (V.to_list v) in + let new_entries = + List.mapi (fun index row -> + if index < vector_length then + let num = V.nth v index in + f' index row num + else row + ) m.entries + in + *) + let new_entries = List.map2i f' m.entries (V.to_list v) in + {entries = new_entries; column_count = m.column_count} let remove_zero_rows m = failwith "TODO" let rref_with m = - failwith "TODO" + failwith "Do not use!" let rref_with m = timing_wrap "rref_with" rref_with m @@ -988,19 +1002,19 @@ module SparseMatrix: AbstractMatrix = (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) (*m must be in rref form and contain the same num of cols as v*) (*If m is empty then v is simply normalized and returned*) - failwith "TODO" + failwith "Do not use!" let rref_vec_with m v = timing_wrap "rref_vec_with" (rref_vec_with m) v let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - failwith "TODO" + failwith "Do not use!" let rref_matrix_with m1 m2 = timing_wrap "rref_matrix_with" (rref_matrix_with m1) m2 let normalize_with m = - failwith "TODO" + failwith "Do not use!" let normalize_with m = timing_wrap "normalize_with" normalize_with m @@ -1054,24 +1068,44 @@ module SparseMatrix: AbstractMatrix = in failwith "TODO" + let is_covered_by m1 m2 = failwith "TODO" let is_covered_by m1 m2 = timing_wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = - failwith "TODO" + let rec find_opt_vec_list f m = + match m with + | [] -> None + | x::xs -> if f x then Some x else find_opt_vec_list f xs + in + let m_vector = List.map (fun row -> V.of_sparse_list row m.column_count) m.entries in + find_opt_vec_list f m_vector let map2 f m v = - failwith "TODO" + let f' row num = V.to_sparse_list @@ f (V.of_sparse_list row m.column_count) num in + (* TODO: Do we need to consider different lengths here? + let vector_length = List.length (V.to_list v) in + let new_entries = + List.mapi (fun index row -> + if index < vector_length then + let num = V.nth v index in + f' row num + else row + ) m.entries + in + *) + let new_entries = List.map2 f' m.entries (V.to_list v) in + {entries = new_entries; column_count = m.column_count} let map2_with f m v = - failwith "TODO" + failwith "Do not use!" let map2_with f m v = timing_wrap "map2_with" (map2_with f m) v let map2i_with f m v = - failwith "TODO" + failwith "Do not use!" let map2i_with f m v = timing_wrap "map2i_with" (map2i_with f m) v end \ No newline at end of file From 128d3680f680b9186c38ab878ecda732f9ac183d Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Mon, 18 Nov 2024 16:38:15 +0100 Subject: [PATCH 017/150] added rref_vec und rref_matrix ohne _with --- src/cdomains/vectorMatrix.ml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index bd981b05ae..34524db06f 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -176,8 +176,12 @@ sig val normalize_with: t -> bool + val rref_vec: t -> vec -> t Option.t (* added to remove side effects in affineEqualityDomain*) + val rref_vec_with: t -> vec -> t Option.t + val rref_matrix: t -> t -> t Option.t (* this as well *) + val rref_matrix_with: t -> t -> t Option.t val find_opt: (vec -> bool) -> t -> vec option @@ -186,7 +190,7 @@ sig val map2_with: (vec -> num -> vec) -> t -> vec -> unit - val map2: (vec -> num -> vec) -> t -> vec -> t + val map2: (vec -> num -> vec) -> t -> vec -> t (* why is this here twice??*) val map2i: (int -> vec-> num -> vec) -> t -> vec -> t @@ -523,7 +527,7 @@ module ArrayMatrix: AbstractMatrix = let pivot_elements = Array.make (num_rows m) 0 in Array.iteri (fun i x -> pivot_elements.(i) <- Array.findi (fun z -> z =: A.one) x) m; pivot_elements - let rref_vec m pivot_positions v = + let rref_vec_helper m pivot_positions v = let insert = ref (-1) in for j = 0 to Array.length v -2 do if v.(j) <>: A.zero then @@ -561,10 +565,15 @@ module ArrayMatrix: AbstractMatrix = Array.iteri (fun j x -> v.(j) <- x /: v_i) v; Some (init_with_vec @@ V.of_array v) else let pivot_elements = get_pivot_positions m in - rref_vec m pivot_elements v + rref_vec_helper m pivot_elements v let rref_vec_with m v = timing_wrap "rref_vec_with" (rref_vec_with m) v + let rref_vec m v = (* !! There was another rref_vec function that has been renamed to rref_vec_helper !!*) + let m' = copy m in + let v' = V.copy v in + rref_vec_with m' v' + let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) @@ -574,7 +583,7 @@ module ArrayMatrix: AbstractMatrix = try ( for i = 0 to num_rows s_m - 1 do let pivot_elements = get_pivot_positions !b in - let res = rref_vec !b pivot_elements s_m.(i) in + let res = rref_vec_helper !b pivot_elements s_m.(i) in match res with | None -> raise Unsolvable | Some res -> b := res @@ -585,6 +594,11 @@ module ArrayMatrix: AbstractMatrix = let rref_matrix_with m1 m2 = timing_wrap "rref_matrix_with" (rref_matrix_with m1) m2 + let rref_matrix m1 m2 = + let m1' = copy m1 in + let m2' = copy m2 in + rref_matrix_with m1' m2' + let normalize_with m = rref_with m From 89588abeaa283c3bfc6c94003664625436d39a0a Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Mon, 18 Nov 2024 16:40:03 +0100 Subject: [PATCH 018/150] added new interface functions to sparsematrix --- src/cdomains/vectorMatrix.ml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 34524db06f..03ce545ef4 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -1020,6 +1020,8 @@ module SparseMatrix: AbstractMatrix = let rref_vec_with m v = timing_wrap "rref_vec_with" (rref_vec_with m) v + let rref_vec m v = failwith "TODO" + let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) @@ -1027,6 +1029,8 @@ module SparseMatrix: AbstractMatrix = let rref_matrix_with m1 m2 = timing_wrap "rref_matrix_with" (rref_matrix_with m1) m2 + let rref_matrix m1 m2 = failwith "TODO" + let normalize_with m = failwith "Do not use!" From d3477c0f3eebcf1e45528bb5c489b6ee079f6d75 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 19 Nov 2024 15:55:36 +0100 Subject: [PATCH 019/150] implemented reduce_col and remove_zero_rows and fixed some bugs --- src/cdomains/vectorMatrix.ml | 62 +++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 03ce545ef4..8e1bcf8a82 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -696,22 +696,22 @@ module SparseVector: AbstractVector = | x::xs -> if fst x = n then dec_idx xs else if fst x > n then dec_idx (x::xs) else - x::(remove_val_vec xs n) + x::(remove_val_vec xs n) | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_val_vec v.entries n; len = v.len - 1} + {entries = remove_val_vec v.entries n; len = v.len - 1} let set_val v n m = let rec set_val_vec v n m = match v with | x::xs -> if fst x = n then (n, m)::xs else - if fst x < n then x::(set_val_vec xs n m) - else v + if fst x < n then x::(set_val_vec xs n m) + else v | [] -> [] in - if n >= v.len then failwith "Out of bounds" else - {entries=set_val_vec v.entries n m; len=v.len} + if n >= v.len then failwith "Out of bounds" else + {entries=set_val_vec v.entries n m; len=v.len} let set_val_with v n m = failwith "TODO" @@ -734,7 +734,7 @@ module SparseVector: AbstractVector = let length v = failwith "TODO" - let map2 f v v' = + let map2 f v v' = failwith "TODO" let map2_with f v v' = @@ -821,7 +821,7 @@ module SparseMatrix: AbstractMatrix = } [@@deriving eq, ord, hash] let show x = - List.fold_left (^) " " (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) + List.fold_left (^) "" (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) let empty () = {entries = []; column_count = 0} @@ -880,7 +880,7 @@ module SparseMatrix: AbstractMatrix = timing_wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - {entries = m.entries @ [V.to_sparse_list row]; column_count = m.column_count} + {entries = m.entries @ [V.to_sparse_list row]; column_count = V.length row} let get_row m n = V.of_sparse_list (List.nth m.entries n) m.column_count @@ -939,7 +939,43 @@ module SparseMatrix: AbstractMatrix = let reduce_col_with m j = timing_wrap "reduce_col_with" (reduce_col_with m) j let reduce_col m j = - failwith "TODO" + if is_empty m then m + else + let rec find_pivot idx entries = (* Finds non-zero element in row j and return pair of row idx and the pivot value *) + match entries with + | [] -> None + | row :: rest -> match (List.assoc_opt j row) with + | None -> find_pivot (idx - 1) rest + | Some value -> Some (idx, value) + in + match (find_pivot (num_rows m - 1) (List.rev m.entries)) with + | None -> m (* column is already filled with zeroes *) + | Some (row_idx, pivot) -> + let pivot_row = List.nth m.entries row_idx in + let entries' = + List.mapi(fun idx row -> + if idx = row_idx then + [] + else + match (List.assoc_opt j row) with (* Find column element in row and, if it exists, subtract row *) + | None -> row + | Some row_value -> (let s = row_value /: pivot in + let rec merge acc piv_row cur_row = + match piv_row, cur_row with + | [], [] -> acc + | [], (i, value) :: rest -> merge ((i, value) :: acc) piv_row rest + | (i, value) :: rest, [] -> let new_value = A.zero -: s *: value in merge ((i, new_value) :: acc) rest cur_row + | (i, piv_val) :: piv_rest, (j, cur_val) :: cur_rest -> + if i = j then + let new_value = cur_val -: s *: piv_val in merge ((i, new_value) :: acc) piv_rest cur_rest + else if i < j then + let new_value = A.zero -: s *: piv_val in merge ((i, new_value) :: acc) piv_rest cur_row + else + merge ((j, cur_val) :: acc) piv_row cur_rest + in List.rev @@ merge [] pivot_row row) + ) m.entries + in + {entries = entries'; column_count = m.column_count} let del_col m j = if is_empty m then m else @@ -991,7 +1027,9 @@ module SparseMatrix: AbstractMatrix = {entries = new_entries; column_count = m.column_count} let remove_zero_rows m = - failwith "TODO" + let entries' = List.filter (fun row -> row <> []) m.entries in + if List.length entries' = 0 then empty() else + {entries = entries'; column_count = m.column_count} let rref_with m = failwith "Do not use!" @@ -1002,7 +1040,7 @@ module SparseMatrix: AbstractMatrix = failwith "TODO" - let reduce_col_with_vec m j v = + let reduce_col_with_vec m j v = failwith "TODO" let get_pivot_positions m = From 5a28e34242c084c3b27063c5f77c8b9f0ca97582 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 19 Nov 2024 16:30:47 +0100 Subject: [PATCH 020/150] matrix_normalize_stub --- src/cdomains/vectorMatrix.ml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index b1aff09538..5a4e48e4c2 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -1014,8 +1014,21 @@ module SparseMatrix: AbstractMatrix = else row ) entries in - let sub_rows row pivot_row : (int * A.t) list = - failwith "TODO" + let rec sub_rows minu subt : (int * A.t) list = + match (minu, subt) with + | ((xidx, xv)::xs, (yidx,yv)::ys) -> + if xidx = yidx && xv <> yv + then (xidx, xv -: yv)::(sub_rows xs ys) + else + if xidx < yidx + then (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) + else + if xidx > yidx + then (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) + else sub_rows xs ys + | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) + | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) + | ([],[]) -> [] in let div_row row pivot = List.map (fun (idx, value) -> (idx, value /: pivot)) row From 225c730f658cbaf0f7f389929bce517576d0d10a Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 19 Nov 2024 17:40:05 +0100 Subject: [PATCH 021/150] sexier sub function --- src/cdomains/vectorMatrix.ml | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 6d0be02274..bb992da3da 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -713,8 +713,8 @@ module SparseVector: AbstractVector = if n >= v.len then failwith "Out of bounds" else {entries=set_val_vec v.entries n m; len=v.len} - let set_val_with v n m = - failwith "TODO" + let set_val_with = + failwith "deprecated" let insert_val n m t = failwith "TODO" @@ -800,7 +800,7 @@ module SparseVector: AbstractVector = failwith "TODO" let to_sparse_list v = - failwith "TODO" + v.entries end @@ -1085,19 +1085,15 @@ module SparseMatrix: AbstractMatrix = ) entries in let rec sub_rows minu subt : (int * A.t) list = - match (minu, subt) with - | ((xidx, xv)::xs, (yidx,yv)::ys) -> - if xidx = yidx && xv <> yv - then (xidx, xv -: yv)::(sub_rows xs ys) - else - if xidx < yidx - then (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) - else - if xidx > yidx - then (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) - else sub_rows xs ys - | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) - | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) + match minu, subt with + | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( + match xidx - yidx with + | d when d = 0 && xv <> yv -> (xidx, xv -: yv)::(sub_rows xs ys) + | d when d < 0 -> (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) + | d when d > 0 -> (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) + | _ -> sub_rows xs ys ) (* remove row when is (0, 0) *) + | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) + | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) | ([],[]) -> [] in let div_row row pivot = From 420bde890ec3da76fea21bf81f6e4097ea6f6c6e Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 19 Nov 2024 18:13:42 +0100 Subject: [PATCH 022/150] toMatrix vec funcs --- src/cdomains/vectorMatrix.ml | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index bb992da3da..28b89156e9 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -718,6 +718,28 @@ module SparseVector: AbstractVector = let insert_val n m t = failwith "TODO" + + let mul_vec_scal v s = + {entries= (List.map (fun (idx, va) -> (idx, va *: s)) v.entries); len=v.len} + + let add_vec v1 v2 = + let rec add_vec m s = + match m, s with + | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( + match xidx - yidx with + | d when d = 0 && (xv +: yv = A.zero) -> (xidx, xv +: yv)::(add_vec xs ys) + | d when d < 0 -> (xidx, xv)::(add_vec xs ((yidx, yv)::ys)) + | d when d > 0 -> (yidx, yv)::(add_vec ((xidx, xv)::xs) ys) + | _ -> add_vec xs ys ) (* remove row when is (0, 0) *) + | ([], y::ys) -> y::(add_vec [] ys) + | (x::xs, []) -> x::(add_vec xs []) + | ([],[]) -> [] + in + if v1.len <> v2.len then failwith "Different Vector length" else + {entries= add_vec v1.entries v2.entries; len=v1.len} + + let sub_vec v1 v2 = (*change to duplicate def of add if performance*) + add_vec v1 ({entries= (List.map (fun (idx, va) -> (idx, A.zero -: va)) v2.entries); len=v2.len}) let apply_with_c f m v = failwith "TODO" @@ -820,6 +842,8 @@ module SparseMatrix: AbstractMatrix = column_count : int } [@@deriving eq, ord, hash] + let tM e l = {entries= e; column_count=l} + let show x = List.fold_left (^) "" (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) @@ -838,7 +862,7 @@ module SparseMatrix: AbstractMatrix = m.column_count let copy m = - {entries = m.entries; column_count = m.column_count} (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + m (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) let copy m = timing_wrap "copy" (copy) m @@ -874,7 +898,7 @@ module SparseMatrix: AbstractMatrix = match m with | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) | [] -> [] - in {entries = add_empty_columns_on_list m.entries colsL; column_count = m.column_count + Array.length cols} + in tM (add_empty_columns_on_list m.entries colsL) (m.column_count + Array.length cols) let add_empty_columns m (cols : int enumerable) = timing_wrap "add_empty_cols" (add_empty_columns m) cols From 4dbc81f98e527dceb5f312bd28681fe6d9e4189c Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 19 Nov 2024 18:20:11 +0100 Subject: [PATCH 023/150] toVector --- src/cdomains/vectorMatrix.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 28b89156e9..b57b908bc1 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -674,6 +674,7 @@ module SparseVector: AbstractVector = len: int }[@@deriving eq, ord, hash] + let tV e l = {entries=e; len=l} let show v = failwith "TODO" @@ -721,6 +722,7 @@ module SparseVector: AbstractVector = let mul_vec_scal v s = {entries= (List.map (fun (idx, va) -> (idx, va *: s)) v.entries); len=v.len} + let add_vec v1 v2 = let rec add_vec m s = From af2fc0fcd6657d7a6f59ec7434d62a6954a6be21 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 19 Nov 2024 21:13:25 +0100 Subject: [PATCH 024/150] Change of_sparse_list param order and continued normalize function --- src/cdomains/vectorMatrix.ml | 80 ++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index b57b908bc1..31b33348b8 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -121,7 +121,7 @@ sig val copy: t -> t - val of_sparse_list: (int * num) list -> int -> t + val of_sparse_list: int -> (int * num) list -> t val to_sparse_list: t -> (int * num) list @@ -302,7 +302,7 @@ module ArrayVector: AbstractVector = let copy = copy v in mapi_with f copy; copy - let of_sparse_list ls col_count = + let of_sparse_list col_count ls = let vec = Array.make col_count A.zero in List.iter (fun (idx, value) -> vec.(idx) <- value) ls; vec @@ -719,26 +719,26 @@ module SparseVector: AbstractVector = let insert_val n m t = failwith "TODO" - + let mul_vec_scal v s = {entries= (List.map (fun (idx, va) -> (idx, va *: s)) v.entries); len=v.len} - - + + let add_vec v1 v2 = let rec add_vec m s = - match m, s with + match m, s with | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( - match xidx - yidx with - | d when d = 0 && (xv +: yv = A.zero) -> (xidx, xv +: yv)::(add_vec xs ys) - | d when d < 0 -> (xidx, xv)::(add_vec xs ((yidx, yv)::ys)) - | d when d > 0 -> (yidx, yv)::(add_vec ((xidx, xv)::xs) ys) - | _ -> add_vec xs ys ) (* remove row when is (0, 0) *) + match xidx - yidx with + | d when d = 0 && (xv +: yv = A.zero) -> (xidx, xv +: yv)::(add_vec xs ys) + | d when d < 0 -> (xidx, xv)::(add_vec xs ((yidx, yv)::ys)) + | d when d > 0 -> (yidx, yv)::(add_vec ((xidx, xv)::xs) ys) + | _ -> add_vec xs ys ) (* remove row when is (0, 0) *) | ([], y::ys) -> y::(add_vec [] ys) | (x::xs, []) -> x::(add_vec xs []) | ([],[]) -> [] in - if v1.len <> v2.len then failwith "Different Vector length" else - {entries= add_vec v1.entries v2.entries; len=v1.len} + if v1.len <> v2.len then failwith "Different Vector length" else + {entries= add_vec v1.entries v2.entries; len=v1.len} let sub_vec v1 v2 = (*change to duplicate def of add if performance*) add_vec v1 ({entries= (List.map (fun (idx, va) -> (idx, A.zero -: va)) v2.entries); len=v2.len}) @@ -820,8 +820,8 @@ module SparseVector: AbstractVector = let copy v = v - let of_sparse_list ls col_count = - failwith "TODO" + let of_sparse_list col_count ls = + {entries = ls; len = col_count} let to_sparse_list v = v.entries @@ -847,7 +847,7 @@ module SparseMatrix: AbstractMatrix = let tM e l = {entries= e; column_count=l} let show x = - List.fold_left (^) "" (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) + List.fold_left (^) "" (List.map (fun row -> V.show @@ V.of_sparse_list x.column_count row) x.entries) let empty () = {entries = []; column_count = 0} @@ -909,7 +909,7 @@ module SparseMatrix: AbstractMatrix = {entries = m.entries @ [V.to_sparse_list row]; column_count = V.length row} let get_row m n = - V.of_sparse_list (List.nth m.entries n) m.column_count + V.of_sparse_list m.column_count (List.nth m.entries n) let remove_row m n = let rec aux idx entries = match idx, entries with @@ -1037,7 +1037,7 @@ module SparseMatrix: AbstractMatrix = let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols let map2i f m v = - let f' index row num = V.to_sparse_list @@ f index (V.of_sparse_list row m.column_count) num in + let f' index row num = V.to_sparse_list @@ f index (V.of_sparse_list m.column_count row) num in (* TODO: Do we need to consider different lengths here? let vector_length = List.length (V.to_list v) in let new_entries = @@ -1113,11 +1113,11 @@ module SparseMatrix: AbstractMatrix = let rec sub_rows minu subt : (int * A.t) list = match minu, subt with | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( - match xidx - yidx with - | d when d = 0 && xv <> yv -> (xidx, xv -: yv)::(sub_rows xs ys) - | d when d < 0 -> (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) - | d when d > 0 -> (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) - | _ -> sub_rows xs ys ) (* remove row when is (0, 0) *) + match xidx - yidx with + | d when d = 0 && xv <> yv -> (xidx, xv -: yv)::(sub_rows xs ys) + | d when d < 0 -> (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) + | d when d > 0 -> (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) + | _ -> sub_rows xs ys ) (* remove row when is (0, 0) *) | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) | ([],[]) -> [] @@ -1141,23 +1141,23 @@ module SparseMatrix: AbstractMatrix = | None -> find_pivot m (col_idx + 1) row_idx in *) let rec main_loop m m' row_idx col_idx : (int * A.t) list list = - match find_pivot_in_col m' row_idx col_idx with - | None -> ( - if col_idx = (col_count - 1) - then m - else main_loop m m' row_idx (col_idx + 1) - ) - | Some (piv_row_idx, piv_val) -> ( - let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in - let m = List.map (fun row -> div_row row piv_val) m in - let piv_row = (List.nth m row_idx) in - let m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) m in - let m' = dec_mat_2D m in - failwith "TODO" - ) + if col_idx = (col_count - 1) (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) + then m + else + match find_pivot_in_col m' row_idx col_idx with + | None -> main_loop m m' row_idx (col_idx + 1) + | Some (piv_row_idx, piv_val) -> ( + let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in + let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in + let piv_row = (List.nth normalized_m row_idx) in + let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in + let m' = dec_mat_2D m in + main_loop subtracted_m m' (row_idx + 1) (col_idx + 1) + ) in - failwith "TODO" + let e' = main_loop m.entries m.entries 0 0 in + Some {entries = e'; column_count = m.column_count} let is_covered_by m1 m2 = @@ -1171,11 +1171,11 @@ module SparseMatrix: AbstractMatrix = | [] -> None | x::xs -> if f x then Some x else find_opt_vec_list f xs in - let m_vector = List.map (fun row -> V.of_sparse_list row m.column_count) m.entries in + let m_vector = List.map (fun row -> V.of_sparse_list m.column_count row) m.entries in find_opt_vec_list f m_vector let map2 f m v = - let f' row num = V.to_sparse_list @@ f (V.of_sparse_list row m.column_count) num in + let f' row num = V.to_sparse_list @@ f (V.of_sparse_list m.column_count row) num in (* TODO: Do we need to consider different lengths here? let vector_length = List.length (V.to_list v) in let new_entries = From acf5851a89fcfbe878e08e58ae36297ad6f66ce9 Mon Sep 17 00:00:00 2001 From: Havercake Date: Wed, 20 Nov 2024 21:04:06 +0100 Subject: [PATCH 025/150] Split up vectorMatrix into multiple files; Removed VectorMatrix from goblint_lib.ml; Reintroduced Timing.wrap; --- .../apron/affineEqualityAnalysis.apron.ml | 5 +- .../affineEqualityMatrices/abstractMatrix.ml | 11 + .../affineEqualityMatrices/abstractVector.ml | 10 + .../arrayImplementation/arrayMatrix.ml | 341 ++++++ .../arrayImplementation/arrayVector.ml | 106 ++ .../convenienceOps.ml | 0 src/cdomains/affineEqualityMatrices/matrix.ml | 70 ++ .../ratOps.ml | 0 .../sparseImplementation/sparseMatrix.ml | 242 +++++ .../sparseImplementation/sparseVector.ml | 134 +++ src/cdomains/affineEqualityMatrices/vector.ml | 81 ++ .../apron/affineEqualityDomain.apron.ml | 41 +- .../apron/linearTwoVarEqualityDomain.apron.ml | 27 +- src/cdomains/apron/sharedFunctions.apron.ml | 15 +- src/cdomains/vectorMatrix.ml | 988 ------------------ src/goblint_lib.ml | 2 +- 16 files changed, 1044 insertions(+), 1029 deletions(-) create mode 100644 src/cdomains/affineEqualityMatrices/abstractMatrix.ml create mode 100644 src/cdomains/affineEqualityMatrices/abstractVector.ml create mode 100644 src/cdomains/affineEqualityMatrices/arrayImplementation/arrayMatrix.ml create mode 100644 src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml rename src/cdomains/{affineEquality => affineEqualityMatrices}/convenienceOps.ml (100%) create mode 100644 src/cdomains/affineEqualityMatrices/matrix.ml rename src/cdomains/{affineEquality => affineEqualityMatrices}/ratOps.ml (100%) create mode 100644 src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml create mode 100644 src/cdomains/affineEqualityMatrices/sparseImplementation/sparseVector.ml create mode 100644 src/cdomains/affineEqualityMatrices/vector.ml delete mode 100644 src/cdomains/vectorMatrix.ml diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index d4a1e5be2e..73ad59162f 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -4,11 +4,14 @@ open Analyses +open ArrayVector +open ArrayMatrix + include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( - let module AD = AffineEqualityDomain.D2 (VectorMatrix.ArrayVector) (VectorMatrix.ArrayMatrix) in + let module AD = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/affineEqualityMatrices/abstractMatrix.ml b/src/cdomains/affineEqualityMatrices/abstractMatrix.ml new file mode 100644 index 0000000000..64181c1a2b --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/abstractMatrix.ml @@ -0,0 +1,11 @@ +open RatOps +open AbstractVector +open Matrix + +(** Some functions inside have the suffix _with, which means that the function has side effects. *) +module type AbstractMatrix = + functor (A: RatOps) (V: AbstractVector) -> + sig + include Matrix with type vec := V(A).t and type num := A.t + end + diff --git a/src/cdomains/affineEqualityMatrices/abstractVector.ml b/src/cdomains/affineEqualityMatrices/abstractVector.ml new file mode 100644 index 0000000000..e5d7cd40e6 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/abstractVector.ml @@ -0,0 +1,10 @@ +open RatOps +open Vector + +(** Some functions inside have the suffix _with, which means that the function has side effects. *) +module type AbstractVector = + functor (A: RatOps) -> + sig + include Vector with type num:= A.t + end + diff --git a/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayMatrix.ml new file mode 100644 index 0000000000..882e897813 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayMatrix.ml @@ -0,0 +1,341 @@ +open AbstractVector +open RatOps +open ConvenienceOps +open AbstractMatrix + +open Batteries +module Array = Batteries.Array + +(** Array-based matrix implementation. + It provides a normalization function to reduce a matrix into reduced row echelon form. + Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) +module ArrayMatrix: AbstractMatrix = + functor (A: RatOps) (V: AbstractVector) -> + struct + include ConvenienceOps(A) + module V = V(A) + + type t = A.t array array [@@deriving eq, ord, hash] + + let show x = + Array.fold_left (^) "" (Array.map (fun v -> V.show @@ V.of_array v) x) + + let empty () = + Array.make_matrix 0 0 A.zero + + let num_rows m = + Array.length m + + let is_empty m = + (num_rows m = 0) + + let num_cols m = + if is_empty m then 0 else Array.length m.(0) + + let copy m = + let cp = Array.make_matrix (num_rows m) (num_cols m) A.zero in + Array.iteri (fun i x -> Array.blit x 0 cp.(i) 0 (num_cols m)) m; cp + + let copy m = Timing.wrap "copy" (copy) m + + let add_empty_columns m cols = + let nnc = Array.length cols in + if is_empty m || nnc = 0 then m else + let nr, nc = num_rows m, num_cols m in + let m' = Array.make_matrix nr (nc + nnc) A.zero in + for i = 0 to nr - 1 do + let offset = ref 0 in + for j = 0 to nc - 1 do + while !offset < nnc && !offset + j = cols.(!offset) do incr offset done; + m'.(i).(j + !offset) <- m.(i).(j); + done + done; + m' + + let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols + + let append_row m row = + let size = num_rows m in + let new_matrix = Array.make_matrix (size + 1) (num_cols m) A.zero in + for i = 0 to size - 1 do + new_matrix.(i) <- m.(i) + done; + new_matrix.(size) <- V.to_array row; + new_matrix + + let get_row m n = + V.of_array m.(n) + + let remove_row m n = + let new_matrix = Array.make_matrix (num_rows m - 1) (num_cols m) A.zero in + if not @@ is_empty new_matrix then + if n = 0 then + Array.blit m 1 new_matrix 0 (num_rows m - 1) + else + (Array.blit m 0 new_matrix 0 n; + if n <> (num_rows m - 1) then + Array.blit m (n + 1) new_matrix n (num_rows new_matrix - n)); new_matrix + + let get_col m n = + V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)) + + let get_col m n = Timing.wrap "get_col" (get_col m) n + + let set_col_with m new_col n = + for i = 0 to num_rows m - 1 do + m.(i).(n) <- V.nth new_col i + done; m + + let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n + + let set_col m new_col n = + let copy = copy m in + set_col_with copy new_col n + + let append_matrices m1 m2 = + Array.append m1 m2 + + let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 + + let reduce_col_with m j = + if not @@ is_empty m then + (let r = ref (-1) in + for i' = 0 to num_rows m - 1 do + let rev_i' = num_rows m - i' - 1 in + if !r < 0 && m.(rev_i').(j) <>: A.zero then r := rev_i'; + if !r <> rev_i' then + let g = m.(rev_i').(j) in + if g <>: A.zero then + let s = g /: m.(!r).(j) in + for j' = 0 to num_cols m - 1 do + m.(rev_i').(j') <- m.(rev_i').(j') -: s *: m.(!r).(j') + done + done; + if !r >= 0 then Array.fill m.(!r) 0 (num_cols m) A.zero) + + let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j + let reduce_col m j = + let copy = copy m in + reduce_col_with copy j; + copy + + let del_col m j = + if is_empty m then m else + let new_matrix = Array.make_matrix (num_rows m) (num_cols m - 1) A.zero in + for i = 0 to num_rows m - 1 do + new_matrix.(i) <- Array.remove_at j m.(i) + done; new_matrix + + let del_cols m cols = + let n_c = Array.length cols in + if n_c = 0 || is_empty m then m + else + let m_r, m_c = num_rows m, num_cols m in + if m_c = n_c then empty () else + let m' = Array.make_matrix m_r (m_c - n_c) A.zero in + for i = 0 to m_r - 1 do + let offset = ref 0 in + for j = 0 to (m_c - n_c) - 1 do + while !offset < n_c && !offset + j = cols.(!offset) do incr offset done; + m'.(i).(j) <- m.(i).(j + !offset); + done + done; + m' + + let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols + + let map2i f m v = + let f' x (i,y) = V.to_array @@ f i (V.of_array x) y in + let range_array = Array.init (V.length v) Fun.id in + Array.map2 f' m (Array.combine range_array (V.to_array v)) + + let remove_zero_rows m = + Array.filter (fun x -> Array.exists (fun y -> y <>: A.zero) x) m + + let rref_with m = + (*Based on Cousot - Principles of Abstract Interpretation (2021)*) + let swap_rows i1 i2 = + let tmp = m.(i1) in + m.(i1) <- m.(i2); + m.(i2) <- tmp; + in + let exception Unsolvable in + let num_rows = num_rows m in + let num_cols = num_cols m in + try ( + for i = 0 to num_rows-1 do + let exception Found in + try ( + for j = i to num_cols -2 do + for k = i to num_rows -1 do + if m.(k).(j) <>: A.zero then + ( + if k <> i then swap_rows k i; + let piv = m.(i).(j) in + Array.iteri(fun j' x -> m.(i).(j') <- x /: piv) m.(i); + for l = 0 to num_rows-1 do + if l <> i && m.(l).(j) <>: A.zero then ( + let is_only_zero = ref true in + let m_lj = m.(l).(j) in + for k = 0 to num_cols - 2 do + m.(l).(k) <- m.(l).(k) -: m.(i).(k) *: m_lj /: m.(i).(j); + if m.(l).(k) <>: A.zero then is_only_zero := false; + done; + let k_end = num_cols - 1 in + m.(l).(k_end) <- m.(l).(k_end) -: m.(i).(k_end) *: m_lj /: m.(i).(j); + if !is_only_zero && m.(l).(k_end) <>: A.zero then raise Unsolvable; + ) + done; + raise Found + ) + done; + done; + ) + with Found -> () + done; + true) + with Unsolvable -> false + + let rref_with m = Timing.wrap "rref_with" rref_with m + + let init_with_vec v = + let new_matrix = Array.make_matrix 1 (V.length v) A.zero in + new_matrix.(0) <- (V.to_array v); new_matrix + + + let reduce_col_with_vec m j v = + for i = 0 to num_rows m - 1 do + if m.(i).(j) <>: A.zero then + let beta = m.(i).(j) /: v.(j) in + Array.iteri (fun j' x -> m.(i).(j') <- x -: beta *: v.(j')) m.(i) + done + + let get_pivot_positions m = + let pivot_elements = Array.make (num_rows m) 0 + in Array.iteri (fun i x -> pivot_elements.(i) <- Array.findi (fun z -> z =: A.one) x) m; pivot_elements + + let rref_vec m pivot_positions v = + let insert = ref (-1) in + for j = 0 to Array.length v -2 do + if v.(j) <>: A.zero then + match Array.bsearch Int.ord pivot_positions j with + | `At i -> let beta = v.(j) /: m.(i).(j) in + Array.iteri (fun j' x -> v.(j') <- x -: beta *: m.(i).(j')) v + | _ -> if !insert < 0 then (let v_i = v.(j) in + Array.iteri (fun j' x -> v.(j') <- x /: v_i) v; insert := j; + reduce_col_with_vec m j v) + + done; + if !insert < 0 then ( + if v.(Array.length v - 1) <>: A.zero then None + else Some m + ) + else + let new_m = Array.make_matrix (num_rows m + 1) (num_cols m) A.zero + in let (i, j) = Array.pivot_split Int.ord pivot_positions !insert in + if i = 0 && j = 0 then (new_m.(0) <- v; Array.blit m 0 new_m 1 (num_rows m)) + else if i = num_rows m && j = num_rows m then (Array.blit m 0 new_m 0 j; new_m.(j) <- v) + else (Array.blit m 0 new_m 0 i; new_m.(i) <- v; Array.blit m i new_m (i + 1) (Array.length m - j)); + Some new_m + + + let rref_vec_with m v = + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) + (*m must be in rref form and contain the same num of cols as v*) + (*If m is empty then v is simply normalized and returned*) + let v = V.to_array v in + if is_empty m then + match Array.findi (fun x -> x <>: A.zero) v with + | exception Not_found -> None + | i -> if i = Array.length v - 1 then None else + let v_i = v.(i) in + Array.iteri (fun j x -> v.(j) <- x /: v_i) v; Some (init_with_vec @@ V.of_array v) + else + let pivot_elements = get_pivot_positions m in + rref_vec m pivot_elements v + + let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v + + let rref_matrix_with m1 m2 = + (*Similar to rref_vec_with but takes two matrices instead.*) + (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) + let b_m, s_m = if num_rows m1 > num_rows m2 then m1, m2 else m2, m1 in + let b = ref b_m in + let exception Unsolvable in + try ( + for i = 0 to num_rows s_m - 1 do + let pivot_elements = get_pivot_positions !b in + let res = rref_vec !b pivot_elements s_m.(i) in + match res with + | None -> raise Unsolvable + | Some res -> b := res + done; + Some !b + ) + with Unsolvable -> None + + let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 + + let normalize_with m = + rref_with m + + let normalize_with m = Timing.wrap "normalize_with" normalize_with m + + let normalize m = + let copy = copy m in + if normalize_with copy then + Some copy + else + None + + let is_covered_by m1 m2 = + (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) + (*Both input matrices must be in rref form!*) + if num_rows m1 > num_rows m2 then false else + let p2 = lazy (get_pivot_positions m2) in + try ( + for i = 0 to num_rows m1 - 1 do + if Array.exists2 (<>:) m1.(i) m2.(i) then + let m1_i = Array.copy m1.(i) in + for j = 0 to Array.length m1_i - 2 do + if m1_i.(j) <>: A.zero then + match Array.bsearch Int.ord (Lazy.force p2) j with + | `At pos -> let beta = m1_i.(j) in + Array.iteri (fun j' x -> m1_i.(j') <- m1_i.(j') -: beta *: m2.(pos).(j') ) m1_i + | _ -> raise Stdlib.Exit; + done; + if m1_i. (num_cols m1 - 1) <>: A.zero then + raise Stdlib.Exit + done; + true + ) + with Stdlib.Exit -> false;; + + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 + + let find_opt f m = + let f' x = f (V.of_array x) in Option.map V.of_array (Array.find_opt f' m) + + let map2 f m v = + let f' x y = V.to_array @@ f (V.of_array x) y in Array.map2 f' m (V.to_array v) + + let map2_with f m v = + if num_rows m = V.length v then + Array.iter2i (fun i x y -> m.(i) <- V.to_array @@ f (V.of_array x) y) m (V.to_array v) + else + for i = 0 to Stdlib.min (num_rows m) (V.length v) -1 do + m.(i) <- V.to_array @@ f (V.of_array m.(i)) (V.nth v i) + done + + let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v + + let map2i_with f m v = + if num_rows m = V.length v then + Array.iter2i (fun i x y -> m.(i) <- V.to_array @@ f i (V.of_array x) y) m (V.to_array v) + else + for i = 0 to Stdlib.min (num_rows m) (V.length v) -1 do + m.(i) <- V.to_array @@ f i (V.of_array m.(i)) (V.nth v i) + done + + let map2i_with f m v = Timing.wrap "map2i_with" (map2i_with f m) v + end \ No newline at end of file diff --git a/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml b/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml new file mode 100644 index 0000000000..ca79d90515 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml @@ -0,0 +1,106 @@ +open AbstractVector +open RatOps +open ConvenienceOps + +open Batteries +module Array = Batteries.Array + + +(** Array-based vector implementation. *) +module ArrayVector: AbstractVector = + functor (A: RatOps) -> + struct + include ConvenienceOps (A) + include Array + type t = A.t array [@@deriving eq, ord, hash] + + let show t = + let t = Array.to_list t in + let rec list_str l = + match l with + | [] -> "]" + | x :: xs -> (A.to_string x) ^" "^(list_str xs) + in + "["^list_str t^"\n" + + let keep_vals v n = + if n >= Array.length v then v else + Array.filteri (fun i x -> i < n) v (* TODO: take? *) + + let compare_length_with v len = + Int.compare (Array.length v) len + + let remove_val v n = + if n >= Array.length v then failwith "n outside of Array range" else + Array.init (Array.length v - 1) (fun i -> if i < n then Array.get v i else Array.get v (i + 1)) (* TODO: remove_at? *) + + let set_val_with v n new_val = + if n >= Array.length v then failwith "n outside of Array range" else + Array.set v n new_val + + let set_val v n new_val = + let copy = copy v in + set_val_with copy n new_val; copy + + let insert_val n new_val v = + if n > Array.length v then failwith "n too large" else + Array.init (Array.length v + 1) (fun i -> if i < n then Array.get v i else if i = n then new_val else Array.get v (i -1)) (* insert? *) + + let apply_with_c f c v = + Array.map (fun x -> f x c) v + + let zero_vec n = Array.make n A.zero + + let nth = Array.get + + let map2i f v1 v2 = + let f' i = uncurry (f i) in + Array.mapi f' (Array.combine v1 v2) (* TODO: iter2i? *) + + let map2i_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f i x y) v1 v2 + + let find2i f v1 v2 = + Array.findi (uncurry f) (Array.combine v1 v2) (* TODO: iter2i? *) + + let to_array v = v + + let of_array v = v + + let apply_with_c_with f c v = Array.modify (fun x -> f x c) v + + let rev_with v = Array.rev_in_place v + + let rev v = Array.rev v + + let map_with f v = Array.modify f v + + let map f v = Array.map f v + + let map2_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f x y) v1 v2 + + let map2 f v1 v2 = + let copy_v1 = copy v1 in + map2_with f copy_v1 v2; copy_v1 + + let copy v = Array.copy v + + let mapi_with f v = Array.iteri (fun i x -> v.(i) <- f i x) v + + let mapi f v = + let copy = copy v in + mapi_with f copy; copy + + let of_sparse_list ls col_count = + let vec = Array.make col_count A.zero in + List.iter (fun (idx, value) -> vec.(idx) <- value) ls; + vec + + let to_sparse_list v = + let rec aux idx acc = + if idx < 0 then acc + else + let value = v.(idx) in + let acc = if value <> A.zero then (idx, value):: acc else acc in + aux (idx - 1) acc + in aux (length v - 1) [] + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/convenienceOps.ml b/src/cdomains/affineEqualityMatrices/convenienceOps.ml similarity index 100% rename from src/cdomains/affineEquality/convenienceOps.ml rename to src/cdomains/affineEqualityMatrices/convenienceOps.ml diff --git a/src/cdomains/affineEqualityMatrices/matrix.ml b/src/cdomains/affineEqualityMatrices/matrix.ml new file mode 100644 index 0000000000..fac420c5a7 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/matrix.ml @@ -0,0 +1,70 @@ +(** High-level abstraction of a matrix. *) +module type Matrix = +sig + type num + type vec + type t [@@deriving eq, ord, hash] + + val empty: unit -> t (* TODO: needs unit? *) + + val is_empty: t -> bool + + val show: t -> string + + val add_empty_columns: t -> int array -> t + + val append_row: t -> vec -> t + + val get_row: t -> int -> vec + + val del_col: t -> int -> t + + val del_cols: t -> int array -> t + + val remove_row: t -> int -> t + + val get_col: t -> int -> vec + + val append_matrices: t -> t -> t + + val num_rows: t -> int + + val num_cols: t -> int + + val reduce_col: t -> int -> t + + val reduce_col_with: t -> int -> unit + + val normalize: t -> t Option.t (*Gauss-Jordan Elimination to get matrix in reduced row echelon form (rref) + deletion of zero rows. None matrix has no solution*) + + val normalize_with: t -> bool + + val rref_vec_with: t -> vec -> t Option.t + + val rref_matrix_with: t -> t -> t Option.t + + val find_opt: (vec -> bool) -> t -> vec option + + val map2: (vec -> num -> vec) -> t -> vec -> t + + val map2_with: (vec -> num -> vec) -> t -> vec -> unit + + val map2: (vec -> num -> vec) -> t -> vec -> t + + val map2i: (int -> vec-> num -> vec) -> t -> vec -> t + + val map2i_with: (int -> vec -> num -> vec) -> t -> vec -> unit + + val set_col: t -> vec -> int -> t + + val set_col_with: t -> vec -> int -> t + + val init_with_vec: vec -> t + + val remove_zero_rows: t -> t + + val is_covered_by: t -> t -> bool + + val copy: t -> t + +end \ No newline at end of file diff --git a/src/cdomains/affineEquality/ratOps.ml b/src/cdomains/affineEqualityMatrices/ratOps.ml similarity index 100% rename from src/cdomains/affineEquality/ratOps.ml rename to src/cdomains/affineEqualityMatrices/ratOps.ml diff --git a/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml new file mode 100644 index 0000000000..f17b0d5bc9 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml @@ -0,0 +1,242 @@ +open AbstractMatrix +open AbstractVector +open RatOps +open ConvenienceOps + +(** Sparse matrix implementation. + It provides a normalization function to reduce a matrix into reduced row echelon form. + Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) +module SparseMatrix: AbstractMatrix = + functor (A: RatOps) (V: AbstractVector) -> + struct + include ConvenienceOps(A) + module V = V(A) + + (* Array of arrays implementation. One array per row containing tuple of column index and value *) + type t = { + entries : (int * A.t) list list; + column_count : int + } [@@deriving eq, ord, hash] + + let show x = + List.fold_left (^) " " (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) + + let empty () = + {entries = []; column_count = 0} + + let num_rows m = + List.length m.entries + + let is_empty m = + num_rows m = 0 + (*This should be different if the implimentation is sound*) + (*m.column_count = 0*) + + let num_cols m = + m.column_count + + let copy m = + {entries = m.entries; column_count = m.column_count} (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + + let copy m = + Timing.wrap "copy" (copy) m + + let add_empty_columns m cols = + let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in + let emptyT = A.zero in + let rec list_of_all_before_index idx cols = + match cols with + | x::xs -> + if x < idx + then + let (h,t) = list_of_all_before_index idx xs in + (x::h, t) + else ([],x::xs) + | [] -> ([],[]) + in + (*This could easily be abstracted into the above functions, but its nice to have + it here for readability and debugging*) + let rec make_empty_entries_for_idxs idxs = + match idxs with + | x::xs -> (x, emptyT)::(make_empty_entries_for_idxs xs) + | [] -> [] + in + let rec add_column_element r cols = + match r with + | (idx, _)::xs -> + let (bef,aft) = list_of_all_before_index idx cols in + (make_empty_entries_for_idxs bef)@(add_column_element xs aft) + | [] -> [] + in + let rec add_empty_columns_on_list m cols = + match m with + | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) + | [] -> [] + in {entries = add_empty_columns_on_list m.entries colsL; column_count = m.column_count + Array.length cols} + + let add_empty_columns m cols = + Timing.wrap "add_empty_cols" (add_empty_columns m) cols + + let append_row m row = + {entries = m.entries @ [V.to_sparse_list row]; column_count = m.column_count} + + let get_row m n = + V.of_sparse_list (List.nth m.entries n) m.column_count + + let remove_row m n = + let rec aux idx entries = match idx, entries with + | i, x :: xs when i = n -> xs + | _, x :: xs -> x :: aux (idx + 1) xs + | _, _ -> failwith "trying to remove out of bounds row" + in + let new_entries = aux 0 m.entries in + let new_col_count = if new_entries = [] then 0 else m.column_count in + {entries = new_entries; column_count = new_col_count} + + let get_col m n = + (* Uses the fact that row is sorted to return Zero when index n is exceeded *) + let rec get_col_from_row row = + match row with + | [] -> A.zero + | (col_idx, value)::_ when col_idx = n -> value + | (col_idx, _)::_ when col_idx > n -> A.zero + | _::cs -> get_col_from_row cs + in + V.of_list @@ List.map (fun row -> get_col_from_row row ) m.entries + + let get_col m n = + Timing.wrap "get_col" (get_col m) n + + let set_col_with m new_col n = + failwith "TODO" + + let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n + + let set_col m new_col n = + let rec set_col_in_row row value = + match row with + | [] -> if value =: A.zero then [] else [(n, value)] + | (col_idx, v)::cs when col_idx > n -> if value =: A.zero then (col_idx, v)::cs else (n, value)::(col_idx, v)::cs + | (col_idx, v)::cs when col_idx = n -> if value =: A.zero then cs else (n, value)::cs + | (col_idx, v)::cs -> (col_idx, v)::(set_col_in_row cs value) + in + let new_entries = List.mapi (fun row_idx row -> + let value = V.nth new_col row_idx in + set_col_in_row row value + ) m.entries in + {entries = new_entries; column_count = m.column_count} + + let append_matrices m1 m2 = + failwith "TODO" + + let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 + + let reduce_col_with m j = + failwith "TODO" + + let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j + let reduce_col m j = + failwith "TODO" + + let del_col m j = + if is_empty m then m else + let del_col_from_row row = + List.filter_map (fun (col_idx, value) -> + if col_idx = j then + None + else if col_idx > j then + Some (col_idx - 1, value) + else + Some (col_idx, value) + ) row + in + let new_entries = List.map (fun row -> del_col_from_row row) m.entries in + {entries = new_entries; column_count = m.column_count - 1} + + (* TODO: Might be more efficient to check for each entry how much to reduce their index and not by recursively calling del_col *) + let del_cols m cols = + let cols = Array.to_list cols in (* TODO: Get away from Arrays *) + let to_delete_count = List.length cols in + if to_delete_count = 0 || is_empty m then m + else + if num_cols m = to_delete_count then empty () else + let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification)*) + let rec del_cols_aux m cols deleted_col_count = + match cols with + | [] -> m + | col_idx::cs -> + let m' = del_col m (col_idx - deleted_col_count) in (* Taking already deleted cols into account because of new index *) + del_cols_aux m' cs (deleted_col_count + 1) + in del_cols_aux m sorted_cols 0 + + let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols + + let map2i f m v = + failwith "TODO" + + let remove_zero_rows m = + failwith "TODO" + + let rref_with m = + failwith "TODO" + + let rref_with m = Timing.wrap "rref_with" rref_with m + + let init_with_vec v = + failwith "TODO" + + + let reduce_col_with_vec m j v = + failwith "TODO" + + let get_pivot_positions m = + failwith "TODO" + + let rref_vec m pivot_positions v = + failwith "TODO" + + + let rref_vec_with m v = + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) + (*m must be in rref form and contain the same num of cols as v*) + (*If m is empty then v is simply normalized and returned*) + failwith "TODO" + + let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v + + let rref_matrix_with m1 m2 = + (*Similar to rref_vec_with but takes two matrices instead.*) + (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) + failwith "TODO" + + let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 + + let normalize_with m = + failwith "TODO" + + let normalize_with m = Timing.wrap "normalize_with" normalize_with m + + let normalize m = + failwith "TODO" + + let is_covered_by m1 m2 = + failwith "TODO" + + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 + + let find_opt f m = + failwith "TODO" + + let map2 f m v = + failwith "TODO" + + let map2_with f m v = + failwith "TODO" + + let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v + + let map2i_with f m v = + failwith "TODO" + + let map2i_with f m v = Timing.wrap "map2i_with" (map2i_with f m) v + end \ No newline at end of file diff --git a/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseVector.ml b/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseVector.ml new file mode 100644 index 0000000000..7a2d579b23 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseVector.ml @@ -0,0 +1,134 @@ +open AbstractVector +open RatOps +open ConvenienceOps + +module SparseVector: AbstractVector = + functor (A: RatOps) -> + struct + include ConvenienceOps (A) + + type t = { + entries: (int * A.t) list ; + len: int + }[@@deriving eq, ord, hash] + + let show v = + failwith "TODO" + + let keep_vals v n = + let rec keep_vals_vec v n = + match v with + | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) + | [] -> [] + in + if n >= v.len then v else (*could be left out but maybe performance??*) + {entries = keep_vals_vec v.entries n; len=n} + + let remove_val v n = + let dec_idx v = + List.map (fun (a,b) -> (a-1, b)) v + in + let rec remove_val_vec v n = + match v with + | x::xs -> + if fst x = n then dec_idx xs else + if fst x > n then dec_idx (x::xs) else + x::(remove_val_vec xs n) + | [] -> [] + in + if n >= v.len then v else (*could be left out but maybe performance??*) + {entries = remove_val_vec v.entries n; len = v.len - 1} + + let set_val v n m = + failwith "TODO" + + let set_val_with v n m = + failwith "TODO" + + let insert_val n m t = + failwith "TODO" + + let apply_with_c f m v = + failwith "TODO" + + let apply_with_c_with f m v = + failwith "TODO" + + let zero_vec n = + failwith "TODO" + + let nth v n = + failwith "TODO" + + let length v = + failwith "TODO" + + let map2 f v v' = + failwith "TODO" + + let map2_with f v v' = + failwith "TODO" + + let findi f v = + failwith "TODO" + + let map f v = + failwith "TODO" + + let map_with f v = + failwith "TODO" + + let compare_length_with v n = + failwith "TODO" + + let of_list l = + failwith "TODO" + + let to_list v = + failwith "TODO" + + let filteri f v = + failwith "TODO" + + let append v v' = + failwith "TODO" + + let exists f v = + failwith "TODO" + + let rev v = + failwith "TODO" + + let rev_with v = + failwith "TODO" + + let map2i f v v' = + failwith "TODO" + + let map2i_with f v v' = + failwith "TODO" + + let mapi f v = + failwith "TODO" + + let mapi_with f v = + failwith "TODO" + + let find2i f v v' = + failwith "TODO" + + let to_array v = + failwith "TODO" + + let of_array a = + failwith "TODO" + + let copy v = v + + let of_sparse_list ls col_count = + failwith "TODO" + + let to_sparse_list v = + failwith "TODO" + + end \ No newline at end of file diff --git a/src/cdomains/affineEqualityMatrices/vector.ml b/src/cdomains/affineEqualityMatrices/vector.ml new file mode 100644 index 0000000000..8c9b8a4e33 --- /dev/null +++ b/src/cdomains/affineEqualityMatrices/vector.ml @@ -0,0 +1,81 @@ +(** High-level abstraction of a vector. *) +module type Vector = +sig + type num + type t [@@deriving eq, ord, hash] + + val show: t -> string + + val keep_vals: t -> int -> t + + val remove_val: t -> int -> t + + val set_val: t -> int -> num -> t + + val set_val_with: t -> int -> num -> unit + + val insert_val: int -> num -> t -> t + + val apply_with_c: (num -> num -> num) -> num -> t -> t + + val apply_with_c_with: (num -> num -> num) -> num -> t -> unit + + val zero_vec: int -> t + + val nth: t -> int -> num + + val length: t -> int + + val map2: (num -> num -> num) -> t -> t -> t + + val map2_with: (num -> num -> num) -> t -> t -> unit + + val findi: (num -> bool) -> t -> int + + val map: (num -> num) -> t -> t + + val map_with: (num -> num) -> t -> unit + + val map: (num -> num) -> t -> t + + val compare_length_with: t -> int -> int + + val of_list: num list -> t + + val to_list: t -> num list + + val filteri: (int -> num -> bool) -> t -> t + + val append: t -> t -> t + + val exists: (num -> bool) -> t -> bool + + val rev: t -> t + + val rev_with: t -> unit + + val rev: t -> t + + val map2i: (int -> num -> num -> num) -> t -> t -> t + + val map2i_with: (int -> num -> num -> num) -> t -> t -> unit + + val mapi: (int -> num -> num) -> t -> t + + val mapi_with: (int -> num -> num) -> t -> unit + + val mapi: (int -> num -> num) -> t -> t + + val find2i: (num -> num -> bool) -> t -> t -> int + + val to_array: t -> num array + + val of_array: num array -> t + + val copy: t -> t + + val of_sparse_list: (int * num) list -> int -> t + + val to_sparse_list: t -> (int * num) list + +end \ No newline at end of file diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 5850568e5b..531f914248 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -8,11 +8,16 @@ open GoblintCil open Pretty + module M = Messages open GobApron -open VectorMatrix open ConvenienceOps +open AbstractVector +open AbstractMatrix + +open Batteries +module Array = Batteries.Array module Mpqf = SharedFunctions.Mpqf @@ -23,7 +28,7 @@ struct Array.modifyi (+) ch.dim; add_empty_columns m ch.dim - let dim_add ch m = timing_wrap "dim add" (dim_add ch) m + let dim_add ch m = Timing.wrap "dim add" (dim_add ch) m let dim_remove (ch: Apron.Dim.change) m ~del = @@ -34,7 +39,7 @@ struct let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col_with y x; y) m ch.dim else m in remove_zero_rows @@ del_cols m' ch.dim) - let dim_remove ch m ~del = VectorMatrix.timing_wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del + let dim_remove ch m ~del = Timing.wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del end (** It defines the type t of the affine equality domain (a struct that contains an optional matrix and an apron environment) and provides the functions needed for handling variables (which are defined by RelationDomain.D2) such as add_vars remove_vars. @@ -112,7 +117,7 @@ struct Some (convert_texpr texp) with NotLinear -> None - let get_coeff_vec t texp = timing_wrap "coeff_vec" (get_coeff_vec t) texp + let get_coeff_vec t texp = Timing.wrap "coeff_vec" (get_coeff_vec t) texp end (** As it is specifically used for the new affine equality domain, it can only provide bounds if the expression contains known constants only and in that case, min and max are the same. *) @@ -139,7 +144,7 @@ struct res - let bound_texpr d texpr1 = timing_wrap "bounds calculation" (bound_texpr d) texpr1 + let bound_texpr d texpr1 = Timing.wrap "bounds calculation" (bound_texpr d) texpr1 end module D(Vc: AbstractVector) (Mx: AbstractMatrix) = @@ -194,7 +199,7 @@ struct in let res = (String.concat "" @@ Array.to_list @@ Array.map dim_to_str vars) ^ (const_to_str arr.(Array.length arr - 1)) ^ "=0" in - if String.starts_with res ~prefix:"+" then + if String.starts_with res "+" then Str.string_after res 1 else res @@ -254,7 +259,7 @@ struct if M.tracing then M.tracel "meet" "meet a: %s b: %s -> %s " (show t1) (show t2) (show res) ; res - let meet t1 t2 = timing_wrap "meet" (meet t1) t2 + let meet t1 t2 = Timing.wrap "meet" (meet t1) t2 let leq t1 t2 = let env_comp = Environment.cmp t1.env t2.env in (* Apron's Environment.cmp has defined return values. *) @@ -273,7 +278,7 @@ struct let m1' = if env_comp = 0 then m1 else dim_add (Environment.dimchange t1.env t2.env) m1 in Matrix.is_covered_by m2 m1' - let leq a b = timing_wrap "leq" (leq a) b + let leq a b = Timing.wrap "leq" (leq a) b let leq t1 t2 = let res = leq t1 t2 in @@ -342,7 +347,7 @@ struct | x, y when Matrix.equal x y -> {d = Some x; env = a.env} | x, y -> {d = Some(lin_disjunc 0 0 (Matrix.copy x) (Matrix.copy y)); env = a.env} - let join a b = timing_wrap "join" (join a) b + let join a b = Timing.wrap "join" (join a) b let join a b = let res = join a b in @@ -367,7 +372,7 @@ struct else Matrix.reduce_col x j0 - let remove_rels_with_var x var env inplace = timing_wrap "remove_rels_with_var" (remove_rels_with_var x var env) inplace + let remove_rels_with_var x var env inplace = Timing.wrap "remove_rels_with_var" (remove_rels_with_var x var env) inplace let forget_vars t vars = if is_bot t || is_top_env t || vars = [] then @@ -382,7 +387,7 @@ struct if M.tracing then M.tracel "ops" "forget_vars %s -> %s" (show t) (show res); res - let forget_vars t vars = timing_wrap "forget_vars" (forget_vars t) vars + let forget_vars t vars = Timing.wrap "forget_vars" (forget_vars t) vars let assign_texpr (t: VarManagement(Vc)(Mx).t) var texp = let assign_invertible_rels x var b env = @@ -398,7 +403,7 @@ struct recalc_entries x a_j0; if Matrix.normalize_with x then {d = Some x; env = env} else bot () in - let assign_invertible_rels x var b env = timing_wrap "assign_invertible" (assign_invertible_rels x var b) env in + let assign_invertible_rels x var b env = Timing.wrap "assign_invertible" (assign_invertible_rels x var b) env in let assign_uninvertible_rel x var b env = let b_length = Vector.length b in Vector.mapi_with (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b; @@ -407,7 +412,7 @@ struct if Option.is_none opt_m then bot () else {d = opt_m; env = env} in - (* let assign_uninvertible_rel x var b env = timing_wrap "assign_uninvertible" (assign_uninvertible_rel x var b) env in *) + (* let assign_uninvertible_rel x var b env = Timing.wrap "assign_uninvertible" (assign_uninvertible_rel x var b) env in *) let is_invertible v = Vector.nth v @@ Environment.dim_of_var t.env var <>: Mpqf.zero in let affineEq_vec = get_coeff_vec t texp in if is_bot t then t else let m = Option.get t.d in @@ -418,7 +423,7 @@ struct in assign_uninvertible_rel new_m var v t.env | None -> {d = Some (Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env false); env = t.env} - let assign_texpr t var texp = timing_wrap "assign_texpr" (assign_texpr t var) texp + let assign_texpr t var texp = Timing.wrap "assign_texpr" (assign_texpr t var) texp let assign_exp ask (t: VarManagement(Vc)(Mx).t) var exp (no_ov: bool Lazy.t) = let t = if not @@ Environment.mem_var t.env var then add_vars t [var] else t in @@ -472,7 +477,7 @@ struct if M.tracing then M.tracel "ops" "assign_var parallel: %s -> %s " (show t) (show res); res - let assign_var_parallel t vv's = timing_wrap "var_parallel" (assign_var_parallel t) vv's + let assign_var_parallel t vv's = Timing.wrap "var_parallel" (assign_var_parallel t) vv's let assign_var_parallel_with t vv's = let t' = assign_var_parallel t vv's in @@ -502,7 +507,7 @@ struct if M.tracing then M.tracel "ops" "Substitute_expr t: \n %s \n var: %a \n exp: %a \n -> \n %s" (show t) Var.pretty var d_exp exp (show res); res - let substitute_exp ask t var exp no_ov = timing_wrap "substitution" (substitute_exp ask t var exp) no_ov + let substitute_exp ask t var exp no_ov = Timing.wrap "substitution" (substitute_exp ask t var exp) no_ov (** Assert a constraint expression. @@ -547,7 +552,7 @@ struct end | None -> t - let meet_tcons t tcons expr = timing_wrap "meet_tcons" (meet_tcons t tcons) expr + let meet_tcons t tcons expr = Timing.wrap "meet_tcons" (meet_tcons t tcons) expr let unify a b = meet a b @@ -563,7 +568,7 @@ struct | tcons1 -> meet_tcons ask d tcons1 e | exception Convert.Unsupported_CilExp _ -> d - let assert_constraint ask d e negate no_ov = timing_wrap "assert_constraint" (assert_constraint ask d e negate) no_ov + let assert_constraint ask d e negate no_ov = Timing.wrap "assert_constraint" (assert_constraint ask d e negate) no_ov let relift t = t diff --git a/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml b/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml index 62118a9134..72f24610c6 100644 --- a/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml +++ b/src/cdomains/apron/linearTwoVarEqualityDomain.apron.ml @@ -13,7 +13,6 @@ open Pretty module M = Messages open GobApron -open VectorMatrix open ConvenienceOps module Mpqf = SharedFunctions.Mpqf @@ -175,7 +174,7 @@ module EqualitiesConjunction = struct let dim_add (ch: Apron.Dim.change) m = modify_variables_in_domain m ch.dim (+) - let dim_add ch m = timing_wrap "dim add" (dim_add ch) m + let dim_add ch m = Timing.wrap "dim add" (dim_add ch) m let dim_remove (ch: Apron.Dim.change) m = if Array.length ch.dim = 0 || is_empty m then @@ -186,7 +185,7 @@ module EqualitiesConjunction = struct let m' = Array.fold_lefti (fun y i x -> forget_variable y (x)) m cpy in (* clear m' from relations concerning ch.dim *) modify_variables_in_domain m' cpy (-)) - let dim_remove ch m = VectorMatrix.timing_wrap "dim remove" (fun m -> dim_remove ch m) m + let dim_remove ch m = Timing.wrap "dim remove" (fun m -> dim_remove ch m) m let dim_remove ch m ~del = let res = dim_remove ch m in if M.tracing then M.tracel "dim_remove" "dim remove at positions [%s] in { %s } -> { %s }" @@ -345,7 +344,7 @@ struct | [(coeff,var,divi)] -> Some (Rhs.canonicalize (Some (Z.mul divisor coeff,var), Z.mul constant divi,Z.mul divisor divi)) |_ -> None)) - let simplify_to_ref_and_offset t texp = timing_wrap "coeff_vec" (simplify_to_ref_and_offset t) texp + let simplify_to_ref_and_offset t texp = Timing.wrap "coeff_vec" (simplify_to_ref_and_offset t) texp let assign_const t var const divi = match t.d with | None -> t @@ -367,7 +366,7 @@ struct Some res, Some res) | _ -> None, None - let bound_texpr d texpr1 = timing_wrap "bounds calculation" (bound_texpr d) texpr1 + let bound_texpr d texpr1 = Timing.wrap "bounds calculation" (bound_texpr d) texpr1 end module D = @@ -458,7 +457,7 @@ struct if M.tracing then M.tracel "meet" "meet a: %s\n U \n b: %s \n -> %s" (show t1) (show t2) (show res) ; res - let meet t1 t2 = timing_wrap "meet" (meet t1) t2 + let meet t1 t2 = Timing.wrap "meet" (meet t1) t2 let leq t1 t2 = let env_comp = Environment.cmp t1.env t2.env in (* Apron's Environment.cmp has defined return values. *) @@ -477,7 +476,7 @@ struct let m1' = if env_comp = 0 then m1 else VarManagement.dim_add (Environment.dimchange t1.env t2.env) m1 in EConj.IntMap.for_all (implies m1') (snd m2) (* even on sparse m2, it suffices to check the non-trivial equalities, still present in sparse m2 *) - let leq a b = timing_wrap "leq" (leq a) b + let leq a b = Timing.wrap "leq" (leq a) b let leq t1 t2 = let res = leq t1 t2 in @@ -553,7 +552,7 @@ struct | Some x, Some y when EConj.equal x y -> {d = Some x; env = a.env} | Some x, Some y -> {d = join_d x y; env = a.env} - let join a b = timing_wrap "join" (join a) b + let join a b = Timing.wrap "join" (join a) b let join a b = let res = join a b in @@ -595,7 +594,7 @@ struct if M.tracing then M.tracel "ops" "forget_vars %s -> %s" (show t) (show res); res - let forget_vars t vars = timing_wrap "forget_vars" (forget_vars t) vars + let forget_vars t vars = Timing.wrap "forget_vars" (forget_vars t) vars (** implemented as described on page 10 in the paper about Fast Interprocedural Linear Two-Variable Equalities in the Section "Abstract Effect of Statements" This makes a copy of the data structure, it doesn't change it in-place. *) @@ -619,7 +618,7 @@ struct end | None -> bot_env - let assign_texpr t var texp = timing_wrap "assign_texpr" (assign_texpr t var) texp + let assign_texpr t var texp = Timing.wrap "assign_texpr" (assign_texpr t var) texp (* no_ov -> no overflow if it's true then there is no overflow @@ -666,7 +665,7 @@ struct if M.tracing then M.tracel "ops" "assign_var parallel: %s -> %s" (show t) (show res); res - let assign_var_parallel t vv's = timing_wrap "var_parallel" (assign_var_parallel t) vv's + let assign_var_parallel t vv's = Timing.wrap "var_parallel" (assign_var_parallel t) vv's let assign_var_parallel_with t vv's = (* TODO: If we are angling for more performance, this might be a good place ot try. `assign_var_parallel_with` is used whenever a function is entered (body), @@ -698,7 +697,7 @@ struct if M.tracing then M.tracel "ops" "Substitute_expr t: \n %s \n var: %a \n exp: %a \n -> \n %s" (show t) Var.pretty var d_exp exp (show res); res - let substitute_exp ask t var exp no_ov = timing_wrap "substitution" (substitute_exp ask t var exp) no_ov + let substitute_exp ask t var exp no_ov = Timing.wrap "substitution" (substitute_exp ask t var exp) no_ov (** Assert a constraint expression. @@ -753,7 +752,7 @@ struct if M.tracing then M.tracel "meet_tcons" "meet_tcons with expr: %a no_ov:%b" d_exp original_expr (Lazy.force no_ov); meet_tcons ask t tcons original_expr no_ov - let meet_tcons t tcons expr = timing_wrap "meet_tcons" (meet_tcons t tcons) expr + let meet_tcons t tcons expr = Timing.wrap "meet_tcons" (meet_tcons t tcons) expr let unify a b = meet a b @@ -779,7 +778,7 @@ struct | tcons1 -> meet_tcons ask d tcons1 e no_ov | exception Convert.Unsupported_CilExp _ -> d - let assert_constraint ask d e negate no_ov = timing_wrap "assert_constraint" (assert_constraint ask d e negate) no_ov + let assert_constraint ask d e negate no_ov = Timing.wrap "assert_constraint" (assert_constraint ask d e negate) no_ov let relift t = t diff --git a/src/cdomains/apron/sharedFunctions.apron.ml b/src/cdomains/apron/sharedFunctions.apron.ml index 86b5f2770f..bda88a3f62 100644 --- a/src/cdomains/apron/sharedFunctions.apron.ml +++ b/src/cdomains/apron/sharedFunctions.apron.ml @@ -4,6 +4,7 @@ open Batteries open GobApron + module M = Messages @@ -402,7 +403,7 @@ struct in {d = Some (if add then RelDomain.dim_add dim_change m else RelDomain.dim_remove dim_change m ~del:del); env = new_env} - let change_d t new_env ~add ~del = VectorMatrix.timing_wrap "dimension change" (fun del -> change_d t new_env ~add:add ~del:del) del + let change_d t new_env ~add ~del = Timing.wrap "dimension change" (fun del -> change_d t new_env ~add:add ~del:del) del let vars x = Environment.ivars_only x.env @@ -411,18 +412,18 @@ struct let env' = Environment.add_vars t.env vars in change_d t env' ~add:true ~del:false - let add_vars t vars = VectorMatrix.timing_wrap "add_vars" (add_vars t) vars + let add_vars t vars = Timing.wrap "add_vars" (add_vars t) vars let drop_vars t vars ~del = let t = copy t in let env' = Environment.remove_vars t.env vars in change_d t env' ~add:false ~del:del - let drop_vars t vars = VectorMatrix.timing_wrap "drop_vars" (drop_vars t) vars + let drop_vars t vars = Timing.wrap "drop_vars" (drop_vars t) vars let remove_vars t vars = drop_vars t vars ~del:false - let remove_vars t vars = VectorMatrix.timing_wrap "remove_vars" (remove_vars t) vars + let remove_vars t vars = Timing.wrap "remove_vars" (remove_vars t) vars let remove_vars_with t vars = let t' = remove_vars t vars in @@ -433,7 +434,7 @@ struct let env' = Environment.remove_filter t.env f in change_d t env' ~add:false ~del:false - let remove_filter t f = VectorMatrix.timing_wrap "remove_filter" (remove_filter t) f + let remove_filter t f = Timing.wrap "remove_filter" (remove_filter t) f let remove_filter_with t f = let t' = remove_filter t f in @@ -445,14 +446,14 @@ struct let env' = Environment.keep_filter t.env f in change_d t env' ~add:false ~del:false - let keep_filter t f = VectorMatrix.timing_wrap "keep_filter" (keep_filter t) f + let keep_filter t f = Timing.wrap "keep_filter" (keep_filter t) f let keep_vars t vs = let t = copy t in let env' = Environment.keep_vars t.env vs in change_d t env' ~add:false ~del:false - let keep_vars t vs = VectorMatrix.timing_wrap "keep_vars" (keep_vars t) vs + let keep_vars t vs = Timing.wrap "keep_vars" (keep_vars t) vs let mem_var t var = Environment.mem_var t.env var diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml deleted file mode 100644 index b1fa41fb5e..0000000000 --- a/src/cdomains/vectorMatrix.ml +++ /dev/null @@ -1,988 +0,0 @@ -(** OCaml implementations of vectors and matrices. *) - -open Batteries -module Array = Batteries.Array -module M = Messages - -open RatOps -open ConvenienceOps - -(* let timing_wrap = Timing.wrap *) -(* Disable timing of VectorMatrix and AffineEqualityDomain. - This is cleaner than a timing functor because the timed functions also call each other. *) -let timing_wrap _ f x = f x - -(** High-level abstraction of a vector. *) -module type Vector = -sig - type num - type t [@@deriving eq, ord, hash] - - val show: t -> string - - val keep_vals: t -> int -> t - - val remove_val: t -> int -> t - - val set_val: t -> int -> num -> t - - val set_val_with: t -> int -> num -> unit - - val insert_val: int -> num -> t -> t - - val apply_with_c: (num -> num -> num) -> num -> t -> t - - val apply_with_c_with: (num -> num -> num) -> num -> t -> unit - - val zero_vec: int -> t - - val nth: t -> int -> num - - val length: t -> int - - val map2: (num -> num -> num) -> t -> t -> t - - val map2_with: (num -> num -> num) -> t -> t -> unit - - val findi: (num -> bool) -> t -> int - - val map: (num -> num) -> t -> t - - val map_with: (num -> num) -> t -> unit - - val map: (num -> num) -> t -> t - - val compare_length_with: t -> int -> int - - val of_list: num list -> t - - val to_list: t -> num list - - val filteri: (int -> num -> bool) -> t -> t - - val append: t -> t -> t - - val exists: (num -> bool) -> t -> bool - - val rev: t -> t - - val rev_with: t -> unit - - val rev: t -> t - - val map2i: (int -> num -> num -> num) -> t -> t -> t - - val map2i_with: (int -> num -> num -> num) -> t -> t -> unit - - val mapi: (int -> num -> num) -> t -> t - - val mapi_with: (int -> num -> num) -> t -> unit - - val mapi: (int -> num -> num) -> t -> t - - val find2i: (num -> num -> bool) -> t -> t -> int - - val to_array: t -> num array - - val of_array: num array -> t - - val copy: t -> t - - val of_sparse_list: (int * num) list -> int -> t - - val to_sparse_list: t -> (int * num) list - -end - -(** Some functions inside have the suffix _with, which means that the function has side effects. *) -module type AbstractVector = - functor (A: RatOps) -> - sig - include Vector with type num:= A.t - end - - -(** High-level abstraction of a matrix. *) -module type Matrix = -sig - type num - type vec - type t [@@deriving eq, ord, hash] - - val empty: unit -> t (* TODO: needs unit? *) - - val is_empty: t -> bool - - val show: t -> string - - val add_empty_columns: t -> int array -> t - - val append_row: t -> vec -> t - - val get_row: t -> int -> vec - - val del_col: t -> int -> t - - val del_cols: t -> int array -> t - - val remove_row: t -> int -> t - - val get_col: t -> int -> vec - - val append_matrices: t -> t -> t - - val num_rows: t -> int - - val num_cols: t -> int - - val reduce_col: t -> int -> t - - val reduce_col_with: t -> int -> unit - - val normalize: t -> t Option.t (*Gauss-Jordan Elimination to get matrix in reduced row echelon form (rref) + deletion of zero rows. None matrix has no solution*) - - val normalize_with: t -> bool - - val rref_vec_with: t -> vec -> t Option.t - - val rref_matrix_with: t -> t -> t Option.t - - val find_opt: (vec -> bool) -> t -> vec option - - val map2: (vec -> num -> vec) -> t -> vec -> t - - val map2_with: (vec -> num -> vec) -> t -> vec -> unit - - val map2: (vec -> num -> vec) -> t -> vec -> t - - val map2i: (int -> vec-> num -> vec) -> t -> vec -> t - - val map2i_with: (int -> vec -> num -> vec) -> t -> vec -> unit - - val set_col: t -> vec -> int -> t - - val set_col_with: t -> vec -> int -> t - - val init_with_vec: vec -> t - - val remove_zero_rows: t -> t - - val is_covered_by: t -> t -> bool - - val copy: t -> t - -end - -(** Some functions inside have the suffix _with, which means that the function has side effects. *) -module type AbstractMatrix = - functor (A: RatOps) (V: AbstractVector) -> - sig - include Matrix with type vec := V(A).t and type num := A.t - end - - -(** Array-based vector implementation. *) -module ArrayVector: AbstractVector = - functor (A: RatOps) -> - struct - include ConvenienceOps (A) - include Array - type t = A.t array [@@deriving eq, ord, hash] - - let show t = - let t = Array.to_list t in - let rec list_str l = - match l with - | [] -> "]" - | x :: xs -> (A.to_string x) ^" "^(list_str xs) - in - "["^list_str t^"\n" - - let keep_vals v n = - if n >= Array.length v then v else - Array.filteri (fun i x -> i < n) v (* TODO: take? *) - - let compare_length_with v len = - Int.compare (Array.length v) len - - let remove_val v n = - if n >= Array.length v then failwith "n outside of Array range" else - Array.init (Array.length v - 1) (fun i -> if i < n then Array.get v i else Array.get v (i + 1)) (* TODO: remove_at? *) - - let set_val_with v n new_val = - if n >= Array.length v then failwith "n outside of Array range" else - Array.set v n new_val - - let set_val v n new_val = - let copy = copy v in - set_val_with copy n new_val; copy - - let insert_val n new_val v = - if n > Array.length v then failwith "n too large" else - Array.init (Array.length v + 1) (fun i -> if i < n then Array.get v i else if i = n then new_val else Array.get v (i -1)) (* insert? *) - - let apply_with_c f c v = - Array.map (fun x -> f x c) v - - let zero_vec n = Array.make n A.zero - - let nth = Array.get - - let map2i f v1 v2 = - let f' i = uncurry (f i) in - Array.mapi f' (Array.combine v1 v2) (* TODO: iter2i? *) - - let map2i_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f i x y) v1 v2 - - let find2i f v1 v2 = - Array.findi (uncurry f) (Array.combine v1 v2) (* TODO: iter2i? *) - - let to_array v = v - - let of_array v = v - - let apply_with_c_with f c v = Array.modify (fun x -> f x c) v - - let rev_with v = Array.rev_in_place v - - let rev v = Array.rev v - - let map_with f v = Array.modify f v - - let map f v = Array.map f v - - let map2_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f x y) v1 v2 - - let map2 f v1 v2 = - let copy_v1 = copy v1 in - map2_with f copy_v1 v2; copy_v1 - - let copy v = Array.copy v - - let mapi_with f v = Array.iteri (fun i x -> v.(i) <- f i x) v - - let mapi f v = - let copy = copy v in - mapi_with f copy; copy - - let of_sparse_list ls col_count = - let vec = Array.make col_count A.zero in - List.iter (fun (idx, value) -> vec.(idx) <- value) ls; - vec - - let to_sparse_list v = - let rec aux idx acc = - if idx < 0 then acc - else - let value = v.(idx) in - let acc = if value <> A.zero then (idx, value):: acc else acc in - aux (idx - 1) acc - in aux (length v - 1) [] - end - -open Batteries.Array - -(** Array-based matrix implementation. - It provides a normalization function to reduce a matrix into reduced row echelon form. - Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) -module ArrayMatrix: AbstractMatrix = - functor (A: RatOps) (V: AbstractVector) -> - struct - include ConvenienceOps(A) - module V = V(A) - - type t = A.t array array [@@deriving eq, ord, hash] - - let show x = - Array.fold_left (^) "" (Array.map (fun v -> V.show @@ V.of_array v) x) - - let empty () = - Array.make_matrix 0 0 A.zero - - let num_rows m = - Array.length m - - let is_empty m = - (num_rows m = 0) - - let num_cols m = - if is_empty m then 0 else Array.length m.(0) - - let copy m = - let cp = Array.make_matrix (num_rows m) (num_cols m) A.zero in - Array.iteri (fun i x -> Array.blit x 0 cp.(i) 0 (num_cols m)) m; cp - - let copy m = timing_wrap "copy" (copy) m - - let add_empty_columns m cols = - let nnc = Array.length cols in - if is_empty m || nnc = 0 then m else - let nr, nc = num_rows m, num_cols m in - let m' = make_matrix nr (nc + nnc) A.zero in - for i = 0 to nr - 1 do - let offset = ref 0 in - for j = 0 to nc - 1 do - while !offset < nnc && !offset + j = cols.(!offset) do incr offset done; - m'.(i).(j + !offset) <- m.(i).(j); - done - done; - m' - - let add_empty_columns m cols = timing_wrap "add_empty_cols" (add_empty_columns m) cols - - let append_row m row = - let size = num_rows m in - let new_matrix = make_matrix (size + 1) (num_cols m) A.zero in - for i = 0 to size - 1 do - new_matrix.(i) <- m.(i) - done; - new_matrix.(size) <- V.to_array row; - new_matrix - - let get_row m n = - V.of_array m.(n) - - let remove_row m n = - let new_matrix = make_matrix (num_rows m - 1) (num_cols m) A.zero in - if not @@ is_empty new_matrix then - if n = 0 then - Array.blit m 1 new_matrix 0 (num_rows m - 1) - else - (Array.blit m 0 new_matrix 0 n; - if n <> (num_rows m - 1) then - Array.blit m (n + 1) new_matrix n (num_rows new_matrix - n)); new_matrix - - let get_col m n = - V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)) - - let get_col m n = timing_wrap "get_col" (get_col m) n - - let set_col_with m new_col n = - for i = 0 to num_rows m - 1 do - m.(i).(n) <- V.nth new_col i - done; m - - let set_col_with m new_col n = timing_wrap "set_col" (set_col_with m new_col) n - - let set_col m new_col n = - let copy = copy m in - set_col_with copy new_col n - - let append_matrices m1 m2 = - Array.append m1 m2 - - let equal m1 m2 = timing_wrap "equal" (equal m1) m2 - - let reduce_col_with m j = - if not @@ is_empty m then - (let r = ref (-1) in - for i' = 0 to num_rows m - 1 do - let rev_i' = num_rows m - i' - 1 in - if !r < 0 && m.(rev_i').(j) <>: A.zero then r := rev_i'; - if !r <> rev_i' then - let g = m.(rev_i').(j) in - if g <>: A.zero then - let s = g /: m.(!r).(j) in - for j' = 0 to num_cols m - 1 do - m.(rev_i').(j') <- m.(rev_i').(j') -: s *: m.(!r).(j') - done - done; - if !r >= 0 then Array.fill m.(!r) 0 (num_cols m) A.zero) - - let reduce_col_with m j = timing_wrap "reduce_col_with" (reduce_col_with m) j - let reduce_col m j = - let copy = copy m in - reduce_col_with copy j; - copy - - let del_col m j = - if is_empty m then m else - let new_matrix = Array.make_matrix (num_rows m) (num_cols m - 1) A.zero in - for i = 0 to num_rows m - 1 do - new_matrix.(i) <- Array.remove_at j m.(i) - done; new_matrix - - let del_cols m cols = - let n_c = Array.length cols in - if n_c = 0 || is_empty m then m - else - let m_r, m_c = num_rows m, num_cols m in - if m_c = n_c then empty () else - let m' = Array.make_matrix m_r (m_c - n_c) A.zero in - for i = 0 to m_r - 1 do - let offset = ref 0 in - for j = 0 to (m_c - n_c) - 1 do - while !offset < n_c && !offset + j = cols.(!offset) do incr offset done; - m'.(i).(j) <- m.(i).(j + !offset); - done - done; - m' - - let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols - - let map2i f m v = - let f' x (i,y) = V.to_array @@ f i (V.of_array x) y in - let range_array = Array.init (V.length v) Fun.id in - Array.map2 f' m (Array.combine range_array (V.to_array v)) - - let remove_zero_rows m = - Array.filter (fun x -> Array.exists (fun y -> y <>: A.zero) x) m - - let rref_with m = - (*Based on Cousot - Principles of Abstract Interpretation (2021)*) - let swap_rows i1 i2 = - let tmp = m.(i1) in - m.(i1) <- m.(i2); - m.(i2) <- tmp; - in - let exception Unsolvable in - let num_rows = num_rows m in - let num_cols = num_cols m in - try ( - for i = 0 to num_rows-1 do - let exception Found in - try ( - for j = i to num_cols -2 do - for k = i to num_rows -1 do - if m.(k).(j) <>: A.zero then - ( - if k <> i then swap_rows k i; - let piv = m.(i).(j) in - Array.iteri(fun j' x -> m.(i).(j') <- x /: piv) m.(i); - for l = 0 to num_rows-1 do - if l <> i && m.(l).(j) <>: A.zero then ( - let is_only_zero = ref true in - let m_lj = m.(l).(j) in - for k = 0 to num_cols - 2 do - m.(l).(k) <- m.(l).(k) -: m.(i).(k) *: m_lj /: m.(i).(j); - if m.(l).(k) <>: A.zero then is_only_zero := false; - done; - let k_end = num_cols - 1 in - m.(l).(k_end) <- m.(l).(k_end) -: m.(i).(k_end) *: m_lj /: m.(i).(j); - if !is_only_zero && m.(l).(k_end) <>: A.zero then raise Unsolvable; - ) - done; - raise Found - ) - done; - done; - ) - with Found -> () - done; - true) - with Unsolvable -> false - - let rref_with m = timing_wrap "rref_with" rref_with m - - let init_with_vec v = - let new_matrix = Array.make_matrix 1 (V.length v) A.zero in - new_matrix.(0) <- (V.to_array v); new_matrix - - - let reduce_col_with_vec m j v = - for i = 0 to num_rows m - 1 do - if m.(i).(j) <>: A.zero then - let beta = m.(i).(j) /: v.(j) in - Array.iteri (fun j' x -> m.(i).(j') <- x -: beta *: v.(j')) m.(i) - done - - let get_pivot_positions m = - let pivot_elements = Array.make (num_rows m) 0 - in Array.iteri (fun i x -> pivot_elements.(i) <- Array.findi (fun z -> z =: A.one) x) m; pivot_elements - - let rref_vec m pivot_positions v = - let insert = ref (-1) in - for j = 0 to Array.length v -2 do - if v.(j) <>: A.zero then - match Array.bsearch Int.ord pivot_positions j with - | `At i -> let beta = v.(j) /: m.(i).(j) in - Array.iteri (fun j' x -> v.(j') <- x -: beta *: m.(i).(j')) v - | _ -> if !insert < 0 then (let v_i = v.(j) in - Array.iteri (fun j' x -> v.(j') <- x /: v_i) v; insert := j; - reduce_col_with_vec m j v) - - done; - if !insert < 0 then ( - if v.(Array.length v - 1) <>: A.zero then None - else Some m - ) - else - let new_m = Array.make_matrix (num_rows m + 1) (num_cols m) A.zero - in let (i, j) = Array.pivot_split Int.ord pivot_positions !insert in - if i = 0 && j = 0 then (new_m.(0) <- v; Array.blit m 0 new_m 1 (num_rows m)) - else if i = num_rows m && j = num_rows m then (Array.blit m 0 new_m 0 j; new_m.(j) <- v) - else (Array.blit m 0 new_m 0 i; new_m.(i) <- v; Array.blit m i new_m (i + 1) (Array.length m - j)); - Some new_m - - - let rref_vec_with m v = - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) - (*m must be in rref form and contain the same num of cols as v*) - (*If m is empty then v is simply normalized and returned*) - let v = V.to_array v in - if is_empty m then - match Array.findi (fun x -> x <>: A.zero) v with - | exception Not_found -> None - | i -> if i = Array.length v - 1 then None else - let v_i = v.(i) in - Array.iteri (fun j x -> v.(j) <- x /: v_i) v; Some (init_with_vec @@ V.of_array v) - else - let pivot_elements = get_pivot_positions m in - rref_vec m pivot_elements v - - let rref_vec_with m v = timing_wrap "rref_vec_with" (rref_vec_with m) v - - let rref_matrix_with m1 m2 = - (*Similar to rref_vec_with but takes two matrices instead.*) - (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - let b_m, s_m = if num_rows m1 > num_rows m2 then m1, m2 else m2, m1 in - let b = ref b_m in - let exception Unsolvable in - try ( - for i = 0 to num_rows s_m - 1 do - let pivot_elements = get_pivot_positions !b in - let res = rref_vec !b pivot_elements s_m.(i) in - match res with - | None -> raise Unsolvable - | Some res -> b := res - done; - Some !b - ) - with Unsolvable -> None - - let rref_matrix_with m1 m2 = timing_wrap "rref_matrix_with" (rref_matrix_with m1) m2 - - let normalize_with m = - rref_with m - - let normalize_with m = timing_wrap "normalize_with" normalize_with m - - let normalize m = - let copy = copy m in - if normalize_with copy then - Some copy - else - None - - let is_covered_by m1 m2 = - (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) - (*Both input matrices must be in rref form!*) - if num_rows m1 > num_rows m2 then false else - let p2 = lazy (get_pivot_positions m2) in - try ( - for i = 0 to num_rows m1 - 1 do - if Array.exists2 (<>:) m1.(i) m2.(i) then - let m1_i = Array.copy m1.(i) in - for j = 0 to Array.length m1_i - 2 do - if m1_i.(j) <>: A.zero then - match Array.bsearch Int.ord (Lazy.force p2) j with - | `At pos -> let beta = m1_i.(j) in - Array.iteri (fun j' x -> m1_i.(j') <- m1_i.(j') -: beta *: m2.(pos).(j') ) m1_i - | _ -> raise Stdlib.Exit; - done; - if m1_i. (num_cols m1 - 1) <>: A.zero then - raise Stdlib.Exit - done; - true - ) - with Stdlib.Exit -> false;; - - let is_covered_by m1 m2 = timing_wrap "is_covered_by" (is_covered_by m1) m2 - - let find_opt f m = - let f' x = f (V.of_array x) in Option.map V.of_array (Array.find_opt f' m) - - let map2 f m v = - let f' x y = V.to_array @@ f (V.of_array x) y in Array.map2 f' m (V.to_array v) - - let map2_with f m v = - if num_rows m = V.length v then - Array.iter2i (fun i x y -> m.(i) <- V.to_array @@ f (V.of_array x) y) m (V.to_array v) - else - for i = 0 to Stdlib.min (num_rows m) (V.length v) -1 do - m.(i) <- V.to_array @@ f (V.of_array m.(i)) (V.nth v i) - done - - let map2_with f m v = timing_wrap "map2_with" (map2_with f m) v - - let map2i_with f m v = - if num_rows m = V.length v then - Array.iter2i (fun i x y -> m.(i) <- V.to_array @@ f i (V.of_array x) y) m (V.to_array v) - else - for i = 0 to Stdlib.min (num_rows m) (V.length v) -1 do - m.(i) <- V.to_array @@ f i (V.of_array m.(i)) (V.nth v i) - done - - let map2i_with f m v = timing_wrap "map2i_with" (map2i_with f m) v - end - - -module SparseVector: AbstractVector = - functor (A: RatOps) -> - struct - include ConvenienceOps (A) - - type t = { - entries: (int * A.t) list ; - len: int - }[@@deriving eq, ord, hash] - - let show v = - failwith "TODO" - - let keep_vals v n = - let rec keep_vals_vec v n = - match v with - | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) - | [] -> [] - in - if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = keep_vals_vec v.entries n; len=n} - - let remove_val v n = - let dec_idx v = - List.map (fun (a,b) -> (a-1, b)) v - in - let rec remove_val_vec v n = - match v with - | x::xs -> - if fst x = n then dec_idx xs else - if fst x > n then dec_idx (x::xs) else - x::(remove_val_vec xs n) - | [] -> [] - in - if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_val_vec v.entries n; len = v.len - 1} - - let set_val v n m = - failwith "TODO" - - let set_val_with v n m = - failwith "TODO" - - let insert_val n m t = - failwith "TODO" - - let apply_with_c f m v = - failwith "TODO" - - let apply_with_c_with f m v = - failwith "TODO" - - let zero_vec n = - failwith "TODO" - - let nth v n = - failwith "TODO" - - let length v = - failwith "TODO" - - let map2 f v v' = - failwith "TODO" - - let map2_with f v v' = - failwith "TODO" - - let findi f v = - failwith "TODO" - - let map f v = - failwith "TODO" - - let map_with f v = - failwith "TODO" - - let compare_length_with v n = - failwith "TODO" - - let of_list l = - failwith "TODO" - - let to_list v = - failwith "TODO" - - let filteri f v = - failwith "TODO" - - let append v v' = - failwith "TODO" - - let exists f v = - failwith "TODO" - - let rev v = - failwith "TODO" - - let rev_with v = - failwith "TODO" - - let map2i f v v' = - failwith "TODO" - - let map2i_with f v v' = - failwith "TODO" - - let mapi f v = - failwith "TODO" - - let mapi_with f v = - failwith "TODO" - - let find2i f v v' = - failwith "TODO" - - let to_array v = - failwith "TODO" - - let of_array a = - failwith "TODO" - - let copy v = v - - let of_sparse_list ls col_count = - failwith "TODO" - - let to_sparse_list v = - failwith "TODO" - - end - - -(** Sparse matrix implementation. - It provides a normalization function to reduce a matrix into reduced row echelon form. - Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) -module SparseMatrix: AbstractMatrix = - functor (A: RatOps) (V: AbstractVector) -> - struct - include ConvenienceOps(A) - module V = V(A) - - (* Array of arrays implementation. One array per row containing tuple of column index and value *) - type t = { - entries : (int * A.t) list list; - column_count : int - } [@@deriving eq, ord, hash] - - let show x = - List.fold_left (^) " " (List.map (fun row -> V.show @@ V.of_sparse_list row x.column_count) x.entries) - - let empty () = - {entries = []; column_count = 0} - - let num_rows m = - List.length m.entries - - let is_empty m = - num_rows m = 0 - (*This should be different if the implimentation is sound*) - (*m.column_count = 0*) - - let num_cols m = - m.column_count - - let copy m = - {entries = m.entries; column_count = m.column_count} (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) - - let copy m = - timing_wrap "copy" (copy) m - - let add_empty_columns m (cols : int enumerable) = - let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in - let emptyT = A.zero in - let rec list_of_all_before_index idx cols = - match cols with - | x::xs -> - if x < idx - then - let (h,t) = list_of_all_before_index idx xs in - (x::h, t) - else ([],x::xs) - | [] -> ([],[]) - in - (*This could easily be abstracted into the above functions, but its nice to have - it here for readability and debugging*) - let rec make_empty_entries_for_idxs idxs = - match idxs with - | x::xs -> (x, emptyT)::(make_empty_entries_for_idxs xs) - | [] -> [] - in - let rec add_column_element r cols = - match r with - | (idx, _)::xs -> - let (bef,aft) = list_of_all_before_index idx cols in - (make_empty_entries_for_idxs bef)@(add_column_element xs aft) - | [] -> [] - in - let rec add_empty_columns_on_list m cols = - match m with - | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) - | [] -> [] - in {entries = add_empty_columns_on_list m.entries colsL; column_count = m.column_count + Array.length cols} - - let add_empty_columns m (cols : int enumerable) = - timing_wrap "add_empty_cols" (add_empty_columns m) cols - - let append_row m row = - {entries = m.entries @ [V.to_sparse_list row]; column_count = m.column_count} - - let get_row m n = - V.of_sparse_list (List.nth m.entries n) m.column_count - - let remove_row m n = - let rec aux idx entries = match idx, entries with - | i, x :: xs when i = n -> xs - | _, x :: xs -> x :: aux (idx + 1) xs - | _, _ -> failwith "trying to remove out of bounds row" - in - let new_entries = aux 0 m.entries in - let new_col_count = if new_entries = [] then 0 else m.column_count in - {entries = new_entries; column_count = new_col_count} - - let get_col m n = - (* Uses the fact that row is sorted to return Zero when index n is exceeded *) - let rec get_col_from_row row = - match row with - | [] -> A.zero - | (col_idx, value)::_ when col_idx = n -> value - | (col_idx, _)::_ when col_idx > n -> A.zero - | _::cs -> get_col_from_row cs - in - V.of_list @@ List.map (fun row -> get_col_from_row row ) m.entries - - let get_col m n = - timing_wrap "get_col" (get_col m) n - - let set_col_with m new_col n = - failwith "TODO" - - let set_col_with m new_col n = timing_wrap "set_col" (set_col_with m new_col) n - - let set_col m new_col n = - let rec set_col_in_row row value = - match row with - | [] -> if value =: A.zero then [] else [(n, value)] - | (col_idx, v)::cs when col_idx > n -> if value =: A.zero then (col_idx, v)::cs else (n, value)::(col_idx, v)::cs - | (col_idx, v)::cs when col_idx = n -> if value =: A.zero then cs else (n, value)::cs - | (col_idx, v)::cs -> (col_idx, v)::(set_col_in_row cs value) - in - let new_entries = List.mapi (fun row_idx row -> - let value = V.nth new_col row_idx in - set_col_in_row row value - ) m.entries in - {entries = new_entries; column_count = m.column_count} - - let append_matrices m1 m2 = - failwith "TODO" - - let equal m1 m2 = timing_wrap "equal" (equal m1) m2 - - let reduce_col_with m j = - failwith "TODO" - - let reduce_col_with m j = timing_wrap "reduce_col_with" (reduce_col_with m) j - let reduce_col m j = - failwith "TODO" - - let del_col m j = - if is_empty m then m else - let del_col_from_row row = - List.filter_map (fun (col_idx, value) -> - if col_idx = j then - None - else if col_idx > j then - Some (col_idx - 1, value) - else - Some (col_idx, value) - ) row - in - let new_entries = List.map (fun row -> del_col_from_row row) m.entries in - {entries = new_entries; column_count = m.column_count - 1} - - (* TODO: Might be more efficient to check for each entry how much to reduce their index and not by recursively calling del_col *) - let del_cols m cols = - let cols = Array.to_list cols in (* TODO: Get away from Arrays *) - let to_delete_count = List.length cols in - if to_delete_count = 0 || is_empty m then m - else - if num_cols m = to_delete_count then empty () else - let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification)*) - let rec del_cols_aux m cols deleted_col_count = - match cols with - | [] -> m - | col_idx::cs -> - let m' = del_col m (col_idx - deleted_col_count) in (* Taking already deleted cols into account because of new index *) - del_cols_aux m' cs (deleted_col_count + 1) - in del_cols_aux m sorted_cols 0 - - let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols - - let map2i f m v = - failwith "TODO" - - let remove_zero_rows m = - failwith "TODO" - - let rref_with m = - failwith "TODO" - - let rref_with m = timing_wrap "rref_with" rref_with m - - let init_with_vec v = - failwith "TODO" - - - let reduce_col_with_vec m j v = - failwith "TODO" - - let get_pivot_positions m = - failwith "TODO" - - let rref_vec m pivot_positions v = - failwith "TODO" - - - let rref_vec_with m v = - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) - (*m must be in rref form and contain the same num of cols as v*) - (*If m is empty then v is simply normalized and returned*) - failwith "TODO" - - let rref_vec_with m v = timing_wrap "rref_vec_with" (rref_vec_with m) v - - let rref_matrix_with m1 m2 = - (*Similar to rref_vec_with but takes two matrices instead.*) - (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - failwith "TODO" - - let rref_matrix_with m1 m2 = timing_wrap "rref_matrix_with" (rref_matrix_with m1) m2 - - let normalize_with m = - failwith "TODO" - - let normalize_with m = timing_wrap "normalize_with" normalize_with m - - let normalize m = - failwith "TODO" - - let is_covered_by m1 m2 = - failwith "TODO" - - let is_covered_by m1 m2 = timing_wrap "is_covered_by" (is_covered_by m1) m2 - - let find_opt f m = - failwith "TODO" - - let map2 f m v = - failwith "TODO" - - let map2_with f m v = - failwith "TODO" - - let map2_with f m v = timing_wrap "map2_with" (map2_with f m) v - - let map2i_with f m v = - failwith "TODO" - - let map2i_with f m v = timing_wrap "map2i_with" (map2i_with f m) v - end \ No newline at end of file diff --git a/src/goblint_lib.ml b/src/goblint_lib.ml index 91f9837419..91207ba617 100644 --- a/src/goblint_lib.ml +++ b/src/goblint_lib.ml @@ -430,7 +430,7 @@ module BaseInvariant = BaseInvariant module CommonPriv = CommonPriv module WideningThresholds = WideningThresholds -module VectorMatrix = VectorMatrix +(*module VectorMatrix = VectorMatrix (*Why is this needed anyway?*)*) module SharedFunctions = SharedFunctions module GobApron = GobApron From 5ce5ee82655a10df87db861f5c1f86126356aff3 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 21 Nov 2024 15:48:27 +0100 Subject: [PATCH 026/150] Bugfix Matrix.map2i without side effects (different length lists) --- src/cdomains/vectorMatrix.ml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/cdomains/vectorMatrix.ml b/src/cdomains/vectorMatrix.ml index 31b33348b8..178e8ab1f0 100644 --- a/src/cdomains/vectorMatrix.ml +++ b/src/cdomains/vectorMatrix.ml @@ -456,11 +456,8 @@ module ArrayMatrix: AbstractMatrix = m' let del_cols m cols = timing_wrap "del_cols" (del_cols m) cols - - let map2i f m v = - let f' x (i,y) = V.to_array @@ f i (V.of_array x) y in - let range_array = Array.init (V.length v) Fun.id in - Array.map2 f' m (Array.combine range_array (V.to_array v)) + + let remove_zero_rows m = Array.filter (fun x -> Array.exists (fun y -> y <>: A.zero) x) m @@ -661,6 +658,18 @@ module ArrayMatrix: AbstractMatrix = done let map2i_with f m v = timing_wrap "map2i_with" (map2i_with f m) v + + + (* Deprecated + let map2i f m v = + let f' x (i,y) = V.to_array @@ f i (V.of_array x) y in + let range_array = Array.init (V.length v) Fun.id in + Array.map2 f' m (Array.combine range_array (V.to_array v)) + *) + let map2i f m v = + let m' = copy m in + map2i_with f m' v; + m' end From 7643899a2a5fff2cf082b76a55a442531dbd94e0 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 21 Nov 2024 16:29:39 +0100 Subject: [PATCH 027/150] added missing module BatList --- .../arrayImplementation/arrayVector.ml | 2 +- .../sparseImplementation/sparseMatrix.ml | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml b/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml index ca79d90515..a65892f2eb 100644 --- a/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml @@ -90,7 +90,7 @@ module ArrayVector: AbstractVector = let copy = copy v in mapi_with f copy; copy - let of_sparse_list ls col_count = + let of_sparse_list col_count ls = let vec = Array.make col_count A.zero in List.iter (fun (idx, value) -> vec.(idx) <- value) ls; vec diff --git a/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml index 36b38322d4..916513ece9 100644 --- a/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml @@ -3,6 +3,9 @@ open AbstractVector open RatOps open ConvenienceOps +open BatList +module List = BatList + (** Sparse matrix implementation. It provides a normalization function to reduce a matrix into reduced row echelon form. Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) @@ -43,7 +46,7 @@ module SparseMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m - let add_empty_columns m (cols : int enumerable) = + let add_empty_columns m cols = let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in let emptyT = A.zero in let rec list_of_all_before_index idx cols = @@ -76,7 +79,7 @@ module SparseMatrix: AbstractMatrix = | [] -> [] in tM (add_empty_columns_on_list m.entries colsL) (m.column_count + Array.length cols) - let add_empty_columns m (cols : int enumerable) = + let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = From 41bb6ed012bc27b48da700cb097c2e2633760d36 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 21 Nov 2024 16:37:18 +0100 Subject: [PATCH 028/150] RenamedFolder; Revealed modules to goblint_lib --- .../abstractMatrix.ml | 0 .../abstractVector.ml | 0 src/cdomains/affineEquality/affineEquality.ml | 10 ++++++++++ .../arrayImplementation/arrayMatrix.ml | 0 .../arrayImplementation/arrayVector.ml | 0 .../convenienceOps.ml | 0 .../matrix.ml | 0 .../ratOps.ml | 0 .../sparseImplementation/sparseMatrix.ml | 0 .../sparseImplementation/sparseVector.ml | 0 .../vector.ml | 0 src/goblint_lib.ml | 2 +- 12 files changed, 11 insertions(+), 1 deletion(-) rename src/cdomains/{affineEqualityMatrices => affineEquality}/abstractMatrix.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/abstractVector.ml (100%) create mode 100644 src/cdomains/affineEquality/affineEquality.ml rename src/cdomains/{affineEqualityMatrices => affineEquality}/arrayImplementation/arrayMatrix.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/arrayImplementation/arrayVector.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/convenienceOps.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/matrix.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/ratOps.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/sparseImplementation/sparseMatrix.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/sparseImplementation/sparseVector.ml (100%) rename src/cdomains/{affineEqualityMatrices => affineEquality}/vector.ml (100%) diff --git a/src/cdomains/affineEqualityMatrices/abstractMatrix.ml b/src/cdomains/affineEquality/abstractMatrix.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/abstractMatrix.ml rename to src/cdomains/affineEquality/abstractMatrix.ml diff --git a/src/cdomains/affineEqualityMatrices/abstractVector.ml b/src/cdomains/affineEquality/abstractVector.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/abstractVector.ml rename to src/cdomains/affineEquality/abstractVector.ml diff --git a/src/cdomains/affineEquality/affineEquality.ml b/src/cdomains/affineEquality/affineEquality.ml new file mode 100644 index 0000000000..71846bf0d7 --- /dev/null +++ b/src/cdomains/affineEquality/affineEquality.ml @@ -0,0 +1,10 @@ +(** This module is used to reveal modules to goblint_lib *) +module AbstractVector = AbstractVector +module ArrayMatrix = ArrayMatrix +module SparseMatrix = SparseMatrix +module Matrix = Matrix +module AbstractMatrix = AbstractMatrix +module ConvenienceOps = ConvenienceOps +module SparseVector = SparseVector +module RatOps = RatOps +module Vector = Vector \ No newline at end of file diff --git a/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/arrayImplementation/arrayMatrix.ml rename to src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml diff --git a/src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/arrayImplementation/arrayVector.ml rename to src/cdomains/affineEquality/arrayImplementation/arrayVector.ml diff --git a/src/cdomains/affineEqualityMatrices/convenienceOps.ml b/src/cdomains/affineEquality/convenienceOps.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/convenienceOps.ml rename to src/cdomains/affineEquality/convenienceOps.ml diff --git a/src/cdomains/affineEqualityMatrices/matrix.ml b/src/cdomains/affineEquality/matrix.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/matrix.ml rename to src/cdomains/affineEquality/matrix.ml diff --git a/src/cdomains/affineEqualityMatrices/ratOps.ml b/src/cdomains/affineEquality/ratOps.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/ratOps.ml rename to src/cdomains/affineEquality/ratOps.ml diff --git a/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/sparseImplementation/sparseMatrix.ml rename to src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml diff --git a/src/cdomains/affineEqualityMatrices/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/sparseImplementation/sparseVector.ml rename to src/cdomains/affineEquality/sparseImplementation/sparseVector.ml diff --git a/src/cdomains/affineEqualityMatrices/vector.ml b/src/cdomains/affineEquality/vector.ml similarity index 100% rename from src/cdomains/affineEqualityMatrices/vector.ml rename to src/cdomains/affineEquality/vector.ml diff --git a/src/goblint_lib.ml b/src/goblint_lib.ml index 91207ba617..b52cc94293 100644 --- a/src/goblint_lib.ml +++ b/src/goblint_lib.ml @@ -430,7 +430,7 @@ module BaseInvariant = BaseInvariant module CommonPriv = CommonPriv module WideningThresholds = WideningThresholds -(*module VectorMatrix = VectorMatrix (*Why is this needed anyway?*)*) +module AffineEquality = AffineEquality module SharedFunctions = SharedFunctions module GobApron = GobApron From 6602d75b65ef1b13d81fea88b56a5ec6ef6d3b79 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 21 Nov 2024 16:39:46 +0100 Subject: [PATCH 029/150] Directly revealed modules to goblint_lib --- src/cdomains/affineEquality/affineEquality.ml | 10 ---------- src/goblint_lib.ml | 12 +++++++++++- 2 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 src/cdomains/affineEquality/affineEquality.ml diff --git a/src/cdomains/affineEquality/affineEquality.ml b/src/cdomains/affineEquality/affineEquality.ml deleted file mode 100644 index 71846bf0d7..0000000000 --- a/src/cdomains/affineEquality/affineEquality.ml +++ /dev/null @@ -1,10 +0,0 @@ -(** This module is used to reveal modules to goblint_lib *) -module AbstractVector = AbstractVector -module ArrayMatrix = ArrayMatrix -module SparseMatrix = SparseMatrix -module Matrix = Matrix -module AbstractMatrix = AbstractMatrix -module ConvenienceOps = ConvenienceOps -module SparseVector = SparseVector -module RatOps = RatOps -module Vector = Vector \ No newline at end of file diff --git a/src/goblint_lib.ml b/src/goblint_lib.ml index b52cc94293..7792588864 100644 --- a/src/goblint_lib.ml +++ b/src/goblint_lib.ml @@ -430,7 +430,17 @@ module BaseInvariant = BaseInvariant module CommonPriv = CommonPriv module WideningThresholds = WideningThresholds -module AffineEquality = AffineEquality +(* There might be a more elegant solution. *) +module AbstractVector = AbstractVector +module ArrayMatrix = ArrayMatrix +module SparseMatrix = SparseMatrix +module Matrix = Matrix +module AbstractMatrix = AbstractMatrix +module ConvenienceOps = ConvenienceOps +module SparseVector = SparseVector +module RatOps = RatOps +module Vector = Vector + module SharedFunctions = SharedFunctions module GobApron = GobApron From b7d5c1ace4bbe16805463d54b86fd0b71127c399 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 21 Nov 2024 16:49:39 +0100 Subject: [PATCH 030/150] Added missing ArrayVector module to goblint_lib --- src/goblint_lib.ml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/goblint_lib.ml b/src/goblint_lib.ml index 7792588864..a5fe9230fe 100644 --- a/src/goblint_lib.ml +++ b/src/goblint_lib.ml @@ -431,15 +431,16 @@ module CommonPriv = CommonPriv module WideningThresholds = WideningThresholds (* There might be a more elegant solution. *) -module AbstractVector = AbstractVector -module ArrayMatrix = ArrayMatrix -module SparseMatrix = SparseMatrix +module Vector = Vector module Matrix = Matrix +module AbstractVector = AbstractVector module AbstractMatrix = AbstractMatrix -module ConvenienceOps = ConvenienceOps +module ArrayVector = ArrayVector +module ArrayMatrix = ArrayMatrix module SparseVector = SparseVector +module SparseMatrix = SparseMatrix module RatOps = RatOps -module Vector = Vector +module ConvenienceOps = ConvenienceOps module SharedFunctions = SharedFunctions module GobApron = GobApron From 8476f95212324b5c3b34956158b9455ca65f3bd8 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 26 Nov 2024 16:16:17 +0100 Subject: [PATCH 031/150] Vector List --- .../affineEquality/sparseImplementation/sparseMatrix.ml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 916513ece9..851706a685 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -9,17 +9,14 @@ module List = BatList (** Sparse matrix implementation. It provides a normalization function to reduce a matrix into reduced row echelon form. Operations exploit that the input matrix/matrices are in reduced row echelon form already. *) -module SparseMatrix: AbstractMatrix = +module ListMatrix: AbstractMatrix = functor (A: RatOps) (V: AbstractVector) -> struct include ConvenienceOps(A) module V = V(A) - (* Array of arrays implementation. One array per row containing tuple of column index and value *) - type t = { - entries : (int * A.t) list list; - column_count : int - } [@@deriving eq, ord, hash] + type t = V.t list (*List of rows*) + [@@deriving eq, ord, hash] let tM e l = {entries= e; column_count=l} From 5fb804134f6fa0e79ed1a231ad7451553227d65f Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 26 Nov 2024 16:47:37 +0100 Subject: [PATCH 032/150] someMatFuncs --- .../sparseImplementation/sparseMatrix.ml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 851706a685..ccc88ca7d1 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -18,27 +18,22 @@ module ListMatrix: AbstractMatrix = type t = V.t list (*List of rows*) [@@deriving eq, ord, hash] - let tM e l = {entries= e; column_count=l} - let show x = - List.fold_left (^) "" (List.map (fun row -> V.show @@ V.of_sparse_list x.column_count row) x.entries) + List.fold_left (^) "" (List.map (fun x -> (V.show x) ^ "\n") x) - let empty () = - {entries = []; column_count = 0} + let empty () = [] - let num_rows m = - List.length m.entries + let num_rows = List.length let is_empty m = num_rows m = 0 (*This should be different if the implimentation is sound*) (*m.column_count = 0*) - let num_cols m = - m.column_count + let num_cols m = if m = [] then 0 else V.length (hd m) - let copy m = - m (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + let copy m = m + (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) let copy m = Timing.wrap "copy" (copy) m From 8c3824f2f9c922a0ba1e29178553125cc45a4cbb Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 26 Nov 2024 16:56:22 +0100 Subject: [PATCH 033/150] some functions changed to use vectors --- .../sparseImplementation/sparseMatrix.ml | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 851706a685..904c87e37e 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -80,20 +80,13 @@ module ListMatrix: AbstractMatrix = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - {entries = m.entries @ [V.to_sparse_list row]; column_count = V.length row} + m @ [row] let get_row m n = - V.of_sparse_list m.column_count (List.nth m.entries n) + List.nth m n let remove_row m n = - let rec aux idx entries = match idx, entries with - | i, x :: xs when i = n -> xs - | _, x :: xs -> x :: aux (idx + 1) xs - | _, _ -> failwith "trying to remove out of bounds row" - in - let new_entries = aux 0 m.entries in - let new_col_count = if new_entries = [] then 0 else m.column_count in - {entries = new_entries; column_count = new_col_count} + List.remove_at n m let get_col m n = (* Uses the fact that row is sorted to return Zero when index n is exceeded *) @@ -128,9 +121,8 @@ module ListMatrix: AbstractMatrix = ) m.entries in {entries = new_entries; column_count = m.column_count} - let append_matrices m1 m2 = - let new_entries = List.append m1.entries m2.entries in - {entries = new_entries; column_count = m1.column_count} + let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) + m1 @ m2 let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 @@ -227,9 +219,7 @@ module ListMatrix: AbstractMatrix = {entries = new_entries; column_count = m.column_count} let remove_zero_rows m = - let entries' = List.filter (fun row -> row <> []) m.entries in - if List.length entries' = 0 then empty() else - {entries = entries'; column_count = m.column_count} + List.filter (fun row -> not (V.is_zero_vec row)) m let rref_with m = failwith "Do not use!" @@ -237,7 +227,7 @@ module ListMatrix: AbstractMatrix = let rref_with m = Timing.wrap "rref_with" rref_with m let init_with_vec v = - failwith "TODO" + [v] let reduce_col_with_vec m j v = From 3234896086e8332d98f6969654496206f01be3c0 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 26 Nov 2024 16:57:14 +0100 Subject: [PATCH 034/150] again --- src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 904c87e37e..08ca44d2dc 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -229,7 +229,6 @@ module ListMatrix: AbstractMatrix = let init_with_vec v = [v] - let reduce_col_with_vec m j v = failwith "TODO" From 251f1c993b909d17c4dfd9c6306c66023e55a7af Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 26 Nov 2024 16:57:31 +0100 Subject: [PATCH 035/150] Reimplemented some matrix functions to vector --- .../sparseImplementation/sparseMatrix.ml | 40 +++---------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 14bf26234a..f4d3e3bfe1 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -198,20 +198,8 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols let map2i f m v = - let f' index row num = V.to_sparse_list @@ f index (V.of_sparse_list m.column_count row) num in - (* TODO: Do we need to consider different lengths here? - let vector_length = List.length (V.to_list v) in - let new_entries = - List.mapi (fun index row -> - if index < vector_length then - let num = V.nth v index in - f' index row num - else row - ) m.entries - in - *) - let new_entries = List.map2i f' m.entries (V.to_list v) in - {entries = new_entries; column_count = m.column_count} + let vector_length = V.length v in + List.mapi (fun index row -> if index < vector_length then f index row (V.nth v index) else row) m let remove_zero_rows m = List.filter (fun row -> not (V.is_zero_vec row)) m @@ -324,29 +312,11 @@ module ListMatrix: AbstractMatrix = let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = - let rec find_opt_vec_list f m = - match m with - | [] -> None - | x::xs -> if f x then Some x else find_opt_vec_list f xs - in - let m_vector = List.map (fun row -> V.of_sparse_list m.column_count row) m.entries in - find_opt_vec_list f m_vector + List.find_opt f m let map2 f m v = - let f' row num = V.to_sparse_list @@ f (V.of_sparse_list m.column_count row) num in - (* TODO: Do we need to consider different lengths here? - let vector_length = List.length (V.to_list v) in - let new_entries = - List.mapi (fun index row -> - if index < vector_length then - let num = V.nth v index in - f' row num - else row - ) m.entries - in - *) - let new_entries = List.map2 f' m.entries (V.to_list v) in - {entries = new_entries; column_count = m.column_count} + let vector_length = V.length v in + List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m let map2_with f m v = failwith "Do not use!" From 67c9ef4dec1d515d9d23b5c64acf04f43e6c0a74 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 26 Nov 2024 17:10:54 +0100 Subject: [PATCH 036/150] Added find_opt and remove_nth to vector interface --- .../affineEquality/arrayImplementation/arrayVector.ml | 6 ++++++ .../affineEquality/sparseImplementation/sparseVector.ml | 6 ++++++ src/cdomains/affineEquality/vector.ml | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index a65892f2eb..492fa7cb14 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -103,4 +103,10 @@ module ArrayVector: AbstractVector = let acc = if value <> A.zero then (idx, value):: acc else acc in aux (idx - 1) acc in aux (length v - 1) [] + + let remove_nth v n = + failwith "TODO" + + let find_opt f v = + failwith "TODO" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6ec6bb834a..ac68ac249b 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -164,4 +164,10 @@ module SparseVector: AbstractVector = let to_sparse_list v = v.entries + let remove_nth v n = + failwith "TODO" + + let find_opt f v = + failwith "TODO" + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 81014bcf24..9b2801e667 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -24,6 +24,8 @@ sig val nth: t -> int -> num + val remove_nth: t -> int -> t + val length: t -> int val map2: (num -> num -> num) -> t -> t -> t @@ -32,6 +34,8 @@ sig val findi: (num -> bool) -> t -> int + val find_opt: (num -> bool) -> t -> t Option.t + val map: (num -> num) -> t -> t val map_with: (num -> num) -> t -> unit From 19ac2dbdc4656941d6c4f871b778afa6e3ef5748 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 26 Nov 2024 17:12:47 +0100 Subject: [PATCH 037/150] pushing is_zero_vec --- src/cdomains/affineEquality/arrayImplementation/arrayVector.ml | 2 ++ .../affineEquality/sparseImplementation/sparseMatrix.ml | 2 +- .../affineEquality/sparseImplementation/sparseVector.ml | 2 ++ src/cdomains/affineEquality/vector.ml | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index a65892f2eb..bd78e7e453 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -51,6 +51,8 @@ module ArrayVector: AbstractVector = let zero_vec n = Array.make n A.zero + let is_zero_vec v = not (Array.exists (fun x -> x <>: A.zero) v) + let nth = Array.get let map2i f v1 v2 = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 14bf26234a..4cb3e85fa5 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -128,7 +128,7 @@ module ListMatrix: AbstractMatrix = let reduce_col m j = if is_empty m then m else - let rec find_pivot idx entries = (* Finds non-zero element in row j and return pair of row idx and the pivot value *) + let rec find_pivot idx entries = (* Finds non-zero element in column j and returns pair of row idx and the pivot value *) match entries with | [] -> None | row :: rest -> match (List.assoc_opt j row) with diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6ec6bb834a..e7db344e26 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -90,6 +90,8 @@ module SparseVector: AbstractVector = let zero_vec n = failwith "TODO" + let is_zero_vec v = (v.entries = []) + let nth v n = failwith "TODO" diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 81014bcf24..e16eb00be0 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -22,6 +22,8 @@ sig val zero_vec: int -> t + val is_zero_vec: t -> bool + val nth: t -> int -> num val length: t -> int From a0e0f1b40151906f7337ae3e7be79e5c891f9d4b Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 26 Nov 2024 17:47:23 +0100 Subject: [PATCH 038/150] Formatting --- .../arrayImplementation/arrayVector.ml | 12 ++++---- .../sparseImplementation/sparseMatrix.ml | 30 +++---------------- .../sparseImplementation/sparseVector.ml | 20 ++++++------- src/cdomains/affineEquality/vector.ml | 10 +++---- 4 files changed, 23 insertions(+), 49 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 12b162fbb7..650b908b6c 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -30,19 +30,19 @@ module ArrayVector: AbstractVector = let compare_length_with v len = Int.compare (Array.length v) len - let remove_val v n = + let remove_nth v n = if n >= Array.length v then failwith "n outside of Array range" else Array.init (Array.length v - 1) (fun i -> if i < n then Array.get v i else Array.get v (i + 1)) (* TODO: remove_at? *) - let set_val_with v n new_val = + let set_nth_with v n new_val = if n >= Array.length v then failwith "n outside of Array range" else Array.set v n new_val - let set_val v n new_val = + let set_nth v n new_val = let copy = copy v in - set_val_with copy n new_val; copy + set_nth_with copy n new_val; copy - let insert_val n new_val v = + let insert_val_at n new_val v = if n > Array.length v then failwith "n too large" else Array.init (Array.length v + 1) (fun i -> if i < n then Array.get v i else if i = n then new_val else Array.get v (i -1)) (* insert? *) @@ -106,8 +106,6 @@ module ArrayVector: AbstractVector = aux (idx - 1) acc in aux (length v - 1) [] - let remove_nth v n = - failwith "TODO" let find_opt f v = failwith "TODO" diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index a702229c51..5518c45e99 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -33,7 +33,7 @@ module ListMatrix: AbstractMatrix = let num_cols m = if m = [] then 0 else V.length (hd m) let copy m = m - (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) let copy m = Timing.wrap "copy" (copy) m @@ -103,18 +103,7 @@ module ListMatrix: AbstractMatrix = let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n let set_col m new_col n = - let rec set_col_in_row row value = - match row with - | [] -> if value =: A.zero then [] else [(n, value)] - | (col_idx, v)::cs when col_idx > n -> if value =: A.zero then (col_idx, v)::cs else (n, value)::(col_idx, v)::cs - | (col_idx, v)::cs when col_idx = n -> if value =: A.zero then cs else (n, value)::cs - | (col_idx, v)::cs -> (col_idx, v)::(set_col_in_row cs value) - in - let new_entries = List.mapi (fun row_idx row -> - let value = V.nth new_col row_idx in - set_col_in_row row value - ) m.entries in - {entries = new_entries; column_count = m.column_count} + List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) m1 @ m2 @@ -165,19 +154,8 @@ module ListMatrix: AbstractMatrix = {entries = entries'; column_count = m.column_count} let del_col m j = - if is_empty m then m else - let del_col_from_row row = - List.filter_map (fun (col_idx, value) -> - if col_idx = j then - None - else if col_idx > j then - Some (col_idx - 1, value) - else - Some (col_idx, value) - ) row - in - let new_entries = List.map (fun row -> del_col_from_row row) m.entries in - {entries = new_entries; column_count = m.column_count - 1} + List.map (fun row -> V.remove_nth row j) m + (* TODO: Might be more efficient to check for each entry how much to reduce their index and not by recursively calling del_col *) let del_cols m cols = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 4f5df2eac7..3a04d9a86d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -26,36 +26,36 @@ module SparseVector: AbstractVector = {entries = keep_vals_vec v.entries n; len=n} - let remove_val v n = + let remove_nth v n = let dec_idx v = List.map (fun (a,b) -> (a-1, b)) v in - let rec remove_val_vec v n = + let rec remove_nth_vec v n = match v with | x::xs -> if fst x = n then dec_idx xs else if fst x > n then dec_idx (x::xs) else - x::(remove_val_vec xs n) + x::(remove_nth_vec xs n) | [] -> [] in if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_val_vec v.entries n; len = v.len - 1} + {entries = remove_nth_vec v.entries n; len = v.len - 1} - let set_val v n m = - let rec set_val_vec v n m = + let set_nth v n m = + let rec set_nth_vec v n m = match v with | x::xs -> if fst x = n then (n, m)::xs else - if fst x < n then x::(set_val_vec xs n m) + if fst x < n then x::(set_nth_vec xs n m) else v | [] -> [] in if n >= v.len then failwith "Out of bounds" else - {entries=set_val_vec v.entries n m; len=v.len} + {entries=set_nth_vec v.entries n m; len=v.len} - let set_val_with = + let set_nth_with = failwith "deprecated" - let insert_val n m t = + let insert_val_at n m t = failwith "TODO" let mul_vec_scal v s = diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 90f61baa94..3a7431629f 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -8,13 +8,13 @@ sig val keep_vals: t -> int -> t - val remove_val: t -> int -> t + val remove_nth: t -> int -> t - val set_val: t -> int -> num -> t + val set_nth: t -> int -> num -> t - val set_val_with: t -> int -> num -> unit + val set_nth_with: t -> int -> num -> unit - val insert_val: int -> num -> t -> t + val insert_val_at: int -> num -> t -> t val apply_with_c: (num -> num -> num) -> num -> t -> t @@ -26,8 +26,6 @@ sig val nth: t -> int -> num - val remove_nth: t -> int -> t - val length: t -> int val map2: (num -> num -> num) -> t -> t -> t From d768b46c949612cf4970b3bfc81b00b6a6138f8d Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 26 Nov 2024 17:48:58 +0100 Subject: [PATCH 039/150] vector functions --- .../sparseImplementation/sparseMatrix.ml | 10 +--------- .../sparseImplementation/sparseVector.ml | 8 +++++++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index a702229c51..e32f71da2c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -84,15 +84,7 @@ module ListMatrix: AbstractMatrix = List.remove_at n m let get_col m n = - (* Uses the fact that row is sorted to return Zero when index n is exceeded *) - let rec get_col_from_row row = - match row with - | [] -> A.zero - | (col_idx, value)::_ when col_idx = n -> value - | (col_idx, _)::_ when col_idx > n -> A.zero - | _::cs -> get_col_from_row cs - in - V.of_list @@ List.map (fun row -> get_col_from_row row ) m.entries + V.of_list @@ List.map (fun row -> V.nth row n) m (* builds full col including zeros, maybe use sparselist instead? *) let get_col m n = Timing.wrap "get_col" (get_col m) n diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 4f5df2eac7..67cc85c11f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -93,7 +93,13 @@ module SparseVector: AbstractVector = let is_zero_vec v = (v.entries = []) let nth v n = - failwith "TODO" + if n >= v.len then failwith "V.nth out of bounds" + else + let rec nth v = match v with + | [] -> A.zero + | (col_idx, value) :: xs when col_idx = n -> value + | (col_idx, value) :: xs -> nth xs + in nth v.entries let length v = failwith "TODO" From 422dd549c11d26e77984c4138413e6f116acdd88 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 26 Nov 2024 18:19:01 +0100 Subject: [PATCH 040/150] Removed some _with functions from the AffineEqualityDomain --- .../apron/affineEqualityDomain.apron.ml | 66 +++++++++---------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index aa64b7f741..9a2999c021 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -240,11 +240,9 @@ struct else if is_top_env t2 then {d = Some (dim_add (Environment.dimchange t1.env sup_env) m1); env = sup_env} else - let rref_matr = Matrix.rref_matrix_with (Matrix.copy m1) (Matrix.copy m2) in - if Option.is_none rref_matr then - bot () - else - {d = rref_matr; env = sup_env} + match Matrix.rref_matrix m1 m2 with + | None -> bot () + | rref_matr -> {d = rref_matr; env = sup_env} let meet t1 t2 = @@ -283,8 +281,7 @@ struct if s >= Matrix.num_cols a then a else let case_two a r col_b = let a_r = Matrix.get_row a r in - Matrix.map2i_with (fun i x y -> if i < r then - Vector.map2_with (fun u j -> u +: y *: j) x a_r; x) a col_b; + let a = Matrix.map2i (fun i x y -> if i < r then Vector.map2 (fun u j -> u +: y *: j) x a_r else x) a col_b; in Matrix.remove_row a r in let case_three a b col_a col_b max = @@ -357,21 +354,17 @@ struct let pretty_diff () (x, y) = dprintf "%s: %a not leq %a" (name ()) pretty x pretty y - let remove_rels_with_var x var env inplace = - let j0 = Environment.dim_of_var env var in - if inplace then - (Matrix.reduce_col_with x j0; x) - else - Matrix.reduce_col x j0 + let remove_rels_with_var x var env = + let j0 = Environment.dim_of_var env var in Matrix.reduce_col x j0 - let remove_rels_with_var x var env inplace = timing_wrap "remove_rels_with_var" (remove_rels_with_var x var env) inplace + let remove_rels_with_var x var env = Timing.wrap "remove_rels_with_var" (remove_rels_with_var x var env) inplace let forget_vars t vars = if is_bot t || is_top_env t || vars = [] then t else let m = Option.get t.d in - let rem_from m = List.fold_left (fun m' x -> remove_rels_with_var m' x t.env true) m vars in + let rem_from m = List.fold_left (fun m' x -> remove_rels_with_var m' x t.env) m vars in {d = Some (Matrix.remove_zero_rows @@ rem_from (Matrix.copy m)); env = t.env} let forget_vars t vars = @@ -386,23 +379,25 @@ struct let j0 = Environment.dim_of_var env var in let a_j0 = Matrix.get_col x j0 in (*Corresponds to Axj0*) let b0 = Vector.nth b j0 in - Vector.apply_with_c_with (/:) b0 a_j0; (*Corresponds to Axj0/Bj0*) - let recalc_entries m rd_a = Matrix.map2_with (fun x y -> Vector.map2i_with (fun j z d -> + let a_j0 = Vector.apply_with_c (/:) b0 a_j0 in (*Corresponds to Axj0/Bj0*) + let recalc_entries m rd_a = Matrix.map2 (fun x y -> Vector.map2i (fun j z d -> if j = j0 then y else if Vector.compare_length_with b (j + 1) > 0 then z -: y *: d - else z +: y *: d) x b; x) m rd_a + else z +: y *: d) x b) m rd_a in - recalc_entries x a_j0; - if Matrix.normalize_with x then {d = Some x; env = env} else bot () + let x = recalc_entries x a_j0 in + match Matrix.normalize x with + | None -> bot () + | some_normalized_matrix -> {d = some_normalized_matrix; env = env} in let assign_invertible_rels x var b env = timing_wrap "assign_invertible" (assign_invertible_rels x var b) env in let assign_uninvertible_rel x var b env = let b_length = Vector.length b in - Vector.mapi_with (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b; - Vector.set_val_with b (Environment.dim_of_var env var) Mpqf.one; - let opt_m = Matrix.rref_vec_with x b in - if Option.is_none opt_m then bot () else - {d = opt_m; env = env} + let b = Vector.mapi (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b in + let b = Vector.set_val b (Environment.dim_of_var env var) Mpqf.one in + match Matrix.rref_vec x b with + | None -> bot () + | some_matrix -> {d = some_matrix; env = env} in (* let assign_uninvertible_rel x var b env = timing_wrap "assign_uninvertible" (assign_uninvertible_rel x var b) env in *) let is_invertible v = Vector.nth v @@ Environment.dim_of_var t.env var <>: Mpqf.zero @@ -411,9 +406,9 @@ struct match affineEq_vec with | Some v when is_top_env t -> if is_invertible v then t else assign_uninvertible_rel m var v t.env | Some v -> if is_invertible v then let t' = assign_invertible_rels (Matrix.copy m) var v t.env in {d = t'.d; env = t'.env} - else let new_m = Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env false + else let new_m = Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env in assign_uninvertible_rel new_m var v t.env - | None -> {d = Some (Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env false); env = t.env} + | None -> {d = Some (Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env); env = t.env} let assign_texpr t var texp = timing_wrap "assign_texpr" (assign_texpr t var) texp @@ -452,16 +447,15 @@ struct let replace_col m x y = let dim_x, dim_y = Environment.dim_of_var multi_t.env x, Environment.dim_of_var multi_t.env y in let col_x = Matrix.get_col m dim_x in - Matrix.set_col_with m col_x dim_y + Matrix.set_col m col_x dim_y in let m_cp = Matrix.copy m in let switched_m = List.fold_left2 replace_col m_cp primed_vars assigned_vars in let res = drop_vars {d = Some switched_m; env = multi_t.env} primed_vars ~del:true in let x = Option.get res.d in - if Matrix.normalize_with x then - {d = Some x; env = res.env} - else - bot () + (match Matrix.normalize x with + | None -> bot () + | some_matrix -> {d = some_matrix; env = res.env}) | _ -> t let assign_var_parallel t vv's = @@ -513,13 +507,13 @@ struct let meet_vec e = (* Flip the sign of the const. val in coeff vec *) let coeff = Vector.nth e (Vector.length e - 1) in - Vector.set_val_with e (Vector.length e - 1) (Mpqf.neg coeff); + let e = Vector.set_val e (Vector.length e - 1) (Mpqf.neg coeff) in if is_bot t then bot () else - let opt_m = Matrix.rref_vec_with (Matrix.copy @@ Option.get t.d) e in - if Option.is_none opt_m then bot () else {d = opt_m; env = t.env} - + match Matrix.rref_vec (Option.get t.d) e with + | None -> bot () + | some_matrix -> {d = some_matrix; env = t.env} in match get_coeff_vec t (Texpr1.to_expr @@ Tcons1.get_texpr1 tcons) with | Some v -> From 6afcb81e51045a57c72454f1331d1901af0e7298 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 26 Nov 2024 18:21:50 +0100 Subject: [PATCH 041/150] Implement inefficient rref functions --- .../sparseImplementation/sparseMatrix.ml | 63 ++++++++++--------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 5518c45e99..2b66de2b24 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -98,7 +98,7 @@ module ListMatrix: AbstractMatrix = Timing.wrap "get_col" (get_col m) n let set_col_with m new_col n = - failwith "Do not use!" + failwith "deprecated" let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n @@ -111,7 +111,7 @@ module ListMatrix: AbstractMatrix = let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 let reduce_col_with m j = - failwith "Do not use!" + failwith "deprecated" let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j let reduce_col m j = @@ -183,7 +183,7 @@ module ListMatrix: AbstractMatrix = List.filter (fun row -> not (V.is_zero_vec row)) m let rref_with m = - failwith "Do not use!" + failwith "deprecated" let rref_with m = Timing.wrap "rref_with" rref_with m @@ -196,31 +196,8 @@ module ListMatrix: AbstractMatrix = let get_pivot_positions m = failwith "TODO" - let rref_vec m pivot_positions v = - failwith "TODO" - - - let rref_vec_with m v = - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) - (*m must be in rref form and contain the same num of cols as v*) - (*If m is empty then v is simply normalized and returned*) - failwith "Do not use!" - - let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v - - let rref_vec m v = failwith "TODO" - - let rref_matrix_with m1 m2 = - (*Similar to rref_vec_with but takes two matrices instead.*) - (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - failwith "Do not use!" - - let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 - - let rref_matrix m1 m2 = failwith "TODO" - let normalize_with m = - failwith "Do not use!" + failwith "deprecated" let normalize_with m = Timing.wrap "normalize_with" normalize_with m @@ -283,6 +260,36 @@ module ListMatrix: AbstractMatrix = let e' = main_loop m.entries m.entries 0 0 in Some {entries = e'; column_count = m.column_count} + let rref_vec_helper m pivot_positions v = + failwith "TODO" + + let rref_vec_with m v = + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) + (*m must be in rref form and contain the same num of cols as v*) + (*If m is empty then v is simply normalized and returned*) + failwith "deprecated" + + let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v + + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) + (*m must be in rref form and contain the same num of cols as v*) + (*If m is empty then v is simply normalized and returned*) + (* TODO: OPTIMIZE! *) + let rref_vec m v = + normalize @@ append_matrices m (init_with_vec v) + + let rref_matrix_with m1 m2 = + (*Similar to rref_vec_with but takes two matrices instead.*) + (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) + failwith "deprecated" + + let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 + + (*Similar to rref_vec_with but takes two matrices instead.*) + (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) + (*TODO: OPTIMIZE!*) + let rref_matrix m1 m2 = + normalize @@ append_matrices m1 m2 let is_covered_by m1 m2 = failwith "TODO" @@ -297,7 +304,7 @@ module ListMatrix: AbstractMatrix = List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m let map2_with f m v = - failwith "Do not use!" + failwith "deprecated" let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v From 7b4173a4314d11061acb7296861dd4c216121757 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 26 Nov 2024 18:23:05 +0100 Subject: [PATCH 042/150] ocp-indent on sparseMatrix.ml --- .../affineEquality/sparseImplementation/sparseMatrix.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index a702229c51..c1509ecd1a 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -33,7 +33,7 @@ module ListMatrix: AbstractMatrix = let num_cols m = if m = [] then 0 else V.length (hd m) let copy m = m - (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) let copy m = Timing.wrap "copy" (copy) m From c8db710183f0ca18975a7c8ae5dc972eca0cbf07 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 26 Nov 2024 19:02:38 +0100 Subject: [PATCH 043/150] del_cols and remove_at_indices --- .../arrayImplementation/arrayVector.ml | 2 ++ .../sparseImplementation/sparseMatrix.ml | 24 ++++++------------- .../sparseImplementation/sparseVector.ml | 11 +++++++++ src/cdomains/affineEquality/vector.ml | 2 ++ .../apron/affineEqualityDomain.apron.ml | 10 ++++---- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 650b908b6c..030d397398 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -34,6 +34,8 @@ module ArrayVector: AbstractVector = if n >= Array.length v then failwith "n outside of Array range" else Array.init (Array.length v - 1) (fun i -> if i < n then Array.get v i else Array.get v (i + 1)) (* TODO: remove_at? *) + let remove_at_indices v idx = failwith "TODO" + let set_nth_with v n new_val = if n >= Array.length v then failwith "n outside of Array range" else Array.set v n new_val diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 4b5ca28560..3cee73edc9 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -39,7 +39,7 @@ module ListMatrix: AbstractMatrix = Timing.wrap "copy" (copy) m let add_empty_columns m cols = - let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in + (*let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in let emptyT = A.zero in let rec list_of_all_before_index idx cols = match cols with @@ -69,7 +69,8 @@ module ListMatrix: AbstractMatrix = match m with | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) | [] -> [] - in tM (add_empty_columns_on_list m.entries colsL) (m.column_count + Array.length cols) + in tM (add_empty_columns_on_list m.entries colsL) (m.column_count + Array.length cols)*) + failwith "TODO" let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols @@ -148,22 +149,11 @@ module ListMatrix: AbstractMatrix = let del_col m j = List.map (fun row -> V.remove_nth row j) m - - (* TODO: Might be more efficient to check for each entry how much to reduce their index and not by recursively calling del_col *) let del_cols m cols = - let cols = Array.to_list cols in (* TODO: Get away from Arrays *) - let to_delete_count = List.length cols in - if to_delete_count = 0 || is_empty m then m - else - if num_cols m = to_delete_count then empty () else - let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification)*) - let rec del_cols_aux m cols deleted_col_count = - match cols with - | [] -> m - | col_idx::cs -> - let m' = del_col m (col_idx - deleted_col_count) in (* Taking already deleted cols into account because of new index *) - del_cols_aux m' cs (deleted_col_count + 1) - in del_cols_aux m sorted_cols 0 + if (Array.length cols) = num_cols m then empty() else + let cols = Array.to_list cols in + let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification), maybe use List instead?*) + List.map (fun row -> V.remove_at_indices row sorted_cols) m let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index fbe81edbd3..c8540cb121 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -41,6 +41,17 @@ module SparseVector: AbstractVector = if n >= v.len then v else (*could be left out but maybe performance??*) {entries = remove_nth_vec v.entries n; len = v.len - 1} + let remove_at_indices v idx = + let rec remove_indices_helper vec idx deleted_count = + match vec, idx with + | [], [] -> [] + | [], (y :: ys) -> failwith "remove at indices: no more columns to delete" + | ((col_idx, value) :: xs), [] -> (col_idx - deleted_count, value) :: remove_indices_helper xs idx deleted_count + | ((col_idx, value) :: xs), (y :: ys) when y = col_idx -> remove_indices_helper xs ys (deleted_count + 1) + | ((col_idx, value) :: xs), (y :: ys) -> (col_idx - deleted_count, value) :: remove_indices_helper xs idx deleted_count + in + {entries = remove_indices_helper v.entries idx 0; len = v.len - List.length idx} + let set_nth v n m = let rec set_nth_vec v n m = match v with diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 3a7431629f..f374853b27 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -10,6 +10,8 @@ sig val remove_nth: t -> int -> t + val remove_at_indices: t -> int list -> t + val set_nth: t -> int -> num -> t val set_nth_with: t -> int -> num -> unit diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 96bca14c26..617549db53 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -79,16 +79,16 @@ struct | Scalar Mpqf x -> x | Scalar Mpfrf x -> Mpfr.to_mpq x in - Vector.set_val zero_vec ((Vector.length zero_vec) - 1) (of_union x) + Vector.set_nth zero_vec ((Vector.length zero_vec) - 1) (of_union x) | Var x -> let zero_vec_cp = Vector.copy zero_vec in - let entry_only v = Vector.set_val v (Environment.dim_of_var t.env x) Mpqf.one in + let entry_only v = Vector.set_nth v (Environment.dim_of_var t.env x) Mpqf.one in begin match t.d with | Some m -> let row = Matrix.find_opt (fun r -> Vector.nth r (Environment.dim_of_var t.env x) =: Mpqf.one) m in begin match row with | Some v when is_const_vec v -> - Vector.set_val zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)) + Vector.set_nth zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)) | _ -> entry_only zero_vec_cp end | None -> entry_only zero_vec_cp end @@ -406,7 +406,7 @@ struct let assign_uninvertible_rel x var b env = let b_length = Vector.length b in Vector.mapi_with (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b; - Vector.set_val_with b (Environment.dim_of_var env var) Mpqf.one; + Vector.set_nth_with b (Environment.dim_of_var env var) Mpqf.one; let opt_m = Matrix.rref_vec_with x b in if Option.is_none opt_m then bot () else {d = opt_m; env = env} @@ -520,7 +520,7 @@ struct let meet_vec e = (* Flip the sign of the const. val in coeff vec *) let coeff = Vector.nth e (Vector.length e - 1) in - Vector.set_val_with e (Vector.length e - 1) (Mpqf.neg coeff); + Vector.set_nth_with e (Vector.length e - 1) (Mpqf.neg coeff); if is_bot t then bot () else From 24fd0576e62ef04f78bb55cdc956469d34b1b497 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 26 Nov 2024 19:05:02 +0100 Subject: [PATCH 044/150] commiting again for indentation --- .../sparseImplementation/sparseMatrix.ml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 3cee73edc9..4ed70b03b0 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -38,8 +38,8 @@ module ListMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m - let add_empty_columns m cols = - (*let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in + let add_empty_columns m cols = failwith "TODO" + (*let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in let emptyT = A.zero in let rec list_of_all_before_index idx cols = match cols with @@ -70,7 +70,6 @@ module ListMatrix: AbstractMatrix = | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) | [] -> [] in tM (add_empty_columns_on_list m.entries colsL) (m.column_count + Array.length cols)*) - failwith "TODO" let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols @@ -150,10 +149,11 @@ module ListMatrix: AbstractMatrix = List.map (fun row -> V.remove_nth row j) m let del_cols m cols = - if (Array.length cols) = num_cols m then empty() else - let cols = Array.to_list cols in - let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification), maybe use List instead?*) - List.map (fun row -> V.remove_at_indices row sorted_cols) m + if (Array.length cols) = num_cols m then empty() + else + let cols = Array.to_list cols in + let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification), maybe use List instead?*) + List.map (fun row -> V.remove_at_indices row sorted_cols) m let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols From 0c9eb46b98bdd0ee7ae209df6fabe7df0f551dc3 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 26 Nov 2024 19:40:47 +0100 Subject: [PATCH 045/150] Vector functions --- .../sparseImplementation/sparseMatrix.ml | 4 +- .../sparseImplementation/sparseVector.ml | 39 ++++++++++++------- src/cdomains/affineEquality/vector.ml | 2 +- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index dbaeb5192a..1ba26f2771 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -146,7 +146,9 @@ module ListMatrix: AbstractMatrix = {entries = entries'; column_count = m.column_count} let del_col m j = - List.map (fun row -> V.remove_nth row j) m + if num_cols m = 1 then empty () + else + List.map (fun row -> V.remove_nth row j) m let del_cols m cols = if (Array.length cols) = num_cols m then empty() diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index c8540cb121..4b1754d8f5 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -41,6 +41,19 @@ module SparseVector: AbstractVector = if n >= v.len then v else (*could be left out but maybe performance??*) {entries = remove_nth_vec v.entries n; len = v.len - 1} + (* TODO: Which of both remmove_nth should we use *) + let remove_nth v n = + if n >= v.len then failwith "Out of bounds" + else + let new_entries = List.filter_map (fun (col_idx, value) -> + if col_idx = n + then None + else if col_idx > n + then Some (col_idx - 1, value) + else Some (col_idx, value) + ) v.entries in + {entries = new_entries; len = v.len - 1} + let remove_at_indices v idx = let rec remove_indices_helper vec idx deleted_count = match vec, idx with @@ -52,16 +65,14 @@ module SparseVector: AbstractVector = in {entries = remove_indices_helper v.entries idx 0; len = v.len - List.length idx} - let set_nth v n m = - let rec set_nth_vec v n m = - match v with - | x::xs -> if fst x = n then (n, m)::xs else - if fst x < n then x::(set_nth_vec xs n m) - else v - | [] -> [] - in - if n >= v.len then failwith "Out of bounds" else - {entries=set_nth_vec v.entries n m; len=v.len} + let set_nth v n num = + if n >= v.len then failwith "Out of bounds" + else + let new_entries = List.map (fun (col_idx, value) -> + if col_idx = n then (col_idx, num) else (col_idx, value) + ) v.entries + in + {entries= new_entries; len=v.len} let set_nth_with = failwith "deprecated" @@ -108,12 +119,13 @@ module SparseVector: AbstractVector = else let rec nth v = match v with | [] -> A.zero + | (col_idx, value) :: xs when col_idx > n -> A.zero | (col_idx, value) :: xs when col_idx = n -> value | (col_idx, value) :: xs -> nth xs in nth v.entries let length v = - failwith "TODO" + v.len let map2 f v v' = failwith "TODO" @@ -183,10 +195,7 @@ module SparseVector: AbstractVector = let to_sparse_list v = v.entries - let remove_nth v n = - failwith "TODO" - let find_opt f v = - failwith "TODO" + failwith "TODO: Do we need this?" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index f374853b27..a673b820c7 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -36,7 +36,7 @@ sig val findi: (num -> bool) -> t -> int - val find_opt: (num -> bool) -> t -> t Option.t + val find_opt: (num -> bool) -> t -> num Option.t val map: (num -> num) -> t -> t From 0db8b6101cc3863f74f01eb677b6736062a7ab32 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Wed, 27 Nov 2024 16:11:26 +0100 Subject: [PATCH 046/150] some vector functions --- .../sparseImplementation/sparseVector.ml | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 4b1754d8f5..6a792336c4 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -2,6 +2,9 @@ open AbstractVector open RatOps open ConvenienceOps +open BatList +module List = BatList + module SparseVector: AbstractVector = functor (A: RatOps) -> struct @@ -77,8 +80,14 @@ module SparseVector: AbstractVector = let set_nth_with = failwith "deprecated" - let insert_val_at n m t = - failwith "TODO" + let insert_val_at n new_val v = + if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) + let entries' = List.fold_left (fun acc (idx, value) -> + if idx < n then (idx, value) :: acc + else if idx = n then (n, new_val) :: (idx + 1, value) :: acc + else (idx + 1, value) :: acc + ) [] (List.rev v.entries) in + {entries = entries'; len = v.len + 1} let mul_vec_scal v s = {entries= (List.map (fun (idx, va) -> (idx, va *: s)) v.entries); len=v.len} @@ -110,14 +119,14 @@ module SparseVector: AbstractVector = failwith "TODO" let zero_vec n = - failwith "TODO" + {entries = []; len = n} let is_zero_vec v = (v.entries = []) let nth v n = if n >= v.len then failwith "V.nth out of bounds" else - let rec nth v = match v with + let rec nth v = match v with (* List.assoc would also work, but we use the fact that v is sorted *) | [] -> A.zero | (col_idx, value) :: xs when col_idx > n -> A.zero | (col_idx, value) :: xs when col_idx = n -> value @@ -143,19 +152,22 @@ module SparseVector: AbstractVector = failwith "TODO" let compare_length_with v n = - failwith "TODO" + Int.compare v.len n let of_list l = - failwith "TODO" + let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l + in {entries = entries'; len = List.length l} let to_list v = - failwith "TODO" + let l = List.init v.len (fun _ -> A.zero) in + List.fold_left (fun acc (idx, value) -> (List.modify_at idx (fun _ -> value) acc)) l v.entries let filteri f v = failwith "TODO" let append v v' = - failwith "TODO" + let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in + {entries = entries'; len = v.len + v'.len} let exists f v = failwith "TODO" From d439b20f591beccd6cfc2d9b2627ad87285553e6 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 28 Nov 2024 14:42:10 +0100 Subject: [PATCH 047/150] vector conversion to array --- .../sparseImplementation/sparseVector.ml | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6a792336c4..d4ea9b28fb 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -3,7 +3,9 @@ open RatOps open ConvenienceOps open BatList +open BatArray module List = BatList +module Array = BatArray module SparseVector: AbstractVector = functor (A: RatOps) -> @@ -116,7 +118,7 @@ module SparseVector: AbstractVector = failwith "TODO" let apply_with_c_with f m v = - failwith "TODO" + failwith "deprecated" let zero_vec n = {entries = []; len = n} @@ -173,31 +175,36 @@ module SparseVector: AbstractVector = failwith "TODO" let rev v = - failwith "TODO" + let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - idx, value)) v.entries in + {entries = entries'; len = v.len} let rev_with v = - failwith "TODO" + failwith "deprecated" let map2i f v v' = failwith "TODO" let map2i_with f v v' = - failwith "TODO" + failwith "deprecated" let mapi f v = failwith "TODO" let mapi_with f v = - failwith "TODO" + failwith "deprecated" let find2i f v v' = failwith "TODO" let to_array v = - failwith "TODO" + let vec = Array.make v.len A.zero in + List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; + vec let of_array a = - failwith "TODO" + let len' = Array.length a in + let entries' = List.rev @@ Array.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc ) [] a in + {entries = entries'; len = len'} let copy v = v From 03fab15a0a2b2d3067dedc1e2e65aee86f398d5d Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 15:01:50 +0100 Subject: [PATCH 048/150] Explicit types on normalize --- .../sparseImplementation/sparseMatrix.ml | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 1ba26f2771..d961b2a59c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -184,18 +184,22 @@ module ListMatrix: AbstractMatrix = failwith "deprecated" let normalize_with m = Timing.wrap "normalize_with" normalize_with m - - let normalize m = - let entries = m.entries in - let col_count = m.column_count in - let swap_rows m r1_idx r2_idx = + + let normalize (m : t) : t Option.t = + let entries = m in + let col_count = num_cols m in + let swap_rows (m : t) (r1_idx : int) (r2_idx : int) : t = + failwith "TODO" + (* List.mapi (fun i row -> if i = r1_idx then List.nth m r2_idx else if i = r2_idx then List.nth m r1_idx else row - ) entries + ) entries*) in - let rec sub_rows minu subt : (int * A.t) list = + let rec sub_rows (minu : V.t) (subt : V.t) : (int * A.t) list = + failwith "TODO" + (* match minu, subt with | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( match xidx - yidx with @@ -206,18 +210,25 @@ module ListMatrix: AbstractMatrix = | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) | ([],[]) -> [] + *) in - let div_row row pivot = + let div_row (row : V.t) (pivot : A.t) : V.t = + failwith "TODO" + (* List.map (fun (idx, value) -> (idx, value /: pivot)) row + *) in - let dec_mat_2D m = + let dec_mat_2D (m : t) : t = m in - let rec find_pivot_in_col m row_idx col_idx = + let rec find_pivot_in_col (m : t) (row_idx : int) (col_idx : int) : (int * A.t) Option.t = + failwith "TODO" + (* match m with | ((idx, value)::_)::xs -> if idx = col_idx then Some (row_idx, value) else find_pivot_in_col xs (row_idx + 1) col_idx | ([])::xs -> find_pivot_in_col xs (row_idx + 1) col_idx | [] -> None + *) in (* let rec find_pivot m col_idx row_idx = if col_idx >= col_count then None else @@ -225,7 +236,9 @@ module ListMatrix: AbstractMatrix = | Some (row_idx, value) -> Some (row_idx, value) | None -> find_pivot m (col_idx + 1) row_idx in *) - let rec main_loop m m' row_idx col_idx : (int * A.t) list list = + let rec main_loop (m : t) (m' : t) (row_idx : int) (col_idx : int) : t = + failwith "TODO" + (* if col_idx = (col_count - 1) (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) then m else @@ -239,10 +252,10 @@ module ListMatrix: AbstractMatrix = let m' = dec_mat_2D m in main_loop subtracted_m m' (row_idx + 1) (col_idx + 1) ) - + *) in - let e' = main_loop m.entries m.entries 0 0 in - Some {entries = e'; column_count = m.column_count} + let m' = main_loop m m 0 0 in + Some m' let rref_vec_helper m pivot_positions v = failwith "TODO" From f018a0630b42323d5b3ea35f33c3dae48b2a0bf7 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 28 Nov 2024 14:43:02 +0100 Subject: [PATCH 049/150] map2_preserve_zero --- .../sparseImplementation/sparseVector.ml | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6a792336c4..685fcbd22d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -89,28 +89,31 @@ module SparseVector: AbstractVector = ) [] (List.rev v.entries) in {entries = entries'; len = v.len + 1} - let mul_vec_scal v s = - {entries= (List.map (fun (idx, va) -> (idx, va *: s)) v.entries); len=v.len} - - - let add_vec v1 v2 = - let rec add_vec m s = - match m, s with - | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( - match xidx - yidx with - | d when d = 0 && (xv +: yv = A.zero) -> (xidx, xv +: yv)::(add_vec xs ys) - | d when d < 0 -> (xidx, xv)::(add_vec xs ((yidx, yv)::ys)) - | d when d > 0 -> (yidx, yv)::(add_vec ((xidx, xv)::xs) ys) - | _ -> add_vec xs ys ) (* remove row when is (0, 0) *) - | ([], y::ys) -> y::(add_vec [] ys) - | (x::xs, []) -> x::(add_vec xs []) - | ([],[]) -> [] + let map_preserve_zero f v = tV ((List.map f) v.entries) v.len + + let map2_preserve_zero f v1 v2 = + let rec map2_nonzero_aux v1 v2 = + match v1, v2 with + | [], [] -> [] + | x , y -> + let cons, xtail, ytail = + match x, y with + | (xidx, xv)::xs, (yidx,yv)::ys -> ( + match xidx - yidx with + | d when d < 0 -> (xidx, f xv A.zero), xs, v2 + | d when d > 0 -> (yidx, f A.zero yv), v1, ys + | _ -> (xidx, f xv yv) , xs, ys + ) + | (xidx, xv)::xs, [] -> (xidx, f xv A.zero), xs, [] + | [], (yidx, yv)::ys -> (yidx, f A.zero yv), [], ys + | [],[] -> raise (Failure "Should never be reached") + in + let res = if snd cons = A.zero then [] else [cons] in + res@(map2_nonzero_aux xtail ytail) in - if v1.len <> v2.len then failwith "Different Vector length" else - {entries= add_vec v1.entries v2.entries; len=v1.len} + if v1.len <> v2.len then raise (Invalid_argument "Different lengths") else + tV (map2_nonzero_aux v1.entries v2.entries) v1.len - let sub_vec v1 v2 = (*change to duplicate def of add if performance*) - add_vec v1 ({entries= (List.map (fun (idx, va) -> (idx, A.zero -: va)) v2.entries); len=v2.len}) let apply_with_c f m v = failwith "TODO" From 70dbf4de31d5ca9e4e86a4e7a23116d23bf0fa82 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 28 Nov 2024 15:15:17 +0100 Subject: [PATCH 050/150] exists, vector interface --- .../sparseImplementation/sparseVector.ml | 13 +++++++++---- src/cdomains/affineEquality/vector.ml | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 685fcbd22d..9fffacb57d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -143,7 +143,7 @@ module SparseVector: AbstractVector = failwith "TODO" let map2_with f v v' = - failwith "TODO" + failwith "deprecated" let findi f v = failwith "TODO" @@ -173,9 +173,14 @@ module SparseVector: AbstractVector = {entries = entries'; len = v.len + v'.len} let exists f v = - failwith "TODO" - - let rev v = + let c = v.len in + let rec exists_aux at f v = + match v with + | [] -> if at = 0 then false else f A.zero + | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs + in (exists_aux c f v.entries) + + let rev v = failwith "TODO" let rev_with v = diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index a673b820c7..ce7558c05a 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -18,6 +18,8 @@ sig val insert_val_at: int -> num -> t -> t + val map_preserve_zero: ((int * num) -> (int * num)) -> t -> t + val map2_preserve_zero: ((int * num) -> (int * num) -> (int * num)) -> t -> t -> t val apply_with_c: (num -> num -> num) -> num -> t -> t val apply_with_c_with: (num -> num -> num) -> num -> t -> unit From 215b25eb599b6b94a6c0efb2bc0c52d6c57b126e Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 28 Nov 2024 15:17:01 +0100 Subject: [PATCH 051/150] ups --- src/cdomains/affineEquality/vector.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index ce7558c05a..9da0729cc5 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -18,8 +18,8 @@ sig val insert_val_at: int -> num -> t -> t - val map_preserve_zero: ((int * num) -> (int * num)) -> t -> t - val map2_preserve_zero: ((int * num) -> (int * num) -> (int * num)) -> t -> t -> t + val map_preserve_zero: (num -> num) -> t -> t + val map2_preserve_zero: (num -> num -> num) -> t -> t -> t val apply_with_c: (num -> num -> num) -> num -> t -> t val apply_with_c_with: (num -> num -> num) -> num -> t -> unit From 680e56ba3ba99a8226fa0d5857d58e35ae686e16 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 16:43:01 +0100 Subject: [PATCH 052/150] Reimplemented normalize in SparseMatrix, some TODOs missing --- .../arrayImplementation/arrayMatrix.ml | 3 + src/cdomains/affineEquality/matrix.ml | 2 + .../sparseImplementation/sparseMatrix.ml | 97 ++++++++----------- src/cdomains/affineEquality/vector.ml | 2 + 4 files changed, 45 insertions(+), 59 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index dc24b7f641..9212cf501f 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -355,4 +355,7 @@ module ArrayMatrix: AbstractMatrix = map2i_with f m' v; m' + let swap_rows m j k = + failwith "TODO" + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/matrix.ml b/src/cdomains/affineEquality/matrix.ml index 33a622d81a..3b45c12f91 100644 --- a/src/cdomains/affineEquality/matrix.ml +++ b/src/cdomains/affineEquality/matrix.ml @@ -71,4 +71,6 @@ sig val copy: t -> t + val swap_rows: t -> int -> int -> t + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index d961b2a59c..658e8b4c7e 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -184,75 +184,54 @@ module ListMatrix: AbstractMatrix = failwith "deprecated" let normalize_with m = Timing.wrap "normalize_with" normalize_with m - + + + let sub_rows (minu : V.t) (subt : V.t) : V.t = + V.map2_preserve_zero (-:) minu subt + + let div_row (row : V.t) (pivot : A.t) : V.t = + V.map_preserve_zero (fun a -> a /: pivot) row + + let swap_rows m j k = + List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m k else row) m + let normalize (m : t) : t Option.t = - let entries = m in let col_count = num_cols m in - let swap_rows (m : t) (r1_idx : int) (r2_idx : int) : t = - failwith "TODO" - (* - List.mapi (fun i row -> - if i = r1_idx then List.nth m r2_idx - else if i = r2_idx then List.nth m r1_idx - else row - ) entries*) - in - let rec sub_rows (minu : V.t) (subt : V.t) : (int * A.t) list = - failwith "TODO" - (* - match minu, subt with - | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( - match xidx - yidx with - | d when d = 0 && xv <> yv -> (xidx, xv -: yv)::(sub_rows xs ys) - | d when d < 0 -> (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) - | d when d > 0 -> (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) - | _ -> sub_rows xs ys ) (* remove row when is (0, 0) *) - | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) - | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) - | ([],[]) -> [] - *) - in - let div_row (row : V.t) (pivot : A.t) : V.t = - failwith "TODO" - (* - List.map (fun (idx, value) -> (idx, value /: pivot)) row - *) - in - let dec_mat_2D (m : t) : t = + + let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = m in - let rec find_pivot_in_col (m : t) (row_idx : int) (col_idx : int) : (int * A.t) Option.t = - failwith "TODO" - (* - match m with - | ((idx, value)::_)::xs -> if idx = col_idx then Some (row_idx, value) else find_pivot_in_col xs (row_idx + 1) col_idx - | ([])::xs -> find_pivot_in_col xs (row_idx + 1) col_idx - | [] -> None - *) - in - (* let rec find_pivot m col_idx row_idx = - if col_idx >= col_count then None else - match find_pivot_in_col m col_idx row_idx with - | Some (row_idx, value) -> Some (row_idx, value) - | None -> find_pivot m (col_idx + 1) row_idx - in *) + (* Function for finding a pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) + let rec find_pivot (m : t) (row_idx : int) (col_idx : int) : (int * int * A.t) Option.t = + if col_idx >= col_count then None else + let get_first_non_zero v = (* Returns (col_idx, value) of first non-zero row*) + let v' = V.to_sparse_list v in + match v' with + | [] -> None + | (idx, value)::_ -> Some (idx, value) + in + (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) + let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> + let row_first_non_zero = get_first_non_zero row in + match row_first_non_zero with + | None -> (cur_row, cur_col, cur_val) + | Some (col_idx, value) -> if col_idx < cur_col then (i, col_idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) + in + if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) + in let rec main_loop (m : t) (m' : t) (row_idx : int) (col_idx : int) : t = - failwith "TODO" - (* - if col_idx = (col_count - 1) (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) - then m + if col_idx = (col_count - 1) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else - match find_pivot_in_col m' row_idx col_idx with - | None -> main_loop m m' row_idx (col_idx + 1) - | Some (piv_row_idx, piv_val) -> ( + match find_pivot m' row_idx col_idx with + | None -> m (* No pivot found means already normalized*) + | Some (piv_row_idx, piv_col_idx, piv_val) -> ( let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in let piv_row = (List.nth normalized_m row_idx) in let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in - let m' = dec_mat_2D m in - main_loop subtracted_m m' (row_idx + 1) (col_idx + 1) - ) - *) + let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in + main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in Some m' diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 9da0729cc5..0412c05356 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -19,7 +19,9 @@ sig val insert_val_at: int -> num -> t -> t val map_preserve_zero: (num -> num) -> t -> t + val map2_preserve_zero: (num -> num -> num) -> t -> t -> t + val apply_with_c: (num -> num -> num) -> num -> t -> t val apply_with_c_with: (num -> num -> num) -> num -> t -> unit From 40996b77fdc523a3a52055cf7690ec4ff18eb383 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 28 Nov 2024 16:50:14 +0100 Subject: [PATCH 053/150] Renamed sparseMatrix.ml to match module name --- .../sparseImplementation/{sparseMatrix.ml => listMatrix.ml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/cdomains/affineEquality/sparseImplementation/{sparseMatrix.ml => listMatrix.ml} (99%) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml similarity index 99% rename from src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml rename to src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index d961b2a59c..8756be9712 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -184,7 +184,7 @@ module ListMatrix: AbstractMatrix = failwith "deprecated" let normalize_with m = Timing.wrap "normalize_with" normalize_with m - + let normalize (m : t) : t Option.t = let entries = m in let col_count = num_cols m in From 702f258a9c3f3914a9751531ed0d574a7975dcc1 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 28 Nov 2024 16:56:34 +0100 Subject: [PATCH 054/150] builds now + reduce_col --- .../arrayImplementation/arrayVector.ml | 3 ++ .../sparseImplementation/sparseMatrix.ml | 44 ++++++------------- .../sparseImplementation/sparseVector.ml | 18 ++++++-- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 030d397398..05cbaec7d1 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -111,4 +111,7 @@ module ArrayVector: AbstractVector = let find_opt f v = failwith "TODO" + + let map_preserve_zero f v = failwith "TODO" + let map2_preserve_zero f v1 v2 = failwith "TODO" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml index 8756be9712..76b7868f5f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseMatrix.ml @@ -106,44 +106,28 @@ module ListMatrix: AbstractMatrix = failwith "deprecated" let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j - let reduce_col m j = + let reduce_col m j = if is_empty m then m else let rec find_pivot idx entries = (* Finds non-zero element in column j and returns pair of row idx and the pivot value *) match entries with | [] -> None - | row :: rest -> match (List.assoc_opt j row) with - | None -> find_pivot (idx - 1) rest - | Some value -> Some (idx, value) + | row :: rest -> let value = V.nth row j in + if value =: A.zero then find_pivot (idx - 1) rest else Some (idx, value) in - match (find_pivot (num_rows m - 1) (List.rev m.entries)) with + match (find_pivot (num_rows m - 1) (List.rev m)) with | None -> m (* column is already filled with zeroes *) | Some (row_idx, pivot) -> - let pivot_row = List.nth m.entries row_idx in - let entries' = - List.mapi(fun idx row -> - if idx = row_idx then - [] - else - match (List.assoc_opt j row) with (* Find column element in row and, if it exists, subtract row *) - | None -> row - | Some row_value -> (let s = row_value /: pivot in - let rec merge acc piv_row cur_row = - match piv_row, cur_row with - | [], [] -> acc - | [], (i, value) :: rest -> merge ((i, value) :: acc) piv_row rest - | (i, value) :: rest, [] -> let new_value = A.zero -: s *: value in merge ((i, new_value) :: acc) rest cur_row - | (i, piv_val) :: piv_rest, (j, cur_val) :: cur_rest -> - if i = j then - let new_value = cur_val -: s *: piv_val in merge ((i, new_value) :: acc) piv_rest cur_rest - else if i < j then - let new_value = A.zero -: s *: piv_val in merge ((i, new_value) :: acc) piv_rest cur_row - else - merge ((j, cur_val) :: acc) piv_row cur_rest - in List.rev @@ merge [] pivot_row row) - ) m.entries - in - {entries = entries'; column_count = m.column_count} + let pivot_row = List.nth m row_idx in + List.mapi (fun idx row -> + if idx = row_idx then + V.zero_vec (num_cols m) + else + let row_value = V.nth row j in + if row_value = A.zero then row + else (let s = row_value /: pivot in + V.map2_preserve_zero (fun x y -> x -: s *: y) row pivot_row) + ) m let del_col m j = if num_cols m = 1 then empty () diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 218fb36578..a346d0fc51 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -18,8 +18,6 @@ module SparseVector: AbstractVector = }[@@deriving eq, ord, hash] let tV e l = {entries=e; len=l} - let show v = - failwith "TODO" let keep_vals v n = let rec keep_vals_vec v n = @@ -91,8 +89,13 @@ module SparseVector: AbstractVector = ) [] (List.rev v.entries) in {entries = entries'; len = v.len + 1} - let map_preserve_zero f v = tV ((List.map f) v.entries) v.len + let map_preserve_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) + let entries' = List.filter_map ( + fun (idx, value) -> let new_val = f value in + if new_val = A.zero then None else Some (idx, new_val)) v.entries in + {entries = entries'; len = v.len} + (* map for functions f such that f 0 0 = 0 since f won't be applied to if both values are zero. See also map *) let map2_preserve_zero f v1 v2 = let rec map2_nonzero_aux v1 v2 = match v1, v2 with @@ -225,4 +228,13 @@ module SparseVector: AbstractVector = let find_opt f v = failwith "TODO: Do we need this?" + let show v = + let t = to_list v in + let rec list_str l = + match l with + | [] -> "]" + | x :: xs -> (A.to_string x) ^" "^(list_str xs) + in + "["^list_str t^"\n" + end \ No newline at end of file From bec7535afb3f47a6824e45675cb8543c5e0b8fc7 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 17:14:15 +0100 Subject: [PATCH 055/150] Moved swap, div, sub and normalize to new listMatrix.ml --- .../sparseImplementation/listMatrix.ml | 94 +++++++------------ 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 76b7868f5f..a4b66bf4b2 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -169,74 +169,52 @@ module ListMatrix: AbstractMatrix = let normalize_with m = Timing.wrap "normalize_with" normalize_with m + let sub_rows (minu : V.t) (subt : V.t) : V.t = + V.map2_preserve_zero (-:) minu subt + + let div_row (row : V.t) (pivot : A.t) : V.t = + V.map_preserve_zero (fun a -> a /: pivot) row + + let swap_rows m j k = + List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m k else row) m + let normalize (m : t) : t Option.t = - let entries = m in let col_count = num_cols m in - let swap_rows (m : t) (r1_idx : int) (r2_idx : int) : t = - failwith "TODO" - (* - List.mapi (fun i row -> - if i = r1_idx then List.nth m r2_idx - else if i = r2_idx then List.nth m r1_idx - else row - ) entries*) - in - let rec sub_rows (minu : V.t) (subt : V.t) : (int * A.t) list = - failwith "TODO" - (* - match minu, subt with - | ((xidx, xv)::xs, (yidx,yv)::ys) -> ( - match xidx - yidx with - | d when d = 0 && xv <> yv -> (xidx, xv -: yv)::(sub_rows xs ys) - | d when d < 0 -> (xidx, xv)::(sub_rows xs ((yidx, yv)::ys)) - | d when d > 0 -> (yidx, A.zero -: yv)::(sub_rows ((xidx, xv)::xs) ys) - | _ -> sub_rows xs ys ) (* remove row when is (0, 0) *) - | ([], (yidx, yv)::ys) -> (yidx, A.zero -: yv)::(sub_rows [] ys) - | ((xidx, xv)::xs, []) -> (xidx, xv)::(sub_rows xs []) - | ([],[]) -> [] - *) - in - let div_row (row : V.t) (pivot : A.t) : V.t = - failwith "TODO" - (* - List.map (fun (idx, value) -> (idx, value /: pivot)) row - *) - in - let dec_mat_2D (m : t) : t = + + let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = m in - let rec find_pivot_in_col (m : t) (row_idx : int) (col_idx : int) : (int * A.t) Option.t = - failwith "TODO" - (* - match m with - | ((idx, value)::_)::xs -> if idx = col_idx then Some (row_idx, value) else find_pivot_in_col xs (row_idx + 1) col_idx - | ([])::xs -> find_pivot_in_col xs (row_idx + 1) col_idx - | [] -> None - *) - in - (* let rec find_pivot m col_idx row_idx = - if col_idx >= col_count then None else - match find_pivot_in_col m col_idx row_idx with - | Some (row_idx, value) -> Some (row_idx, value) - | None -> find_pivot m (col_idx + 1) row_idx - in *) + (* Function for finding a pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) + let rec find_pivot (m : t) (row_idx : int) (col_idx : int) : (int * int * A.t) Option.t = + if col_idx >= col_count then None else + let get_first_non_zero v = (* Returns (col_idx, value) of first non-zero row*) + let v' = V.to_sparse_list v in + match v' with + | [] -> None + | (idx, value)::_ -> Some (idx, value) + in + (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) + let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> + let row_first_non_zero = get_first_non_zero row in + match row_first_non_zero with + | None -> (cur_row, cur_col, cur_val) + | Some (col_idx, value) -> if col_idx < cur_col then (i, col_idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) + in + if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) + in let rec main_loop (m : t) (m' : t) (row_idx : int) (col_idx : int) : t = - failwith "TODO" - (* - if col_idx = (col_count - 1) (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) - then m + if col_idx = (col_count - 1) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else - match find_pivot_in_col m' row_idx col_idx with - | None -> main_loop m m' row_idx (col_idx + 1) - | Some (piv_row_idx, piv_val) -> ( + match find_pivot m' row_idx col_idx with + | None -> m (* No pivot found means already normalized*) + | Some (piv_row_idx, piv_col_idx, piv_val) -> ( let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in let piv_row = (List.nth normalized_m row_idx) in let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in - let m' = dec_mat_2D m in - main_loop subtracted_m m' (row_idx + 1) (col_idx + 1) - ) - *) + let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in + main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in Some m' From ad34bc7470a70b33e14b2bd6bf8f71a63294eae9 Mon Sep 17 00:00:00 2001 From: Havercake Date: Thu, 28 Nov 2024 17:19:51 +0100 Subject: [PATCH 056/150] Renamed tV according to best practices --- .../affineEquality/sparseImplementation/sparseVector.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index a346d0fc51..f8b65afb9a 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -17,7 +17,7 @@ module SparseVector: AbstractVector = len: int }[@@deriving eq, ord, hash] - let tV e l = {entries=e; len=l} + let to_vector e l = {entries=e; len=l} let keep_vals v n = let rec keep_vals_vec v n = @@ -117,7 +117,7 @@ module SparseVector: AbstractVector = res@(map2_nonzero_aux xtail ytail) in if v1.len <> v2.len then raise (Invalid_argument "Different lengths") else - tV (map2_nonzero_aux v1.entries v2.entries) v1.len + to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len let apply_with_c f m v = From bd81ac15d0726adc1207c0cc04121ff7ccf27568 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 18:00:42 +0100 Subject: [PATCH 057/150] Implement vector findi and minor bugfix in ListMatrix normalize --- .../affineEquality/sparseImplementation/listMatrix.ml | 2 +- .../affineEquality/sparseImplementation/sparseVector.ml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index a4b66bf4b2..4fb1f80969 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -198,7 +198,7 @@ module ListMatrix: AbstractMatrix = let row_first_non_zero = get_first_non_zero row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) - | Some (col_idx, value) -> if col_idx < cur_col then (i, col_idx, value) else (cur_row, cur_col, cur_val) + | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) in if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index f8b65afb9a..1fefe8e545 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -151,7 +151,10 @@ module SparseVector: AbstractVector = failwith "deprecated" let findi f v = - failwith "TODO" + if f A.zero then + fst @@ List.findi (fun i (idx, value) -> if idx > i then true else f value) v.entries (* Here fst is the iteration variable i, not the tuple idx *) + else + fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) let map f v = failwith "TODO" From 06a32ea49ae2d8393f9846648ffd05f06e1be0d4 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 28 Nov 2024 18:26:52 +0100 Subject: [PATCH 058/150] vectorfuncs, foldleftpreservezero --- .../sparseImplementation/sparseVector.ml | 42 ++++++++++++------- src/cdomains/affineEquality/vector.ml | 8 +++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 1fefe8e545..10dfdb90c6 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -117,8 +117,13 @@ module SparseVector: AbstractVector = res@(map2_nonzero_aux xtail ytail) in if v1.len <> v2.len then raise (Invalid_argument "Different lengths") else - to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len + to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len + let fold_left_preserve_zero f v = + failwith "TODO" + + let fold_left2_preserve_zero f v v' = + failwith "TODO" let apply_with_c f m v = failwith "TODO" @@ -143,10 +148,24 @@ module SparseVector: AbstractVector = let length v = v.len + + let of_list l = + let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l + in {entries = entries'; len = List.length l} + let to_list v = + let[@tail_mod_cons] rec extend_zero_aux i v' = + if i >= v.len then failwith "out of Bounds for to_list" else (*can probably be removed*) + match v' with + | (xi,xv)::xs -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero::(extend_zero_aux (i+1) v') + | [] -> [] + in + (extend_zero_aux 0 v.entries) + let map2 f v v' = - failwith "TODO" - + if v.len <> v'.len then failwith "Unequal vector length" else + of_list (List.map2 f (to_list v) (to_list v')) + let map2_with f v v' = failwith "deprecated" @@ -157,22 +176,14 @@ module SparseVector: AbstractVector = fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) let map f v = - failwith "TODO" + of_list (List.map f (to_list v)) let map_with f v = - failwith "TODO" + failwith "deprecated" let compare_length_with v n = Int.compare v.len n - let of_list l = - let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l - in {entries = entries'; len = List.length l} - - let to_list v = - let l = List.init v.len (fun _ -> A.zero) in - List.fold_left (fun acc (idx, value) -> (List.modify_at idx (fun _ -> value) acc)) l v.entries - let filteri f v = failwith "TODO" @@ -196,20 +207,19 @@ module SparseVector: AbstractVector = failwith "deprecated" let map2i f v v' = - failwith "TODO" + of_list (List.map2i f (to_list v) (to_list v')) let map2i_with f v v' = failwith "deprecated" let mapi f v = - failwith "TODO" + of_list (List.mapi f (to_list v)) let mapi_with f v = failwith "deprecated" let find2i f v v' = failwith "TODO" - let to_array v = let vec = Array.make v.len A.zero in List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 9da0729cc5..96f89dcb18 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -19,7 +19,13 @@ sig val insert_val_at: int -> num -> t -> t val map_preserve_zero: (num -> num) -> t -> t - val map2_preserve_zero: (num -> num -> num) -> t -> t -> t + + val map2_preserve_zero: (num -> num -> num) -> t -> t -> t + + val fold_left_preserve_zero: ('acc -> num -> 'acc) -> t -> 'acc + + val fold_left2_preserve_zero: ('acc -> num -> num -> 'acc) -> t -> t -> 'acc + val apply_with_c: (num -> num -> num) -> num -> t -> t val apply_with_c_with: (num -> num -> num) -> num -> t -> unit From 05a3dc5dd1cc7c6aa79647f0d7b163590acd64a8 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 18:37:11 +0100 Subject: [PATCH 059/150] Add normalize check for invalid affeq matrix --- .../affineEquality/sparseImplementation/listMatrix.ml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 4fb1f80969..9b684406aa 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -178,6 +178,12 @@ module ListMatrix: AbstractMatrix = let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m k else row) m + let is_valid_affeq_matrix m = + let col_count = num_cols m in + List.exists (fun row -> (* Invalid if row is zero, but coefficient is not zero *) + V.fold_left_preserve_zero (fun found_non_zero (col_idx, value) -> if col_idx = col_count - 1 && (not found_non_zero) && (value <>: A.zero) then false else found_non_zero) false row + ) m + let normalize (m : t) : t Option.t = let col_count = num_cols m in @@ -204,7 +210,7 @@ module ListMatrix: AbstractMatrix = if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) in let rec main_loop (m : t) (m' : t) (row_idx : int) (col_idx : int) : t = - if col_idx = (col_count - 1) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) + if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else match find_pivot m' row_idx col_idx with | None -> m (* No pivot found means already normalized*) @@ -217,7 +223,7 @@ module ListMatrix: AbstractMatrix = main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in - Some m' + if is_valid_affeq_matrix m' then Some m' else None let rref_vec_helper m pivot_positions v = failwith "TODO" From 409c01d0f42b914cca3a5c39119eee9499a5f4b8 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 21:09:55 +0100 Subject: [PATCH 060/150] Vector function findi_val_opt --- .../arrayImplementation/arrayVector.ml | 16 +++++++++ .../sparseImplementation/sparseVector.ml | 33 ++++++++++++------- src/cdomains/affineEquality/vector.ml | 5 ++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 05cbaec7d1..dcd442f498 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -114,4 +114,20 @@ module ArrayVector: AbstractVector = let map_preserve_zero f v = failwith "TODO" let map2_preserve_zero f v1 v2 = failwith "TODO" + + let fold_left_preserve_zero f v = + failwith "TODO" + + let fold_left2_preserve_zero f v v' = + failwith "TODO" + + let fold_left_preserve_zero f v = + failwith "TODO" + + let fold_left2_preserve_zero f v v' = + failwith "TODO" + + let findi_val_opt f v = + failwith "TODO" + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 10dfdb90c6..4f275f4514 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -117,7 +117,7 @@ module SparseVector: AbstractVector = res@(map2_nonzero_aux xtail ytail) in if v1.len <> v2.len then raise (Invalid_argument "Different lengths") else - to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len + to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len let fold_left_preserve_zero f v = failwith "TODO" @@ -148,24 +148,24 @@ module SparseVector: AbstractVector = let length v = v.len - + let of_list l = let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l in {entries = entries'; len = List.length l} let to_list v = let[@tail_mod_cons] rec extend_zero_aux i v' = - if i >= v.len then failwith "out of Bounds for to_list" else (*can probably be removed*) - match v' with - | (xi,xv)::xs -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero::(extend_zero_aux (i+1) v') - | [] -> [] - in - (extend_zero_aux 0 v.entries) - + if i >= v.len then failwith "out of Bounds for to_list" else (*can probably be removed*) + match v' with + | (xi,xv)::xs -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero::(extend_zero_aux (i+1) v') + | [] -> [] + in + (extend_zero_aux 0 v.entries) + let map2 f v v' = if v.len <> v'.len then failwith "Unequal vector length" else - of_list (List.map2 f (to_list v) (to_list v')) - + of_list (List.map2 f (to_list v) (to_list v')) + let map2_with f v v' = failwith "deprecated" @@ -175,6 +175,17 @@ module SparseVector: AbstractVector = else fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) + let findi_val_opt f v = + if f A.zero then + ( + let i, (col_idx, value) = List.findi (fun i (idx, value) -> if idx > i then true else f value) v.entries in + if i < col_idx then (* In this case, Zero was the first element found because iteration index i is smaller than "found" value *) + Some (i, A.zero) + else Some (col_idx, value) + ) + else + Some (List.find (fun (idx, value) -> f value) v.entries) + let map f v = of_list (List.map f (to_list v)) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 96f89dcb18..a97289b768 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -21,7 +21,7 @@ sig val map_preserve_zero: (num -> num) -> t -> t val map2_preserve_zero: (num -> num -> num) -> t -> t -> t - + val fold_left_preserve_zero: ('acc -> num -> 'acc) -> t -> 'acc val fold_left2_preserve_zero: ('acc -> num -> num -> 'acc) -> t -> t -> 'acc @@ -44,6 +44,9 @@ sig val findi: (num -> bool) -> t -> int + (* Returns optional tuple of position and value which was found*) + val findi_val_opt: (num -> bool) -> t -> (int * num) Option.t + val find_opt: (num -> bool) -> t -> num Option.t val map: (num -> num) -> t -> t From ad9f6180fe84e8c466dc74942ff4a1224738db52 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 21:11:15 +0100 Subject: [PATCH 061/150] Adapting normalize and reordering deprecated functions in ListMatrix.ml --- .../arrayImplementation/arrayMatrix.ml | 12 +- .../sparseImplementation/listMatrix.ml | 107 +++++++++--------- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 9212cf501f..1f4722adff 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -321,8 +321,6 @@ module ArrayMatrix: AbstractMatrix = let find_opt f m = let f' x = f (V.of_array x) in Option.map V.of_array (Array.find_opt f' m) - let map2 f m v = - let f' x y = V.to_array @@ f (V.of_array x) y in Array.map2 f' m (V.to_array v) let map2_with f m v = if num_rows m = V.length v then @@ -332,6 +330,16 @@ module ArrayMatrix: AbstractMatrix = m.(i) <- V.to_array @@ f (V.of_array m.(i)) (V.nth v i) done + (* Deprecated + let map2 f m v = + let f' x y = V.to_array @@ f (V.of_array x) y in Array.map2 f' m (V.to_array v) + *) + + let map2 f m v = + let m' = copy m in + map2_with f m' v; + m' + let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v let map2i_with f m v = diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 9b684406aa..6b1c71d52c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -89,11 +89,6 @@ module ListMatrix: AbstractMatrix = let get_col m n = Timing.wrap "get_col" (get_col m) n - let set_col_with m new_col n = - failwith "deprecated" - - let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n - let set_col m new_col n = List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m @@ -102,10 +97,6 @@ module ListMatrix: AbstractMatrix = let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 - let reduce_col_with m j = - failwith "deprecated" - - let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j let reduce_col m j = if is_empty m then m else @@ -150,11 +141,6 @@ module ListMatrix: AbstractMatrix = let remove_zero_rows m = List.filter (fun row -> not (V.is_zero_vec row)) m - let rref_with m = - failwith "deprecated" - - let rref_with m = Timing.wrap "rref_with" rref_with m - let init_with_vec v = [v] @@ -164,11 +150,6 @@ module ListMatrix: AbstractMatrix = let get_pivot_positions m = failwith "TODO" - let normalize_with m = - failwith "deprecated" - - let normalize_with m = Timing.wrap "normalize_with" normalize_with m - let sub_rows (minu : V.t) (subt : V.t) : V.t = V.map2_preserve_zero (-:) minu subt @@ -176,32 +157,28 @@ module ListMatrix: AbstractMatrix = V.map_preserve_zero (fun a -> a /: pivot) row let swap_rows m j k = - List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m k else row) m + List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m let is_valid_affeq_matrix m = + failwith "TODO" + (* let col_count = num_cols m in List.exists (fun row -> (* Invalid if row is zero, but coefficient is not zero *) - V.fold_left_preserve_zero (fun found_non_zero (col_idx, value) -> if col_idx = col_count - 1 && (not found_non_zero) && (value <>: A.zero) then false else found_non_zero) false row + V.fold_left_preserve_zero (fun found_non_zero (col_idx, value) -> if col_idx = col_count - 1 && (not found_non_zero) && (value <>: A.zero) then false else found_non_zero) false row ) m + *) - let normalize (m : t) : t Option.t = + let normalize m = let col_count = num_cols m in - let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = m in - (* Function for finding a pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) - let rec find_pivot (m : t) (row_idx : int) (col_idx : int) : (int * int * A.t) Option.t = + (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) + let find_first_pivot m row_idx col_idx = if col_idx >= col_count then None else - let get_first_non_zero v = (* Returns (col_idx, value) of first non-zero row*) - let v' = V.to_sparse_list v in - match v' with - | [] -> None - | (idx, value)::_ -> Some (idx, value) - in (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> - let row_first_non_zero = get_first_non_zero row in + let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) @@ -209,10 +186,10 @@ module ListMatrix: AbstractMatrix = in if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) in - let rec main_loop (m : t) (m' : t) (row_idx : int) (col_idx : int) : t = + let rec main_loop m m' row_idx col_idx = if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else - match find_pivot m' row_idx col_idx with + match find_first_pivot m' row_idx col_idx with | None -> m (* No pivot found means already normalized*) | Some (piv_row_idx, piv_col_idx, piv_val) -> ( let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in @@ -225,16 +202,6 @@ module ListMatrix: AbstractMatrix = let m' = main_loop m m 0 0 in if is_valid_affeq_matrix m' then Some m' else None - let rref_vec_helper m pivot_positions v = - failwith "TODO" - - let rref_vec_with m v = - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) - (*m must be in rref form and contain the same num of cols as v*) - (*If m is empty then v is simply normalized and returned*) - failwith "deprecated" - - let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) (*m must be in rref form and contain the same num of cols as v*) @@ -243,13 +210,6 @@ module ListMatrix: AbstractMatrix = let rref_vec m v = normalize @@ append_matrices m (init_with_vec v) - let rref_matrix_with m1 m2 = - (*Similar to rref_vec_with but takes two matrices instead.*) - (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - failwith "deprecated" - - let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 - (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) (*TODO: OPTIMIZE!*) @@ -268,13 +228,56 @@ module ListMatrix: AbstractMatrix = let vector_length = V.length v in List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m + let rref_vec_helper m pivot_positions v = + failwith "TODO" + + + (* ------------------------- Deprecated ------------------------*) + + let rref_vec_with m v = + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) + (*m must be in rref form and contain the same num of cols as v*) + (*If m is empty then v is simply normalized and returned*) + failwith "deprecated" + + let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v + let rref_with m = + failwith "deprecated" + + let reduce_col_with m j = + failwith "deprecated" + + let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j + + + let rref_with m = Timing.wrap "rref_with" rref_with m + + let normalize_with m = + failwith "deprecated" + + let normalize_with m = Timing.wrap "normalize_with" normalize_with m + + + let set_col_with m new_col n = + failwith "deprecated" + + let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n + let map2_with f m v = failwith "deprecated" let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v let map2i_with f m v = - failwith "Do not use!" + failwith "deprecated" let map2i_with f m v = Timing.wrap "map2i_with" (map2i_with f m) v + + let rref_matrix_with m1 m2 = + (*Similar to rref_vec_with but takes two matrices instead.*) + (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) + failwith "deprecated" + + let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 + end \ No newline at end of file From 33b8723cb16e9ff1ac0aa304027acecd84237df1 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 28 Nov 2024 21:44:04 +0100 Subject: [PATCH 062/150] Implement Vector foldleft and apply_with_c --- .../arrayImplementation/arrayVector.ml | 10 ++-------- .../sparseImplementation/sparseVector.ml | 13 +++++++------ src/cdomains/affineEquality/vector.ml | 4 ++-- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index dcd442f498..9a0bc3b8a8 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -115,16 +115,10 @@ module ArrayVector: AbstractVector = let map_preserve_zero f v = failwith "TODO" let map2_preserve_zero f v1 v2 = failwith "TODO" - let fold_left_preserve_zero f v = + let fold_left_preserve_zero f acc v = failwith "TODO" - let fold_left2_preserve_zero f v v' = - failwith "TODO" - - let fold_left_preserve_zero f v = - failwith "TODO" - - let fold_left2_preserve_zero f v v' = + let fold_left2_preserve_zero f acc v v' = failwith "TODO" let findi_val_opt f v = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 4f275f4514..814121349c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -119,14 +119,15 @@ module SparseVector: AbstractVector = if v1.len <> v2.len then raise (Invalid_argument "Different lengths") else to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len - let fold_left_preserve_zero f v = - failwith "TODO" + let fold_left_preserve_zero f acc v = + List.fold_left (fun acc (_, value) -> f acc value) acc v.entries - let fold_left2_preserve_zero f v v' = - failwith "TODO" + let fold_left2_preserve_zero f acc v v' = + List.fold_left2 (fun acc (_, value) (_, value') -> f acc value value') acc v.entries v'.entries - let apply_with_c f m v = - failwith "TODO" + let apply_with_c f c v = + let entries' = List.map (fun (idx, value) -> (idx, f value c)) v.entries in + {entries = entries'; len = v.len} let apply_with_c_with f m v = failwith "deprecated" diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index a97289b768..3fe0fa69e4 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -22,9 +22,9 @@ sig val map2_preserve_zero: (num -> num -> num) -> t -> t -> t - val fold_left_preserve_zero: ('acc -> num -> 'acc) -> t -> 'acc + val fold_left_preserve_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc - val fold_left2_preserve_zero: ('acc -> num -> num -> 'acc) -> t -> t -> 'acc + val fold_left2_preserve_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc val apply_with_c: (num -> num -> num) -> num -> t -> t From 785f75d85b0d759f2d226a77a2479c481ef9257b Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Fri, 29 Nov 2024 18:16:42 +0100 Subject: [PATCH 063/150] add column and helper functions --- .../arrayImplementation/arrayVector.ml | 2 + .../sparseImplementation/listMatrix.ml | 41 +++++-------------- .../sparseImplementation/sparseVector.ml | 15 ++++++- src/cdomains/affineEquality/vector.ml | 2 + .../apron/affineEqualityDomain.apron.ml | 1 + src/goblint_lib.ml | 2 +- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 9a0bc3b8a8..2fefdd0043 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -36,6 +36,8 @@ module ArrayVector: AbstractVector = let remove_at_indices v idx = failwith "TODO" + let insert_zero_at_indices v idx = failwith "TODO" + let set_nth_with v n new_val = if n >= Array.length v then failwith "n outside of Array range" else Array.set v n new_val diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 6b1c71d52c..a888834a73 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -38,38 +38,17 @@ module ListMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m - let add_empty_columns m cols = failwith "TODO" - (*let colsL = List.sort (fun a b -> a-b) (Array.to_list cols) in - let emptyT = A.zero in - let rec list_of_all_before_index idx cols = - match cols with - | x::xs -> - if x < idx - then - let (h,t) = list_of_all_before_index idx xs in - (x::h, t) - else ([],x::xs) - | [] -> ([],[]) + let add_empty_columns m cols = + let cols = Array.to_list cols in + let sorted_cols = List.sort Stdlib.compare cols in + let rec count_sorted_occ acc cols last count = + match cols with + | [] -> acc + | (x :: xs) when x = last -> count_sorted_occ acc xs x (count + 1) + | (x :: xs) -> count_sorted_occ ((last, count) :: acc) xs x 1 in - (*This could easily be abstracted into the above functions, but its nice to have - it here for readability and debugging*) - let rec make_empty_entries_for_idxs idxs = - match idxs with - | x::xs -> (x, emptyT)::(make_empty_entries_for_idxs xs) - | [] -> [] - in - let rec add_column_element r cols = - match r with - | (idx, _)::xs -> - let (bef,aft) = list_of_all_before_index idx cols in - (make_empty_entries_for_idxs bef)@(add_column_element xs aft) - | [] -> [] - in - let rec add_empty_columns_on_list m cols = - match m with - | x::xs -> (add_column_element x cols)::(add_empty_columns_on_list xs cols) - | [] -> [] - in tM (add_empty_columns_on_list m.entries colsL) (m.column_count + Array.length cols)*) + let occ_cols = count_sorted_occ [] sorted_cols (-1) 0 in + List.map (fun row -> V.insert_zero_at_indices row occ_cols) m let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 814121349c..d01ca2704b 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -62,12 +62,25 @@ module SparseVector: AbstractVector = match vec, idx with | [], [] -> [] | [], (y :: ys) -> failwith "remove at indices: no more columns to delete" - | ((col_idx, value) :: xs), [] -> (col_idx - deleted_count, value) :: remove_indices_helper xs idx deleted_count + | ((col_idx, value) :: xs), [] -> (col_idx - deleted_count, value) :: remove_indices_helper xs [] deleted_count | ((col_idx, value) :: xs), (y :: ys) when y = col_idx -> remove_indices_helper xs ys (deleted_count + 1) + | ((col_idx, value) :: xs), (y :: ys) when y < col_idx -> remove_indices_helper vec ys (deleted_count + 1) | ((col_idx, value) :: xs), (y :: ys) -> (col_idx - deleted_count, value) :: remove_indices_helper xs idx deleted_count in {entries = remove_indices_helper v.entries idx 0; len = v.len - List.length idx} + let insert_zero_at_indices v idx = + let rec add_indices_helper vec idx added_count = + match vec, idx with + | [], [] -> [] + | [], (y :: ys) -> [] (* inserting at the end only means changing the dimension *) + | ((col_idx, value) :: xs), [] -> (col_idx + added_count, value) :: add_indices_helper xs [] added_count + | ((col_idx, value) :: xs), ((i, count) :: ys) when i = col_idx -> add_indices_helper vec ys (added_count + count) + | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> (col_idx + added_count + count, value) :: add_indices_helper xs ys (added_count + count) + | ((col_idx, value) :: xs), ((i, count) :: ys) -> (col_idx + added_count, value) :: add_indices_helper xs idx added_count + in + {entries = add_indices_helper v.entries idx 0; len = v.len + List.length idx} + let set_nth v n num = if n >= v.len then failwith "Out of bounds" else diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 3fe0fa69e4..e4c9fa90b4 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -12,6 +12,8 @@ sig val remove_at_indices: t -> int list -> t + val insert_zero_at_indices: t -> (int * int) list -> t + val set_nth: t -> int -> num -> t val set_nth_with: t -> int -> num -> unit diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 617549db53..7700444018 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -19,6 +19,7 @@ open AbstractMatrix open Batteries module Array = Batteries.Array +module Mpqf = SharedFunctions.Mpqf module Mpqf = SharedFunctions.Mpqf module AffineEqualityMatrix (Vec: AbstractVector) (Mx: AbstractMatrix) = diff --git a/src/goblint_lib.ml b/src/goblint_lib.ml index a5fe9230fe..0bf0be6bfb 100644 --- a/src/goblint_lib.ml +++ b/src/goblint_lib.ml @@ -438,7 +438,7 @@ module AbstractMatrix = AbstractMatrix module ArrayVector = ArrayVector module ArrayMatrix = ArrayMatrix module SparseVector = SparseVector -module SparseMatrix = SparseMatrix +module ListMatrix = ListMatrix module RatOps = RatOps module ConvenienceOps = ConvenienceOps From fe9513ad042b257df6f53896b25d46ee6bfb9d5a Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 30 Nov 2024 14:13:41 +0100 Subject: [PATCH 064/150] Fix del_cols duplicate edge case chech before comparing length --- .../sparseImplementation/listMatrix.ml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index a888834a73..2486e792d6 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -69,7 +69,8 @@ module ListMatrix: AbstractMatrix = Timing.wrap "get_col" (get_col m) n let set_col m new_col n = - List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m + (* List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m *) + List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) m1 @ m2 @@ -105,17 +106,18 @@ module ListMatrix: AbstractMatrix = List.map (fun row -> V.remove_nth row j) m let del_cols m cols = - if (Array.length cols) = num_cols m then empty() + let cols = Array.to_list cols in (* TODO: Is it possible to use list for Apron dimchange? *) + let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification) *) + if (List.length cols) = num_cols m then empty() else - let cols = Array.to_list cols in - let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification), maybe use List instead?*) List.map (fun row -> V.remove_at_indices row sorted_cols) m let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols let map2i f m v = let vector_length = V.length v in - List.mapi (fun index row -> if index < vector_length then f index row (V.nth v index) else row) m + (* List.mapi (fun index row -> if index < vector_length then f index row (V.nth v index) else row) m *) + List.map2i (fun index row value -> if index < vector_length then f index row value else row) m (V.to_list v) let remove_zero_rows m = List.filter (fun row -> not (V.is_zero_vec row)) m From 7a8fab9752fcb5d0bcf4f6f366e191a89a9c3e6a Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 30 Nov 2024 14:13:56 +0100 Subject: [PATCH 065/150] Fix set_nth in Vector --- .../sparseImplementation/sparseVector.ml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index d01ca2704b..0ef6015abc 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -84,11 +84,20 @@ module SparseVector: AbstractVector = let set_nth v n num = if n >= v.len then failwith "Out of bounds" else - let new_entries = List.map (fun (col_idx, value) -> - if col_idx = n then (col_idx, num) else (col_idx, value) - ) v.entries - in - {entries= new_entries; len=v.len} + let rev_entries', _ = List.fold_lefti (fun (acc, found) i (idx, value) -> + if found then ((idx, value) :: acc, true) + else + if i = v.len - 1 then + if idx = n then (if num <>: A.zero then (n, num) :: acc, true else acc, true) + else if idx > n then (if num <>: A.zero then (idx, value) :: (n, num) :: acc, true else (idx, value) :: acc, true) + else failwith "Out of bounds (Should not be reachable)" + else + if idx < n then ((idx, value) :: acc, false) + else if idx = n then (if num <>: A.zero then (n, num) :: acc , true else acc, true) + else (if num <>: A.zero then (idx, value) :: (n, num) :: acc, true else (idx, value) :: acc, true) + + ) ([], false) v.entries in + {entries = List.rev rev_entries'; len = v.len} let set_nth_with = failwith "deprecated" From 519ee02ef6ba1ecf72e851013d21a1030d8b5c1d Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sun, 1 Dec 2024 17:32:48 +0100 Subject: [PATCH 066/150] Remove double Mpqf definition --- src/cdomains/apron/affineEqualityDomain.apron.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 7700444018..94d144c485 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -20,7 +20,7 @@ open Batteries module Array = Batteries.Array module Mpqf = SharedFunctions.Mpqf -module Mpqf = SharedFunctions.Mpqf + module AffineEqualityMatrix (Vec: AbstractVector) (Mx: AbstractMatrix) = struct From d3d998d49f2f0f1a49e7d09d66d892b31622e6ff Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 3 Dec 2024 14:09:09 +0100 Subject: [PATCH 067/150] Renamed SparseMatrix to ListMatrix in goblint_lib.ml --- src/goblint_lib.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/goblint_lib.ml b/src/goblint_lib.ml index a5fe9230fe..0bf0be6bfb 100644 --- a/src/goblint_lib.ml +++ b/src/goblint_lib.ml @@ -438,7 +438,7 @@ module AbstractMatrix = AbstractMatrix module ArrayVector = ArrayVector module ArrayMatrix = ArrayMatrix module SparseVector = SparseVector -module SparseMatrix = SparseMatrix +module ListMatrix = ListMatrix module RatOps = RatOps module ConvenienceOps = ConvenienceOps From d68c719aa30aca0cd7bf7e75401e930485377c6a Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 3 Dec 2024 14:33:33 +0100 Subject: [PATCH 068/150] Implement is_covered_by structure, but helper function still missing --- .../arrayImplementation/arrayVector.ml | 3 +++ .../sparseImplementation/listMatrix.ml | 21 +++++++++++++++++-- .../sparseImplementation/sparseVector.ml | 5 +++++ src/cdomains/affineEquality/vector.ml | 2 ++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 2fefdd0043..24ad36323f 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -126,4 +126,7 @@ module ArrayVector: AbstractVector = let findi_val_opt f v = failwith "TODO" + let exists2 f v1 v1 = + failwith "TODO / deprecated" + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 2486e792d6..ae63a82931 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -129,7 +129,8 @@ module ListMatrix: AbstractMatrix = failwith "TODO" let get_pivot_positions m = - failwith "TODO" + List.mapi (fun i row -> V.findi (fun z -> z =: A.one) row) m + let sub_rows (minu : V.t) (subt : V.t) : V.t = V.map2_preserve_zero (-:) minu subt @@ -197,9 +198,25 @@ module ListMatrix: AbstractMatrix = let rref_matrix m1 m2 = normalize @@ append_matrices m1 m2 - let is_covered_by m1 m2 = + + let delete_row_with_pivots row pivots m = failwith "TODO" + let is_covered_by m1 m2 = + if num_rows m1 > num_rows m2 then false else + let pivots = get_pivot_positions m2 in (* TODO: Lazy? *) + try + let _ = List.map2i (fun i row1 row2 -> + if not @@ V.exists2 (<>:) row1 row2 + then V.zero_vec (V.length row1) else + let row1 = delete_row_with_pivots row1 pivots m2 in + if V.nth row1 (V.length row1 - 1) <>: A.zero + then raise Stdlib.Exit + else V.zero_vec (V.length row1) + ) m1 m2 in + true + with Stdlib.Exit -> false + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 0ef6015abc..d9d773939e 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -198,6 +198,7 @@ module SparseVector: AbstractVector = else fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) + (* Returns optional of (index * value) where f evaluated to true *) let findi_val_opt f v = if f A.zero then ( @@ -233,6 +234,9 @@ module SparseVector: AbstractVector = | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs in (exists_aux c f v.entries) + let exists2 f v1 v2 = + failwith "TODO" + let rev v = let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - idx, value)) v.entries in {entries = entries'; len = v.len} @@ -254,6 +258,7 @@ module SparseVector: AbstractVector = let find2i f v v' = failwith "TODO" + let to_array v = let vec = Array.make v.len A.zero in List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index e4c9fa90b4..623c338dcd 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -69,6 +69,8 @@ sig val exists: (num -> bool) -> t -> bool + val exists2: (num -> num -> bool) -> t -> t -> bool + val rev: t -> t val rev_with: t -> unit From 159d07ee7c7c1154cf1857525969db58d8c29285 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 3 Dec 2024 14:45:11 +0100 Subject: [PATCH 069/150] bugfix in insert_at and reduce_col_with_vec --- .../sparseImplementation/listMatrix.ml | 17 ++++++++++------- .../sparseImplementation/sparseVector.ml | 5 ++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index ae63a82931..96a1caf63f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -100,6 +100,16 @@ module ListMatrix: AbstractMatrix = V.map2_preserve_zero (fun x y -> x -: s *: y) row pivot_row) ) m + let reduce_col_with_vec m j v = + let pivot_element = V.nth v j in + if pivot_element = A.zero then m + else List.mapi (fun idx row -> + let row_value = V.nth row j in + if row_value = A.zero then row + else (let s = row_value /: pivot_element in + V.map2_preserve_zero (fun x y -> x -: s *: y) row v) + ) m + let del_col m j = if num_cols m = 1 then empty () else @@ -125,13 +135,9 @@ module ListMatrix: AbstractMatrix = let init_with_vec v = [v] - let reduce_col_with_vec m j v = - failwith "TODO" - let get_pivot_positions m = List.mapi (fun i row -> V.findi (fun z -> z =: A.one) row) m - let sub_rows (minu : V.t) (subt : V.t) : V.t = V.map2_preserve_zero (-:) minu subt @@ -226,9 +232,6 @@ module ListMatrix: AbstractMatrix = let vector_length = V.length v in List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m - let rref_vec_helper m pivot_positions v = - failwith "TODO" - (* ------------------------- Deprecated ------------------------*) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index d9d773939e..794ec54fe5 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -106,10 +106,9 @@ module SparseVector: AbstractVector = if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) let entries' = List.fold_left (fun acc (idx, value) -> if idx < n then (idx, value) :: acc - else if idx = n then (n, new_val) :: (idx + 1, value) :: acc - else (idx + 1, value) :: acc + else (idx + 1, value) :: acc ) [] (List.rev v.entries) in - {entries = entries'; len = v.len + 1} + {entries = List.sort (fun (i, _) (j, _) -> Int.compare i j) entries'; len = v.len + 1} let map_preserve_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) let entries' = List.filter_map ( From 1f85d28138d96e281277b84305586fac5e2d7f0a Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 3 Dec 2024 15:13:48 +0100 Subject: [PATCH 070/150] Implement more vector functions --- .../sparseImplementation/listMatrix.ml | 71 +++++++++---------- .../sparseImplementation/sparseVector.ml | 64 +++++++++-------- 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 96a1caf63f..023721a0ec 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -149,46 +149,45 @@ module ListMatrix: AbstractMatrix = let is_valid_affeq_matrix m = failwith "TODO" - (* + (* let col_count = num_cols m in List.exists (fun row -> (* Invalid if row is zero, but coefficient is not zero *) V.fold_left_preserve_zero (fun found_non_zero (col_idx, value) -> if col_idx = col_count - 1 && (not found_non_zero) && (value <>: A.zero) then false else found_non_zero) false row - ) m *) - - let normalize m = - let col_count = num_cols m in - let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = - m - in - (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) - let find_first_pivot m row_idx col_idx = - if col_idx >= col_count then None else - (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) - let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> - let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in - match row_first_non_zero with - | None -> (cur_row, cur_col, cur_val) - | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) - ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) - in - if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) - in - let rec main_loop m m' row_idx col_idx = - if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) - else - match find_first_pivot m' row_idx col_idx with - | None -> m (* No pivot found means already normalized*) - | Some (piv_row_idx, piv_col_idx, piv_val) -> ( - let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in - let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in - let piv_row = (List.nth normalized_m row_idx) in - let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in - let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in - main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) - in - let m' = main_loop m m 0 0 in - if is_valid_affeq_matrix m' then Some m' else None + + let normalize m = + let col_count = num_cols m in + let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = + m + in + (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) + let find_first_pivot m row_idx col_idx = + if col_idx >= col_count then None else + (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) + let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> + let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in + match row_first_non_zero with + | None -> (cur_row, cur_col, cur_val) + | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) + in + if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) + in + let rec main_loop m m' row_idx col_idx = + if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) + else + match find_first_pivot m' row_idx col_idx with + | None -> m (* No pivot found means already normalized*) + | Some (piv_row_idx, piv_col_idx, piv_val) -> ( + let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in + let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in + let piv_row = (List.nth normalized_m row_idx) in + let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in + let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in + main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) + in + let m' = main_loop m m 0 0 in + if is_valid_affeq_matrix m' then Some m' else None (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 794ec54fe5..6c1e7cab1d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -4,6 +4,7 @@ open ConvenienceOps open BatList open BatArray + module List = BatList module Array = BatArray @@ -99,9 +100,6 @@ module SparseVector: AbstractVector = ) ([], false) v.entries in {entries = List.rev rev_entries'; len = v.len} - let set_nth_with = - failwith "deprecated" - let insert_val_at n new_val v = if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) let entries' = List.fold_left (fun acc (idx, value) -> @@ -150,9 +148,6 @@ module SparseVector: AbstractVector = let entries' = List.map (fun (idx, value) -> (idx, f value c)) v.entries in {entries = entries'; len = v.len} - let apply_with_c_with f m v = - failwith "deprecated" - let zero_vec n = {entries = []; len = n} @@ -188,8 +183,6 @@ module SparseVector: AbstractVector = if v.len <> v'.len then failwith "Unequal vector length" else of_list (List.map2 f (to_list v) (to_list v')) - let map2_with f v v' = - failwith "deprecated" let findi f v = if f A.zero then @@ -212,14 +205,11 @@ module SparseVector: AbstractVector = let map f v = of_list (List.map f (to_list v)) - let map_with f v = - failwith "deprecated" - let compare_length_with v n = Int.compare v.len n - let filteri f v = - failwith "TODO" + let filteri f v = (* TODO: optimize! *) + of_list (List.filteri f (to_list v)) let append v v' = let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in @@ -233,29 +223,20 @@ module SparseVector: AbstractVector = | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs in (exists_aux c f v.entries) - let exists2 f v1 v2 = - failwith "TODO" + let exists2 f v1 v2 = (* TODO: optimize! *) + List.exists2 f (to_list v1) (to_list v2) let rev v = let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - idx, value)) v.entries in {entries = entries'; len = v.len} - let rev_with v = - failwith "deprecated" - - let map2i f v v' = + let map2i f v v' = (* TODO: optimize! *) of_list (List.map2i f (to_list v) (to_list v')) - let map2i_with f v v' = - failwith "deprecated" - - let mapi f v = + let mapi f v = (* TODO: optimize! *) of_list (List.mapi f (to_list v)) - let mapi_with f v = - failwith "deprecated" - - let find2i f v v' = + let find2i f v v' = (* TODO: optimize! *) failwith "TODO" let to_array v = @@ -276,8 +257,8 @@ module SparseVector: AbstractVector = let to_sparse_list v = v.entries - let find_opt f v = - failwith "TODO: Do we need this?" + let find_opt f v = (* TODO: Do we need this? And optimize!!!*) + List.find_opt f (to_list v) let show v = let t = to_list v in @@ -288,4 +269,27 @@ module SparseVector: AbstractVector = in "["^list_str t^"\n" - end \ No newline at end of file + (* ------------------- Deprecated ------------------- *) + let mapi_with f v = + failwith "deprecated" + + let map2i_with f v v' = + failwith "deprecated" + + + let rev_with v = + failwith "deprecated" + + let map_with f v = + failwith "deprecated" + + + let map2_with f v v' = + failwith "deprecated" + + let apply_with_c_with f m v = + failwith "deprecated" + + let set_nth_with = + failwith "deprecated" + end From 793df4a2468a7c2bd79ee9d1a62c611c11365f2d Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 3 Dec 2024 15:14:20 +0100 Subject: [PATCH 071/150] Formatting --- .../sparseImplementation/listMatrix.ml | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 023721a0ec..f6b71ee1ad 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -154,40 +154,40 @@ module ListMatrix: AbstractMatrix = List.exists (fun row -> (* Invalid if row is zero, but coefficient is not zero *) V.fold_left_preserve_zero (fun found_non_zero (col_idx, value) -> if col_idx = col_count - 1 && (not found_non_zero) && (value <>: A.zero) then false else found_non_zero) false row *) - - let normalize m = - let col_count = num_cols m in - let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = - m - in - (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) - let find_first_pivot m row_idx col_idx = - if col_idx >= col_count then None else - (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) - let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> - let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in - match row_first_non_zero with - | None -> (cur_row, cur_col, cur_val) - | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) - ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) - in - if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) - in - let rec main_loop m m' row_idx col_idx = - if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) - else - match find_first_pivot m' row_idx col_idx with - | None -> m (* No pivot found means already normalized*) - | Some (piv_row_idx, piv_col_idx, piv_val) -> ( - let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in - let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in - let piv_row = (List.nth normalized_m row_idx) in - let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in - let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in - main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) - in - let m' = main_loop m m 0 0 in - if is_valid_affeq_matrix m' then Some m' else None + + let normalize m = + let col_count = num_cols m in + let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = + m + in + (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) + let find_first_pivot m row_idx col_idx = + if col_idx >= col_count then None else + (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) + let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> + let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in + match row_first_non_zero with + | None -> (cur_row, cur_col, cur_val) + | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) + in + if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) + in + let rec main_loop m m' row_idx col_idx = + if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) + else + match find_first_pivot m' row_idx col_idx with + | None -> m (* No pivot found means already normalized*) + | Some (piv_row_idx, piv_col_idx, piv_val) -> ( + let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in + let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in + let piv_row = (List.nth normalized_m row_idx) in + let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in + let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in + main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) + in + let m' = main_loop m m 0 0 in + if is_valid_affeq_matrix m' then Some m' else None (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) From 6021c422fae29b8dbf2319e98fc9c1efa4cdd800 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 3 Dec 2024 18:51:30 +0100 Subject: [PATCH 072/150] Implement is_covered_by --- .../sparseImplementation/listMatrix.ml | 43 +++++++++++++------ .../sparseImplementation/sparseVector.ml | 2 +- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index f6b71ee1ad..d1627ac564 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -207,20 +207,39 @@ module ListMatrix: AbstractMatrix = let delete_row_with_pivots row pivots m = failwith "TODO" + (* Assumes that the first row of the matrix is already the pivot row fitting to the vector. *) + let rec is_linearly_independent_rref v m = + match m with + | [] -> not @@ V.is_zero_vec v + | x::xs -> + let pivot_opt = V.findi_val_opt ((<>:) A.zero) v in + match pivot_opt with + | None -> true (* When we found no pivot, the vector is already A.zero. *) + | Some (pivot_id, pivot) -> + let new_v = V.map2_preserve_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in + is_linearly_independent_rref new_v xs + let is_covered_by m1 m2 = if num_rows m1 > num_rows m2 then false else - let pivots = get_pivot_positions m2 in (* TODO: Lazy? *) - try - let _ = List.map2i (fun i row1 row2 -> - if not @@ V.exists2 (<>:) row1 row2 - then V.zero_vec (V.length row1) else - let row1 = delete_row_with_pivots row1 pivots m2 in - if V.nth row1 (V.length row1 - 1) <>: A.zero - then raise Stdlib.Exit - else V.zero_vec (V.length row1) - ) m1 m2 in - true - with Stdlib.Exit -> false + let rec is_covered_by_helper m1 m2 = + match m1 with + | [] -> true + | v1::vs1 -> + let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in + match first_non_zero with + | None -> true (* vs1 must also be zero-vectors because of rref *) + | Some (idx, _) -> + let m' = List.drop_while (fun v2 -> + match V.findi_val_opt ((<>:) A.zero) v2 with + | None -> true (* In this case, m2 only has zero rows after that *) + | Some (idx', _) -> idx' < idx + ) m2 in (* Only consider the part of m2 where the pivot is at a position useful for deleting first_non_zero of v1*) + let linearly_indep = is_linearly_independent_rref v1 m' in + if linearly_indep then false else is_covered_by_helper vs1 m' + in is_covered_by_helper m1 m2 + + + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6c1e7cab1d..78a94fd886 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -214,7 +214,7 @@ module SparseVector: AbstractVector = let append v v' = let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in {entries = entries'; len = v.len + v'.len} - + let exists f v = let c = v.len in let rec exists_aux at f v = From 97a735bb0e79f93233260c5ee6b3378d6dbda516 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Wed, 4 Dec 2024 17:22:03 +0100 Subject: [PATCH 073/150] small bugfixes --- .../sparseImplementation/listMatrix.ml | 4 +-- .../sparseImplementation/sparseVector.ml | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index d1627ac564..6cb170034e 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -19,7 +19,7 @@ module ListMatrix: AbstractMatrix = [@@deriving eq, ord, hash] let show x = - List.fold_left (^) "" (List.map (fun x -> (V.show x) ^ "\n") x) + List.fold_left (^) "" (List.map (fun x -> (V.show x)) x) let empty () = [] @@ -204,7 +204,7 @@ module ListMatrix: AbstractMatrix = normalize @@ append_matrices m1 m2 - let delete_row_with_pivots row pivots m = + let delete_row_with_pivots row pivots m2 = failwith "TODO" (* Assumes that the first row of the matrix is already the pivot row fitting to the vector. *) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 78a94fd886..2c44f7c9fe 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -172,10 +172,11 @@ module SparseVector: AbstractVector = let to_list v = let[@tail_mod_cons] rec extend_zero_aux i v' = - if i >= v.len then failwith "out of Bounds for to_list" else (*can probably be removed*) - match v' with - | (xi,xv)::xs -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero::(extend_zero_aux (i+1) v') - | [] -> [] + if i >= v.len then [] else (*can probably be removed*) + match v', i with + | (xi,xv)::xs, _ -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero ::(extend_zero_aux (i+1) v') + | [], j when i < v.len -> A.zero :: (extend_zero_aux (i+1) v') + | [], _ -> [] in (extend_zero_aux 0 v.entries) @@ -265,31 +266,31 @@ module SparseVector: AbstractVector = let rec list_str l = match l with | [] -> "]" - | x :: xs -> (A.to_string x) ^" "^(list_str xs) + | x :: xs -> " " ^ (A.to_string x) ^ (list_str xs) in "["^list_str t^"\n" (* ------------------- Deprecated ------------------- *) let mapi_with f v = - failwith "deprecated" + failwith "mapi_with deprecated" let map2i_with f v v' = - failwith "deprecated" + failwith "map2i_with deprecated" let rev_with v = - failwith "deprecated" + failwith "rev_with deprecated" let map_with f v = - failwith "deprecated" + failwith "map_with deprecated" let map2_with f v v' = - failwith "deprecated" + failwith "map2_with deprecated" let apply_with_c_with f m v = - failwith "deprecated" + failwith "apply_with_c_with deprecated" - let set_nth_with = - failwith "deprecated" + let set_nth_with f n num = ( + failwith "set_nth_with deprecated") end From b17f33eed7a7fd54750d119bc897e7387bfa2ed9 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Wed, 4 Dec 2024 18:40:54 +0100 Subject: [PATCH 074/150] Finish normalize first version with dec2D --- .../arrayImplementation/arrayVector.ml | 3 +++ .../sparseImplementation/listMatrix.ml | 15 ++++++++------- .../sparseImplementation/sparseVector.ml | 7 ++++++- src/cdomains/affineEquality/vector.ml | 3 +++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 24ad36323f..937c4ee36f 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -129,4 +129,7 @@ module ArrayVector: AbstractVector = let exists2 f v1 v1 = failwith "TODO / deprecated" + let starting_from_nth n v = + failwith "TODO / deprecated" + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 6cb170034e..e04fe6a174 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -148,17 +148,18 @@ module ListMatrix: AbstractMatrix = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m let is_valid_affeq_matrix m = - failwith "TODO" - (* let col_count = num_cols m in - List.exists (fun row -> (* Invalid if row is zero, but coefficient is not zero *) - V.fold_left_preserve_zero (fun found_non_zero (col_idx, value) -> if col_idx = col_count - 1 && (not found_non_zero) && (value <>: A.zero) then false else found_non_zero) false row - *) + let row_is_invalid row = (* TODO: Vector findi_opt *) + match V.findi_val_opt ((<>:) A.zero) row with + | Some (idx, _) -> if idx = col_count - 1 then true else false (* If all cofactors of the affeq are zero, but the constant is non-zero, the row is invalid *) + | None -> false (* Full zero row is not invalid *) + in + List.exists row_is_invalid m let normalize m = let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = - m + List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m in (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) let find_first_pivot m row_idx col_idx = @@ -187,7 +188,7 @@ module ListMatrix: AbstractMatrix = main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in - if is_valid_affeq_matrix m' then Some m' else None + if is_valid_affeq_matrix m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 2c44f7c9fe..cad838a474 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -215,7 +215,7 @@ module SparseVector: AbstractVector = let append v v' = let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in {entries = entries'; len = v.len + v'.len} - + let exists f v = let c = v.len in let rec exists_aux at f v = @@ -261,6 +261,10 @@ module SparseVector: AbstractVector = let find_opt f v = (* TODO: Do we need this? And optimize!!!*) List.find_opt f (to_list v) + let starting_from_nth n v = + let entries' = List.filter_map (fun (idx, value) -> if idx < n then None else Some (idx - n, value)) v.entries in + {entries = entries'; len = v.len - n} + let show v = let t = to_list v in let rec list_str l = @@ -293,4 +297,5 @@ module SparseVector: AbstractVector = let set_nth_with f n num = ( failwith "set_nth_with deprecated") + end diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 623c338dcd..7b067018e4 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -99,4 +99,7 @@ sig val to_sparse_list: t -> (int * num) list + (* Returns the part of the vector starting from index n*) + val starting_from_nth : int -> t -> t + end \ No newline at end of file From 80672a1f42f1f2b78b351aea9c245d78fbe6d680 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 5 Dec 2024 09:52:52 +0100 Subject: [PATCH 075/150] bugfix in find_val_opt and lin_independent --- .../sparseImplementation/listMatrix.ml | 7 ++----- .../sparseImplementation/sparseVector.ml | 17 ++++++++--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index e04fe6a174..f1183dcd95 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -215,7 +215,7 @@ module ListMatrix: AbstractMatrix = | x::xs -> let pivot_opt = V.findi_val_opt ((<>:) A.zero) v in match pivot_opt with - | None -> true (* When we found no pivot, the vector is already A.zero. *) + | None -> false (* When we found no pivot, the vector is already A.zero. *) | Some (pivot_id, pivot) -> let new_v = V.map2_preserve_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in is_linearly_independent_rref new_v xs @@ -238,10 +238,7 @@ module ListMatrix: AbstractMatrix = let linearly_indep = is_linearly_independent_rref v1 m' in if linearly_indep then false else is_covered_by_helper vs1 m' in is_covered_by_helper m1 m2 - - - - + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index cad838a474..7ac1d4c434 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -193,15 +193,14 @@ module SparseVector: AbstractVector = (* Returns optional of (index * value) where f evaluated to true *) let findi_val_opt f v = - if f A.zero then - ( - let i, (col_idx, value) = List.findi (fun i (idx, value) -> if idx > i then true else f value) v.entries in - if i < col_idx then (* In this case, Zero was the first element found because iteration index i is smaller than "found" value *) - Some (i, A.zero) - else Some (col_idx, value) - ) - else - Some (List.find (fun (idx, value) -> f value) v.entries) + let rec find_zero_or_val vec last_col_idx = + match vec, last_col_idx with + | [], _ -> if v.len <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) else None + | (idx, value) :: xs, i -> + if idx <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) + else if f value then Some (idx, value) + else find_zero_or_val xs idx + in find_zero_or_val v.entries (-1) let map f v = of_list (List.map f (to_list v)) From 418de56be635e161de3d0d826f47d927f1876a53 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 5 Dec 2024 15:37:17 +0100 Subject: [PATCH 076/150] Fixed affeq_rows_are_valid helper for normalize --- .../sparseImplementation/listMatrix.ml | 21 +++++++++---------- .../sparseImplementation/sparseVector.ml | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index f1183dcd95..2e0eda574f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -147,15 +147,6 @@ module ListMatrix: AbstractMatrix = let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m - let is_valid_affeq_matrix m = - let col_count = num_cols m in - let row_is_invalid row = (* TODO: Vector findi_opt *) - match V.findi_val_opt ((<>:) A.zero) row with - | Some (idx, _) -> if idx = col_count - 1 then true else false (* If all cofactors of the affeq are zero, but the constant is non-zero, the row is invalid *) - | None -> false (* Full zero row is not invalid *) - in - List.exists row_is_invalid m - let normalize m = let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = @@ -174,6 +165,14 @@ module ListMatrix: AbstractMatrix = in if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) in + let affeq_rows_are_valid m = (* Check if the semantics of an rref-affeq matrix are correct *) + let col_count = num_cols m in + let row_is_valid row = (* TODO: Vector findi_opt *) + match V.findi_val_opt ((<>:) A.zero) row with + | Some (idx, _) -> if idx < col_count - 1 then true else false (* If all cofactors of the affeq are zero, but the constant is non-zero, the row is invalid *) + | None -> true (* Full zero row is valid *) + in + List.for_all row_is_valid m in let rec main_loop m m' row_idx col_idx = if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else @@ -188,7 +187,7 @@ module ListMatrix: AbstractMatrix = main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in - if is_valid_affeq_matrix m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) + if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) @@ -238,7 +237,7 @@ module ListMatrix: AbstractMatrix = let linearly_indep = is_linearly_independent_rref v1 m' in if linearly_indep then false else is_covered_by_helper vs1 m' in is_covered_by_helper m1 m2 - + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 7ac1d4c434..3f80cc7d46 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -191,7 +191,7 @@ module SparseVector: AbstractVector = else fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) - (* Returns optional of (index * value) where f evaluated to true *) + (* Returns optional of (index * value) where f value evaluated to true *) let findi_val_opt f v = let rec find_zero_or_val vec last_col_idx = match vec, last_col_idx with From e10493adaf387d28378dd4a1a8fee64e44d92ec5 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 5 Dec 2024 16:27:43 +0100 Subject: [PATCH 077/150] better map2pz,better naming --- .../sparseImplementation/sparseVector.ml | 45 +++++++++---------- src/cdomains/affineEquality/vector.ml | 8 ++-- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 3f80cc7d46..47d63ca87d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -108,40 +108,37 @@ module SparseVector: AbstractVector = ) [] (List.rev v.entries) in {entries = List.sort (fun (i, _) (j, _) -> Int.compare i j) entries'; len = v.len + 1} - let map_preserve_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) + let map_f_preserve_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) let entries' = List.filter_map ( fun (idx, value) -> let new_val = f value in if new_val = A.zero then None else Some (idx, new_val)) v.entries in {entries = entries'; len = v.len} (* map for functions f such that f 0 0 = 0 since f won't be applied to if both values are zero. See also map *) - let map2_preserve_zero f v1 v2 = - let rec map2_nonzero_aux v1 v2 = + let map2_f_preserve_zero f v1 v2 = + let f_rem_zero acc idx e1 e2 = + let r = f e1 e2 in + if r =: A.zero then acc else (idx, r)::acc + in + let rec aux acc v1 v2 = match v1, v2 with - | [], [] -> [] - | x , y -> - let cons, xtail, ytail = - match x, y with - | (xidx, xv)::xs, (yidx,yv)::ys -> ( - match xidx - yidx with - | d when d < 0 -> (xidx, f xv A.zero), xs, v2 - | d when d > 0 -> (yidx, f A.zero yv), v1, ys - | _ -> (xidx, f xv yv) , xs, ys - ) - | (xidx, xv)::xs, [] -> (xidx, f xv A.zero), xs, [] - | [], (yidx, yv)::ys -> (yidx, f A.zero yv), [], ys - | [],[] -> raise (Failure "Should never be reached") - in - let res = if snd cons = A.zero then [] else [cons] in - res@(map2_nonzero_aux xtail ytail) - in - if v1.len <> v2.len then raise (Invalid_argument "Different lengths") else - to_vector (map2_nonzero_aux v1.entries v2.entries) v1.len + | [], [] -> acc + | [], (yidx, yval)::ys -> aux (f_rem_zero acc yidx A.zero yval) [] ys + | (xidx, xval)::xs, [] -> aux (f_rem_zero acc xidx xval A.zero) xs [] + | (xidx, xval)::xs, (yidx, yval)::ys -> + match xidx - yidx with + | d when d < 0 -> aux (f_rem_zero acc xidx xval A.zero) xs v2 + | d when d > 0 -> aux (f_rem_zero acc yidx A.zero yval) v1 ys + | _ -> aux (f_rem_zero acc xidx xval yval) xs ys + in + if v1.len <> v2.len then raise (Invalid_argument "Unequal lengths") else + to_vector (List.rev (aux [] v1.entries v2.entries)) v1.len + - let fold_left_preserve_zero f acc v = + let fold_left_f_preserve_zero f acc v = List.fold_left (fun acc (_, value) -> f acc value) acc v.entries - let fold_left2_preserve_zero f acc v v' = + let fold_left2_f_preserve_zero f acc v v' = List.fold_left2 (fun acc (_, value) (_, value') -> f acc value value') acc v.entries v'.entries let apply_with_c f c v = diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 7b067018e4..d9c2d7d299 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -20,13 +20,13 @@ sig val insert_val_at: int -> num -> t -> t - val map_preserve_zero: (num -> num) -> t -> t + val map_f_preserve_zero: (num -> num) -> t -> t - val map2_preserve_zero: (num -> num -> num) -> t -> t -> t + val map2_f_preserve_zero: (num -> num -> num) -> t -> t -> t - val fold_left_preserve_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc + val fold_left_f_preserve_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc - val fold_left2_preserve_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc + val fold_left2_f_preserve_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc val apply_with_c: (num -> num -> num) -> num -> t -> t From d2b0be74812ae47b908a988f6b3b6d99c2c53580 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 5 Dec 2024 16:37:03 +0100 Subject: [PATCH 078/150] small hickup --- .../affineEquality/sparseImplementation/listMatrix.ml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 2e0eda574f..b580aad2af 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -97,7 +97,7 @@ module ListMatrix: AbstractMatrix = let row_value = V.nth row j in if row_value = A.zero then row else (let s = row_value /: pivot in - V.map2_preserve_zero (fun x y -> x -: s *: y) row pivot_row) + V.map2_f_preserve_zero (fun x y -> x -: s *: y) row pivot_row) ) m let reduce_col_with_vec m j v = @@ -107,7 +107,7 @@ module ListMatrix: AbstractMatrix = let row_value = V.nth row j in if row_value = A.zero then row else (let s = row_value /: pivot_element in - V.map2_preserve_zero (fun x y -> x -: s *: y) row v) + V.map2_f_preserve_zero (fun x y -> x -: s *: y) row v) ) m let del_col m j = @@ -139,10 +139,10 @@ module ListMatrix: AbstractMatrix = List.mapi (fun i row -> V.findi (fun z -> z =: A.one) row) m let sub_rows (minu : V.t) (subt : V.t) : V.t = - V.map2_preserve_zero (-:) minu subt + V.map2_f_preserve_zero (-:) minu subt let div_row (row : V.t) (pivot : A.t) : V.t = - V.map_preserve_zero (fun a -> a /: pivot) row + V.map_f_preserve_zero (fun a -> a /: pivot) row let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m @@ -216,7 +216,7 @@ module ListMatrix: AbstractMatrix = match pivot_opt with | None -> false (* When we found no pivot, the vector is already A.zero. *) | Some (pivot_id, pivot) -> - let new_v = V.map2_preserve_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in + let new_v = V.map2_f_preserve_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in is_linearly_independent_rref new_v xs let is_covered_by m1 m2 = From 859ec26b7fbc661e0586ea96205e467abd02f852 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 5 Dec 2024 16:50:53 +0100 Subject: [PATCH 079/150] normalize bug fix --- .../sparseImplementation/listMatrix.ml | 28 +++++++++++++++---- .../sparseImplementation/sparseVector.ml | 14 +++++----- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index b580aad2af..6fabd9295d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -77,6 +77,18 @@ module ListMatrix: AbstractMatrix = let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 + let sub_rows (minu : V.t) (subt : V.t) : V.t = + V.map2_f_preserve_zero (-:) minu subt + + let div_row (row : V.t) (pivot : A.t) : V.t = + V.map_f_preserve_zero (fun a -> a /: pivot) row + + let swap_rows m j k = + List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m + + let sub_scaled_row row1 row2 s = + V.map2_f_preserve_zero (fun x y -> x -: s *: y) row1 row2 + let reduce_col m j = if is_empty m then m else @@ -97,7 +109,7 @@ module ListMatrix: AbstractMatrix = let row_value = V.nth row j in if row_value = A.zero then row else (let s = row_value /: pivot in - V.map2_f_preserve_zero (fun x y -> x -: s *: y) row pivot_row) + sub_scaled_row row pivot_row s) ) m let reduce_col_with_vec m j v = @@ -153,17 +165,18 @@ module ListMatrix: AbstractMatrix = List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m in (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) - let find_first_pivot m row_idx col_idx = + let find_first_pivot m' row_idx col_idx = if col_idx >= col_count then None else (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) - | Some (col_idx, value) -> if col_idx < cur_col then (row_idx + i, col_idx, value) else (cur_row, cur_col, cur_val) - ) (num_rows m, num_cols m, A.zero) m (* Initializing with max, so num_cols m indicates that pivot is not found *) + | Some (idx, value) -> let () = Printf.printf "We found first non-zero at index %i in row %i\n" idx i in + if idx < cur_col then (row_idx + i, idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m', num_cols m', A.zero) m' (* Initializing with max, so num_cols m indicates that pivot is not found *) in - if piv_col = (num_cols m) then None else Some (piv_row, piv_col, piv_val) + if piv_col = (num_cols m') then None else Some (piv_row, piv_col + col_idx, piv_val) in let affeq_rows_are_valid m = (* Check if the semantics of an rref-affeq matrix are correct *) let col_count = num_cols m in @@ -179,10 +192,13 @@ module ListMatrix: AbstractMatrix = match find_first_pivot m' row_idx col_idx with | None -> m (* No pivot found means already normalized*) | Some (piv_row_idx, piv_col_idx, piv_val) -> ( + let () = Printf.printf "The current matrix is: \n%s and the pivot is (%i, %i, %s)\n" (show m) piv_row_idx piv_col_idx (A.to_string piv_val) in let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in let piv_row = (List.nth normalized_m row_idx) in - let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then sub_rows row piv_row else row) normalized_m in + let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then + let scale = V.nth row piv_col_idx in + sub_scaled_row row piv_row scale else row) normalized_m in let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 47d63ca87d..6f51f01d3c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -132,7 +132,7 @@ module SparseVector: AbstractVector = | _ -> aux (f_rem_zero acc xidx xval yval) xs ys in if v1.len <> v2.len then raise (Invalid_argument "Unequal lengths") else - to_vector (List.rev (aux [] v1.entries v2.entries)) v1.len + to_vector (List.rev (aux [] v1.entries v2.entries)) v1.len let fold_left_f_preserve_zero f acc v = @@ -191,12 +191,12 @@ module SparseVector: AbstractVector = (* Returns optional of (index * value) where f value evaluated to true *) let findi_val_opt f v = let rec find_zero_or_val vec last_col_idx = - match vec, last_col_idx with - | [], _ -> if v.len <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) else None - | (idx, value) :: xs, i -> - if idx <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) - else if f value then Some (idx, value) - else find_zero_or_val xs idx + match vec, last_col_idx with + | [], _ -> if v.len <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) else None + | (idx, value) :: xs, i -> + if idx <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) + else if f value then Some (idx, value) + else find_zero_or_val xs idx in find_zero_or_val v.entries (-1) let map f v = From 67c1d5c48477dfbc9cf8635682b4c42d2bedf00f Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 5 Dec 2024 16:56:34 +0100 Subject: [PATCH 080/150] small naming --- .../arrayImplementation/arrayVector.ml | 8 ++++---- .../sparseImplementation/listMatrix.ml | 14 +++++++------- .../sparseImplementation/sparseVector.ml | 8 ++++---- src/cdomains/affineEquality/vector.ml | 8 ++++---- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 937c4ee36f..3bf873df78 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -114,13 +114,13 @@ module ArrayVector: AbstractVector = let find_opt f v = failwith "TODO" - let map_preserve_zero f v = failwith "TODO" - let map2_preserve_zero f v1 v2 = failwith "TODO" + let map_f_preserves_zero f v = failwith "TODO" + let map2_f_preserves_zero f v1 v2 = failwith "TODO" - let fold_left_preserve_zero f acc v = + let fold_left_f_preserves_zero f acc v = failwith "TODO" - let fold_left2_preserve_zero f acc v v' = + let fold_left2_f_preserves_zero f acc v v' = failwith "TODO" let findi_val_opt f v = diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 6fabd9295d..3d00d37fbf 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -78,16 +78,16 @@ module ListMatrix: AbstractMatrix = let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 let sub_rows (minu : V.t) (subt : V.t) : V.t = - V.map2_f_preserve_zero (-:) minu subt + V.map2_f_preserves_zero (-:) minu subt let div_row (row : V.t) (pivot : A.t) : V.t = - V.map_f_preserve_zero (fun a -> a /: pivot) row + V.map_f_preserves_zero (fun a -> a /: pivot) row let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m let sub_scaled_row row1 row2 s = - V.map2_f_preserve_zero (fun x y -> x -: s *: y) row1 row2 + V.map2_f_preserves_zero (fun x y -> x -: s *: y) row1 row2 let reduce_col m j = if is_empty m then m @@ -119,7 +119,7 @@ module ListMatrix: AbstractMatrix = let row_value = V.nth row j in if row_value = A.zero then row else (let s = row_value /: pivot_element in - V.map2_f_preserve_zero (fun x y -> x -: s *: y) row v) + V.map2_f_preserves_zero (fun x y -> x -: s *: y) row v) ) m let del_col m j = @@ -151,10 +151,10 @@ module ListMatrix: AbstractMatrix = List.mapi (fun i row -> V.findi (fun z -> z =: A.one) row) m let sub_rows (minu : V.t) (subt : V.t) : V.t = - V.map2_f_preserve_zero (-:) minu subt + V.map2_f_preserves_zero (-:) minu subt let div_row (row : V.t) (pivot : A.t) : V.t = - V.map_f_preserve_zero (fun a -> a /: pivot) row + V.map_f_preserves_zero (fun a -> a /: pivot) row let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m @@ -232,7 +232,7 @@ module ListMatrix: AbstractMatrix = match pivot_opt with | None -> false (* When we found no pivot, the vector is already A.zero. *) | Some (pivot_id, pivot) -> - let new_v = V.map2_f_preserve_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in + let new_v = V.map2_f_preserves_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in is_linearly_independent_rref new_v xs let is_covered_by m1 m2 = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6f51f01d3c..3591782507 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -108,14 +108,14 @@ module SparseVector: AbstractVector = ) [] (List.rev v.entries) in {entries = List.sort (fun (i, _) (j, _) -> Int.compare i j) entries'; len = v.len + 1} - let map_f_preserve_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) + let map_f_preserves_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) let entries' = List.filter_map ( fun (idx, value) -> let new_val = f value in if new_val = A.zero then None else Some (idx, new_val)) v.entries in {entries = entries'; len = v.len} (* map for functions f such that f 0 0 = 0 since f won't be applied to if both values are zero. See also map *) - let map2_f_preserve_zero f v1 v2 = + let map2_f_preserves_zero f v1 v2 = let f_rem_zero acc idx e1 e2 = let r = f e1 e2 in if r =: A.zero then acc else (idx, r)::acc @@ -135,10 +135,10 @@ module SparseVector: AbstractVector = to_vector (List.rev (aux [] v1.entries v2.entries)) v1.len - let fold_left_f_preserve_zero f acc v = + let fold_left_f_preserves_zero f acc v = List.fold_left (fun acc (_, value) -> f acc value) acc v.entries - let fold_left2_f_preserve_zero f acc v v' = + let fold_left2_f_preserves_zero f acc v v' = List.fold_left2 (fun acc (_, value) (_, value') -> f acc value value') acc v.entries v'.entries let apply_with_c f c v = diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index d9c2d7d299..15215b5512 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -20,13 +20,13 @@ sig val insert_val_at: int -> num -> t -> t - val map_f_preserve_zero: (num -> num) -> t -> t + val map_f_preserves_zero: (num -> num) -> t -> t - val map2_f_preserve_zero: (num -> num -> num) -> t -> t -> t + val map2_f_preserves_zero: (num -> num -> num) -> t -> t -> t - val fold_left_f_preserve_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc + val fold_left_f_preserves_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc - val fold_left2_f_preserve_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc + val fold_left2_f_preserves_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc val apply_with_c: (num -> num -> num) -> num -> t -> t From 71768bee4808fe569a2f8a99d254f2521f52132f Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 5 Dec 2024 17:04:18 +0100 Subject: [PATCH 081/150] fold_left2_f_preserves_zero --- .../sparseImplementation/sparseVector.ml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 3591782507..262dfb8c32 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -138,8 +138,20 @@ module SparseVector: AbstractVector = let fold_left_f_preserves_zero f acc v = List.fold_left (fun acc (_, value) -> f acc value) acc v.entries - let fold_left2_f_preserves_zero f acc v v' = - List.fold_left2 (fun acc (_, value) (_, value') -> f acc value value') acc v.entries v'.entries + let fold_left2_f_preserves_zero f acc v v' = + let rec aux acc v1 v2 = + match v1, v2 with + | [], [] -> acc + | [], (yidx, yval)::ys -> aux (f acc A.zero yval) [] ys + | (xidx, xval)::xs, [] -> aux (f acc xval A.zero) xs [] + | (xidx, xval)::xs, (yidx, yval)::ys -> + match xidx - yidx with + | d when d < 0 -> aux (f acc xval A.zero) xs v2 + | d when d > 0 -> aux (f acc A.zero yval) v1 ys + | _ -> aux (f acc xval yval) xs ys + in + if v.len <> v'.len then raise (Invalid_argument "Unequal lengths") else + (aux acc v.entries v'.entries) let apply_with_c f c v = let entries' = List.map (fun (idx, value) -> (idx, f value c)) v.entries in From 0207a737cda601d2fb05207c8c0ced200e57fae8 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 5 Dec 2024 17:39:57 +0100 Subject: [PATCH 082/150] print for debugging --- regtest.sh | 2 +- src/analyses/apron/affineEqualityAnalysis.apron.ml | 5 ++++- .../affineEquality/arrayImplementation/arrayMatrix.ml | 5 +++++ .../affineEquality/arrayImplementation/arrayVector.ml | 8 ++++---- .../affineEquality/sparseImplementation/listMatrix.ml | 3 +++ src/cdomains/apron/affineEqualityDomain.apron.ml | 2 +- 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/regtest.sh b/regtest.sh index 488dd0bab4..f263b2b968 100755 --- a/regtest.sh +++ b/regtest.sh @@ -14,7 +14,7 @@ if [[ $OSTYPE == 'darwin'* ]]; then grep="ggrep" fi params="`$grep -oP "PARAM: \K.*" $file`" -cmd="./goblint --enable warn.debug --enable dbg.regression --html $params ${@:3} $file" # -v +cmd="./goblint --enable warn.debug --enable dbg.regression $params ${@:3} $file -v" # -v --html echo "$cmd" eval $cmd echo "See result/index.xml" diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index 73ad59162f..80d3b32874 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -7,11 +7,14 @@ open Analyses open ArrayVector open ArrayMatrix +open SparseVector +open ListMatrix + include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( - let module AD = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in + let module AD = AffineEqualityDomain.D2 (SparseVector) (ListMatrix) in let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 1f4722adff..0981c17626 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -288,7 +288,9 @@ module ArrayMatrix: AbstractMatrix = let normalize m = let copy = copy m in + let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in if normalize_with copy then + let () = Printf.printf "After normalizing we have m:\n%s" (show copy) in Some copy else None @@ -297,6 +299,8 @@ module ArrayMatrix: AbstractMatrix = (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) (*Both input matrices must be in rref form!*) if num_rows m1 > num_rows m2 then false else + let m1' = copy m1 in + let m2' = copy m2 in let p2 = lazy (get_pivot_positions m2) in try ( for i = 0 to num_rows m1 - 1 do @@ -312,6 +316,7 @@ module ArrayMatrix: AbstractMatrix = if m1_i. (num_cols m1 - 1) <>: A.zero then raise Stdlib.Exit done; + (*let () = Printf.printf "m1: %sand m2: %s return true in is_covered_by.\n" (show m1') (show m2') in*) true ) with Stdlib.Exit -> false;; diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 937c4ee36f..b469245c27 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -114,13 +114,13 @@ module ArrayVector: AbstractVector = let find_opt f v = failwith "TODO" - let map_preserve_zero f v = failwith "TODO" - let map2_preserve_zero f v1 v2 = failwith "TODO" + let map_f_preserve_zero f v = failwith "TODO" + let map2_f_preserve_zero f v1 v2 = failwith "TODO" - let fold_left_preserve_zero f acc v = + let fold_left_f_preserve_zero f acc v = failwith "TODO" - let fold_left2_preserve_zero f acc v v' = + let fold_left2_f_preserve_zero f acc v v' = failwith "TODO" let findi_val_opt f v = diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 6fabd9295d..0276662cc6 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -90,6 +90,7 @@ module ListMatrix: AbstractMatrix = V.map2_f_preserve_zero (fun x y -> x -: s *: y) row1 row2 let reduce_col m j = + let () = Printf.printf "We are reducing matrix m:\n%s with %i\n" (show m) j in if is_empty m then m else let rec find_pivot idx entries = (* Finds non-zero element in column j and returns pair of row idx and the pivot value *) @@ -160,6 +161,7 @@ module ListMatrix: AbstractMatrix = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m let normalize m = + let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m @@ -203,6 +205,7 @@ module ListMatrix: AbstractMatrix = main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in + let () = Printf.printf "After normalizing we have m:\n%s" (show m') in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 2897559c43..000363286a 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -451,7 +451,7 @@ struct let t_primed = add_vars t primed_vars in let multi_t = List.fold_left2 (fun t' v_prime (_,v') -> assign_var t' v_prime v') t_primed primed_vars vv's in match multi_t.d with - | Some m when not @@ is_top_env multi_t -> + | Some m when not @@ is_top_env multi_t -> let () = Printf.printf "Matrix in Domain m:\n%s" (Matrix.show m) in let replace_col m x y = let dim_x, dim_y = Environment.dim_of_var multi_t.env x, Environment.dim_of_var multi_t.env y in let col_x = Matrix.get_col m dim_x in From ef0cc364fcfe82073b468099ba37b414c5c539cd Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 5 Dec 2024 22:59:32 +0100 Subject: [PATCH 083/150] Bugfixes in Vector and more Debug prints --- .../arrayImplementation/arrayMatrix.ml | 11 ++++- .../sparseImplementation/listMatrix.ml | 8 ++++ .../sparseImplementation/sparseVector.ml | 45 ++++++++++--------- .../apron/affineEqualityDomain.apron.ml | 12 ++++- 4 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 0981c17626..1103f8c0a7 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -39,6 +39,7 @@ module ArrayMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m let add_empty_columns m cols = + let () = Printf.printf "Before add_empty_columns m:\n%s\n" (show m) in let nnc = Array.length cols in if is_empty m || nnc = 0 then m else let nr, nc = num_rows m, num_cols m in @@ -50,17 +51,20 @@ module ArrayMatrix: AbstractMatrix = m'.(i).(j + !offset) <- m.(i).(j); done done; + let () = Printf.printf "After add_empty_columns m:\n%s\n" (show m') in m' let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = + let () = Printf.printf "Before append_row m:\n%s\n" (show m) in let size = num_rows m in let new_matrix = Array.make_matrix (size + 1) (num_cols m) A.zero in for i = 0 to size - 1 do new_matrix.(i) <- m.(i) done; new_matrix.(size) <- V.to_array row; + let () = Printf.printf "After append_row m:\n%s\n" (show new_matrix) in new_matrix let get_row m n = @@ -84,11 +88,14 @@ module ArrayMatrix: AbstractMatrix = let set_col_with m new_col n = for i = 0 to num_rows m - 1 do m.(i).(n) <- V.nth new_col i - done; m + done; + let () = Printf.printf "After set_col m:\n%s\n" (show m) in + m let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n let set_col m new_col n = + let () = Printf.printf "Before set_col m:\n%s\n" (show m) in let copy = copy m in set_col_with copy new_col n @@ -341,8 +348,10 @@ module ArrayMatrix: AbstractMatrix = *) let map2 f m v = + let () = Printf.printf "Before map2 m:\n%s\n" (show m) in let m' = copy m in map2_with f m' v; + let () = Printf.printf "After map2 m:\n%s\n" (show m') in m' let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 1269396e66..081bcf206f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -39,6 +39,7 @@ module ListMatrix: AbstractMatrix = Timing.wrap "copy" (copy) m let add_empty_columns m cols = + let () = Printf.printf "Before add_empty_columns m:\n%s\n" (show m) in let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in let rec count_sorted_occ acc cols last count = @@ -48,12 +49,15 @@ module ListMatrix: AbstractMatrix = | (x :: xs) -> count_sorted_occ ((last, count) :: acc) xs x 1 in let occ_cols = count_sorted_occ [] sorted_cols (-1) 0 in + let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols) m)) in List.map (fun row -> V.insert_zero_at_indices row occ_cols) m let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = + let () = Printf.printf "Before append_row m:\n%s\n" (show m) in + let () = Printf.printf "After append_row m:\n%s\n" (show ( m @ [row])) in m @ [row] let get_row m n = @@ -69,7 +73,9 @@ module ListMatrix: AbstractMatrix = Timing.wrap "get_col" (get_col m) n let set_col m new_col n = + let () = Printf.printf "Before set_col m:\n%s\n" (show m) in (* List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m *) + let () = Printf.printf "After set_col m:\n%s\n" (show (List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col))) in List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) @@ -263,7 +269,9 @@ module ListMatrix: AbstractMatrix = List.find_opt f m let map2 f m v = + let () = Printf.printf "Before map2 we have m:\n%s\n" (show m) in let vector_length = V.length v in + let () = Printf.printf "After map2 we have m:\n%s\n" (show (List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m)) in List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 262dfb8c32..aa9b7394d7 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -4,6 +4,7 @@ open ConvenienceOps open BatList open BatArray +open Batteries module List = BatList module Array = BatArray @@ -20,6 +21,20 @@ module SparseVector: AbstractVector = let to_vector e l = {entries=e; len=l} + let to_list v = + let[@tail_mod_cons] rec extend_zero_aux i v' = + if i >= v.len then [] else (*can probably be removed*) + match v', i with + | (xi,xv)::xs, _ -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero ::(extend_zero_aux (i+1) v') + | [], j when i < v.len -> A.zero :: (extend_zero_aux (i+1) v') + | [], _ -> [] + in + (extend_zero_aux 0 v.entries) + + let of_list l = + let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l + in {entries = entries'; len = List.length l} + let keep_vals v n = let rec keep_vals_vec v n = match v with @@ -82,7 +97,8 @@ module SparseVector: AbstractVector = in {entries = add_indices_helper v.entries idx 0; len = v.len + List.length idx} - let set_nth v n num = + let set_nth v n num = (* TODO: Optimize! *) + (* if n >= v.len then failwith "Out of bounds" else let rev_entries', _ = List.fold_lefti (fun (acc, found) i (idx, value) -> @@ -99,6 +115,8 @@ module SparseVector: AbstractVector = ) ([], false) v.entries in {entries = List.rev rev_entries'; len = v.len} + *) + of_list @@ List.mapi (fun i x -> if i = n then num else x) (to_list v) let insert_val_at n new_val v = if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) @@ -153,17 +171,14 @@ module SparseVector: AbstractVector = if v.len <> v'.len then raise (Invalid_argument "Unequal lengths") else (aux acc v.entries v'.entries) - let apply_with_c f c v = - let entries' = List.map (fun (idx, value) -> (idx, f value c)) v.entries in - {entries = entries'; len = v.len} let zero_vec n = {entries = []; len = n} let is_zero_vec v = (v.entries = []) - let nth v n = - if n >= v.len then failwith "V.nth out of bounds" + let nth v n = (* Note: This exception HAS TO BE THROWN! It is expected by the domain *) + if n >= v.len then raise (Invalid_argument "Cannot access vector element (out of bounds)") else let rec nth v = match v with (* List.assoc would also work, but we use the fact that v is sorted *) | [] -> A.zero @@ -175,24 +190,12 @@ module SparseVector: AbstractVector = let length v = v.len - let of_list l = - let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l - in {entries = entries'; len = List.length l} - - let to_list v = - let[@tail_mod_cons] rec extend_zero_aux i v' = - if i >= v.len then [] else (*can probably be removed*) - match v', i with - | (xi,xv)::xs, _ -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero ::(extend_zero_aux (i+1) v') - | [], j when i < v.len -> A.zero :: (extend_zero_aux (i+1) v') - | [], _ -> [] - in - (extend_zero_aux 0 v.entries) - let map2 f v v' = if v.len <> v'.len then failwith "Unequal vector length" else of_list (List.map2 f (to_list v) (to_list v')) + let apply_with_c f c v = (* TODO: optimize! *) + of_list @@ List.map (fun value -> f value c) (to_list v) let findi f v = if f A.zero then @@ -246,7 +249,7 @@ module SparseVector: AbstractVector = of_list (List.mapi f (to_list v)) let find2i f v v' = (* TODO: optimize! *) - failwith "TODO" + fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) let to_array v = let vec = Array.make v.len A.zero in diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 000363286a..f8e632ee6b 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -33,11 +33,13 @@ struct let dim_remove (ch: Apron.Dim.change) m ~del = + let () = Printf.printf "Before dim_remove m:\n%s" (show m) in if Array.length ch.dim = 0 || is_empty m then m else ( Array.modifyi (+) ch.dim; let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col y x) m ch.dim else m in + let () = Printf.printf "After dim_remove m':\n%s" (show (remove_zero_rows @@ del_cols m' ch.dim)) in remove_zero_rows @@ del_cols m' ch.dim) let dim_remove ch m ~del = Timing.wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del @@ -348,6 +350,7 @@ struct let join a b = let res = join a b in + let () = Printf.printf "join a: %s b: %s -> %s \n" (show a) (show b) (show res) in if M.tracing then M.tracel "join" "join a: %s b: %s -> %s " (show a) (show b) (show res) ; res @@ -368,6 +371,7 @@ struct let remove_rels_with_var x var env = Timing.wrap "remove_rels_with_var" remove_rels_with_var x var env let forget_vars t vars = + let () = Printf.printf "forget_vars m:\n%s" (show t) in if is_bot t || is_top_env t || vars = [] then t else @@ -409,7 +413,8 @@ struct in (* let assign_uninvertible_rel x var b env = Timing.wrap "assign_uninvertible" (assign_uninvertible_rel x var b) env in *) let is_invertible v = Vector.nth v @@ Environment.dim_of_var t.env var <>: Mpqf.zero - in let affineEq_vec = get_coeff_vec t texp + in let affineEq_vec = get_coeff_vec t texp in + let () = Printf.printf "After affineEq_vec m:\n%s\n" (Vector.show (Option.get affineEq_vec)) in if is_bot t then t else let m = Option.get t.d in match affineEq_vec with | Some v when is_top_env t -> if is_invertible v then t else assign_uninvertible_rel m var v t.env @@ -445,13 +450,15 @@ struct res let assign_var_parallel t vv's = + let () = Printf.printf "Before assign_var_parallel m:\n%s\n" (show t) in let assigned_vars = List.map fst vv's in let t = add_vars t assigned_vars in let primed_vars = List.init (List.length assigned_vars) (fun i -> Var.of_string (Int.to_string i ^"'")) in (* TODO: we use primed vars in analysis, conflict? *) let t_primed = add_vars t primed_vars in let multi_t = List.fold_left2 (fun t' v_prime (_,v') -> assign_var t' v_prime v') t_primed primed_vars vv's in + let () = Printf.printf "After assign_var_parallel multi_t:\n%s\n" (show multi_t) in match multi_t.d with - | Some m when not @@ is_top_env multi_t -> let () = Printf.printf "Matrix in Domain m:\n%s" (Matrix.show m) in + | Some m when not @@ is_top_env multi_t -> let () = Printf.printf "Matrix in Domain m:\n%s\n" (Matrix.show m) in let replace_col m x y = let dim_x, dim_y = Environment.dim_of_var multi_t.env x, Environment.dim_of_var multi_t.env y in let col_x = Matrix.get_col m dim_x in @@ -459,6 +466,7 @@ struct in let m_cp = Matrix.copy m in let switched_m = List.fold_left2 replace_col m_cp primed_vars assigned_vars in + let () = Printf.printf "Switched Matrix in Domain switched_m:\n%s\n" (Matrix.show switched_m) in let res = drop_vars {d = Some switched_m; env = multi_t.env} primed_vars ~del:true in let x = Option.get res.d in (match Matrix.normalize x with From c038dc76417f271e821bd2a2b648bbf046ffa450 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 6 Dec 2024 08:32:17 +0100 Subject: [PATCH 084/150] Bugfix in Vector keep_vals and to_list; Implement set_nth in Vector" --- .../sparseImplementation/listMatrix.ml | 5 +- .../sparseImplementation/sparseVector.ml | 46 +++++++------------ .../apron/affineEqualityDomain.apron.ml | 3 ++ 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 081bcf206f..fdc78a8a8a 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -56,8 +56,8 @@ module ListMatrix: AbstractMatrix = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - let () = Printf.printf "Before append_row m:\n%s\n" (show m) in - let () = Printf.printf "After append_row m:\n%s\n" (show ( m @ [row])) in + let () = Printf.printf "Before append_row m:\n%s\n" (show m) in + let () = Printf.printf "After append_row m:\n%s\n" (show ( m @ [row])) in m @ [row] let get_row m n = @@ -67,6 +67,7 @@ module ListMatrix: AbstractMatrix = List.remove_at n m let get_col m n = + let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_list @@ List.map (fun row -> V.nth row n) m)) in V.of_list @@ List.map (fun row -> V.nth row n) m (* builds full col including zeros, maybe use sparselist instead? *) let get_col m n = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index aa9b7394d7..46cd68b990 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -23,11 +23,10 @@ module SparseVector: AbstractVector = let to_list v = let[@tail_mod_cons] rec extend_zero_aux i v' = - if i >= v.len then [] else (*can probably be removed*) - match v', i with - | (xi,xv)::xs, _ -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero ::(extend_zero_aux (i+1) v') - | [], j when i < v.len -> A.zero :: (extend_zero_aux (i+1) v') - | [], _ -> [] + match v', i with + | (xi,xv)::xs, _ -> if xi = i then xv::(extend_zero_aux (i+1) xs) else A.zero ::(extend_zero_aux (i+1) v') + | [], j when i < v.len -> A.zero :: (extend_zero_aux (i+1) v') + | [], _ -> [] in (extend_zero_aux 0 v.entries) @@ -36,13 +35,8 @@ module SparseVector: AbstractVector = in {entries = entries'; len = List.length l} let keep_vals v n = - let rec keep_vals_vec v n = - match v with - | x::xs -> if fst x > n then [] else x::(keep_vals_vec xs n) - | [] -> [] - in - if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = keep_vals_vec v.entries n; len=n} + if n >= v.len then v else + {entries = take_while (fun (idx, _) -> idx < n) v.entries; len=n} let remove_nth v n = @@ -98,25 +92,17 @@ module SparseVector: AbstractVector = {entries = add_indices_helper v.entries idx 0; len = v.len + List.length idx} let set_nth v n num = (* TODO: Optimize! *) - (* if n >= v.len then failwith "Out of bounds" else - let rev_entries', _ = List.fold_lefti (fun (acc, found) i (idx, value) -> - if found then ((idx, value) :: acc, true) - else - if i = v.len - 1 then - if idx = n then (if num <>: A.zero then (n, num) :: acc, true else acc, true) - else if idx > n then (if num <>: A.zero then (idx, value) :: (n, num) :: acc, true else (idx, value) :: acc, true) - else failwith "Out of bounds (Should not be reachable)" - else - if idx < n then ((idx, value) :: acc, false) - else if idx = n then (if num <>: A.zero then (n, num) :: acc , true else acc, true) - else (if num <>: A.zero then (idx, value) :: (n, num) :: acc, true else (idx, value) :: acc, true) - - ) ([], false) v.entries in - {entries = List.rev rev_entries'; len = v.len} - *) - of_list @@ List.mapi (fun i x -> if i = n then num else x) (to_list v) + (* of_list @@ List.mapi (fun i x -> if i = n then num else x) (to_list v) *) + let rec set_nth_helper vec acc = + match vec with + | [] -> if num <>: A.zero then List.rev ((n, num) :: acc) else List.rev acc + | (idx, value) :: xs when n = idx -> if num <>: A.zero then List.rev_append ((idx, num) :: acc) xs else List.rev_append acc xs + | (idx, value) :: xs when n < idx -> if num <>: A.zero then List.rev_append ((n, num) :: acc) vec else List.rev_append acc ((idx, value) :: xs) + | x :: xs -> set_nth_helper xs (x :: acc) + in + {entries = set_nth_helper v.entries []; len = v.len} let insert_val_at n new_val v = if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) @@ -190,7 +176,7 @@ module SparseVector: AbstractVector = let length v = v.len - let map2 f v v' = + let map2 f v v' = (* TODO: Optimize! *) if v.len <> v'.len then failwith "Unequal vector length" else of_list (List.map2 f (to_list v) (to_list v')) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index f8e632ee6b..9823227b03 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -257,6 +257,7 @@ struct let meet t1 t2 = let res = meet t1 t2 in + let () = Printf.printf "meet a: %s b: %s -> %s \n" (show t1) (show t2) (show res) in if M.tracing then M.tracel "meet" "meet a: %s b: %s -> %s " (show t1) (show t2) (show res) ; res @@ -283,6 +284,7 @@ struct let leq t1 t2 = let res = leq t1 t2 in + let () = Printf.printf "leq a: %s b: %s -> %b \n" (show t1) (show t2) res in if M.tracing then M.tracel "leq" "leq a: %s b: %s -> %b " (show t1) (show t2) res ; res @@ -355,6 +357,7 @@ struct res let widen a b = + let () = Printf.printf "Widen a: %s b: %s\n" (show a) (show b) in if Environment.equal a.env b.env then join a b else From 92b784a805db6341378e97be12c399f8f8a12fa1 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 6 Dec 2024 10:51:34 +0100 Subject: [PATCH 085/150] Bugfix insert_val_at --- .../affineEquality/sparseImplementation/sparseVector.ml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 46cd68b990..ea306745ad 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -59,8 +59,7 @@ module SparseVector: AbstractVector = if n >= v.len then failwith "Out of bounds" else let new_entries = List.filter_map (fun (col_idx, value) -> - if col_idx = n - then None + if col_idx = n then None else if col_idx > n then Some (col_idx - 1, value) else Some (col_idx, value) @@ -108,7 +107,7 @@ module SparseVector: AbstractVector = if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) let entries' = List.fold_left (fun acc (idx, value) -> if idx < n then (idx, value) :: acc - else (idx + 1, value) :: acc + else (idx + 1, value) :: (idx, new_val):: acc ) [] (List.rev v.entries) in {entries = List.sort (fun (i, _) (j, _) -> Int.compare i j) entries'; len = v.len + 1} From 8ba57776013acdf49ef27e330c2fbcb8c18017b4 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 6 Dec 2024 12:32:21 +0100 Subject: [PATCH 086/150] Bugfix Matrix map2i and Vector insert_val_at again --- .../sparseImplementation/listMatrix.ml | 12 ++++++++---- .../sparseImplementation/sparseVector.ml | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index fdc78a8a8a..236da00c64 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -144,10 +144,14 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols - let map2i f m v = - let vector_length = V.length v in - (* List.mapi (fun index row -> if index < vector_length then f index row (V.nth v index) else row) m *) - List.map2i (fun index row value -> if index < vector_length then f index row value else row) m (V.to_list v) + let map2i f m v= + let rec map2i_min i acc m v = + match m, v with + | [], _ | _, [] -> List.rev acc + | row :: rs, value :: vs -> + map2i_min (i + 1) (f i row value :: acc) rs vs + in + map2i_min 0 [] m (V.to_list v) let remove_zero_rows m = List.filter (fun row -> not (V.is_zero_vec row)) m diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index ea306745ad..338d8f396c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -105,11 +105,11 @@ module SparseVector: AbstractVector = let insert_val_at n new_val v = if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) - let entries' = List.fold_left (fun acc (idx, value) -> + let entries' = List.rev @@ List.fold_left (fun acc (idx, value) -> if idx < n then (idx, value) :: acc - else (idx + 1, value) :: (idx, new_val):: acc - ) [] (List.rev v.entries) in - {entries = List.sort (fun (i, _) (j, _) -> Int.compare i j) entries'; len = v.len + 1} + else (if new_val <>: A.zero then (idx + 1, value) :: (n, new_val) :: acc else (idx + 1, value) :: acc) + ) [] v.entries in + {entries = entries'; len = v.len + 1} let map_f_preserves_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) let entries' = List.filter_map ( From f6a415ee35b8c7a1a0679831d7446434e32a9e89 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 6 Dec 2024 13:53:42 +0100 Subject: [PATCH 087/150] Add more debug-prints --- src/analyses/apron/affineEqualityAnalysis.apron.ml | 2 +- .../affineEquality/arrayImplementation/arrayMatrix.ml | 5 +++++ .../affineEquality/sparseImplementation/listMatrix.ml | 9 ++++++--- .../affineEquality/sparseImplementation/sparseVector.ml | 4 ++-- src/cdomains/apron/affineEqualityDomain.apron.ml | 3 +++ 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index 80d3b32874..e262b2653b 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -14,7 +14,7 @@ include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( - let module AD = AffineEqualityDomain.D2 (SparseVector) (ListMatrix) in + let module AD = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 1103f8c0a7..2248b1f414 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -81,6 +81,7 @@ module ArrayMatrix: AbstractMatrix = Array.blit m (n + 1) new_matrix n (num_rows new_matrix - n)); new_matrix let get_col m n = + let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)))) in V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)) let get_col m n = Timing.wrap "get_col" (get_col m) n @@ -206,12 +207,14 @@ module ArrayMatrix: AbstractMatrix = let reduce_col_with_vec m j v = + let () = Printf.printf "Matrix: Before reduce_col_with_vec %i with vec %s of m:\n%s\n" j (V.show (V.of_array v)) (show m) in for i = 0 to num_rows m - 1 do if m.(i).(j) <>: A.zero then let beta = m.(i).(j) /: v.(j) in Array.iteri (fun j' x -> m.(i).(j') <- x -: beta *: v.(j')) m.(i) done + let get_pivot_positions m = let pivot_elements = Array.make (num_rows m) 0 in Array.iteri (fun i x -> pivot_elements.(i) <- Array.findi (fun z -> z =: A.one) x) m; pivot_elements @@ -373,8 +376,10 @@ module ArrayMatrix: AbstractMatrix = Array.map2 f' m (Array.combine range_array (V.to_array v)) *) let map2i f m v = + let () = Printf.printf "Before map2i m:\n%sv:%s\n" (show m) (V.show v) in let m' = copy m in map2i_with f m' v; + let () = Printf.printf "After map2i m:\n%s\n" (show m') in m' let swap_rows m j k = diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 236da00c64..87bf5702da 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -97,7 +97,7 @@ module ListMatrix: AbstractMatrix = V.map2_f_preserves_zero (fun x y -> x -: s *: y) row1 row2 let reduce_col m j = - let () = Printf.printf "We are reducing matrix m:\n%s with %i\n" (show m) j in + let () = Printf.printf "Matrix: reduce_col %i of m:\n%s\n" j (show m) in if is_empty m then m else let rec find_pivot idx entries = (* Finds non-zero element in column j and returns pair of row idx and the pivot value *) @@ -121,6 +121,7 @@ module ListMatrix: AbstractMatrix = ) m let reduce_col_with_vec m j v = + let () = Printf.printf "Before reduce_col_with_vec %i with vec %s of m:\n%s\n" j (V.show v) (show m) in let pivot_element = V.nth v j in if pivot_element = A.zero then m else List.mapi (fun idx row -> @@ -144,13 +145,15 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols - let map2i f m v= + let map2i f m v = + let () = Printf.printf "Before map2i m:\n%sv:%s\n" (show m) (V.show v) in let rec map2i_min i acc m v = match m, v with | [], _ | _, [] -> List.rev acc | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs - in + in + let () = Printf.printf "After map2i m:\n%s\n" (show (map2i_min 0 [] m (V.to_list v))) in map2i_min 0 [] m (V.to_list v) let remove_zero_rows m = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 338d8f396c..1dd59d1454 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -192,9 +192,9 @@ module SparseVector: AbstractVector = let findi_val_opt f v = let rec find_zero_or_val vec last_col_idx = match vec, last_col_idx with - | [], _ -> if v.len <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) else None + | [], _ -> if f A.zero && v.len <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else None | (idx, value) :: xs, i -> - if idx <> last_col_idx + 1 && f A.zero then Some (last_col_idx + 1, A.zero) + if f A.zero && idx <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else if f value then Some (idx, value) else find_zero_or_val xs idx in find_zero_or_val v.entries (-1) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 9823227b03..a08c44b661 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -298,7 +298,9 @@ struct in let case_three a b col_a col_b max = let col_a, col_b = Vector.copy col_a, Vector.copy col_b in + let () = Printf.printf "Before keep_vals: \ncol_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in let col_a, col_b = Vector.keep_vals col_a max, Vector.keep_vals col_b max in + let () = Printf.printf "After keep_vals: \ncol_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in if Vector.equal col_a col_b then (a, b, max) else @@ -312,6 +314,7 @@ struct let col_a = Vector.map2 (-:) col_a col_b in let col_a = Vector.rev col_a in let multiply_by_t m t = + let () = Printf.printf "Before multiply_by_t col_a: %s" (Vector.show col_a) in Matrix.map2i (fun i' x c -> if i' <= max then (let beta = c /: diff in Vector.map2 (fun u j -> u -: (beta *: j)) x t) else x) m col_a; in From 3e7d3d6ae503011ec665bc49d6dfd06d0e266b5f Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 6 Dec 2024 18:42:36 +0100 Subject: [PATCH 088/150] Bugfix in Vector rev and Matrix map2i again --- src/analyses/apron/affineEqualityAnalysis.apron.ml | 2 +- .../affineEquality/arrayImplementation/arrayMatrix.ml | 1 + .../affineEquality/sparseImplementation/listMatrix.ml | 7 ++++--- .../affineEquality/sparseImplementation/sparseVector.ml | 2 +- src/cdomains/apron/affineEqualityDomain.apron.ml | 2 ++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index e262b2653b..80d3b32874 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -14,7 +14,7 @@ include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( - let module AD = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in + let module AD = AffineEqualityDomain.D2 (SparseVector) (ListMatrix) in let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 2248b1f414..5e8407d621 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -71,6 +71,7 @@ module ArrayMatrix: AbstractMatrix = V.of_array m.(n) let remove_row m n = + let () = Printf.printf "Before remove_row %i of m:\n%s\n" n (show m) in let new_matrix = Array.make_matrix (num_rows m - 1) (num_cols m) A.zero in if not @@ is_empty new_matrix then if n = 0 then diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 87bf5702da..5440c55244 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -64,6 +64,7 @@ module ListMatrix: AbstractMatrix = List.nth m n let remove_row m n = + let () = Printf.printf "Before remove_row %i of m:\n%s\n" n (show m) in List.remove_at n m let get_col m n = @@ -149,9 +150,9 @@ module ListMatrix: AbstractMatrix = let () = Printf.printf "Before map2i m:\n%sv:%s\n" (show m) (V.show v) in let rec map2i_min i acc m v = match m, v with - | [], _ | _, [] -> List.rev acc - | row :: rs, value :: vs -> - map2i_min (i + 1) (f i row value :: acc) rs vs + | [], _ -> List.rev acc + | row :: rs, [] -> List.rev_append (row :: acc) rs + | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs in let () = Printf.printf "After map2i m:\n%s\n" (show (map2i_min 0 [] m (V.to_list v))) in map2i_min 0 [] m (V.to_list v) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 1dd59d1454..a9e5af6fd0 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -224,7 +224,7 @@ module SparseVector: AbstractVector = List.exists2 f (to_list v1) (to_list v2) let rev v = - let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - idx, value)) v.entries in + let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - 1 - idx, value)) v.entries in {entries = entries'; len = v.len} let map2i f v v' = (* TODO: optimize! *) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index a08c44b661..7df3ac7edc 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -305,8 +305,10 @@ struct (a, b, max) else ( + let () = Printf.printf "Before rev col_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in let col_a = Vector.rev col_a in let col_b = Vector.rev col_b in + let () = Printf.printf "After rev col_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in let i = Vector.find2i (<>:) col_a col_b in let (x, y) = Vector.nth col_a i, Vector.nth col_b i in let r, diff = Vector.length col_a - (i + 1), x -: y in From 0c95dc73572d2e5de8b62fb407bde54098725c78 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 6 Dec 2024 20:12:37 +0100 Subject: [PATCH 089/150] Bugfix in Matrix del_cols and Vector remove_at_indices --- .../arrayImplementation/arrayMatrix.ml | 4 +++- .../sparseImplementation/listMatrix.ml | 23 +++++++++++++++---- .../sparseImplementation/sparseVector.ml | 4 +++- .../apron/affineEqualityDomain.apron.ml | 1 + 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 5e8407d621..14963944e2 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -124,8 +124,10 @@ module ArrayMatrix: AbstractMatrix = let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j let reduce_col m j = + let () = Printf.printf "Before reduce_col %i of m:\n%s\n" j (show m) in let copy = copy m in reduce_col_with copy j; + let () = Printf.printf "After reduce_col %i of m:\n%s\n" j (show copy) in copy let del_col m j = @@ -208,7 +210,6 @@ module ArrayMatrix: AbstractMatrix = let reduce_col_with_vec m j v = - let () = Printf.printf "Matrix: Before reduce_col_with_vec %i with vec %s of m:\n%s\n" j (V.show (V.of_array v)) (show m) in for i = 0 to num_rows m - 1 do if m.(i).(j) <>: A.zero then let beta = m.(i).(j) /: v.(j) in @@ -288,6 +289,7 @@ module ArrayMatrix: AbstractMatrix = let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 let rref_matrix m1 m2 = + let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in let m1' = copy m1 in let m2' = copy m2 in rref_matrix_with m1' m2' diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 5440c55244..a4690a55e4 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -98,7 +98,7 @@ module ListMatrix: AbstractMatrix = V.map2_f_preserves_zero (fun x y -> x -: s *: y) row1 row2 let reduce_col m j = - let () = Printf.printf "Matrix: reduce_col %i of m:\n%s\n" j (show m) in + let () = Printf.printf "Before reduce_col %i of m:\n%s\n" j (show m) in if is_empty m then m else let rec find_pivot idx entries = (* Finds non-zero element in column j and returns pair of row idx and the pivot value *) @@ -108,8 +108,18 @@ module ListMatrix: AbstractMatrix = if value =: A.zero then find_pivot (idx - 1) rest else Some (idx, value) in match (find_pivot (num_rows m - 1) (List.rev m)) with - | None -> m (* column is already filled with zeroes *) + | None -> let () = Printf.printf "After reduce_col %i of m:\n%s\n" j (show m) in m (* column is already filled with zeroes *) | Some (row_idx, pivot) -> + let () = Printf.printf "After reduce_col %i of m:\n%s\n" j (show (let pivot_row = List.nth m row_idx in + List.mapi (fun idx row -> + if idx = row_idx then + V.zero_vec (num_cols m) + else + let row_value = V.nth row j in + if row_value = A.zero then row + else (let s = row_value /: pivot in + sub_scaled_row row pivot_row s) + ) m)) in let pivot_row = List.nth m row_idx in List.mapi (fun idx row -> if idx = row_idx then @@ -140,7 +150,8 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = let cols = Array.to_list cols in (* TODO: Is it possible to use list for Apron dimchange? *) let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification) *) - if (List.length cols) = num_cols m then empty() + let () = Printf.printf "Before del_cols cols_length=%i sorted_length=%i \nm:\n%s\n" (List.length cols) (List.length sorted_cols) (show m) in + if (List.length sorted_cols) = num_cols m then empty() else List.map (fun row -> V.remove_at_indices row sorted_cols) m @@ -189,7 +200,7 @@ module ListMatrix: AbstractMatrix = let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) - | Some (idx, value) -> let () = Printf.printf "We found first non-zero at index %i in row %i\n" idx i in + | Some (idx, value) -> (* let () = Printf.printf "We found first non-zero at index %i in row %i\n" idx i in *) if idx < cur_col then (row_idx + i, idx, value) else (cur_row, cur_col, cur_val) ) (num_rows m', num_cols m', A.zero) m' (* Initializing with max, so num_cols m indicates that pivot is not found *) in @@ -209,7 +220,7 @@ module ListMatrix: AbstractMatrix = match find_first_pivot m' row_idx col_idx with | None -> m (* No pivot found means already normalized*) | Some (piv_row_idx, piv_col_idx, piv_val) -> ( - let () = Printf.printf "The current matrix is: \n%s and the pivot is (%i, %i, %s)\n" (show m) piv_row_idx piv_col_idx (A.to_string piv_val) in + (* let () = Printf.printf "The current matrix is: \n%s and the pivot is (%i, %i, %s)\n" (show m) piv_row_idx piv_col_idx (A.to_string piv_val) in *) let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in let normalized_m = List.mapi (fun idx row -> if idx = row_idx then div_row row piv_val else row) m in let piv_row = (List.nth normalized_m row_idx) in @@ -229,12 +240,14 @@ module ListMatrix: AbstractMatrix = (*If m is empty then v is simply normalized and returned*) (* TODO: OPTIMIZE! *) let rref_vec m v = + let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in normalize @@ append_matrices m (init_with_vec v) (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) (*TODO: OPTIMIZE!*) let rref_matrix m1 m2 = + let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in normalize @@ append_matrices m1 m2 diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index a9e5af6fd0..10a841beee 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -66,11 +66,13 @@ module SparseVector: AbstractVector = ) v.entries in {entries = new_entries; len = v.len - 1} + (* Note: It is assumed and necessary here that idx is sorted!!! *) let remove_at_indices v idx = let rec remove_indices_helper vec idx deleted_count = match vec, idx with | [], [] -> [] - | [], (y :: ys) -> failwith "remove at indices: no more columns to delete" + | [], (y :: ys) when deleted_count >= v.len || y >= v.len -> failwith "remove at indices: no more columns to delete" + | [], (y :: ys) -> remove_indices_helper [] ys (deleted_count + 1) (* Removing zero (also in next iteration, else failwith ) *) | ((col_idx, value) :: xs), [] -> (col_idx - deleted_count, value) :: remove_indices_helper xs [] deleted_count | ((col_idx, value) :: xs), (y :: ys) when y = col_idx -> remove_indices_helper xs ys (deleted_count + 1) | ((col_idx, value) :: xs), (y :: ys) when y < col_idx -> remove_indices_helper vec ys (deleted_count + 1) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 7df3ac7edc..3c00ebf263 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -415,6 +415,7 @@ struct let b_length = Vector.length b in let b = Vector.mapi (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b in let b = Vector.set_nth b (Environment.dim_of_var env var) Mpqf.one in + let () = Printf.printf "Before Matrix.rref_vec x:\n%s b:\n%s\n" (Matrix.show x) (Vector.show b) in match Matrix.rref_vec x b with | None -> bot () | some_matrix -> {d = some_matrix; env = env} From c72c77d0203df105e4ad7e846fc7908d9da2b9d7 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Fri, 6 Dec 2024 22:10:43 +0100 Subject: [PATCH 090/150] arraymatrix passes tests again --- src/analyses/apron/affineEqualityAnalysis.apron.ml | 2 +- src/cdomains/apron/affineEqualityDomain.apron.ml | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index 80d3b32874..e262b2653b 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -14,7 +14,7 @@ include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( - let module AD = AffineEqualityDomain.D2 (SparseVector) (ListMatrix) in + let module AD = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 3c00ebf263..5a666f728b 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -423,11 +423,12 @@ struct (* let assign_uninvertible_rel x var b env = Timing.wrap "assign_uninvertible" (assign_uninvertible_rel x var b) env in *) let is_invertible v = Vector.nth v @@ Environment.dim_of_var t.env var <>: Mpqf.zero in let affineEq_vec = get_coeff_vec t texp in - let () = Printf.printf "After affineEq_vec m:\n%s\n" (Vector.show (Option.get affineEq_vec)) - in if is_bot t then t else let m = Option.get t.d in + if is_bot t then t else let m = Option.get t.d in match affineEq_vec with - | Some v when is_top_env t -> if is_invertible v then t else assign_uninvertible_rel m var v t.env - | Some v -> if is_invertible v then let t' = assign_invertible_rels (Matrix.copy m) var v t.env in {d = t'.d; env = t'.env} + | Some v when is_top_env t -> let () = Printf.printf "After affineEq_vec m:\n%s\n" (Vector.show v) in + if is_invertible v then t else assign_uninvertible_rel m var v t.env + | Some v -> let () = Printf.printf "After affineEq_vec m:\n%s\n" (Vector.show v) in + if is_invertible v then let t' = assign_invertible_rels (Matrix.copy m) var v t.env in {d = t'.d; env = t'.env} else let new_m = Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env in assign_uninvertible_rel new_m var v t.env | None -> {d = Some (Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env); env = t.env} From 09054a1eec8e898ee0e2cd8a02104f08ad44e3a8 Mon Sep 17 00:00:00 2001 From: Havercake Date: Fri, 6 Dec 2024 23:12:25 +0100 Subject: [PATCH 091/150] Reduced test suite; Simple normalized test with mxn-Matrix with m!=n; --- .../sparseMatrixImplementationTest.ml | 47 +++++++++++++++++++ tests/unit/mainTest.ml | 5 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml new file mode 100644 index 0000000000..5632dc4e4a --- /dev/null +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -0,0 +1,47 @@ +(* + To run this, type `dune runtest tests/unit/`. +*) + +open Goblint_lib +open OUnit2 +open SparseVector +open ListMatrix +module D = SharedFunctions.Mpqf +module Vector = SparseVector (D) +module Matrix = ListMatrix (D) (SparseVector) + +let normalize _ = + let width = 4 in + let int x = D.of_int x in + let any_matrix = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row + (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 2); (2, int 4); (3, int (-1)) ]) + ) + (Vector.of_sparse_list width [ (0, int 2); (1, int 3); (2, int 4) ]) + ) + (Vector.of_sparse_list width [ (0, int 1); (1, int 1); (2, int 2); (3, int 4) ] + ) + in + let normalized_matrix = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row + (Matrix.empty ()) + (Vector.of_sparse_list width [ (0,int 1); (2,int 2) ]) + ) + (Vector.of_sparse_list width [ (1,int 1) ]) + ) + (Vector.of_sparse_list width [ (3,int 1) ] + ) + in + match Matrix.normalize any_matrix with + | None -> assert_failure "The matrix is normalizable but was not normalized!" + | Some reduced_matrix -> assert_equal reduced_matrix normalized_matrix + +let tests = "SparseMatrixImplementationTest" >::: [ "normalize" >:: normalize ] + +let () = + run_test_tt_main tests diff --git a/tests/unit/mainTest.ml b/tests/unit/mainTest.ml index 4f071ea25c..4fd65f6736 100644 --- a/tests/unit/mainTest.ml +++ b/tests/unit/mainTest.ml @@ -7,6 +7,7 @@ let all_tests = MapDomainTest.test (); SolverTest.test (); LvalTest.test (); + SparseMatrixImplementationTest.tests ; CompilationDatabaseTest.tests; LibraryDslTest.tests; CilfacadeTest.tests; @@ -15,6 +16,8 @@ let all_tests = IntOpsTest.tests; ] +let subset_tests = "" >::: [SparseMatrixImplementationTest.tests] + let () = print_string "\027[0;1munit: \027[0;0;00m"; - run_test_tt_main all_tests + run_test_tt_main subset_tests From 29689633ea5c4514ff4498e8b17c2b332888d409 Mon Sep 17 00:00:00 2001 From: Havercake Date: Fri, 6 Dec 2024 23:20:40 +0100 Subject: [PATCH 092/150] Added example source --- .../sparseImplementation/sparseMatrixImplementationTest.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 5632dc4e4a..cce52c6a7d 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -11,6 +11,7 @@ module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) let normalize _ = + (* Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ)*) let width = 4 in let int x = D.of_int x in let any_matrix = From 4ef3acc661bba131402cb7cc8f7f24955d2b06c8 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Sat, 7 Dec 2024 11:58:34 +0100 Subject: [PATCH 093/150] more debugging prints and added remove_zero_rows to rref_vec --- .../arrayImplementation/arrayMatrix.ml | 44 +++++++++++-------- .../sparseImplementation/listMatrix.ml | 7 ++- .../sparseImplementation/sparseVector.ml | 2 +- .../sparseMatrixImplementationTest.ml | 2 + 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 14963944e2..b9bd503ddc 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -139,6 +139,7 @@ module ArrayMatrix: AbstractMatrix = let del_cols m cols = let n_c = Array.length cols in + let () = Printf.printf "Before del_cols cols_length=%i \nm:\n%s\n" n_c (show m) in if n_c = 0 || is_empty m then m else let m_r, m_c = num_rows m, num_cols m in @@ -210,6 +211,7 @@ module ArrayMatrix: AbstractMatrix = let reduce_col_with_vec m j v = + let () = Printf.printf "Before reduce_col_with_vec %i with vec %s of m:\n%s\n" j (V.show (V.of_array v)) (show m) in for i = 0 to num_rows m - 1 do if m.(i).(j) <>: A.zero then let beta = m.(i).(j) /: v.(j) in @@ -245,12 +247,25 @@ module ArrayMatrix: AbstractMatrix = else (Array.blit m 0 new_m 0 i; new_m.(i) <- v; Array.blit m i new_m (i + 1) (Array.length m - j)); Some new_m + let normalize_with m = + rref_with m + + let normalize_with m = Timing.wrap "normalize_with" normalize_with m + let normalize m = + let copy = copy m in + let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in + if normalize_with copy then + let () = Printf.printf "After normalizing we have m:\n%s" (show copy) in + Some copy + else + let () = Printf.printf "No normalization" in + None let rref_vec_with m v = (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) (*m must be in rref form and contain the same num of cols as v*) (*If m is empty then v is simply normalized and returned*) - let v = V.to_array v in + (*let v = V.to_array v in if is_empty m then match Array.findi (fun x -> x <>: A.zero) v with | exception Not_found -> None @@ -259,14 +274,19 @@ module ArrayMatrix: AbstractMatrix = Array.iteri (fun j x -> v.(j) <- x /: v_i) v; Some (init_with_vec @@ V.of_array v) else let pivot_elements = get_pivot_positions m in - rref_vec_helper m pivot_elements v + rref_vec_helper m pivot_elements v*) + normalize @@ append_row m v let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v let rref_vec m v = (* !! There was another rref_vec function that has been renamed to rref_vec_helper !!*) + let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in let m' = copy m in let v' = V.copy v in - rref_vec_with m' v' + match rref_vec_with m' v' with + | Some res -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in + Some (remove_zero_rows res) + | None -> None let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) @@ -294,20 +314,6 @@ module ArrayMatrix: AbstractMatrix = let m2' = copy m2 in rref_matrix_with m1' m2' - let normalize_with m = - rref_with m - - let normalize_with m = Timing.wrap "normalize_with" normalize_with m - - let normalize m = - let copy = copy m in - let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in - if normalize_with copy then - let () = Printf.printf "After normalizing we have m:\n%s" (show copy) in - Some copy - else - None - let is_covered_by m1 m2 = (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) (*Both input matrices must be in rref form!*) @@ -354,10 +360,10 @@ module ArrayMatrix: AbstractMatrix = *) let map2 f m v = - let () = Printf.printf "Before map2 m:\n%s\n" (show m) in + let () = Printf.printf "Before map2 we have m:\n%s\n" (show m) in let m' = copy m in map2_with f m' v; - let () = Printf.printf "After map2 m:\n%s\n" (show m') in + let () = Printf.printf "After map2 we have m:\n%s\n" (show m') in m' let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index a4690a55e4..8aa2955427 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -150,7 +150,7 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = let cols = Array.to_list cols in (* TODO: Is it possible to use list for Apron dimchange? *) let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification) *) - let () = Printf.printf "Before del_cols cols_length=%i sorted_length=%i \nm:\n%s\n" (List.length cols) (List.length sorted_cols) (show m) in + let () = Printf.printf "Before del_cols cols_length=%i \nm:\n%s\n" (List.length cols) (show m) in if (List.length sorted_cols) = num_cols m then empty() else List.map (fun row -> V.remove_at_indices row sorted_cols) m @@ -241,7 +241,10 @@ module ListMatrix: AbstractMatrix = (* TODO: OPTIMIZE! *) let rref_vec m v = let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in - normalize @@ append_matrices m (init_with_vec v) + match normalize @@ append_matrices m (init_with_vec v) with + | Some res -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in + Some (remove_zero_rows res) + | None -> None (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 10a841beee..76646527ed 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -268,7 +268,7 @@ module SparseVector: AbstractVector = let rec list_str l = match l with | [] -> "]" - | x :: xs -> " " ^ (A.to_string x) ^ (list_str xs) + | x :: xs -> (A.to_string x) ^ " " ^ (list_str xs) in "["^list_str t^"\n" diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index cce52c6a7d..9e9633317d 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -6,6 +6,8 @@ open Goblint_lib open OUnit2 open SparseVector open ListMatrix +open ArrayVector +open ArrayMatrix module D = SharedFunctions.Mpqf module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) From 968c533d673d5b55a066102b29c882324c3d431b Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 7 Dec 2024 12:21:34 +0100 Subject: [PATCH 094/150] Bugfixes in ListMatrix normalize --- .../affineEquality/sparseImplementation/listMatrix.ml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 8aa2955427..3c67dfec02 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -193,18 +193,20 @@ module ListMatrix: AbstractMatrix = List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m in (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) + (* The last column represents the constant in the affeq *) let find_first_pivot m' row_idx col_idx = if col_idx >= col_count then None else + let max_piv_col_idx = num_cols m' - 2 in (* col at num_cols - 1 is the constant of the affeq *) (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) | Some (idx, value) -> (* let () = Printf.printf "We found first non-zero at index %i in row %i\n" idx i in *) - if idx < cur_col then (row_idx + i, idx, value) else (cur_row, cur_col, cur_val) - ) (num_rows m', num_cols m', A.zero) m' (* Initializing with max, so num_cols m indicates that pivot is not found *) + if idx < cur_col then (i, idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m', max_piv_col_idx + 1, A.zero) m' (* Initializing with max, so num_cols m indicates that pivot is not found *) in - if piv_col = (num_cols m') then None else Some (piv_row, piv_col + col_idx, piv_val) + if piv_col = (max_piv_col_idx + 1) then None else Some (row_idx + piv_row, col_idx + piv_col, piv_val) in let affeq_rows_are_valid m = (* Check if the semantics of an rref-affeq matrix are correct *) let col_count = num_cols m in @@ -227,7 +229,7 @@ module ListMatrix: AbstractMatrix = let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then let scale = V.nth row piv_col_idx in sub_scaled_row row piv_row scale else row) normalized_m in - let m' = dec_mat_2D m (row_idx + 1) (piv_col_idx + 1) in + let m' = dec_mat_2D subtracted_m (row_idx + 1) (piv_col_idx + 1) in main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in From fe6b2a6eeb1b415dcfcfd92047333ddd11135cda Mon Sep 17 00:00:00 2001 From: Havercake Date: Mon, 9 Dec 2024 11:39:39 +0100 Subject: [PATCH 095/150] Added a solution vector to the normalize unit test --- .../sparseMatrixImplementationTest.ml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 9e9633317d..17250cd074 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -13,8 +13,12 @@ module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) let normalize _ = - (* Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ)*) - let width = 4 in + (* + Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ) + but extended by a solution vector b = [0;0;25]^T. + *) + + let width = 5 in let int x = D.of_int x in let any_matrix = Matrix.append_row @@ -25,7 +29,7 @@ let normalize _ = ) (Vector.of_sparse_list width [ (0, int 2); (1, int 3); (2, int 4) ]) ) - (Vector.of_sparse_list width [ (0, int 1); (1, int 1); (2, int 2); (3, int 4) ] + (Vector.of_sparse_list width [ (0, int 1); (1, int 1); (2, int 2); (3, int 4); (4, int 25)] ) in let normalized_matrix = @@ -33,11 +37,11 @@ let normalize _ = (Matrix.append_row (Matrix.append_row (Matrix.empty ()) - (Vector.of_sparse_list width [ (0,int 1); (2,int 2) ]) + (Vector.of_sparse_list width [ (0,int 1); (2,int 2); (4, int 3)]) ) - (Vector.of_sparse_list width [ (1,int 1) ]) + (Vector.of_sparse_list width [ (1,int 1); (4, int (-2)) ]) ) - (Vector.of_sparse_list width [ (3,int 1) ] + (Vector.of_sparse_list width [ (3,int 1); (4, int 6)] ) in match Matrix.normalize any_matrix with From 18acca5cbeba2bf5d2920fde1bf8c848a8190c32 Mon Sep 17 00:00:00 2001 From: Havercake Date: Mon, 9 Dec 2024 16:36:16 +0100 Subject: [PATCH 096/150] Normalize test for a shuffeled matrix --- .../sparseMatrixImplementationTest.ml | 92 +++++++++++++------ 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 17250cd074..313f4d5231 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -12,43 +12,81 @@ module D = SharedFunctions.Mpqf module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) -let normalize _ = - (* - Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ) - but extended by a solution vector b = [0;0;25]^T. - *) +(** This function runs the equality assertion with the solution after normalizing the matrix. *) +let normalize_and_assert (matrix : Matrix.t) (solution : Matrix.t) = + let get_dimensions m = (Matrix.num_rows m, Matrix.num_cols m) in + let do_dimensions_match dim1 dim2 = + match (dim1, dim2) with (r1, c1), (r2, c2) -> r1 == r2 && c1 == c2 + in + let matrix_dim = get_dimensions matrix in + let solution_dim = get_dimensions solution in + if not (do_dimensions_match solution_dim matrix_dim) then + failwith + "The matrix to normalize and the solution have different dimensions!" + else + match Matrix.normalize matrix with + | None -> + assert_failure "The matrix is normalizable but was not normalized!" + | Some reduced_matrix -> assert_equal reduced_matrix solution +(** + Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ) + but extended by a solution vector b = [0;0;25]^T. +*) +let standard_normalize _ = let width = 5 in let int x = D.of_int x in let any_matrix = Matrix.append_row (Matrix.append_row - (Matrix.append_row - (Matrix.empty ()) - (Vector.of_sparse_list width [ (0, int 2); (2, int 4); (3, int (-1)) ]) - ) - (Vector.of_sparse_list width [ (0, int 2); (1, int 3); (2, int 4) ]) - ) - (Vector.of_sparse_list width [ (0, int 1); (1, int 1); (2, int 2); (3, int 4); (4, int 25)] - ) + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width + [ (0, int 2); (2, int 4); (3, int (-1)) ])) + (Vector.of_sparse_list width [ (0, int 2); (1, int 3); (2, int 4) ])) + (Vector.of_sparse_list width + [ (0, int 1); (1, int 1); (2, int 2); (3, int 4); (4, int 25) ]) in let normalized_matrix = Matrix.append_row (Matrix.append_row - (Matrix.append_row - (Matrix.empty ()) - (Vector.of_sparse_list width [ (0,int 1); (2,int 2); (4, int 3)]) - ) - (Vector.of_sparse_list width [ (1,int 1); (4, int (-2)) ]) - ) - (Vector.of_sparse_list width [ (3,int 1); (4, int 6)] - ) + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 1); (2, int 2); (4, int 3) ])) + (Vector.of_sparse_list width [ (1, int 1); (4, int (-2)) ])) + (Vector.of_sparse_list width [ (3, int 1); (4, int 6) ]) + in + normalize_and_assert any_matrix normalized_matrix + +let should_just_sort_normalize _ = + let width = 10 in + let int x = D.of_int x in + let chaotic_matrix = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (2, int 1) ])) + (Vector.of_sparse_list width [ (5, int 1) ])) + (Vector.of_sparse_list width [ (0, int 1); (3, int 1) ])) + (Vector.of_sparse_list width [ (1, int 1); (4, int (-3)) ]) + in + + let sorted_matrix = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 1); (3, int 1) ])) + (Vector.of_sparse_list width [ (1, int 1); (4, int (-3)) ])) + (Vector.of_sparse_list width [ (2, int 1) ])) + (Vector.of_sparse_list width [ (5, int 1) ]) in - match Matrix.normalize any_matrix with - | None -> assert_failure "The matrix is normalizable but was not normalized!" - | Some reduced_matrix -> assert_equal reduced_matrix normalized_matrix + normalize_and_assert chaotic_matrix sorted_matrix -let tests = "SparseMatrixImplementationTest" >::: [ "normalize" >:: normalize ] +let tests = + "SparseMatrixImplementationTest" + >::: [ + "standard" >:: standard_normalize; + "should_sort" >:: should_just_sort_normalize; + ] -let () = - run_test_tt_main tests +let () = run_test_tt_main tests From 43e042f9c932d8ac10fa1b13bedc01ee10738c20 Mon Sep 17 00:00:00 2001 From: Havercake Date: Mon, 9 Dec 2024 16:48:57 +0100 Subject: [PATCH 097/150] Normalize test for row elimination --- .../sparseMatrixImplementationTest.ml | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 313f4d5231..85e813efa6 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -12,6 +12,8 @@ module D = SharedFunctions.Mpqf module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) +let int x = D.of_int x + (** This function runs the equality assertion with the solution after normalizing the matrix. *) let normalize_and_assert (matrix : Matrix.t) (solution : Matrix.t) = let get_dimensions m = (Matrix.num_rows m, Matrix.num_cols m) in @@ -26,16 +28,15 @@ let normalize_and_assert (matrix : Matrix.t) (solution : Matrix.t) = else match Matrix.normalize matrix with | None -> - assert_failure "The matrix is normalizable but was not normalized!" + assert_failure "The matrix is normalizable but was not normalized!" | Some reduced_matrix -> assert_equal reduced_matrix solution (** - Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ) - but extended by a solution vector b = [0;0;25]^T. + Example from a [Youtube video](https://www.youtube.com/watch?v=TYs4h-AoqyQ) + but extended by a solution vector b = [0;0;25]^T. *) let standard_normalize _ = let width = 5 in - let int x = D.of_int x in let any_matrix = Matrix.append_row (Matrix.append_row @@ -57,8 +58,7 @@ let standard_normalize _ = normalize_and_assert any_matrix normalized_matrix let should_just_sort_normalize _ = - let width = 10 in - let int x = D.of_int x in + let width = 7 in let chaotic_matrix = Matrix.append_row (Matrix.append_row @@ -82,11 +82,33 @@ let should_just_sort_normalize _ = in normalize_and_assert chaotic_matrix sorted_matrix +let should_eliminate_rows _ = + let width = 3 in + let linearly_dependent_rows = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 1); (2, int 4) ])) + (Vector.of_sparse_list width [ (0, int 2); (2, int 8) ])) + (Vector.of_sparse_list width [ (0, int 3); (2, int 12) ]) + in + + let minimized_matrix = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 1); (2, int 4) ])) + (Vector.zero_vec width)) + (Vector.zero_vec width) + in + normalize_and_assert linearly_dependent_rows minimized_matrix + let tests = "SparseMatrixImplementationTest" >::: [ - "standard" >:: standard_normalize; - "should_sort" >:: should_just_sort_normalize; - ] + "standard" >:: standard_normalize; + "should_sort" >:: should_just_sort_normalize; + "should_eliminate" >:: should_eliminate_rows; + ] let () = run_test_tt_main tests From ef07123f1137e41a30385f7c0ac447f9f036b317 Mon Sep 17 00:00:00 2001 From: Havercake Date: Mon, 9 Dec 2024 17:20:32 +0100 Subject: [PATCH 098/150] Normalize tests with different domains --- .../sparseMatrixImplementationTest.ml | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 85e813efa6..14ccdf8c04 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -12,8 +12,14 @@ module D = SharedFunctions.Mpqf module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) +(** Shorthands for common functions. *) let int x = D.of_int x +let frac numerator denominator = D.of_frac numerator denominator + +(** Shorthands for common functions. *) +let float x = D.of_float x + (** This function runs the equality assertion with the solution after normalizing the matrix. *) let normalize_and_assert (matrix : Matrix.t) (solution : Matrix.t) = let get_dimensions m = (Matrix.num_rows m, Matrix.num_cols m) in @@ -57,7 +63,10 @@ let standard_normalize _ = in normalize_and_assert any_matrix normalized_matrix -let should_just_sort_normalize _ = +(** + Normalization just sorts the matrix, as the rows are already reduced. +*) +let does_just_sort _ = let width = 7 in let chaotic_matrix = Matrix.append_row @@ -82,7 +91,10 @@ let should_just_sort_normalize _ = in normalize_and_assert chaotic_matrix sorted_matrix -let should_eliminate_rows _ = +(** + Normalization should eliminate both linearly dependent rows. +*) +let does_eliminate_dependent_rows _ = let width = 3 in let linearly_dependent_rows = Matrix.append_row @@ -103,12 +115,51 @@ let should_eliminate_rows _ = in normalize_and_assert linearly_dependent_rows minimized_matrix +let does_handle_floats _ = + let width = 3 in + let any_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, float 5.); (2, float (1. /. 2.)) ])) + (Vector.of_sparse_list width + [ (0, float (1. /. 4.)); (2, float 23.); (2, float 2.) ]) + in + + let normalized_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, float 1.); (2, float (1. /. 10.)) ])) + (Vector.of_sparse_list width [ (2, float 1.); (2, float (79. /. 920.)) ]) + in + normalize_and_assert any_matrix normalized_matrix + +let does_handle_fractions _ = + let width = 3 in + let any_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, frac 5 1); (2, frac 1 2) ])) + (Vector.of_sparse_list width + [ (0, frac 1 4); (2, frac 23 1); (2, frac 2 1) ]) + in + + let normalized_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, frac 1 1); (2, frac 1 10) ])) + (Vector.of_sparse_list width [ (2, frac 1 1); (2, frac 79 920) ]) + in + normalize_and_assert any_matrix normalized_matrix + let tests = "SparseMatrixImplementationTest" >::: [ - "standard" >:: standard_normalize; - "should_sort" >:: should_just_sort_normalize; - "should_eliminate" >:: should_eliminate_rows; + "can solve a standard normalization" >:: standard_normalize; + "does sort already reduzed" >:: does_just_sort; + "does eliminate dependent rows" >:: does_eliminate_dependent_rows; + (* Looks like deadlocking or inifinite execution when the bottom tests are activated. *) + (*"can handle float domain" >:: does_handle_floats;*) + (*"can handle fraction domain" >:: does_handle_fractions;*) ] let () = run_test_tt_main tests From 8d1c5485abe208ce80af1bb98fd196ed495a5277 Mon Sep 17 00:00:00 2001 From: Havercake Date: Mon, 9 Dec 2024 17:33:53 +0100 Subject: [PATCH 099/150] Normalize tests for idempotency and negation --- .../sparseMatrixImplementationTest.ml | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 14ccdf8c04..9f8a63b83c 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -151,15 +151,49 @@ let does_handle_fractions _ = in normalize_and_assert any_matrix normalized_matrix +let does_negate_negative _ = + let width = 5 in + let negative_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int (-1)); (3, int (-3)) ])) + (Vector.of_sparse_list width [ (2, int (-1)); (4, int (-5)) ]) + in + + let negated_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 1); (3, int 3) ])) + (Vector.of_sparse_list width [ (2, int 1); (4, int 5) ]) + in + normalize_and_assert negative_matrix negated_matrix + +(** + Normalization is idempotent. +*) +let does_not_change_normalized_matrix _ = + let width = 5 in + let already_normalized = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 1); (3, int 1) ])) + (Vector.of_sparse_list width [ (1, int 1); (3, int 3) ])) + (Vector.of_sparse_list width [ (2, int 1); (3, int 1) ]) + in + normalize_and_assert already_normalized already_normalized + let tests = "SparseMatrixImplementationTest" >::: [ "can solve a standard normalization" >:: standard_normalize; "does sort already reduzed" >:: does_just_sort; "does eliminate dependent rows" >:: does_eliminate_dependent_rows; - (* Looks like deadlocking or inifinite execution when the bottom tests are activated. *) + (* Looks like the tests are deadlock or inifinite execution when those are activated. *) (*"can handle float domain" >:: does_handle_floats;*) (*"can handle fraction domain" >:: does_handle_fractions;*) + "does negate negative matrix" >:: does_negate_negative; + "does not change already normalized matrix" >:: does_not_change_normalized_matrix; ] let () = run_test_tt_main tests From d71d7bde130bff32b930e5407504f5be27817b1b Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 10 Dec 2024 10:05:05 +0100 Subject: [PATCH 100/150] bugfix in add_empty_columns, behavious still differs from arraymatrix --- .../arrayImplementation/arrayMatrix.ml | 6 ++--- .../arrayImplementation/arrayVector.ml | 2 +- .../sparseImplementation/listMatrix.ml | 23 +++++++++++-------- .../sparseImplementation/sparseVector.ml | 4 ++-- src/cdomains/affineEquality/vector.ml | 2 +- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index b9bd503ddc..eec27c0c48 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -39,7 +39,7 @@ module ArrayMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m let add_empty_columns m cols = - let () = Printf.printf "Before add_empty_columns m:\n%s\n" (show m) in + let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> s ^ (Int.to_string x) ^ ",") cols "") in let nnc = Array.length cols in if is_empty m || nnc = 0 then m else let nr, nc = num_rows m, num_cols m in @@ -82,7 +82,7 @@ module ArrayMatrix: AbstractMatrix = Array.blit m (n + 1) new_matrix n (num_rows new_matrix - n)); new_matrix let get_col m n = - let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)))) in + (*let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)))) in*) V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)) let get_col m n = Timing.wrap "get_col" (get_col m) n @@ -286,7 +286,7 @@ module ArrayMatrix: AbstractMatrix = match rref_vec_with m' v' with | Some res -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in Some (remove_zero_rows res) - | None -> None + | None -> let () = Printf.printf "After rref_vec there is no normalization\n" in None let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 3bf873df78..622a12e328 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -36,7 +36,7 @@ module ArrayVector: AbstractVector = let remove_at_indices v idx = failwith "TODO" - let insert_zero_at_indices v idx = failwith "TODO" + let insert_zero_at_indices v idx count = failwith "TODO" let set_nth_with v n new_val = if n >= Array.length v then failwith "n outside of Array range" else diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 3c67dfec02..ee200f1923 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -39,18 +39,21 @@ module ListMatrix: AbstractMatrix = Timing.wrap "copy" (copy) m let add_empty_columns m cols = - let () = Printf.printf "Before add_empty_columns m:\n%s\n" (show m) in + let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> s ^ (Int.to_string x) ^ ",") cols "") in let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in - let rec count_sorted_occ acc cols last count = + let rec count_sorted_occ acc cols last count = match cols with - | [] -> acc - | (x :: xs) when x = last -> count_sorted_occ acc xs x (count + 1) - | (x :: xs) -> count_sorted_occ ((last, count) :: acc) xs x 1 + | [] -> if count > 0 then (last, count) :: acc else acc + | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) + | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in + count_sorted_occ acc xs x 1 in - let occ_cols = count_sorted_occ [] sorted_cols (-1) 0 in - let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols) m)) in - List.map (fun row -> V.insert_zero_at_indices row occ_cols) m + let occ_cols = List.rev @@ count_sorted_occ [] sorted_cols 0 0 in + (*let () = Printf.printf "sorted cols is: %s\n" (List.fold_right (fun x s -> (Int.to_string x) ^ s) sorted_cols "") in + let () = Printf.printf "sorted_occ is: %s\n" (List.fold_right (fun (i, count) s -> "(" ^ (Int.to_string i) ^ "," ^ (Int.to_string count) ^ ")" ^ s) occ_cols "") in*) + let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m)) in + List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols @@ -68,7 +71,7 @@ module ListMatrix: AbstractMatrix = List.remove_at n m let get_col m n = - let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_list @@ List.map (fun row -> V.nth row n) m)) in + (*let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_list @@ List.map (fun row -> V.nth row n) m)) in*) V.of_list @@ List.map (fun row -> V.nth row n) m (* builds full col including zeros, maybe use sparselist instead? *) let get_col m n = @@ -246,7 +249,7 @@ module ListMatrix: AbstractMatrix = match normalize @@ append_matrices m (init_with_vec v) with | Some res -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in Some (remove_zero_rows res) - | None -> None + | None -> let () = Printf.printf "After rref_vec there is no normalization\n " in None (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 76646527ed..51753475e6 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -80,7 +80,7 @@ module SparseVector: AbstractVector = in {entries = remove_indices_helper v.entries idx 0; len = v.len - List.length idx} - let insert_zero_at_indices v idx = + let insert_zero_at_indices v idx count = let rec add_indices_helper vec idx added_count = match vec, idx with | [], [] -> [] @@ -90,7 +90,7 @@ module SparseVector: AbstractVector = | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> (col_idx + added_count + count, value) :: add_indices_helper xs ys (added_count + count) | ((col_idx, value) :: xs), ((i, count) :: ys) -> (col_idx + added_count, value) :: add_indices_helper xs idx added_count in - {entries = add_indices_helper v.entries idx 0; len = v.len + List.length idx} + {entries = add_indices_helper v.entries idx 0; len = v.len + count} let set_nth v n num = (* TODO: Optimize! *) if n >= v.len then failwith "Out of bounds" diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 15215b5512..f52f6eadbb 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -12,7 +12,7 @@ sig val remove_at_indices: t -> int list -> t - val insert_zero_at_indices: t -> (int * int) list -> t + val insert_zero_at_indices: t -> (int * int) list -> int -> t val set_nth: t -> int -> num -> t From db97f30245e47d06096e2d3d2156cfeca08f4dda Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 10 Dec 2024 12:51:48 +0100 Subject: [PATCH 101/150] add_emtpy_cols uses arraymatrix logic here + bugfix in normalize - one test still missing --- .../apron/affineEqualityAnalysis.apron.ml | 2 +- .../arrayImplementation/arrayMatrix.ml | 8 +-- .../sparseImplementation/listMatrix.ml | 54 ++++++++++++++----- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index e262b2653b..80d3b32874 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -14,7 +14,7 @@ include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( - let module AD = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in + let module AD = AffineEqualityDomain.D2 (SparseVector) (ListMatrix) in let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index eec27c0c48..7d640a7bdc 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -39,7 +39,7 @@ module ArrayMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m let add_empty_columns m cols = - let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> s ^ (Int.to_string x) ^ ",") cols "") in + let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in let nnc = Array.length cols in if is_empty m || nnc = 0 then m else let nr, nc = num_rows m, num_cols m in @@ -284,7 +284,7 @@ module ArrayMatrix: AbstractMatrix = let m' = copy m in let v' = V.copy v in match rref_vec_with m' v' with - | Some res -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in + | Some res -> let () = Printf.printf "After rref_vec, before removing zero rows, we have m:\n%s\n" (show res) in Some (remove_zero_rows res) | None -> let () = Printf.printf "After rref_vec there is no normalization\n" in None @@ -312,7 +312,9 @@ module ArrayMatrix: AbstractMatrix = let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in let m1' = copy m1 in let m2' = copy m2 in - rref_matrix_with m1' m2' + match rref_matrix_with m1' m2' with + | Some m -> let () = Printf.printf "After rref_matrix m:\n %s\n" (show m) in Some m + | None -> let () = Printf.printf "No normalization for rref_matrix found" in None let is_covered_by m1 m2 = (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index ee200f1923..6264dce9d6 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -38,22 +38,50 @@ module ListMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m - let add_empty_columns m cols = - let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> s ^ (Int.to_string x) ^ ",") cols "") in + (* This uses the logic from ArrayMatrix to add empty_columns*) + let add_empty_columns (m : t) (cols : int array) : t = + let nr = num_rows m in + let nc = if nr = 0 then 0 else num_cols m in + let nnc = Array.length cols in + + (* If no rows or no new columns, just return m as is *) + if nr = 0 || nnc = 0 then m + else + (* Create a new list of rows with additional columns. *) + let new_rows = + List.map (fun row -> + let old_row_arr = V.to_array row in + let new_row_arr = Array.make (nc + nnc) A.zero in + + let offset = ref 0 in + for j = 0 to nc - 1 do + (* Check if we need to insert zero columns before placing old_row_arr.(j) *) + while !offset < nnc && !offset + j = cols.(!offset) do + incr offset + done; + new_row_arr.(j + !offset) <- old_row_arr.(j); + done; + + V.of_array new_row_arr + ) m + in + + new_rows + (*let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in let rec count_sorted_occ acc cols last count = - match cols with - | [] -> if count > 0 then (last, count) :: acc else acc - | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) - | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in - count_sorted_occ acc xs x 1 + match cols with + | [] -> if count > 0 then (last, count) :: acc else acc + | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) + | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in + count_sorted_occ acc xs x 1 in let occ_cols = List.rev @@ count_sorted_occ [] sorted_cols 0 0 in (*let () = Printf.printf "sorted cols is: %s\n" (List.fold_right (fun x s -> (Int.to_string x) ^ s) sorted_cols "") in - let () = Printf.printf "sorted_occ is: %s\n" (List.fold_right (fun (i, count) s -> "(" ^ (Int.to_string i) ^ "," ^ (Int.to_string count) ^ ")" ^ s) occ_cols "") in*) + let () = Printf.printf "sorted_occ is: %s\n" (List.fold_right (fun (i, count) s -> "(" ^ (Int.to_string i) ^ "," ^ (Int.to_string count) ^ ")" ^ s) occ_cols "") in*) let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m)) in - List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m + List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m*) let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols @@ -220,7 +248,7 @@ module ListMatrix: AbstractMatrix = in List.for_all row_is_valid m in let rec main_loop m m' row_idx col_idx = - if col_idx = (col_count - 2) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) + if col_idx >= (col_count - 1) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else match find_first_pivot m' row_idx col_idx with | None -> m (* No pivot found means already normalized*) @@ -247,7 +275,7 @@ module ListMatrix: AbstractMatrix = let rref_vec m v = let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in match normalize @@ append_matrices m (init_with_vec v) with - | Some res -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in + | Some res -> let () = Printf.printf "After rref_vec, before removing zero rows, we have m:\n%s\n" (show res) in Some (remove_zero_rows res) | None -> let () = Printf.printf "After rref_vec there is no normalization\n " in None @@ -256,7 +284,9 @@ module ListMatrix: AbstractMatrix = (*TODO: OPTIMIZE!*) let rref_matrix m1 m2 = let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in - normalize @@ append_matrices m1 m2 + match normalize @@ append_matrices m1 m2 with + | Some m -> let () = Printf.printf "After rref_matrix m, before removing zero rows:\n %s\n" (show m) in Some (remove_zero_rows m) + | None -> let () = Printf.printf "No normalization for rref_matrix found" in None let delete_row_with_pivots row pivots m2 = From 315dac61fa1e11bb934194d74698849f44b9a834 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 10 Dec 2024 13:54:07 +0100 Subject: [PATCH 102/150] appending and normalizing in is_covered_by - all tests pass --- .../arrayImplementation/arrayMatrix.ml | 6 +-- .../sparseImplementation/listMatrix.ml | 39 ++++++++++--------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 7d640a7bdc..4e2d0f6e5e 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -57,14 +57,12 @@ module ArrayMatrix: AbstractMatrix = let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - let () = Printf.printf "Before append_row m:\n%s\n" (show m) in let size = num_rows m in let new_matrix = Array.make_matrix (size + 1) (num_cols m) A.zero in for i = 0 to size - 1 do new_matrix.(i) <- m.(i) done; new_matrix.(size) <- V.to_array row; - let () = Printf.printf "After append_row m:\n%s\n" (show new_matrix) in new_matrix let get_row m n = @@ -319,12 +317,12 @@ module ArrayMatrix: AbstractMatrix = let is_covered_by m1 m2 = (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) (*Both input matrices must be in rref form!*) + let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in if num_rows m1 > num_rows m2 then false else - let m1' = copy m1 in - let m2' = copy m2 in let p2 = lazy (get_pivot_positions m2) in try ( for i = 0 to num_rows m1 - 1 do + (* check if there are rows in m1 and m2 that aren't equal *) if Array.exists2 (<>:) m1.(i) m2.(i) then let m1_i = Array.copy m1.(i) in for j = 0 to Array.length m1_i - 2 do diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 6264dce9d6..5b12192a4c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -87,8 +87,6 @@ module ListMatrix: AbstractMatrix = Timing.wrap "add_empty_cols" (add_empty_columns m) cols let append_row m row = - let () = Printf.printf "Before append_row m:\n%s\n" (show m) in - let () = Printf.printf "After append_row m:\n%s\n" (show ( m @ [row])) in m @ [row] let get_row m n = @@ -305,23 +303,28 @@ module ListMatrix: AbstractMatrix = is_linearly_independent_rref new_v xs let is_covered_by m1 m2 = + Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2); + match normalize @@ append_matrices m2 m1 with + | None -> false + | Some m -> let m2' = remove_zero_rows m in List.for_all2 (fun x y -> V.equal x y) m2 m2' + (*let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in if num_rows m1 > num_rows m2 then false else - let rec is_covered_by_helper m1 m2 = - match m1 with - | [] -> true - | v1::vs1 -> - let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in - match first_non_zero with - | None -> true (* vs1 must also be zero-vectors because of rref *) - | Some (idx, _) -> - let m' = List.drop_while (fun v2 -> - match V.findi_val_opt ((<>:) A.zero) v2 with - | None -> true (* In this case, m2 only has zero rows after that *) - | Some (idx', _) -> idx' < idx - ) m2 in (* Only consider the part of m2 where the pivot is at a position useful for deleting first_non_zero of v1*) - let linearly_indep = is_linearly_independent_rref v1 m' in - if linearly_indep then false else is_covered_by_helper vs1 m' - in is_covered_by_helper m1 m2 + let rec is_covered_by_helper m1 m2 = + match m1 with + | [] -> true + | v1::vs1 -> + let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in + match first_non_zero with + | None -> true (* vs1 must also be zero-vectors because of rref *) + | Some (idx, _) -> + let m' = List.drop_while (fun v2 -> + match V.findi_val_opt ((<>:) A.zero) v2 with + | None -> true (* In this case, m2 only has zero rows after that *) + | Some (idx', _) -> idx' < idx + ) m2 in (* Only consider the part of m2 where the pivot is at a position useful for deleting first_non_zero of v1*) + let linearly_indep = is_linearly_independent_rref v1 m' in + if linearly_indep then false else is_covered_by_helper vs1 m' + in is_covered_by_helper m1 m2*) let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 From 58e34c0128d4bb08e2306ab1952c6caa0f46bb21 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 10 Dec 2024 15:45:56 +0100 Subject: [PATCH 103/150] Normalize tests for empty matrix, two column matrix and a normalized matrix with rationals --- .../sparseMatrixImplementationTest.ml | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 9f8a63b83c..edd4d51261 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -183,6 +183,54 @@ let does_not_change_normalized_matrix _ = in normalize_and_assert already_normalized already_normalized +(** + Normalization works on an empty matrix. +*) +let normalize_empty _ = + let width = 3 in + let empty_matrix = + Matrix.append_row + (Matrix.append_row + (Matrix.append_row (Matrix.empty ()) (Vector.zero_vec width)) + (Vector.zero_vec width)) + (Vector.zero_vec width) + in + normalize_and_assert empty_matrix empty_matrix + +let normalize_two_columns _ = + let width = 2 in + let two_col_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 3); (1, int 2) ])) + (Vector.of_sparse_list width [ (0, int 9); (1, int 6) ]) + in + let normalized_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width + [ (0, int 1); (1, D.div (int 2) (int 3)) ])) + (Vector.of_sparse_list width []) + in + normalize_and_assert two_col_matrix normalized_matrix + +let int_domain_to_rational _ = + let width = 3 in + let int_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width [ (0, int 3); (2, int 1) ])) + (Vector.of_sparse_list width [ (0, int 2); (1, int 1); (2, int 1) ]) + in + let normalized_matrix = + Matrix.append_row + (Matrix.append_row (Matrix.empty ()) + (Vector.of_sparse_list width + [ (0, int 1); (2, D.div (int 1) (int 3)) ])) + (Vector.of_sparse_list width [ (1, int 1); (2, D.div (int 1) (int 3)) ]) + in + normalize_and_assert int_matrix normalized_matrix + let tests = "SparseMatrixImplementationTest" >::: [ @@ -193,7 +241,11 @@ let tests = (*"can handle float domain" >:: does_handle_floats;*) (*"can handle fraction domain" >:: does_handle_fractions;*) "does negate negative matrix" >:: does_negate_negative; - "does not change already normalized matrix" >:: does_not_change_normalized_matrix; + "does not change already normalized matrix" + >:: does_not_change_normalized_matrix; + "does not change an empty matrix" >:: normalize_empty; + "can correctly normalize a two column matrix" >:: normalize_two_columns; + "can handle a rational solution" >:: int_domain_to_rational; ] let () = run_test_tt_main tests From 9f7cec947dee59627c44b1ed1dc5d2658f9f66a6 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 10 Dec 2024 15:48:07 +0100 Subject: [PATCH 104/150] Added a newline --- .../sparseImplementation/sparseMatrixImplementationTest.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index edd4d51261..7d3ffb48d8 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -241,8 +241,7 @@ let tests = (*"can handle float domain" >:: does_handle_floats;*) (*"can handle fraction domain" >:: does_handle_fractions;*) "does negate negative matrix" >:: does_negate_negative; - "does not change already normalized matrix" - >:: does_not_change_normalized_matrix; + "does not change already normalized matrix" >:: does_not_change_normalized_matrix; "does not change an empty matrix" >:: normalize_empty; "can correctly normalize a two column matrix" >:: normalize_two_columns; "can handle a rational solution" >:: int_domain_to_rational; From 6673aae4635b3e63765b6a9eabfc5161c174075f Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 10 Dec 2024 15:50:23 +0100 Subject: [PATCH 105/150] Changed the assert failure text for when the normalization fails --- .../sparseImplementation/sparseMatrixImplementationTest.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 7d3ffb48d8..08318ec9bc 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -33,8 +33,7 @@ let normalize_and_assert (matrix : Matrix.t) (solution : Matrix.t) = "The matrix to normalize and the solution have different dimensions!" else match Matrix.normalize matrix with - | None -> - assert_failure "The matrix is normalizable but was not normalized!" + | None -> assert_failure "The normalization returned None." | Some reduced_matrix -> assert_equal reduced_matrix solution (** From fe984fb0b857253342a8564cd4dae0cc1588950c Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 10 Dec 2024 15:53:12 +0100 Subject: [PATCH 106/150] Add some is_covered_by tests --- .../sparseMatrixImplementationTest.ml | 90 ++++++++++++++++--- 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 9f8a63b83c..ef4cbf1236 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -20,6 +20,12 @@ let frac numerator denominator = D.of_frac numerator denominator (** Shorthands for common functions. *) let float x = D.of_float x +let make_matrix_of_2d_list l = + List.fold_left + (fun acc row -> Matrix.append_row acc (Vector.of_list row)) + (Matrix.empty ()) + l + (** This function runs the equality assertion with the solution after normalizing the matrix. *) let normalize_and_assert (matrix : Matrix.t) (solution : Matrix.t) = let get_dimensions m = (Matrix.num_rows m, Matrix.num_cols m) in @@ -183,17 +189,77 @@ let does_not_change_normalized_matrix _ = in normalize_and_assert already_normalized already_normalized -let tests = - "SparseMatrixImplementationTest" - >::: [ - "can solve a standard normalization" >:: standard_normalize; - "does sort already reduzed" >:: does_just_sort; - "does eliminate dependent rows" >:: does_eliminate_dependent_rows; - (* Looks like the tests are deadlock or inifinite execution when those are activated. *) - (*"can handle float domain" >:: does_handle_floats;*) - (*"can handle fraction domain" >:: does_handle_fractions;*) - "does negate negative matrix" >:: does_negate_negative; - "does not change already normalized matrix" >:: does_not_change_normalized_matrix; - ] +let is_covered_by_simple _ = + let m1 = Matrix.init_with_vec (Vector.of_list [int 1; int 1; int 2; int 10]) in + let m2 = Matrix.append_row + (Matrix.append_row + (Matrix.empty ()) + (Vector.of_list [int 1; int 1; int 0; int 6])) + (Vector.of_list [int 0; int 0; int 1; int 2]) in + let result = Matrix.is_covered_by m1 m2 in + assert_bool "Matrix m1 is covered by m2, but was false" result + +let is_covered_by_vector_first_row _ = + let m1 = Matrix.init_with_vec (Vector.of_list [int 1; int 2; int 0; int 7]) in + let m2 = Matrix.append_row + (Matrix.append_row + (Matrix.empty ()) + (Vector.of_list [int 1; int 2; int 0; int 7])) + (Vector.of_list [int 0; int 0; int 1; int 2]) in + let result = Matrix.is_covered_by m1 m2 in + assert_bool "Matrix m1 is covered by m2, but was false" result + +let is_zero_vec_covered _ = + let m1 = Matrix.init_with_vec (Vector.zero_vec 4) in + let m2 = Matrix.append_row + (Matrix.append_row + (Matrix.empty ()) + (Vector.of_list [int 1; int 2; int 0; int 7])) + (Vector.of_list [int 0; int 0; int 1; int 2]) in + let result = Matrix.is_covered_by m1 m2 in + assert_bool "Matrix m1 is covered by m2, but was false" result + +let is_not_covered _ = + let m1 = Matrix.init_with_vec (Vector.of_list [int 1; int 1; int 2; int 10]) in + let m2 = Matrix.append_row + (Matrix.append_row + (Matrix.empty ()) + (Vector.of_list [int 1; int 1; int 0; int 6])) + (Vector.of_list [int 0; int 0; int 1; int 3]) in + let result = Matrix.is_covered_by m2 m1 in + assert_bool "Matrix m1 is not covered by m2, but was true" (not result) + +let is_covered_big _ = + let m1 = make_matrix_of_2d_list @@ + [[int 1; int 0; int 0; int 0; int 0; int (-1); int 0]; + [int 0; int 1; int 0; int 0; int 0; int (-2); int 0]; + [int 0; int 0; int 1; (frac (-1) 3); frac 1 3; int 0; frac 1 3]] in + + let m2 = make_matrix_of_2d_list @@ + [[int 1; int 0; int 0; int 0; int 0; int 0; int 0]; + [int 0; int 1; int 0; int 0; int 0; int 0; int 0]; + [int 0; int 0; int 1; frac (-1) 3; frac 1 3; int 0; frac 1 3]; + [int 0; int 0; int 0; int 0; int 0; int 1; int 0]] in + + let result = Matrix.is_covered_by m1 m2 in + assert_bool "Matrix m1 is covered by m2, but was false" (result) + + let tests = + "SparseMatrixImplementationTest" + >::: [ + "can solve a standard normalization" >:: standard_normalize; + "does sort already reduzed" >:: does_just_sort; + "does eliminate dependent rows" >:: does_eliminate_dependent_rows; + (* Looks like the tests are deadlock or inifinite execution when those are activated. *) + (*"can handle float domain" >:: does_handle_floats;*) + (*"can handle fraction domain" >:: does_handle_fractions;*) + "does negate negative matrix" >:: does_negate_negative; + "does not change already normalized matrix" >:: does_not_change_normalized_matrix; + "m1 is covered by m2" >:: is_covered_by_simple; + "m1 is covered by m2 with vector in first row" >:: is_covered_by_vector_first_row; + "zero vector is covered by m2" >:: is_zero_vec_covered; + "m1 is not covered by m2" >:: is_not_covered; + "m1 is covered by m2 with big matrix" >:: is_covered_big; + ] let () = run_test_tt_main tests From f44f2eb861fbebab81862b300d3f60165b68dade Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 10 Dec 2024 15:53:36 +0100 Subject: [PATCH 107/150] Formatting --- .../sparseMatrixImplementationTest.ml | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index ef4cbf1236..c3c94c8d08 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -241,25 +241,25 @@ let is_covered_big _ = [int 0; int 0; int 1; frac (-1) 3; frac 1 3; int 0; frac 1 3]; [int 0; int 0; int 0; int 0; int 0; int 1; int 0]] in - let result = Matrix.is_covered_by m1 m2 in - assert_bool "Matrix m1 is covered by m2, but was false" (result) + let result = Matrix.is_covered_by m1 m2 in + assert_bool "Matrix m1 is covered by m2, but was false" (result) - let tests = - "SparseMatrixImplementationTest" - >::: [ - "can solve a standard normalization" >:: standard_normalize; - "does sort already reduzed" >:: does_just_sort; - "does eliminate dependent rows" >:: does_eliminate_dependent_rows; - (* Looks like the tests are deadlock or inifinite execution when those are activated. *) - (*"can handle float domain" >:: does_handle_floats;*) - (*"can handle fraction domain" >:: does_handle_fractions;*) - "does negate negative matrix" >:: does_negate_negative; - "does not change already normalized matrix" >:: does_not_change_normalized_matrix; - "m1 is covered by m2" >:: is_covered_by_simple; - "m1 is covered by m2 with vector in first row" >:: is_covered_by_vector_first_row; - "zero vector is covered by m2" >:: is_zero_vec_covered; - "m1 is not covered by m2" >:: is_not_covered; - "m1 is covered by m2 with big matrix" >:: is_covered_big; - ] +let tests = + "SparseMatrixImplementationTest" + >::: [ + "can solve a standard normalization" >:: standard_normalize; + "does sort already reduzed" >:: does_just_sort; + "does eliminate dependent rows" >:: does_eliminate_dependent_rows; + (* Looks like the tests are deadlock or inifinite execution when those are activated. *) + (*"can handle float domain" >:: does_handle_floats;*) + (*"can handle fraction domain" >:: does_handle_fractions;*) + "does negate negative matrix" >:: does_negate_negative; + "does not change already normalized matrix" >:: does_not_change_normalized_matrix; + "m1 is covered by m2" >:: is_covered_by_simple; + "m1 is covered by m2 with vector in first row" >:: is_covered_by_vector_first_row; + "zero vector is covered by m2" >:: is_zero_vec_covered; + "m1 is not covered by m2" >:: is_not_covered; + "m1 is covered by m2 with big matrix" >:: is_covered_big; + ] let () = run_test_tt_main tests From 79f890a9ac0488921c69dbe4eb35af2433bfa59d Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 10 Dec 2024 15:53:51 +0100 Subject: [PATCH 108/150] Added some comments on the test setup --- tests/unit/mainTest.ml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/mainTest.ml b/tests/unit/mainTest.ml index 4fd65f6736..b8be9ef8f0 100644 --- a/tests/unit/mainTest.ml +++ b/tests/unit/mainTest.ml @@ -14,10 +14,12 @@ let all_tests = (* etc *) "domaintest" >::: QCheck_ounit.to_ounit2_test_list Maindomaintest.all_testsuite; IntOpsTest.tests; + (* SparseMatrixImplementationTest.tests; *) (* Uncomment this to add the sparse matrix tests to all tests *) ] let subset_tests = "" >::: [SparseMatrixImplementationTest.tests] let () = print_string "\027[0;1munit: \027[0;0;00m"; - run_test_tt_main subset_tests + run_test_tt_main subset_tests (* Remove this and uncomment the line below to run all tests.*) + (* run_test_tt_main all_tests *) From 4b34fda53588d5bb64ee8e5dbaf5b3782bb915e1 Mon Sep 17 00:00:00 2001 From: Havercake Date: Tue, 10 Dec 2024 15:54:03 +0100 Subject: [PATCH 109/150] Added some comments on the test setup --- tests/unit/mainTest.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/mainTest.ml b/tests/unit/mainTest.ml index b8be9ef8f0..9527679fe7 100644 --- a/tests/unit/mainTest.ml +++ b/tests/unit/mainTest.ml @@ -22,4 +22,4 @@ let subset_tests = "" >::: [SparseMatrixImplementationTest.tests] let () = print_string "\027[0;1munit: \027[0;0;00m"; run_test_tt_main subset_tests (* Remove this and uncomment the line below to run all tests.*) - (* run_test_tt_main all_tests *) +(* run_test_tt_main all_tests *) From 1241795438b11c651fda57a42a22d134ab3673a7 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 10 Dec 2024 17:31:21 +0100 Subject: [PATCH 110/150] bugfix in insert_zeros and use list funtionality again, uses apron standard for dim_add array now --- .../arrayImplementation/arrayMatrix.ml | 1 + .../sparseImplementation/listMatrix.ml | 37 ++----------------- .../sparseImplementation/sparseVector.ml | 2 +- .../apron/affineEqualityDomain.apron.ml | 3 +- 4 files changed, 7 insertions(+), 36 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index 4e2d0f6e5e..a3d1199be9 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -40,6 +40,7 @@ module ArrayMatrix: AbstractMatrix = let add_empty_columns m cols = let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in + Array.modifyi (+) cols; let nnc = Array.length cols in if is_empty m || nnc = 0 then m else let nr, nc = num_rows m, num_cols m in diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 5b12192a4c..9a0aef5f5e 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -38,36 +38,9 @@ module ListMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m - (* This uses the logic from ArrayMatrix to add empty_columns*) - let add_empty_columns (m : t) (cols : int array) : t = - let nr = num_rows m in - let nc = if nr = 0 then 0 else num_cols m in - let nnc = Array.length cols in - - (* If no rows or no new columns, just return m as is *) - if nr = 0 || nnc = 0 then m - else - (* Create a new list of rows with additional columns. *) - let new_rows = - List.map (fun row -> - let old_row_arr = V.to_array row in - let new_row_arr = Array.make (nc + nnc) A.zero in - - let offset = ref 0 in - for j = 0 to nc - 1 do - (* Check if we need to insert zero columns before placing old_row_arr.(j) *) - while !offset < nnc && !offset + j = cols.(!offset) do - incr offset - done; - new_row_arr.(j + !offset) <- old_row_arr.(j); - done; - - V.of_array new_row_arr - ) m - in - - new_rows - (*let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in + (* This only works if Array.modifyi has been removed from dim_add *) + let add_empty_columns (m : t) (cols : int array) : t = + let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in let rec count_sorted_occ acc cols last count = @@ -78,10 +51,8 @@ module ListMatrix: AbstractMatrix = count_sorted_occ acc xs x 1 in let occ_cols = List.rev @@ count_sorted_occ [] sorted_cols 0 0 in - (*let () = Printf.printf "sorted cols is: %s\n" (List.fold_right (fun x s -> (Int.to_string x) ^ s) sorted_cols "") in - let () = Printf.printf "sorted_occ is: %s\n" (List.fold_right (fun (i, count) s -> "(" ^ (Int.to_string i) ^ "," ^ (Int.to_string count) ^ ")" ^ s) occ_cols "") in*) let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m)) in - List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m*) + List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 51753475e6..9459db70a0 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -87,7 +87,7 @@ module SparseVector: AbstractVector = | [], (y :: ys) -> [] (* inserting at the end only means changing the dimension *) | ((col_idx, value) :: xs), [] -> (col_idx + added_count, value) :: add_indices_helper xs [] added_count | ((col_idx, value) :: xs), ((i, count) :: ys) when i = col_idx -> add_indices_helper vec ys (added_count + count) - | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> (col_idx + added_count + count, value) :: add_indices_helper xs ys (added_count + count) + | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> add_indices_helper vec ys (added_count + count) | ((col_idx, value) :: xs), ((i, count) :: ys) -> (col_idx + added_count, value) :: add_indices_helper xs idx added_count in {entries = add_indices_helper v.entries idx 0; len = v.len + count} diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 5a666f728b..8df5994c9c 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -26,8 +26,7 @@ module AffineEqualityMatrix (Vec: AbstractVector) (Mx: AbstractMatrix) = struct include Mx(Mpqf) (Vec) let dim_add (ch: Apron.Dim.change) m = - Array.modifyi (+) ch.dim; - add_empty_columns m ch.dim + add_empty_columns m ch.dim let dim_add ch m = Timing.wrap "dim add" (dim_add ch) m From 091b9fa10c6e7a53f66941c9b0569a620cf66fe3 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 10 Dec 2024 17:47:45 +0100 Subject: [PATCH 111/150] coveredddd --- .../sparseImplementation/listMatrix.ml | 42 ++++++++----------- .../sparseImplementation/sparseVector.ml | 1 + .../sparseMatrixImplementationTest.ml | 14 +++++++ 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 9a0aef5f5e..7b26b6ac00 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -257,28 +257,27 @@ module ListMatrix: AbstractMatrix = | Some m -> let () = Printf.printf "After rref_matrix m, before removing zero rows:\n %s\n" (show m) in Some (remove_zero_rows m) | None -> let () = Printf.printf "No normalization for rref_matrix found" in None - let delete_row_with_pivots row pivots m2 = failwith "TODO" - (* Assumes that the first row of the matrix is already the pivot row fitting to the vector. *) - let rec is_linearly_independent_rref v m = - match m with - | [] -> not @@ V.is_zero_vec v - | x::xs -> + let is_covered_by m1 m2 = + let rec is_linearly_independent_rref v m = let pivot_opt = V.findi_val_opt ((<>:) A.zero) v in match pivot_opt with | None -> false (* When we found no pivot, the vector is already A.zero. *) | Some (pivot_id, pivot) -> - let new_v = V.map2_f_preserves_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in - is_linearly_independent_rref new_v xs - - let is_covered_by m1 m2 = - Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2); - match normalize @@ append_matrices m2 m1 with - | None -> false - | Some m -> let m2' = remove_zero_rows m in List.for_all2 (fun x y -> V.equal x y) m2 m2' - (*let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in + let m' = List.drop_while (fun v2 -> + match V.findi_val_opt ((<>:) A.zero) v2 with + | None -> true (* In this case, m2 only has zero rows after that *) + | Some (idx', _) -> idx' < pivot_id + ) m in + match m' with + | [] -> not @@ V.is_zero_vec v + | x::xs -> + let new_v = V.map2_f_preserves_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in + is_linearly_independent_rref new_v m' + in + let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in if num_rows m1 > num_rows m2 then false else let rec is_covered_by_helper m1 m2 = match m1 with @@ -288,15 +287,10 @@ module ListMatrix: AbstractMatrix = match first_non_zero with | None -> true (* vs1 must also be zero-vectors because of rref *) | Some (idx, _) -> - let m' = List.drop_while (fun v2 -> - match V.findi_val_opt ((<>:) A.zero) v2 with - | None -> true (* In this case, m2 only has zero rows after that *) - | Some (idx', _) -> idx' < idx - ) m2 in (* Only consider the part of m2 where the pivot is at a position useful for deleting first_non_zero of v1*) - let linearly_indep = is_linearly_independent_rref v1 m' in - if linearly_indep then false else is_covered_by_helper vs1 m' - in is_covered_by_helper m1 m2*) - + let linearly_indep = is_linearly_independent_rref v1 m2 in + if linearly_indep then false else is_covered_by_helper vs1 m2 + in is_covered_by_helper m1 m2 + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 9459db70a0..2fc3e16e5f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -191,6 +191,7 @@ module SparseVector: AbstractVector = fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) (* Returns optional of (index * value) where f value evaluated to true *) + (*Can be optimized, dont check every zero cell*) let findi_val_opt f v = let rec find_zero_or_val vec last_col_idx = match vec, last_col_idx with diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 22bcae134e..69eae4211b 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -243,6 +243,18 @@ let is_covered_big _ = let result = Matrix.is_covered_by m1 m2 in assert_bool "Matrix m1 is covered by m2, but was false" (result) +let is_covered_big2 _ = + let m1 = make_matrix_of_2d_list @@ + [[int 1; int 0; int 0; int 0; int 0; int 1; int 0] + ] in + + let m2 = make_matrix_of_2d_list @@ + [[int 1; int 0; int 0; int 0; int 0; int 0; int 0]; + [int 0; int 1; int 0; int 0; int 0; int 0; int 0]; + [int 0; int 0; int 0; int 0; int 0; int 1; int 0]] in + + let result = Matrix.is_covered_by m1 m2 in + assert_bool "Matrix m1 is covered by m2, but was false" (result) (** Normalization works on an empty matrix. *) @@ -310,6 +322,8 @@ let tests = "does not change an empty matrix" >:: normalize_empty; "can correctly normalize a two column matrix" >:: normalize_two_columns; "can handle a rational solution" >:: int_domain_to_rational; + "m1 is covered by m2 with big matrix2" >:: is_covered_big2; + ] let () = run_test_tt_main tests From a7a4e1444efffb4d707b345403e91c205255785d Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 12 Dec 2024 15:07:19 +0100 Subject: [PATCH 112/150] Fix normalize tests for floating point and fraction --- .../sparseImplementation/listMatrix.ml | 1 + .../sparseMatrixImplementationTest.ml | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 7b26b6ac00..d7a280fa8f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -142,6 +142,7 @@ module ListMatrix: AbstractMatrix = V.map2_f_preserves_zero (fun x y -> x -: s *: y) row v) ) m + let del_col m j = if num_cols m = 1 then empty () else diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 69eae4211b..0fe269d15e 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -127,14 +127,14 @@ let does_handle_floats _ = (Matrix.append_row (Matrix.empty ()) (Vector.of_sparse_list width [ (0, float 5.); (2, float (1. /. 2.)) ])) (Vector.of_sparse_list width - [ (0, float (1. /. 4.)); (2, float 23.); (2, float 2.) ]) + [ (0, float (1. /. 4.)); (1, float 23.); (2, float 2.) ]) in let normalized_matrix = Matrix.append_row (Matrix.append_row (Matrix.empty ()) - (Vector.of_sparse_list width [ (0, float 1.); (2, float (1. /. 10.)) ])) - (Vector.of_sparse_list width [ (2, float 1.); (2, float (79. /. 920.)) ]) + (Vector.of_sparse_list width [ (0, float 1.); (2, frac 1 10) ])) + (Vector.of_sparse_list width [ (1, float 1.); (2, frac 79 920) ]) in normalize_and_assert any_matrix normalized_matrix @@ -145,14 +145,14 @@ let does_handle_fractions _ = (Matrix.append_row (Matrix.empty ()) (Vector.of_sparse_list width [ (0, frac 5 1); (2, frac 1 2) ])) (Vector.of_sparse_list width - [ (0, frac 1 4); (2, frac 23 1); (2, frac 2 1) ]) + [ (0, frac 1 4); (1, frac 23 1); (2, frac 2 1) ]) in let normalized_matrix = Matrix.append_row (Matrix.append_row (Matrix.empty ()) (Vector.of_sparse_list width [ (0, frac 1 1); (2, frac 1 10) ])) - (Vector.of_sparse_list width [ (2, frac 1 1); (2, frac 79 920) ]) + (Vector.of_sparse_list width [ (1, frac 1 1); (2, frac 79 920) ]) in normalize_and_assert any_matrix normalized_matrix @@ -246,7 +246,7 @@ let is_covered_big _ = let is_covered_big2 _ = let m1 = make_matrix_of_2d_list @@ [[int 1; int 0; int 0; int 0; int 0; int 1; int 0] - ] in + ] in let m2 = make_matrix_of_2d_list @@ [[int 1; int 0; int 0; int 0; int 0; int 0; int 0]; @@ -309,9 +309,8 @@ let tests = "can solve a standard normalization" >:: standard_normalize; "does sort already reduzed" >:: does_just_sort; "does eliminate dependent rows" >:: does_eliminate_dependent_rows; - (* Looks like the tests are deadlock or inifinite execution when those are activated. *) - (*"can handle float domain" >:: does_handle_floats;*) - (*"can handle fraction domain" >:: does_handle_fractions;*) + "can handle float domain" >:: does_handle_floats; + "can handle fraction domain" >:: does_handle_fractions; "does negate negative matrix" >:: does_negate_negative; "does not change already normalized matrix" >:: does_not_change_normalized_matrix; "m1 is covered by m2" >:: is_covered_by_simple; @@ -323,7 +322,6 @@ let tests = "can correctly normalize a two column matrix" >:: normalize_two_columns; "can handle a rational solution" >:: int_domain_to_rational; "m1 is covered by m2 with big matrix2" >:: is_covered_big2; - ] let () = run_test_tt_main tests From b15b9d2dfec55c8ce7df595ce6c55468ab4a2c99 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 12 Dec 2024 15:15:51 +0100 Subject: [PATCH 113/150] small tweak in findi_val_opt, could be even a tini tiny bit faster but not much --- .../affineEquality/sparseImplementation/sparseVector.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 2fc3e16e5f..1b31bfe2c7 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -194,10 +194,11 @@ module SparseVector: AbstractVector = (*Can be optimized, dont check every zero cell*) let findi_val_opt f v = let rec find_zero_or_val vec last_col_idx = - match vec, last_col_idx with - | [], _ -> if f A.zero && v.len <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else None - | (idx, value) :: xs, i -> - if f A.zero && idx <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) + let f0 = f A.zero in + match vec with + | [] -> if f0 && v.len <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else None + | (idx, value) :: xs -> + if f0 && idx <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else if f value then Some (idx, value) else find_zero_or_val xs idx in find_zero_or_val v.entries (-1) From 0f6509b0fac50563d8629f2c6a8dcd824711df99 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 12 Dec 2024 15:42:54 +0100 Subject: [PATCH 114/150] removed prints for benchmarking --- .../sparseImplementation/listMatrix.ml | 48 ++++--------------- .../apron/affineEqualityDomain.apron.ml | 22 ++------- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 7b26b6ac00..d43e858138 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -40,18 +40,16 @@ module ListMatrix: AbstractMatrix = (* This only works if Array.modifyi has been removed from dim_add *) let add_empty_columns (m : t) (cols : int array) : t = - let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in let rec count_sorted_occ acc cols last count = - match cols with - | [] -> if count > 0 then (last, count) :: acc else acc - | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) - | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in - count_sorted_occ acc xs x 1 + match cols with + | [] -> if count > 0 then (last, count) :: acc else acc + | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) + | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in + count_sorted_occ acc xs x 1 in let occ_cols = List.rev @@ count_sorted_occ [] sorted_cols 0 0 in - let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m)) in List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m let add_empty_columns m cols = @@ -64,7 +62,6 @@ module ListMatrix: AbstractMatrix = List.nth m n let remove_row m n = - let () = Printf.printf "Before remove_row %i of m:\n%s\n" n (show m) in List.remove_at n m let get_col m n = @@ -75,9 +72,7 @@ module ListMatrix: AbstractMatrix = Timing.wrap "get_col" (get_col m) n let set_col m new_col n = - let () = Printf.printf "Before set_col m:\n%s\n" (show m) in (* List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m *) - let () = Printf.printf "After set_col m:\n%s\n" (show (List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col))) in List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) @@ -98,7 +93,6 @@ module ListMatrix: AbstractMatrix = V.map2_f_preserves_zero (fun x y -> x -: s *: y) row1 row2 let reduce_col m j = - let () = Printf.printf "Before reduce_col %i of m:\n%s\n" j (show m) in if is_empty m then m else let rec find_pivot idx entries = (* Finds non-zero element in column j and returns pair of row idx and the pivot value *) @@ -108,18 +102,8 @@ module ListMatrix: AbstractMatrix = if value =: A.zero then find_pivot (idx - 1) rest else Some (idx, value) in match (find_pivot (num_rows m - 1) (List.rev m)) with - | None -> let () = Printf.printf "After reduce_col %i of m:\n%s\n" j (show m) in m (* column is already filled with zeroes *) + | None -> m (* column is already filled with zeroes *) | Some (row_idx, pivot) -> - let () = Printf.printf "After reduce_col %i of m:\n%s\n" j (show (let pivot_row = List.nth m row_idx in - List.mapi (fun idx row -> - if idx = row_idx then - V.zero_vec (num_cols m) - else - let row_value = V.nth row j in - if row_value = A.zero then row - else (let s = row_value /: pivot in - sub_scaled_row row pivot_row s) - ) m)) in let pivot_row = List.nth m row_idx in List.mapi (fun idx row -> if idx = row_idx then @@ -132,7 +116,6 @@ module ListMatrix: AbstractMatrix = ) m let reduce_col_with_vec m j v = - let () = Printf.printf "Before reduce_col_with_vec %i with vec %s of m:\n%s\n" j (V.show v) (show m) in let pivot_element = V.nth v j in if pivot_element = A.zero then m else List.mapi (fun idx row -> @@ -150,7 +133,6 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = let cols = Array.to_list cols in (* TODO: Is it possible to use list for Apron dimchange? *) let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification) *) - let () = Printf.printf "Before del_cols cols_length=%i \nm:\n%s\n" (List.length cols) (show m) in if (List.length sorted_cols) = num_cols m then empty() else List.map (fun row -> V.remove_at_indices row sorted_cols) m @@ -158,14 +140,12 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols let map2i f m v = - let () = Printf.printf "Before map2i m:\n%sv:%s\n" (show m) (V.show v) in let rec map2i_min i acc m v = match m, v with | [], _ -> List.rev acc | row :: rs, [] -> List.rev_append (row :: acc) rs | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs in - let () = Printf.printf "After map2i m:\n%s\n" (show (map2i_min 0 [] m (V.to_list v))) in map2i_min 0 [] m (V.to_list v) let remove_zero_rows m = @@ -187,7 +167,6 @@ module ListMatrix: AbstractMatrix = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m let normalize m = - let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m @@ -233,7 +212,6 @@ module ListMatrix: AbstractMatrix = main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in let m' = main_loop m m 0 0 in - let () = Printf.printf "After normalizing we have m:\n%s" (show m') in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) @@ -242,20 +220,17 @@ module ListMatrix: AbstractMatrix = (*If m is empty then v is simply normalized and returned*) (* TODO: OPTIMIZE! *) let rref_vec m v = - let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in match normalize @@ append_matrices m (init_with_vec v) with - | Some res -> let () = Printf.printf "After rref_vec, before removing zero rows, we have m:\n%s\n" (show res) in - Some (remove_zero_rows res) - | None -> let () = Printf.printf "After rref_vec there is no normalization\n " in None + | Some res -> Some (remove_zero_rows res) + | None -> None (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) (*TODO: OPTIMIZE!*) let rref_matrix m1 m2 = - let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in match normalize @@ append_matrices m1 m2 with - | Some m -> let () = Printf.printf "After rref_matrix m, before removing zero rows:\n %s\n" (show m) in Some (remove_zero_rows m) - | None -> let () = Printf.printf "No normalization for rref_matrix found" in None + | Some m -> Some (remove_zero_rows m) + | None -> None let delete_row_with_pivots row pivots m2 = failwith "TODO" @@ -277,7 +252,6 @@ module ListMatrix: AbstractMatrix = let new_v = V.map2_f_preserves_zero (fun v1 v2 -> v1 -: (pivot *: v2)) v x in is_linearly_independent_rref new_v m' in - let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in if num_rows m1 > num_rows m2 then false else let rec is_covered_by_helper m1 m2 = match m1 with @@ -297,9 +271,7 @@ module ListMatrix: AbstractMatrix = List.find_opt f m let map2 f m v = - let () = Printf.printf "Before map2 we have m:\n%s\n" (show m) in let vector_length = V.length v in - let () = Printf.printf "After map2 we have m:\n%s\n" (show (List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m)) in List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 8df5994c9c..bdc715127d 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -32,13 +32,11 @@ struct let dim_remove (ch: Apron.Dim.change) m ~del = - let () = Printf.printf "Before dim_remove m:\n%s" (show m) in if Array.length ch.dim = 0 || is_empty m then m else ( Array.modifyi (+) ch.dim; let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col y x) m ch.dim else m in - let () = Printf.printf "After dim_remove m':\n%s" (show (remove_zero_rows @@ del_cols m' ch.dim)) in remove_zero_rows @@ del_cols m' ch.dim) let dim_remove ch m ~del = Timing.wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del @@ -256,7 +254,6 @@ struct let meet t1 t2 = let res = meet t1 t2 in - let () = Printf.printf "meet a: %s b: %s -> %s \n" (show t1) (show t2) (show res) in if M.tracing then M.tracel "meet" "meet a: %s b: %s -> %s " (show t1) (show t2) (show res) ; res @@ -283,7 +280,6 @@ struct let leq t1 t2 = let res = leq t1 t2 in - let () = Printf.printf "leq a: %s b: %s -> %b \n" (show t1) (show t2) res in if M.tracing then M.tracel "leq" "leq a: %s b: %s -> %b " (show t1) (show t2) res ; res @@ -297,17 +293,13 @@ struct in let case_three a b col_a col_b max = let col_a, col_b = Vector.copy col_a, Vector.copy col_b in - let () = Printf.printf "Before keep_vals: \ncol_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in let col_a, col_b = Vector.keep_vals col_a max, Vector.keep_vals col_b max in - let () = Printf.printf "After keep_vals: \ncol_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in if Vector.equal col_a col_b then (a, b, max) else ( - let () = Printf.printf "Before rev col_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in let col_a = Vector.rev col_a in let col_b = Vector.rev col_b in - let () = Printf.printf "After rev col_a: %s col_b: %s\n" (Vector.show col_a) (Vector.show col_b) in let i = Vector.find2i (<>:) col_a col_b in let (x, y) = Vector.nth col_a i, Vector.nth col_b i in let r, diff = Vector.length col_a - (i + 1), x -: y in @@ -315,7 +307,6 @@ struct let col_a = Vector.map2 (-:) col_a col_b in let col_a = Vector.rev col_a in let multiply_by_t m t = - let () = Printf.printf "Before multiply_by_t col_a: %s" (Vector.show col_a) in Matrix.map2i (fun i' x c -> if i' <= max then (let beta = c /: diff in Vector.map2 (fun u j -> u -: (beta *: j)) x t) else x) m col_a; in @@ -356,12 +347,10 @@ struct let join a b = let res = join a b in - let () = Printf.printf "join a: %s b: %s -> %s \n" (show a) (show b) (show res) in if M.tracing then M.tracel "join" "join a: %s b: %s -> %s " (show a) (show b) (show res) ; res let widen a b = - let () = Printf.printf "Widen a: %s b: %s\n" (show a) (show b) in if Environment.equal a.env b.env then join a b else @@ -378,7 +367,6 @@ struct let remove_rels_with_var x var env = Timing.wrap "remove_rels_with_var" remove_rels_with_var x var env let forget_vars t vars = - let () = Printf.printf "forget_vars m:\n%s" (show t) in if is_bot t || is_top_env t || vars = [] then t else @@ -414,7 +402,6 @@ struct let b_length = Vector.length b in let b = Vector.mapi (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b in let b = Vector.set_nth b (Environment.dim_of_var env var) Mpqf.one in - let () = Printf.printf "Before Matrix.rref_vec x:\n%s b:\n%s\n" (Matrix.show x) (Vector.show b) in match Matrix.rref_vec x b with | None -> bot () | some_matrix -> {d = some_matrix; env = env} @@ -424,9 +411,9 @@ struct in let affineEq_vec = get_coeff_vec t texp in if is_bot t then t else let m = Option.get t.d in match affineEq_vec with - | Some v when is_top_env t -> let () = Printf.printf "After affineEq_vec m:\n%s\n" (Vector.show v) in + | Some v when is_top_env t -> if is_invertible v then t else assign_uninvertible_rel m var v t.env - | Some v -> let () = Printf.printf "After affineEq_vec m:\n%s\n" (Vector.show v) in + | Some v -> if is_invertible v then let t' = assign_invertible_rels (Matrix.copy m) var v t.env in {d = t'.d; env = t'.env} else let new_m = Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env in assign_uninvertible_rel new_m var v t.env @@ -459,15 +446,13 @@ struct res let assign_var_parallel t vv's = - let () = Printf.printf "Before assign_var_parallel m:\n%s\n" (show t) in let assigned_vars = List.map fst vv's in let t = add_vars t assigned_vars in let primed_vars = List.init (List.length assigned_vars) (fun i -> Var.of_string (Int.to_string i ^"'")) in (* TODO: we use primed vars in analysis, conflict? *) let t_primed = add_vars t primed_vars in let multi_t = List.fold_left2 (fun t' v_prime (_,v') -> assign_var t' v_prime v') t_primed primed_vars vv's in - let () = Printf.printf "After assign_var_parallel multi_t:\n%s\n" (show multi_t) in match multi_t.d with - | Some m when not @@ is_top_env multi_t -> let () = Printf.printf "Matrix in Domain m:\n%s\n" (Matrix.show m) in + | Some m when not @@ is_top_env multi_t -> let replace_col m x y = let dim_x, dim_y = Environment.dim_of_var multi_t.env x, Environment.dim_of_var multi_t.env y in let col_x = Matrix.get_col m dim_x in @@ -475,7 +460,6 @@ struct in let m_cp = Matrix.copy m in let switched_m = List.fold_left2 replace_col m_cp primed_vars assigned_vars in - let () = Printf.printf "Switched Matrix in Domain switched_m:\n%s\n" (Matrix.show switched_m) in let res = drop_vars {d = Some switched_m; env = multi_t.env} primed_vars ~del:true in let x = Option.get res.d in (match Matrix.normalize x with From 9ea8cc251c81f8ecb66f392d1eb0df2b25097695 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 12 Dec 2024 16:28:37 +0100 Subject: [PATCH 115/150] Remove old copies in AffineEqualityDomain --- .../apron/affineEqualityDomain.apron.ml | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index bdc715127d..63f785a861 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -36,7 +36,7 @@ struct m else ( Array.modifyi (+) ch.dim; - let m' = if not del then let m = copy m in Array.fold_left (fun y x -> reduce_col y x) m ch.dim else m in + let m' = if not del then Array.fold_left (fun y x -> reduce_col y x) m ch.dim else m in remove_zero_rows @@ del_cols m' ch.dim) let dim_remove ch m ~del = Timing.wrap "dim remove" (fun del -> dim_remove ch m ~del:del) del @@ -81,17 +81,16 @@ struct in Vector.set_nth zero_vec ((Vector.length zero_vec) - 1) (of_union x) | Var x -> - let zero_vec_cp = Vector.copy zero_vec in let entry_only v = Vector.set_nth v (Environment.dim_of_var t.env x) Mpqf.one in begin match t.d with | Some m -> let row = Matrix.find_opt (fun r -> Vector.nth r (Environment.dim_of_var t.env x) =: Mpqf.one) m in begin match row with | Some v when is_const_vec v -> - Vector.set_nth zero_vec_cp ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)) - | _ -> entry_only zero_vec_cp + Vector.set_nth zero_vec ((Vector.length zero_vec) - 1) (Vector.nth v (Vector.length v - 1)) + | _ -> entry_only zero_vec end - | None -> entry_only zero_vec_cp end + | None -> entry_only zero_vec end | Unop (Neg, e, _, _) -> neg @@ convert_texpr e | Unop (Cast, e, _, _) -> convert_texpr e (*Ignore since casts in apron are used for floating point nums and rounding in contrast to CIL casts*) | Unop (Sqrt, e, _, _) -> raise NotLinear @@ -292,7 +291,6 @@ struct Matrix.remove_row a r in let case_three a b col_a col_b max = - let col_a, col_b = Vector.copy col_a, Vector.copy col_b in let col_a, col_b = Vector.keep_vals col_a max, Vector.keep_vals col_b max in if Vector.equal col_a col_b then (a, b, max) @@ -339,9 +337,9 @@ struct let sup_env = Environment.lce a.env b.env in let mod_x = dim_add (Environment.dimchange a.env sup_env) x in let mod_y = dim_add (Environment.dimchange b.env sup_env) y in - {d = Some (lin_disjunc 0 0 (Matrix.copy mod_x) (Matrix.copy mod_y)); env = sup_env} + {d = Some (lin_disjunc 0 0 mod_x mod_y); env = sup_env} | x, y when Matrix.equal x y -> {d = Some x; env = a.env} - | x, y -> {d = Some(lin_disjunc 0 0 (Matrix.copy x) (Matrix.copy y)); env = a.env} + | x, y -> {d = Some(lin_disjunc 0 0 x y); env = a.env} let join a b = Timing.wrap "join" (join a) b @@ -372,7 +370,7 @@ struct else let m = Option.get t.d in let rem_from m = List.fold_left (fun m' x -> remove_rels_with_var m' x t.env) m vars in - {d = Some (Matrix.remove_zero_rows @@ rem_from (Matrix.copy m)); env = t.env} + {d = Some (Matrix.remove_zero_rows @@ rem_from m); env = t.env} let forget_vars t vars = let res = forget_vars t vars in @@ -414,7 +412,7 @@ struct | Some v when is_top_env t -> if is_invertible v then t else assign_uninvertible_rel m var v t.env | Some v -> - if is_invertible v then let t' = assign_invertible_rels (Matrix.copy m) var v t.env in {d = t'.d; env = t'.env} + if is_invertible v then let t' = assign_invertible_rels m var v t.env in {d = t'.d; env = t'.env} else let new_m = Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env in assign_uninvertible_rel new_m var v t.env | None -> {d = Some (Matrix.remove_zero_rows @@ remove_rels_with_var m var t.env); env = t.env} @@ -458,8 +456,7 @@ struct let col_x = Matrix.get_col m dim_x in Matrix.set_col m col_x dim_y in - let m_cp = Matrix.copy m in - let switched_m = List.fold_left2 replace_col m_cp primed_vars assigned_vars in + let switched_m = List.fold_left2 replace_col m primed_vars assigned_vars in let res = drop_vars {d = Some switched_m; env = multi_t.env} primed_vars ~del:true in let x = Option.get res.d in (match Matrix.normalize x with From ca91d4838cd1e8e8268bc37f72c0552f0a379ee5 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 12 Dec 2024 17:10:21 +0100 Subject: [PATCH 116/150] Adapt sparseVector functions to tail recursive --- .../sparseImplementation/sparseVector.ml | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 2fc3e16e5f..20b400756c 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -36,9 +36,10 @@ module SparseVector: AbstractVector = let keep_vals v n = if n >= v.len then v else - {entries = take_while (fun (idx, _) -> idx < n) v.entries; len=n} + {entries = List.take_while (fun (idx, _) -> idx < n) v.entries; len=n} + (* Maybe use the function below instead of this one ?*) let remove_nth v n = let dec_idx v = List.map (fun (a,b) -> (a-1, b)) v @@ -68,39 +69,37 @@ module SparseVector: AbstractVector = (* Note: It is assumed and necessary here that idx is sorted!!! *) let remove_at_indices v idx = - let rec remove_indices_helper vec idx deleted_count = + let rec remove_indices_helper vec idx deleted_count acc = match vec, idx with - | [], [] -> [] + | [], [] -> List.rev acc | [], (y :: ys) when deleted_count >= v.len || y >= v.len -> failwith "remove at indices: no more columns to delete" - | [], (y :: ys) -> remove_indices_helper [] ys (deleted_count + 1) (* Removing zero (also in next iteration, else failwith ) *) - | ((col_idx, value) :: xs), [] -> (col_idx - deleted_count, value) :: remove_indices_helper xs [] deleted_count - | ((col_idx, value) :: xs), (y :: ys) when y = col_idx -> remove_indices_helper xs ys (deleted_count + 1) - | ((col_idx, value) :: xs), (y :: ys) when y < col_idx -> remove_indices_helper vec ys (deleted_count + 1) - | ((col_idx, value) :: xs), (y :: ys) -> (col_idx - deleted_count, value) :: remove_indices_helper xs idx deleted_count + | [], (y :: ys) -> remove_indices_helper [] ys (deleted_count + 1) acc (* Removing zero (also in next iteration, else failwith ) *) + | ((col_idx, value) :: xs), [] -> remove_indices_helper xs [] deleted_count ((col_idx - deleted_count, value) :: acc) + | ((col_idx, value) :: xs), (y :: ys) when y = col_idx -> remove_indices_helper xs ys (deleted_count + 1) acc + | ((col_idx, value) :: xs), (y :: ys) when y < col_idx -> remove_indices_helper vec ys (deleted_count + 1) acc + | ((col_idx, value) :: xs), (y :: ys) -> remove_indices_helper xs idx deleted_count ((col_idx - deleted_count, value) :: acc) in - {entries = remove_indices_helper v.entries idx 0; len = v.len - List.length idx} + {entries = remove_indices_helper v.entries idx 0 []; len = v.len - List.length idx} let insert_zero_at_indices v idx count = - let rec add_indices_helper vec idx added_count = + let rec add_indices_helper vec idx added_count acc = match vec, idx with - | [], [] -> [] - | [], (y :: ys) -> [] (* inserting at the end only means changing the dimension *) - | ((col_idx, value) :: xs), [] -> (col_idx + added_count, value) :: add_indices_helper xs [] added_count - | ((col_idx, value) :: xs), ((i, count) :: ys) when i = col_idx -> add_indices_helper vec ys (added_count + count) - | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> add_indices_helper vec ys (added_count + count) - | ((col_idx, value) :: xs), ((i, count) :: ys) -> (col_idx + added_count, value) :: add_indices_helper xs idx added_count + | [], _ -> List.rev acc (* inserting at the end only means changing the dimension *) + | ((col_idx, value) :: xs), [] -> add_indices_helper xs [] added_count ((col_idx + added_count, value) :: acc) + | ((col_idx, value) :: xs), ((i, count) :: ys) when i = col_idx -> add_indices_helper vec ys (added_count + count) acc + | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> add_indices_helper vec ys (added_count + count) acc + | ((col_idx, value) :: xs), ((i, count) :: ys) -> add_indices_helper xs idx added_count ((col_idx + added_count, value) :: acc) in - {entries = add_indices_helper v.entries idx 0; len = v.len + count} + {entries = add_indices_helper v.entries idx 0 []; len = v.len + count} let set_nth v n num = (* TODO: Optimize! *) if n >= v.len then failwith "Out of bounds" else - (* of_list @@ List.mapi (fun i x -> if i = n then num else x) (to_list v) *) let rec set_nth_helper vec acc = match vec with | [] -> if num <>: A.zero then List.rev ((n, num) :: acc) else List.rev acc | (idx, value) :: xs when n = idx -> if num <>: A.zero then List.rev_append ((idx, num) :: acc) xs else List.rev_append acc xs - | (idx, value) :: xs when n < idx -> if num <>: A.zero then List.rev_append ((n, num) :: acc) vec else List.rev_append acc ((idx, value) :: xs) + | (idx, value) :: xs when n < idx -> if num <>: A.zero then List.rev_append ((n, num) :: acc) vec else List.rev_append acc vec | x :: xs -> set_nth_helper xs (x :: acc) in {entries = set_nth_helper v.entries []; len = v.len} From 6883084363a7a1dbc3e3af238e198aa246da5d26 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Fri, 13 Dec 2024 13:29:35 +0100 Subject: [PATCH 117/150] added Timingwraps to vector functions and alternative to findivalopt --- .../arrayImplementation/arrayVector.ml | 1 + .../sparseImplementation/listMatrix.ml | 21 ++++++++++--------- .../sparseImplementation/sparseVector.ml | 11 ++++++++++ src/cdomains/affineEquality/vector.ml | 2 ++ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 622a12e328..0705853357 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -132,4 +132,5 @@ module ArrayVector: AbstractVector = let starting_from_nth n v = failwith "TODO / deprecated" + let find_first_non_zero v = failwith "TODO" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index d43e858138..02d9896a7b 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -166,11 +166,14 @@ module ListMatrix: AbstractMatrix = let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m + let swap_rows m j k = Timing.wrap "swap rows" (swap_rows m j) k + let normalize m = let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m in + let dec_mat_2D m row_idx col_idx = Timing.wrap "dec_mat_2D" (dec_mat_2D m row_idx) col_idx in (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) (* The last column represents the constant in the affeq *) let find_first_pivot m' row_idx col_idx = @@ -178,7 +181,7 @@ module ListMatrix: AbstractMatrix = let max_piv_col_idx = num_cols m' - 2 in (* col at num_cols - 1 is the constant of the affeq *) (* Finding pivot by extracting the minimum column index of the first non zero value of each row*) let (piv_row, piv_col, piv_val) = List.fold_lefti (fun (cur_row, cur_col, cur_val) i row -> - let row_first_non_zero = V.findi_val_opt ((<>:) A.zero) row in + let row_first_non_zero = V.find_first_non_zero row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) | Some (idx, value) -> (* let () = Printf.printf "We found first non-zero at index %i in row %i\n" idx i in *) @@ -187,10 +190,11 @@ module ListMatrix: AbstractMatrix = in if piv_col = (max_piv_col_idx + 1) then None else Some (row_idx + piv_row, col_idx + piv_col, piv_val) in + let find_first_pivot m' row_idx col_idx = Timing.wrap "find_first_pivot" (find_first_pivot m' row_idx) col_idx in let affeq_rows_are_valid m = (* Check if the semantics of an rref-affeq matrix are correct *) let col_count = num_cols m in let row_is_valid row = (* TODO: Vector findi_opt *) - match V.findi_val_opt ((<>:) A.zero) row with + match V.find_first_non_zero row with | Some (idx, _) -> if idx < col_count - 1 then true else false (* If all cofactors of the affeq are zero, but the constant is non-zero, the row is invalid *) | None -> true (* Full zero row is valid *) in @@ -214,15 +218,12 @@ module ListMatrix: AbstractMatrix = let m' = main_loop m m 0 0 in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) - - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) - (*m must be in rref form and contain the same num of cols as v*) - (*If m is empty then v is simply normalized and returned*) - (* TODO: OPTIMIZE! *) - let rref_vec m v = + let rref_vec m v = match normalize @@ append_matrices m (init_with_vec v) with - | Some res -> Some (remove_zero_rows res) - | None -> None + | Some m -> Some (remove_zero_rows m) + | None -> None + + let rref_vec m v = Timing.wrap "rref_vec" (rref_vec m) v (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 20b400756c..b895befc14 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -118,6 +118,8 @@ module SparseVector: AbstractVector = if new_val = A.zero then None else Some (idx, new_val)) v.entries in {entries = entries'; len = v.len} + let map_f_preserves_zero f v = Timing.wrap "map_f_preserves_zero" (map_f_preserves_zero f) v + (* map for functions f such that f 0 0 = 0 since f won't be applied to if both values are zero. See also map *) let map2_f_preserves_zero f v1 v2 = let f_rem_zero acc idx e1 e2 = @@ -138,6 +140,7 @@ module SparseVector: AbstractVector = if v1.len <> v2.len then raise (Invalid_argument "Unequal lengths") else to_vector (List.rev (aux [] v1.entries v2.entries)) v1.len + let map2_f_preserves_zero f v1 v2 = Timing.wrap "map2_f_preserves_zero" (map2_f_preserves_zero f v1) v2 let fold_left_f_preserves_zero f acc v = List.fold_left (fun acc (_, value) -> f acc value) acc v.entries @@ -201,6 +204,14 @@ module SparseVector: AbstractVector = else find_zero_or_val xs idx in find_zero_or_val v.entries (-1) + let findi_val_opt f v = Timing.wrap "findi_val_opt" (findi_val_opt f) v + + let find_first_non_zero v = + if v.entries = [] then None + else Some (List.hd v.entries) + + let find_first_non_zero v = Timing.wrap "find_first_non_zero" (find_first_non_zero) v + let map f v = of_list (List.map f (to_list v)) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index f52f6eadbb..11b33df151 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -49,6 +49,8 @@ sig (* Returns optional tuple of position and value which was found*) val findi_val_opt: (num -> bool) -> t -> (int * num) Option.t + val find_first_non_zero : t -> (int * num) option + val find_opt: (num -> bool) -> t -> num Option.t val map: (num -> num) -> t -> t From 61caba26fc086dd00b3f77a736c5a3b1a8f58859 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Fri, 13 Dec 2024 17:21:38 +0100 Subject: [PATCH 118/150] implemented different rref_vec that doesn't use normalize --- array.txt | 2150 +++++++++++++++ list.txt | 2318 +++++++++++++++++ rref_vec.txt | 1256 +++++++++ sparse.txt | 1294 +++++++++ .../arrayImplementation/arrayVector.ml | 3 + .../sparseImplementation/listMatrix.ml | 94 +- .../sparseImplementation/sparseVector.ml | 6 + src/cdomains/affineEquality/vector.ml | 2 + 8 files changed, 7101 insertions(+), 22 deletions(-) create mode 100644 array.txt create mode 100644 list.txt create mode 100644 rref_vec.txt create mode 100644 sparse.txt diff --git a/array.txt b/array.txt new file mode 100644 index 0000000000..215bda4a77 --- /dev/null +++ b/array.txt @@ -0,0 +1,2150 @@ +./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set sem.int.signed_overflow assume_none tests/regression/77-lin2vareq/20-function_call2.c +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +Matrix in Domain m: + +Switched Matrix in Domain switched_m: + +Before normalizing we have m: +After normalizing we have m: +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[1 0 0 0 ] + +Before Matrix.rref_vec x: + b: +[-1 1 0 0 ] + +Before rref_vec we have m: +v: [-1 1 0 0 ] + +Before normalizing we have m: +[-1 1 0 0 ] +After normalizing we have m: +[1 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 -1 0 0 ] + +After affineEq_vec m: +[0 1 0 0 ] + +Before reduce_col 2 of m: +[1 -1 0 0 ] + +After reduce_col 2 of m: +[1 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 -1 0 0 ] + b: +[0 -1 1 0 ] + +Before rref_vec we have m: +[1 -1 0 0 ] +v: [0 -1 1 0 ] + +Before normalizing we have m: +[1 -1 0 0 ] +[0 -1 1 0 ] +After normalizing we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] + +After affineEq_vec m: +[0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 1 0 0 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 1 0 ] + +Before reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before assign_var_parallel m: +[|x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +After affineEq_vec m: +[0 0 0 0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[1 0 0 0 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [1 0 0 0 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[1 0 0 0 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 1 0 0 0 0 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 1 0 0 0 0 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 1 0 0 0 0 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 0 1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 0 1 0 0 0 0 0 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 0 1 0 0 0 0 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After assign_var_parallel multi_t: +[|0'-z#324#arg=0; 1'-z#324#arg=0; 2'-z#324#arg=0; x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +Matrix in Domain m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Switched Matrix in Domain switched_m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before dim_remove m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After dim_remove m': +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 -1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 -1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 -1 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 -1 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 1 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 1 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 0 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 0 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 0 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 0 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 8 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + b: +[1 0 0 0 0 0 0 8 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +v: [1 0 0 0 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +[1 0 0 0 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 1 0 0 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 -1 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + b: +[0 1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +v: [0 1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +[0 1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +forget_vars m: +[|#ret-8=0; x#322#arg-x#327=0; y#323#arg-z#324#arg=0|]Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After affineEq_vec m: +[0 0 0 0 1 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +forget_vars m: +[|#ret-8=0; y#323#arg-y#328=0|]Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +forget_vars m: +[|#ret-8=0; z#324#arg-z#329=0|]Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +After dim_remove m': +[1 0 0 0 8 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +Before rref_matrix m1 m2 +m1: [0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +m2: [1 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_matrix m, before removing zero rows: + [1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +meet a: [|x#327-z#329=0; y#328-z#329=0|] b: [|#ret-8=0|] -> [|#ret-8=0; x#327-z#329=0; y#328-z#329=0|] +Before dim_remove m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 0 of m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + b: +[1 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +v: [1 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After dim_remove m': +[1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[1 0 0 0 ] + +Before Matrix.rref_vec x: + b: +[-1 1 0 0 ] + +Before rref_vec we have m: +v: [-1 1 0 0 ] + +Before normalizing we have m: +[-1 1 0 0 ] +After normalizing we have m: +[1 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 -1 0 0 ] + +After affineEq_vec m: +[0 1 0 0 ] + +Before reduce_col 2 of m: +[1 -1 0 0 ] + +After reduce_col 2 of m: +[1 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 -1 0 0 ] + b: +[0 -1 1 0 ] + +Before rref_vec we have m: +[1 -1 0 0 ] +v: [0 -1 1 0 ] + +Before normalizing we have m: +[1 -1 0 0 ] +[0 -1 1 0 ] +After normalizing we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] + +After affineEq_vec m: +[0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 1 0 0 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 1 0 ] + +Before reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before assign_var_parallel m: +[|x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +After affineEq_vec m: +[0 0 0 0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[1 0 0 0 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [1 0 0 0 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[1 0 0 0 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 1 0 0 0 0 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 1 0 0 0 0 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 1 0 0 0 0 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 0 1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 0 1 0 0 0 0 0 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 0 1 0 0 0 0 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After assign_var_parallel multi_t: +[|0'-z#324#arg=0; 1'-z#324#arg=0; 2'-z#324#arg=0; x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +Matrix in Domain m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Switched Matrix in Domain switched_m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before dim_remove m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After dim_remove m': +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 -1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 -1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 -1 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 -1 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 1 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 1 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 0 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 0 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 0 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 0 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 8 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + b: +[1 0 0 0 0 0 0 8 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +v: [1 0 0 0 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +[1 0 0 0 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 1 0 0 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 -1 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + b: +[0 1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +v: [0 1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +[0 1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +forget_vars m: +[|#ret-8=0; x#322#arg-x#327=0; y#323#arg-z#324#arg=0|]Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After affineEq_vec m: +[0 0 0 0 1 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +forget_vars m: +[|#ret-8=0; y#323#arg-y#328=0|]Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +forget_vars m: +[|#ret-8=0; z#324#arg-z#329=0|]Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +After dim_remove m': +[1 0 0 0 8 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +Before rref_matrix m1 m2 +m1: [0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +m2: [1 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_matrix m, before removing zero rows: + [1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +meet a: [|x#327-z#329=0; y#328-z#329=0|] b: [|#ret-8=0|] -> [|#ret-8=0; x#327-z#329=0; y#328-z#329=0|] +Before dim_remove m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 0 of m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + b: +[1 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +v: [1 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After dim_remove m': +[1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +[Info][Deadcode] Logical lines of code (LLoC) summary: + live: 10 + dead: 0 + total lines: 10 +See result/index.xml diff --git a/list.txt b/list.txt new file mode 100644 index 0000000000..6f85b69219 --- /dev/null +++ b/list.txt @@ -0,0 +1,2318 @@ +./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set sem.int.signed_overflow assume_none tests/regression/77-lin2vareq/20-function_call2.c +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +Matrix in Domain m: + +Switched Matrix in Domain switched_m: + +Before normalizing we have m: +After normalizing we have m: +Before add_empty_columns m: +indices: 0,0,0, +Occ_cols is: +(0,3) +After add_empty_columns m: + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[1 0 0 0 ] + +Before Matrix.rref_vec x: + b: +[-1 1 0 0 ] + +Before rref_vec we have m: +v: [-1 1 0 0 ] + +Before normalizing we have m: +[-1 1 0 0 ] +After normalizing we have m: +[1 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 -1 0 0 ] + +After affineEq_vec m: +[0 1 0 0 ] + +Before reduce_col 2 of m: +[1 -1 0 0 ] + +After reduce_col 2 of m: +[1 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 -1 0 0 ] + b: +[0 -1 1 0 ] + +Before rref_vec we have m: +[1 -1 0 0 ] +v: [0 -1 1 0 ] + +Before normalizing we have m: +[1 -1 0 0 ] +[0 -1 1 0 ] +After normalizing we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0,1,2, +Occ_cols is: +(0,1)(1,1)(2,1) +After add_empty_columns m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 1 0 0 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 1 0 ] + +Before reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0,1,2, +Occ_cols is: +(0,1)(1,1)(2,1) +After add_empty_columns m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before assign_var_parallel m: +[|x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +Before add_empty_columns m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +indices: 0,0,0, +Occ_cols is: +(0,3) +After add_empty_columns m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[1 0 0 0 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [1 0 0 0 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[1 0 0 0 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 1 0 0 0 0 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 1 0 0 0 0 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 1 0 0 0 0 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 0 1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 0 1 0 0 0 0 0 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 0 1 0 0 0 0 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After assign_var_parallel multi_t: +[|0'-z#324#arg=0; 1'-z#324#arg=0; 2'-z#324#arg=0; x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +Matrix in Domain m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Switched Matrix in Domain switched_m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before dim_remove m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After dim_remove m': +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 -1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 -1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 -1 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 -1 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 1 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 1 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 0 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 0 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 0 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 0 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +indices: 0, +Occ_cols is: +(0,1) +After add_empty_columns m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 8 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + b: +[1 0 0 0 0 0 0 8 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +v: [1 0 0 0 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +[1 0 0 0 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +indices: 2,3,4, +Occ_cols is: +(2,1)(3,1)(4,1) +After add_empty_columns m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 -1 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After affineEq_vec m: +[0 0 1 0 0 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 -1 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + b: +[0 1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +v: [0 1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +[0 1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +forget_vars m: +[|#ret-8=0; x#322#arg-x#327=0; y#323#arg-z#324#arg=0|]Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After affineEq_vec m: +[0 0 0 0 1 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +forget_vars m: +[|#ret-8=0; y#323#arg-y#328=0|]Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +forget_vars m: +[|#ret-8=0; z#324#arg-z#329=0|]Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +After dim_remove m': +[1 0 0 0 8 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0, +Occ_cols is: +(0,1) +After add_empty_columns m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before rref_matrix m1 m2 +m1: [0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +m2: [1 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_matrix m, before removing zero rows: + [1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +meet a: [|x#327-z#329=0; y#328-z#329=0|] b: [|#ret-8=0|] -> [|#ret-8=0; x#327-z#329=0; y#328-z#329=0|] +Before dim_remove m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 0 of m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0, +Occ_cols is: +(0,1) +After add_empty_columns m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + b: +[1 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +v: [1 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After dim_remove m': +[1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before add_empty_columns m: +indices: 0,0,0, +Occ_cols is: +(0,3) +After add_empty_columns m: + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[1 0 0 0 ] + +Before Matrix.rref_vec x: + b: +[-1 1 0 0 ] + +Before rref_vec we have m: +v: [-1 1 0 0 ] + +Before normalizing we have m: +[-1 1 0 0 ] +After normalizing we have m: +[1 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 -1 0 0 ] + +After affineEq_vec m: +[0 1 0 0 ] + +Before reduce_col 2 of m: +[1 -1 0 0 ] + +After reduce_col 2 of m: +[1 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 -1 0 0 ] + b: +[0 -1 1 0 ] + +Before rref_vec we have m: +[1 -1 0 0 ] +v: [0 -1 1 0 ] + +Before normalizing we have m: +[1 -1 0 0 ] +[0 -1 1 0 ] +After normalizing we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 -1 0 ] +[0 1 -1 0 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0,1,2, +Occ_cols is: +(0,1)(1,1)(2,1) +After add_empty_columns m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 1 0 0 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 1 0 ] + +Before reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +After reduce_col 4 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + b: +[0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +v: [0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 -1 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0,1,2, +Occ_cols is: +(0,1)(1,1)(2,1) +After add_empty_columns m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] + +Before assign_var_parallel m: +[|x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +Before add_empty_columns m: +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +indices: 0,0,0, +Occ_cols is: +(0,3) +After add_empty_columns m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 1 0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[1 0 0 0 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [1 0 0 0 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[1 0 0 0 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 1 0 0 0 0 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 1 0 0 0 0 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 1 0 0 0 0 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 0 1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + b: +[0 0 1 0 0 0 0 0 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +v: [0 0 1 0 0 0 0 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After assign_var_parallel multi_t: +[|0'-z#324#arg=0; 1'-z#324#arg=0; 2'-z#324#arg=0; x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] +Matrix in Domain m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 0 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 0 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After set_col m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Switched Matrix in Domain switched_m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before dim_remove m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +After dim_remove m': +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 1 0 0 0 0 -1 0 ] +[0 1 0 0 0 1 0 0 -1 0 ] +[0 0 1 0 0 0 0 1 -1 0 ] +[0 0 0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 1 0 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 -1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 -1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 1 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 -1 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 -1 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [0 0 1 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 1 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [1 0 0 0 -1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[1 0 0 0 -1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +v: [-1 0 0 0 1 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[-1 0 0 0 1 0 0 ] +After normalizing we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +[0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +[1 0 0 0 0 -1 0 ] +[0 1 0 0 0 -1 0 ] +[0 0 1 0 0 -1 0 ] +[0 0 0 1 0 -1 0 ] +[0 0 0 0 1 -1 0 ] +indices: 0, +Occ_cols is: +(0,1) +After add_empty_columns m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 8 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + b: +[1 0 0 0 0 0 0 8 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +v: [1 0 0 0 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +[1 0 0 0 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 0 -1 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 1 0 0 -1 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +After dim_remove m': +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 0 1 0 -1 0 ] +[0 0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +indices: 2,3,4, +Occ_cols is: +(2,1)(3,1)(4,1) +After add_empty_columns m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 -1 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After affineEq_vec m: +[0 0 1 0 0 0 0 0 ] + +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 0 0 0 -1 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + b: +[0 1 -1 0 0 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +v: [0 1 -1 0 0 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] +[0 1 -1 0 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +forget_vars m: +[|#ret-8=0; x#322#arg-x#327=0; y#323#arg-z#324#arg=0|]Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 1 -1 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] +[0 0 0 1 0 -1 0 0 ] + +After affineEq_vec m: +[0 0 0 0 1 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 0 -1 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 1 -1 0 0 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 1 -1 0 0 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +forget_vars m: +[|#ret-8=0; y#323#arg-y#328=0|]Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 1 -1 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 1 0 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before Matrix.rref_vec x: +[1 0 0 0 0 0 0 8 ] + b: +[0 0 0 0 0 1 -1 0 ] + +Before rref_vec we have m: +[1 0 0 0 0 0 0 8 ] +v: [0 0 0 0 0 1 -1 0 ] + +Before normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After normalizing we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +forget_vars m: +[|#ret-8=0; z#324#arg-z#329=0|]Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 1 -1 0 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] +[0 0 0 0 0 0 0 0 ] + +Before dim_remove m: +[1 0 0 0 0 0 0 8 ] +Before reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 1 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 3 of m: +[1 0 0 0 0 0 0 8 ] + +Before reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +After reduce_col 5 of m: +[1 0 0 0 0 0 0 8 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +After dim_remove m': +[1 0 0 0 8 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 0 0 8 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0, +Occ_cols is: +(0,1) +After add_empty_columns m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before rref_matrix m1 m2 +m1: [0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +m2: [1 0 0 0 8 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 8 ] +After normalizing we have m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_matrix m, before removing zero rows: + [1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +meet a: [|x#327-z#329=0; y#328-z#329=0|] b: [|#ret-8=0|] -> [|#ret-8=0; x#327-z#329=0; y#328-z#329=0|] +Before dim_remove m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 0 of m: +[1 0 0 0 8 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After dim_remove m': +[1 0 -1 0 ] +[0 1 -1 0 ] +Before del_cols cols_length=1 +m: +[0 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before add_empty_columns m: +[1 0 -1 0 ] +[0 1 -1 0 ] +indices: 0, +Occ_cols is: +(0,1) +After add_empty_columns m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After affineEq_vec m: +[0 0 0 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 0 of m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + b: +[1 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +v: [1 0 0 0 0 ] + +Before normalizing we have m: +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +[1 0 0 0 0 ] +After normalizing we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +After rref_vec, before removing zero rows, we have m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +Before dim_remove m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] +Before reduce_col 1 of m: +[1 0 0 0 0 ] +[0 1 0 -1 0 ] +[0 0 1 -1 0 ] + +After reduce_col 1 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +Before reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 1 -1 0 ] + +After reduce_col 2 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After reduce_col 3 of m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +After dim_remove m': +[1 0 ] +Before del_cols cols_length=3 +m: +[1 0 0 0 0 ] +[0 0 0 0 0 ] +[0 0 0 0 0 ] + +[Info][Deadcode] Logical lines of code (LLoC) summary: + live: 10 + dead: 0 + total lines: 10 +See result/index.xml diff --git a/rref_vec.txt b/rref_vec.txt new file mode 100644 index 0000000000..4cccc943b1 --- /dev/null +++ b/rref_vec.txt @@ -0,0 +1,1256 @@ +./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set ana.relation.privatization top --set sem.int.signed_overflow assume_none tests/regression/63-affeq/03-guard-check.c -v +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +Matrix in Domain m: + +Switched Matrix in Domain switched_m: + +Before normalizing we have m: +After normalizing we have m: +Before add_empty_columns m: +indices: 0,0,0,0,0,0, +After add_empty_columns m: + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[0 0 0 0 0 0 0 ] + +Before Matrix.rref_vec x: + b: +[0 1 0 0 0 0 0 ] + +Before rref_vec we have m: +v: [0 1 0 0 0 0 0 ] + +After rref_vec, before removing zero rows, we have m: +[0 1 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 ] + +Before reduce_col 2 of m: +[0 1 0 0 0 0 0 ] + +After reduce_col 2 of m: +[0 1 0 0 0 0 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 0 ] + b: +[0 0 1 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 0 ] +v: [0 0 1 0 0 0 0 ] + +pivot positions are: (0,1) + +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 ] + +Before reduce_col 5 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + +After reduce_col 5 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + b: +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +v: [0 0 0 0 0 1 0 ] + +pivot positions are: (0,1)(1,2) + +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After affineEq_vec m: +[0 0 0 1 1 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + b: +[1 0 0 -1 -1 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,1)(1,2)(2,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 -1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 -1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 -1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before map2i m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] +v:[-1 0 0 0 ] + +After map2i m: +[1 0 0 -2 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before remove_row 3 of m: +[1 0 0 -2 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before keep_vals: +col_a: [-1 0 0 0 ] + col_b: [-1 0 0 0 ] + +After keep_vals: +col_a: [-1 0 0 ] + col_b: [-1 0 0 ] + +Before keep_vals: +col_a: [0 0 0 0 ] + col_b: [0 0 0 0 ] + +After keep_vals: +col_a: [0 0 0 0 ] + col_b: [0 0 0 0 ] + +join a: [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] b: [|f#303-x#301-y#302=0; i#298=0; k#299=0; x#301=0; z#300=0|] -> [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [2 0 0 -2 -2 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 2 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-2 0 0 2 2 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -2 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before dim_remove m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +Before reduce_col 0 of m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 0 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 1 of m: +[0 0 0 0 0 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 1 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 2 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 2 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 3 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 3 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 4 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 4 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 5 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 5 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before del_cols cols_length=6 +m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +After dim_remove m': +Before del_cols cols_length=6 +m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before add_empty_columns m: +indices: 0,0,0,0,0,0, +After add_empty_columns m: + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[0 0 0 0 0 0 0 ] + +Before Matrix.rref_vec x: + b: +[0 1 0 0 0 0 0 ] + +Before rref_vec we have m: +v: [0 1 0 0 0 0 0 ] + +After rref_vec, before removing zero rows, we have m: +[0 1 0 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 ] + +Before reduce_col 2 of m: +[0 1 0 0 0 0 0 ] + +After reduce_col 2 of m: +[0 1 0 0 0 0 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 0 ] + b: +[0 0 1 0 0 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 0 ] +v: [0 0 1 0 0 0 0 ] + +pivot positions are: (0,1) + +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + +After affineEq_vec m: +[0 0 0 0 0 0 0 ] + +Before reduce_col 5 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + +After reduce_col 5 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] + b: +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +v: [0 0 0 0 0 1 0 ] + +pivot positions are: (0,1)(1,2) + +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After affineEq_vec m: +[0 0 0 1 1 0 0 ] + +Before reduce_col 0 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 0 of m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before Matrix.rref_vec x: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + b: +[1 0 0 -1 -1 0 0 ] + +Before rref_vec we have m: +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,1)(1,2)(2,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 -1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 -1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 -1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [0 0 0 1 0 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before map2i m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] +v:[-1 0 0 0 ] + +After map2i m: +[1 0 0 -2 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before remove_row 3 of m: +[1 0 0 -2 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 1 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before keep_vals: +col_a: [-1 0 0 0 ] + col_b: [-1 0 0 0 ] + +After keep_vals: +col_a: [-1 0 0 ] + col_b: [-1 0 0 ] + +Before keep_vals: +col_a: [0 0 0 0 ] + col_b: [0 0 0 0 ] + +After keep_vals: +col_a: [0 0 0 0 ] + col_b: [0 0 0 0 ] + +join a: [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] b: [|f#303-x#301-y#302=0; i#298=0; k#299=0; x#301=0; z#300=0|] -> [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [2 0 0 -2 -2 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 2 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-2 0 0 2 2 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -2 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [1 0 0 -1 -1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is 1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before rref_vec we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +v: [-1 0 0 1 1 0 0 ] + +pivot positions are: (0,0)(1,1)(2,2)(3,5) + +v_at_piv is -1 +piv row is: [1 0 0 -1 -1 0 0 ] + +scaled row is: [0 0 0 0 0 0 0 ] + +v_at_piv is 0 +v_at_piv is 0 +v_at_piv is 0 +After rref_vec, before removing zero rows, we have m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before dim_remove m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] +Before reduce_col 0 of m: +[1 0 0 -1 -1 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 0 of m: +[0 0 0 0 0 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 1 of m: +[0 0 0 0 0 0 0 ] +[0 1 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 1 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 2 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 1 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 2 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 3 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 3 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 4 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 4 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +Before reduce_col 5 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 1 0 ] + +After reduce_col 5 of m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +Before del_cols cols_length=6 +m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +After dim_remove m': +Before del_cols cols_length=6 +m: +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] +[0 0 0 0 0 0 0 ] + +[Info][Deadcode] Logical lines of code (LLoC) summary: + live: 23 + dead: 0 + total lines: 23 +[Warning][Deadcode][CWE-571] condition 'i == 0' is always true (tests/regression/63-affeq/03-guard-check.c:16:9-16:15) +[Warning][Deadcode][CWE-571] condition 'i != 1' is always true (tests/regression/63-affeq/03-guard-check.c:23:9-23:15) +[Warning][Deadcode][CWE-571] condition 'i > -1' is always true (tests/regression/63-affeq/03-guard-check.c:28:9-28:15) +[Warning][Deadcode][CWE-571] condition 'i >= -1' is always true (tests/regression/63-affeq/03-guard-check.c:35:9-35:16) +See result/index.xml diff --git a/sparse.txt b/sparse.txt new file mode 100644 index 0000000000..4a98bd2d95 --- /dev/null +++ b/sparse.txt @@ -0,0 +1,1294 @@ +./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set sem.int.signed_overflow assume_none --set ana.relation.privatization top tests/regression/63-affeq/01-rel_simple.c -v +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +Matrix in Domain m: + +Switched Matrix in Domain switched_m: + +Before normalizing we have m: +After normalizing we have m: +Before add_empty_columns m: + +After add_empty_columns m: + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[ 0 0 0 2] + +Before Matrix.rref_vec x: + b: +[ 1 0 0 2] + +Before rref_vec we have m: +v: [ 1 0 0 2] + +Before normalizing we have m: +[ 1 0 0 2] +After normalizing we have m: +[ 1 0 0 2] +After affineEq_vec m: +[ 0 0 1 5] + +Before reduce_col 1 of m: +[ 1 0 0 2] + +After reduce_col 1 of m: +[ 1 0 0 2] + +Before Matrix.rref_vec x: +[ 1 0 0 2] + b: +[ 0 1 -1 5] + +Before rref_vec we have m: +[ 1 0 0 2] +v: [ 0 1 -1 5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +After affineEq_vec m: +[ 0 0 1 5] + +Before reduce_col 1 of m: +[ 1 0 0 2] + +After reduce_col 1 of m: +[ 1 0 0 2] + +Before Matrix.rref_vec x: +[ 1 0 0 2] + b: +[ 0 1 -1 5] + +Before rref_vec we have m: +[ 1 0 0 2] +v: [ 0 1 -1 5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +Before rref_vec we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +v: [ 0 -1 0 -6] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 -1 0 -6] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 0 -1 -1] +Before rref_vec we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +v: [ 0 1 0 6] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 1 0 6] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +v: [ 0 -1 1 -5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 -1 1 -5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 0 0 0] +Before rref_vec we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +v: [ 0 1 -1 5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 1 -1 5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +[ 0 0 0 0] +After affineEq_vec m: +[ 0 0 0 3] + +Before reduce_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +After reduce_col 0 of m: +[ 0 0 0 0] +[ 0 1 -1 5] + +Before Matrix.rref_vec x: +[ 0 1 -1 5] + b: +[ 1 0 0 3] + +Before rref_vec we have m: +[ 0 1 -1 5] +v: [ 1 0 0 3] + +Before normalizing we have m: +[ 0 1 -1 5] +[ 1 0 0 3] +After normalizing we have m: +[ 1 0 0 3] +[ 0 1 -1 5] +After affineEq_vec m: +[ 0 1 0 3] + +get_col 1 of m: +[ 1 0 0 3] +[ 0 1 -1 5] + +[ 0 1] + +Before map2 we have m: +[ 1 0 0 3] +[ 0 1 -1 5] + +After map2 we have m: +[ 1 0 0 3] +[ 0 1 -1 8] + +Before normalizing we have m: +[ 1 0 0 3] +[ 0 1 -1 8] +After normalizing we have m: +[ 1 0 0 3] +[ 0 1 -1 8] +get_col 0 of m: +[ 1 0 0 3] +[ 0 1 -1 8] + +[ 1 0] + +get_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 1 0] + +get_col 1 of m: +[ 1 0 0 3] +[ 0 1 -1 8] + +[ 0 1] + +get_col 1 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 1] + +get_col 2 of m: +[ 1 0 0 3] +[ 0 1 -1 8] + +[ 0 -1] + +get_col 2 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 -1] + +Before keep_vals: +col_a: [ 0 -1] + col_b: [ 0 -1] + +After keep_vals: +col_a: [ 0 -1] + col_b: [ 0 -1] + +get_col 3 of m: +[ 1 0 0 3] +[ 0 1 -1 8] + +[ 3 8] + +get_col 3 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 2 5] + +Before keep_vals: +col_a: [ 2 5] + col_b: [ 3 8] + +After keep_vals: +col_a: [ 2 5] + col_b: [ 3 8] + +Before rev col_a: [ 2 5] + col_b: [ 3 8] + +After rev col_a: [ 5 2] + col_b: [ 8 3] + +Before multiply_by_t col_a: [ -1 -3] +Before map2i m: +[ 1 0 0 3] +[ 0 1 -1 8] +v:[ -1 -3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] + +Before multiply_by_t col_a: [ -1 -3] +Before map2i m: +[ 1 0 0 2] +[ 0 1 -1 5] +v:[ -1 -3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] + +join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|i#320-3=0; j#321-k#322-8=0|] -> [|3i#320-j#321+k#322-1=0|] +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +get_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 1 0] + +get_col 1 of m: +[ 1 -1/3 1/3 1/3] + +[ -1/3] + +get_col 1 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 1] + +Before map2i m: +[ 1 0 0 2] +[ 0 1 -1 5] +v:[ -1/3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +leq a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> true +Widen a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +get_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 1 0] + +get_col 1 of m: +[ 1 -1/3 1/3 1/3] + +[ -1/3] + +get_col 1 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 1] + +Before map2i m: +[ 1 0 0 2] +[ 0 1 -1 5] +v:[ -1/3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +After affineEq_vec m: +[ 0 0 1 5] + +Before reduce_col 1 of m: +[ 1 0 0 2] + +After reduce_col 1 of m: +[ 1 0 0 2] + +Before Matrix.rref_vec x: +[ 1 0 0 2] + b: +[ 0 1 -1 5] + +Before rref_vec we have m: +[ 1 0 0 2] +v: [ 0 1 -1 5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 1 0 0 100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 1 0 0 100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 1 1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 1 1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 -1 -1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 -1 -1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +After affineEq_vec m: +[ 1 0 0 1] + +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +Before map2 we have m: +[ 1 -1/3 1/3 1/3] + +After map2 we have m: +[ 1 -1/3 1/3 4/3] + +Before normalizing we have m: +[ 1 -1/3 1/3 4/3] +After normalizing we have m: +[ 1 -1/3 1/3 4/3] +After affineEq_vec m: +[ 0 1 0 3] + +get_col 1 of m: +[ 1 -1/3 1/3 4/3] + +[ -1/3] + +Before map2 we have m: +[ 1 -1/3 1/3 4/3] + +After map2 we have m: +[ 1 -1/3 1/3 1/3] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +get_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 1 0] + +get_col 1 of m: +[ 1 -1/3 1/3 1/3] + +[ -1/3] + +get_col 1 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 1] + +Before map2i m: +[ 1 0 0 2] +[ 0 1 -1 5] +v:[ -1/3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +join a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +leq a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -> true +Widen a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] +join a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +After affineEq_vec m: +[ 0 0 1 5] + +Before reduce_col 1 of m: +[ 1 0 0 2] + +After reduce_col 1 of m: +[ 1 0 0 2] + +Before Matrix.rref_vec x: +[ 1 0 0 2] + b: +[ 0 1 -1 5] + +Before rref_vec we have m: +[ 1 0 0 2] +v: [ 0 1 -1 5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 1 0 0 100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 1 0 0 100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 1 1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 1 1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 -1 -1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 -1 -1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +After affineEq_vec m: +[ 1 0 0 1] + +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +Before map2 we have m: +[ 1 -1/3 1/3 1/3] + +After map2 we have m: +[ 1 -1/3 1/3 4/3] + +Before normalizing we have m: +[ 1 -1/3 1/3 4/3] +After normalizing we have m: +[ 1 -1/3 1/3 4/3] +After affineEq_vec m: +[ 0 1 0 3] + +get_col 1 of m: +[ 1 -1/3 1/3 4/3] + +[ -1/3] + +Before map2 we have m: +[ 1 -1/3 1/3 4/3] + +After map2 we have m: +[ 1 -1/3 1/3 1/3] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +get_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 1 0] + +get_col 1 of m: +[ 1 -1/3 1/3 1/3] + +[ -1/3] + +get_col 1 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 1] + +Before map2i m: +[ 1 0 0 2] +[ 0 1 -1 5] +v:[ -1/3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 1 0 0 100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 1 0 0 100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 1 1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 1 1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 -1 -1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 -1 -1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +Before dim_remove m: +[ 1 -1/3 1/3 1/3] +Before reduce_col 0 of m: +[ 1 -1/3 1/3 1/3] + +After reduce_col 0 of m: +[ 0 0 0 0] + +Before reduce_col 1 of m: +[ 0 0 0 0] + +After reduce_col 1 of m: +[ 0 0 0 0] + +Before reduce_col 2 of m: +[ 0 0 0 0] + +After reduce_col 2 of m: +[ 0 0 0 0] + +Before del_cols cols_length=3 sorted_length=3 +m: +[ 0 0 0 0] + +After dim_remove m': +Before del_cols cols_length=3 sorted_length=3 +m: +[ 0 0 0 0] + +Before add_empty_columns m: + +After add_empty_columns m: + +Before assign_var_parallel m: +⊤ +After assign_var_parallel multi_t: +⊤ +After affineEq_vec m: +[ 0 0 0 2] + +Before Matrix.rref_vec x: + b: +[ 1 0 0 2] + +Before rref_vec we have m: +v: [ 1 0 0 2] + +Before normalizing we have m: +[ 1 0 0 2] +After normalizing we have m: +[ 1 0 0 2] +After affineEq_vec m: +[ 0 0 1 5] + +Before reduce_col 1 of m: +[ 1 0 0 2] + +After reduce_col 1 of m: +[ 1 0 0 2] + +Before Matrix.rref_vec x: +[ 1 0 0 2] + b: +[ 0 1 -1 5] + +Before rref_vec we have m: +[ 1 0 0 2] +v: [ 0 1 -1 5] + +Before normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +After normalizing we have m: +[ 1 0 0 2] +[ 0 1 -1 5] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 1 0 0 100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 1 0 0 100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 1 1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 1 1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 -1 -1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 -1 -1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +[Warning][Assert] Assertion "(3 * i - j) + k == 1" is unknown. Expected: SUCCESS -> failed (tests/regression/63-affeq/01-rel_simple.c:13:9-13:44) +After affineEq_vec m: +[ 1 0 0 1] + +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +Before map2 we have m: +[ 1 -1/3 1/3 1/3] + +After map2 we have m: +[ 1 -1/3 1/3 4/3] + +Before normalizing we have m: +[ 1 -1/3 1/3 4/3] +After normalizing we have m: +[ 1 -1/3 1/3 4/3] +After affineEq_vec m: +[ 0 1 0 3] + +get_col 1 of m: +[ 1 -1/3 1/3 4/3] + +[ -1/3] + +Before map2 we have m: +[ 1 -1/3 1/3 4/3] + +After map2 we have m: +[ 1 -1/3 1/3 1/3] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +get_col 0 of m: +[ 1 -1/3 1/3 1/3] + +[ 1] + +get_col 0 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 1 0] + +get_col 1 of m: +[ 1 -1/3 1/3 1/3] + +[ -1/3] + +get_col 1 of m: +[ 1 0 0 2] +[ 0 1 -1 5] + +[ 0 1] + +Before map2i m: +[ 1 0 0 2] +[ 0 1 -1 5] +v:[ -1/3] + +After map2i m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +Before remove_row 1 of m: +[ 1 -1/3 1/3 1/3] +[ 0 1 -1 5] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 2 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +get_col 3 of m: +[ 1 -1/3 1/3 1/3] + +[ 1/3] + +Before keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +After keep_vals: +col_a: [ 1/3] + col_b: [ 1/3] + +join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 1 0 0 100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 1 0 0 100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -1 0 0 -100] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -1 0 0 -100] +After normalizing we have m: +[ 1 -301/900 301/900 1/900] +[ 0 1/300 -1/300 299/300] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 0 0] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 0 0] +After normalizing we have m: +[ 1 -1/3 2/3 2/3] +[ 0 0 1 1] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ 3 -1 1 1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 3 -1 1 1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +Before rref_vec we have m: +[ 1 -1/3 1/3 1/3] +v: [ -3 1 -1 -1] + +Before normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ -3 1 -1 -1] +After normalizing we have m: +[ 1 -1/3 1/3 1/3] +[ 0 0 0 0] +[Warning][Assert] Assertion "(3 * i - j) + k == 1" is unknown. Expected: SUCCESS -> failed (tests/regression/63-affeq/01-rel_simple.c:17:5-17:40) +Before dim_remove m: +[ 1 -1/3 1/3 1/3] +Before reduce_col 0 of m: +[ 1 -1/3 1/3 1/3] + +After reduce_col 0 of m: +[ 0 0 0 0] + +Before reduce_col 1 of m: +[ 0 0 0 0] + +After reduce_col 1 of m: +[ 0 0 0 0] + +Before reduce_col 2 of m: +[ 0 0 0 0] + +After reduce_col 2 of m: +[ 0 0 0 0] + +Before del_cols cols_length=3 sorted_length=3 +m: +[ 0 0 0 0] + +After dim_remove m': +Before del_cols cols_length=3 sorted_length=3 +m: +[ 0 0 0 0] + +[Info][Deadcode] Logical lines of code (LLoC) summary: + live: 9 + dead: 0 + total lines: 9 +See result/index.xml diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 622a12e328..390ae07fdb 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -132,4 +132,7 @@ module ArrayVector: AbstractVector = let starting_from_nth n v = failwith "TODO / deprecated" + let find_first_non_zero v = + failwith "TODO" + end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index d7a280fa8f..0dc0bf14ac 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -44,11 +44,11 @@ module ListMatrix: AbstractMatrix = let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in let rec count_sorted_occ acc cols last count = - match cols with - | [] -> if count > 0 then (last, count) :: acc else acc - | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) - | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in - count_sorted_occ acc xs x 1 + match cols with + | [] -> if count > 0 then (last, count) :: acc else acc + | x :: xs when x = last -> count_sorted_occ acc xs x (count + 1) + | x :: xs -> let acc = if count > 0 then (last, count) :: acc else acc in + count_sorted_occ acc xs x 1 in let occ_cols = List.rev @@ count_sorted_occ [] sorted_cols 0 0 in let () = Printf.printf "After add_empty_columns m:\n%s\n" (show (List.map (fun row -> V.insert_zero_at_indices row occ_cols (List.length cols)) m)) in @@ -116,7 +116,7 @@ module ListMatrix: AbstractMatrix = V.zero_vec (num_cols m) else let row_value = V.nth row j in - if row_value = A.zero then row + if row_value =: A.zero then row else (let s = row_value /: pivot in sub_scaled_row row pivot_row s) ) m)) in @@ -137,12 +137,11 @@ module ListMatrix: AbstractMatrix = if pivot_element = A.zero then m else List.mapi (fun idx row -> let row_value = V.nth row j in - if row_value = A.zero then row + if row_value =: A.zero then row else (let s = row_value /: pivot_element in V.map2_f_preserves_zero (fun x y -> x -: s *: y) row v) ) m - let del_col m j = if num_cols m = 1 then empty () else @@ -237,17 +236,68 @@ module ListMatrix: AbstractMatrix = let () = Printf.printf "After normalizing we have m:\n%s" (show m') in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) + (* This function return a tuple of row index and pivot position (column) in m *) + (* TODO: maybe we could use a Hashmap instead of a list? *) + let get_pivot_positions (m : t) : (int * int) list = + List.rev @@ List.fold_lefti ( + fun acc i row -> match V.find_first_non_zero row with + | None -> acc + | Some (pivot_col, _) -> (i, pivot_col) :: acc + ) [] m + + (* Inserts the vector v with pivot at piv_idx at the correct position in m. m has to be in rref form. *) + let insert_v_according_to_piv m v piv_idx pivot_positions = + match List.find_opt (fun (row_idx, piv_col) -> piv_col > piv_idx) pivot_positions with + | None -> append_row m v + | Some (row_idx, _) -> let (before, after) = List.split_at row_idx m in + before @ (v :: after) + + let rref_vec (m : t) (v : V.t) : t option = + let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in + if is_empty m then (* In this case, v is normalized and returned *) + match V.find_first_non_zero v with + | None -> let () = Printf.printf "After rref_vec there is no normalization\n " in None + | Some (_, value) -> + let normalized_v = V.map_f_preserves_zero (fun x -> x /: value) v in + let res = init_with_vec normalized_v in + let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in + Some res + else (* We try to normalize v and check if a contradiction arises. If not, we insert v at the appropriate place in m (depending on the pivot) *) + let pivot_positions = get_pivot_positions m in + let () = Printf.printf "pivot positions are: %s\n\n" (List.fold_right (fun (row, piv) s -> "(" ^ (Int.to_string row) ^ "," ^ (Int.to_string piv) ^ ")" ^ s) pivot_positions "") in + let v_after_elim = List.fold_left ( + fun acc (row_idx, pivot_position) -> + let v_at_piv = V.nth acc pivot_position in + if v_at_piv =: A.zero then + acc + else + let piv_row = List.nth m row_idx in + sub_scaled_row acc piv_row v_at_piv + ) v pivot_positions + in + match V.find_first_non_zero v_after_elim with (* now we check for contradictions and finally insert v *) + | None -> let () = Printf.printf "After rref_vec we have m:\n%s\n" (show m) in + Some m (* v is zero vector and was therefore already covered by zero *) + | Some (idx, value) -> + if idx = (num_cols m - 1) then + let () = Printf.printf "After rref_vec there is no normalization\n " in None + else + let normalized_v = V.map_f_preserves_zero (fun x -> x /: value) v_after_elim in + let res = insert_v_according_to_piv m normalized_v idx pivot_positions in + let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in + Some res + (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) (*m must be in rref form and contain the same num of cols as v*) (*If m is empty then v is simply normalized and returned*) (* TODO: OPTIMIZE! *) - let rref_vec m v = + (*let rref_vec m v = let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in match normalize @@ append_matrices m (init_with_vec v) with | Some res -> let () = Printf.printf "After rref_vec, before removing zero rows, we have m:\n%s\n" (show res) in Some (remove_zero_rows res) - | None -> let () = Printf.printf "After rref_vec there is no normalization\n " in None + | None -> let () = Printf.printf "After rref_vec there is no normalization\n " in None*) (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) @@ -280,18 +330,18 @@ module ListMatrix: AbstractMatrix = in let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in if num_rows m1 > num_rows m2 then false else - let rec is_covered_by_helper m1 m2 = - match m1 with - | [] -> true - | v1::vs1 -> - let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in - match first_non_zero with - | None -> true (* vs1 must also be zero-vectors because of rref *) - | Some (idx, _) -> - let linearly_indep = is_linearly_independent_rref v1 m2 in - if linearly_indep then false else is_covered_by_helper vs1 m2 - in is_covered_by_helper m1 m2 - + let rec is_covered_by_helper m1 m2 = + match m1 with + | [] -> true + | v1::vs1 -> + let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in + match first_non_zero with + | None -> true (* vs1 must also be zero-vectors because of rref *) + | Some (idx, _) -> + let linearly_indep = is_linearly_independent_rref v1 m2 in + if linearly_indep then false else is_covered_by_helper vs1 m2 + in is_covered_by_helper m1 m2 + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 1b31bfe2c7..7e8e5612e6 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -203,6 +203,12 @@ module SparseVector: AbstractVector = else find_zero_or_val xs idx in find_zero_or_val v.entries (-1) + let find_first_non_zero v = + if v.entries = [] then None + else Some (List.hd v.entries) + + let find_first_non_zero v = Timing.wrap "find_first_non_zero" (find_first_non_zero) v + let map f v = of_list (List.map f (to_list v)) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index f52f6eadbb..11b33df151 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -49,6 +49,8 @@ sig (* Returns optional tuple of position and value which was found*) val findi_val_opt: (num -> bool) -> t -> (int * num) Option.t + val find_first_non_zero : t -> (int * num) option + val find_opt: (num -> bool) -> t -> num Option.t val map: (num -> num) -> t -> t From c9be718cac1b1c2919801cf6b16a7f93592c75ac Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Fri, 13 Dec 2024 18:13:05 +0100 Subject: [PATCH 119/150] new rref_vec should be faster --- .../sparseImplementation/listMatrix.ml | 70 +++++++++++++++---- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 02d9896a7b..8a5313760f 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -218,10 +218,52 @@ module ListMatrix: AbstractMatrix = let m' = main_loop m m 0 0 in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) - let rref_vec m v = + let get_pivot_positions (m : t) : (int * int) list = + List.rev @@ List.fold_lefti ( + fun acc i row -> match V.find_first_non_zero row with + | None -> acc + | Some (pivot_col, _) -> (i, pivot_col) :: acc + ) [] m + + (* Inserts the vector v with pivot at piv_idx at the correct position in m. m has to be in rref form. *) + let insert_v_according_to_piv m v piv_idx pivot_positions = + match List.find_opt (fun (row_idx, piv_col) -> piv_col > piv_idx) pivot_positions with + | None -> append_row m v + | Some (row_idx, _) -> let (before, after) = List.split_at row_idx m in + before @ (v :: after) + + let rref_vec (m : t) (v : V.t) : t option = + if is_empty m then (* In this case, v is normalized and returned *) + match V.find_first_non_zero v with + | None -> None + | Some (_, value) -> + let normalized_v = V.map_f_preserves_zero (fun x -> x /: value) v in + Some (init_with_vec normalized_v) + else (* We try to normalize v and check if a contradiction arises. If not, we insert v at the appropriate place in m (depending on the pivot) *) + let pivot_positions = get_pivot_positions m in + let v_after_elim = List.fold_left ( + fun acc (row_idx, pivot_position) -> + let v_at_piv = V.nth acc pivot_position in + if v_at_piv =: A.zero then + acc + else + let piv_row = List.nth m row_idx in + sub_scaled_row acc piv_row v_at_piv + ) v pivot_positions + in + match V.find_first_non_zero v_after_elim with (* now we check for contradictions and finally insert v *) + | None -> Some m (* v is zero vector and was therefore already covered by zero *) + | Some (idx, value) -> + if idx = (num_cols m - 1) then + None + else + let normalized_v = V.map_f_preserves_zero (fun x -> x /: value) v_after_elim in + Some (insert_v_according_to_piv m normalized_v idx pivot_positions) + + (*let rref_vec m v = match normalize @@ append_matrices m (init_with_vec v) with - | Some m -> Some (remove_zero_rows m) | None -> None + | Some m -> Some (remove_zero_rows m) *) let rref_vec m v = Timing.wrap "rref_vec" (rref_vec m) v @@ -254,18 +296,18 @@ module ListMatrix: AbstractMatrix = is_linearly_independent_rref new_v m' in if num_rows m1 > num_rows m2 then false else - let rec is_covered_by_helper m1 m2 = - match m1 with - | [] -> true - | v1::vs1 -> - let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in - match first_non_zero with - | None -> true (* vs1 must also be zero-vectors because of rref *) - | Some (idx, _) -> - let linearly_indep = is_linearly_independent_rref v1 m2 in - if linearly_indep then false else is_covered_by_helper vs1 m2 - in is_covered_by_helper m1 m2 - + let rec is_covered_by_helper m1 m2 = + match m1 with + | [] -> true + | v1::vs1 -> + let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in + match first_non_zero with + | None -> true (* vs1 must also be zero-vectors because of rref *) + | Some (idx, _) -> + let linearly_indep = is_linearly_independent_rref v1 m2 in + if linearly_indep then false else is_covered_by_helper vs1 m2 + in is_covered_by_helper m1 m2 + let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 let find_opt f m = From fb1f36a0812e72d897f51ce058c1da38a0c4e9f6 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Fri, 13 Dec 2024 18:17:52 +0100 Subject: [PATCH 120/150] removed files with debug logs that I pushed by accident --- array.txt | 2150 -------------------------------------------------- rref_vec.txt | 1256 ----------------------------- sparse.txt | 1294 ------------------------------ 3 files changed, 4700 deletions(-) delete mode 100644 array.txt delete mode 100644 rref_vec.txt delete mode 100644 sparse.txt diff --git a/array.txt b/array.txt deleted file mode 100644 index 215bda4a77..0000000000 --- a/array.txt +++ /dev/null @@ -1,2150 +0,0 @@ -./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set sem.int.signed_overflow assume_none tests/regression/77-lin2vareq/20-function_call2.c -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -Matrix in Domain m: - -Switched Matrix in Domain switched_m: - -Before normalizing we have m: -After normalizing we have m: -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -After affineEq_vec m: -[1 0 0 0 ] - -Before Matrix.rref_vec x: - b: -[-1 1 0 0 ] - -Before rref_vec we have m: -v: [-1 1 0 0 ] - -Before normalizing we have m: -[-1 1 0 0 ] -After normalizing we have m: -[1 -1 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 -1 0 0 ] - -After affineEq_vec m: -[0 1 0 0 ] - -Before reduce_col 2 of m: -[1 -1 0 0 ] - -After reduce_col 2 of m: -[1 -1 0 0 ] - -Before Matrix.rref_vec x: -[1 -1 0 0 ] - b: -[0 -1 1 0 ] - -Before rref_vec we have m: -[1 -1 0 0 ] -v: [0 -1 1 0 ] - -Before normalizing we have m: -[1 -1 0 0 ] -[0 -1 1 0 ] -After normalizing we have m: -[1 0 -1 0 ] -[0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 -1 0 ] -[0 1 -1 0 ] - -After affineEq_vec m: -[0 1 0 0 0 0 0 ] - -Before reduce_col 0 of m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After reduce_col 0 of m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - b: -[1 -1 0 0 0 0 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -v: [1 -1 0 0 0 0 0 ] - -Before normalizing we have m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[1 -1 0 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 1 0 0 0 ] - -Before reduce_col 2 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After reduce_col 2 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - b: -[0 0 1 -1 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -v: [0 0 1 -1 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 1 -1 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 1 0 ] - -Before reduce_col 4 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After reduce_col 4 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - b: -[0 0 0 0 1 -1 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -v: [0 0 0 0 1 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -Before dim_remove m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -Before reduce_col 1 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 1 -1 0 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 1 -1 0 ] - -After reduce_col 5 of m: -[1 0 0 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -After dim_remove m': -[1 0 -1 0 ] -[0 1 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before assign_var_parallel m: -[|x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] -After affineEq_vec m: -[0 0 0 0 1 0 0 0 0 0 ] - -Before reduce_col 0 of m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After reduce_col 0 of m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - b: -[1 0 0 0 -1 0 0 0 0 0 ] - -Before rref_vec we have m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -v: [1 0 0 0 -1 0 0 0 0 0 ] - -Before normalizing we have m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -[1 0 0 0 -1 0 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 1 0 0 0 ] - -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - b: -[0 1 0 0 0 0 -1 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -v: [0 1 0 0 0 0 -1 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -[0 1 0 0 0 0 -1 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 0 1 0 ] - -Before reduce_col 2 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After reduce_col 2 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - b: -[0 0 1 0 0 0 0 0 -1 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -v: [0 0 1 0 0 0 0 0 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After assign_var_parallel multi_t: -[|0'-z#324#arg=0; 1'-z#324#arg=0; 2'-z#324#arg=0; x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] -Matrix in Domain m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before set_col m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Switched Matrix in Domain switched_m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before dim_remove m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After dim_remove m': -[1 0 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [1 0 -1 0 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[1 0 -1 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [-1 0 1 0 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[-1 0 1 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [0 0 -1 0 1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 -1 0 1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [0 0 1 0 -1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 1 0 -1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [1 0 0 0 -1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[1 0 0 0 -1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [-1 0 0 0 1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[-1 0 0 0 1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 8 ] - -Before reduce_col 0 of m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 0 of m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - b: -[1 0 0 0 0 0 0 8 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -v: [1 0 0 0 0 0 0 8 ] - -Before normalizing we have m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -[1 0 0 0 0 0 0 8 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before dim_remove m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] - -After dim_remove m': -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 1 0 0 0 0 0 ] - -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 -1 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] - b: -[0 1 -1 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] -v: [0 1 -1 0 0 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] -[0 1 -1 0 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 -1 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 -1 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -forget_vars m: -[|#ret-8=0; x#322#arg-x#327=0; y#323#arg-z#324#arg=0|]Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 1 -1 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -After affineEq_vec m: -[0 0 0 0 1 0 0 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 8 ] - b: -[0 0 0 1 -1 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 8 ] -v: [0 0 0 1 -1 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] - -forget_vars m: -[|#ret-8=0; y#323#arg-y#328=0|]Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 1 0 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 8 ] - b: -[0 0 0 0 0 1 -1 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 8 ] -v: [0 0 0 0 0 1 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] - -forget_vars m: -[|#ret-8=0; z#324#arg-z#329=0|]Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] - -Before dim_remove m: -[1 0 0 0 0 0 0 8 ] -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] - -After dim_remove m': -[1 0 0 0 8 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] - -Before rref_matrix m1 m2 -m1: [0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -m2: [1 0 0 0 8 ] - -Before normalizing we have m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -[1 0 0 0 8 ] -After normalizing we have m: -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -After rref_matrix m, before removing zero rows: - [1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -meet a: [|x#327-z#329=0; y#328-z#329=0|] b: [|#ret-8=0|] -> [|#ret-8=0; x#327-z#329=0; y#328-z#329=0|] -Before dim_remove m: -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -Before reduce_col 0 of m: -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After reduce_col 0 of m: -[0 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -Before del_cols cols_length=1 -m: -[0 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After dim_remove m': -[1 0 -1 0 ] -[0 1 -1 0 ] -Before del_cols cols_length=1 -m: -[0 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 ] - -Before reduce_col 0 of m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After reduce_col 0 of m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - b: -[1 0 0 0 0 ] - -Before rref_vec we have m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -v: [1 0 0 0 0 ] - -Before normalizing we have m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -[1 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -Before dim_remove m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -Before reduce_col 1 of m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 1 -1 0 ] - -Before reduce_col 2 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 1 -1 0 ] - -After reduce_col 2 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -After dim_remove m': -[1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -After affineEq_vec m: -[1 0 0 0 ] - -Before Matrix.rref_vec x: - b: -[-1 1 0 0 ] - -Before rref_vec we have m: -v: [-1 1 0 0 ] - -Before normalizing we have m: -[-1 1 0 0 ] -After normalizing we have m: -[1 -1 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 -1 0 0 ] - -After affineEq_vec m: -[0 1 0 0 ] - -Before reduce_col 2 of m: -[1 -1 0 0 ] - -After reduce_col 2 of m: -[1 -1 0 0 ] - -Before Matrix.rref_vec x: -[1 -1 0 0 ] - b: -[0 -1 1 0 ] - -Before rref_vec we have m: -[1 -1 0 0 ] -v: [0 -1 1 0 ] - -Before normalizing we have m: -[1 -1 0 0 ] -[0 -1 1 0 ] -After normalizing we have m: -[1 0 -1 0 ] -[0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 -1 0 ] -[0 1 -1 0 ] - -After affineEq_vec m: -[0 1 0 0 0 0 0 ] - -Before reduce_col 0 of m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After reduce_col 0 of m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - b: -[1 -1 0 0 0 0 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -v: [1 -1 0 0 0 0 0 ] - -Before normalizing we have m: -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[1 -1 0 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 1 0 0 0 ] - -Before reduce_col 2 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After reduce_col 2 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - b: -[0 0 1 -1 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -v: [0 0 1 -1 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 1 -1 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 1 0 ] - -Before reduce_col 4 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -After reduce_col 4 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] - b: -[0 0 0 0 1 -1 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -v: [0 0 0 0 1 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -Before dim_remove m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -Before reduce_col 1 of m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 1 -1 0 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 1 -1 0 ] - -After reduce_col 5 of m: -[1 0 0 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -After dim_remove m': -[1 0 -1 0 ] -[0 1 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 -1 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before assign_var_parallel m: -[|x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] -After affineEq_vec m: -[0 0 0 0 1 0 0 0 0 0 ] - -Before reduce_col 0 of m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After reduce_col 0 of m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - b: -[1 0 0 0 -1 0 0 0 0 0 ] - -Before rref_vec we have m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -v: [1 0 0 0 -1 0 0 0 0 0 ] - -Before normalizing we have m: -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -[1 0 0 0 -1 0 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 1 0 0 0 ] - -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - b: -[0 1 0 0 0 0 -1 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -v: [0 1 0 0 0 0 -1 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -[0 1 0 0 0 0 -1 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 0 1 0 ] - -Before reduce_col 2 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After reduce_col 2 of m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - b: -[0 0 1 0 0 0 0 0 -1 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -v: [0 0 1 0 0 0 0 0 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After assign_var_parallel multi_t: -[|0'-z#324#arg=0; 1'-z#324#arg=0; 2'-z#324#arg=0; x#322#arg-z#324#arg=0; y#323#arg-z#324#arg=0|] -Matrix in Domain m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before set_col m: -[1 0 0 0 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 0 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After set_col m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Switched Matrix in Domain switched_m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before dim_remove m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -After dim_remove m': -[1 0 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 1 0 0 0 0 -1 0 ] -[0 1 0 0 0 1 0 0 -1 0 ] -[0 0 1 0 0 0 0 1 -1 0 ] -[0 0 0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 1 0 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [1 0 -1 0 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[1 0 -1 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [-1 0 1 0 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[-1 0 1 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [0 0 -1 0 1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 -1 0 1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [0 0 1 0 -1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 1 0 -1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [1 0 0 0 -1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[1 0 0 0 -1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -v: [-1 0 0 0 1 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[-1 0 0 0 1 0 0 ] -After normalizing we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 -1 0 ] -[0 1 0 0 0 -1 0 ] -[0 0 1 0 0 -1 0 ] -[0 0 0 1 0 -1 0 ] -[0 0 0 0 1 -1 0 ] -[0 0 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 8 ] - -Before reduce_col 0 of m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 0 of m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - b: -[1 0 0 0 0 0 0 8 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -v: [1 0 0 0 0 0 0 8 ] - -Before normalizing we have m: -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -[1 0 0 0 0 0 0 8 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before dim_remove m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 0 -1 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 1 0 0 -1 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] - -After dim_remove m': -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 0 1 0 -1 0 ] -[0 0 0 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 1 0 0 0 0 0 ] - -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 1 0 0 0 -1 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] - b: -[0 1 -1 0 0 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] -v: [0 1 -1 0 0 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] -[0 1 -1 0 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 -1 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 1 -1 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -forget_vars m: -[|#ret-8=0; x#322#arg-x#327=0; y#323#arg-z#324#arg=0|]Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 1 -1 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] -[0 0 0 1 0 -1 0 0 ] - -After affineEq_vec m: -[0 0 0 0 1 0 0 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 0 -1 0 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 8 ] - b: -[0 0 0 1 -1 0 0 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 8 ] -v: [0 0 0 1 -1 0 0 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] - -forget_vars m: -[|#ret-8=0; y#323#arg-y#328=0|]Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 1 -1 0 0 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 1 0 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -Before Matrix.rref_vec x: -[1 0 0 0 0 0 0 8 ] - b: -[0 0 0 0 0 1 -1 0 ] - -Before rref_vec we have m: -[1 0 0 0 0 0 0 8 ] -v: [0 0 0 0 0 1 -1 0 ] - -Before normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] -After normalizing we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] - -forget_vars m: -[|#ret-8=0; z#324#arg-z#329=0|]Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 1 -1 0 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] -[0 0 0 0 0 0 0 0 ] - -Before dim_remove m: -[1 0 0 0 0 0 0 8 ] -Before reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 1 of m: -[1 0 0 0 0 0 0 8 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 3 of m: -[1 0 0 0 0 0 0 8 ] - -Before reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -After reduce_col 5 of m: -[1 0 0 0 0 0 0 8 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] - -After dim_remove m': -[1 0 0 0 8 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 0 0 0 8 ] - -Before rref_matrix m1 m2 -m1: [0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -m2: [1 0 0 0 8 ] - -Before normalizing we have m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -[1 0 0 0 8 ] -After normalizing we have m: -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -After rref_matrix m, before removing zero rows: - [1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -meet a: [|x#327-z#329=0; y#328-z#329=0|] b: [|#ret-8=0|] -> [|#ret-8=0; x#327-z#329=0; y#328-z#329=0|] -Before dim_remove m: -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -Before reduce_col 0 of m: -[1 0 0 0 8 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After reduce_col 0 of m: -[0 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -Before del_cols cols_length=1 -m: -[0 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After dim_remove m': -[1 0 -1 0 ] -[0 1 -1 0 ] -Before del_cols cols_length=1 -m: -[0 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After affineEq_vec m: -[0 0 0 0 0 ] - -Before reduce_col 0 of m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After reduce_col 0 of m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - b: -[1 0 0 0 0 ] - -Before rref_vec we have m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -v: [1 0 0 0 0 ] - -Before normalizing we have m: -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -[1 0 0 0 0 ] -After normalizing we have m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -After rref_vec, before removing zero rows, we have m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -Before dim_remove m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] -Before reduce_col 1 of m: -[1 0 0 0 0 ] -[0 1 0 -1 0 ] -[0 0 1 -1 0 ] - -After reduce_col 1 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 1 -1 0 ] - -Before reduce_col 2 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 1 -1 0 ] - -After reduce_col 2 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -Before reduce_col 3 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -After reduce_col 3 of m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -Before del_cols cols_length=3 -m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -After dim_remove m': -[1 0 ] -Before del_cols cols_length=3 -m: -[1 0 0 0 0 ] -[0 0 0 0 0 ] -[0 0 0 0 0 ] - -[Info][Deadcode] Logical lines of code (LLoC) summary: - live: 10 - dead: 0 - total lines: 10 -See result/index.xml diff --git a/rref_vec.txt b/rref_vec.txt deleted file mode 100644 index 4cccc943b1..0000000000 --- a/rref_vec.txt +++ /dev/null @@ -1,1256 +0,0 @@ -./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set ana.relation.privatization top --set sem.int.signed_overflow assume_none tests/regression/63-affeq/03-guard-check.c -v -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -Matrix in Domain m: - -Switched Matrix in Domain switched_m: - -Before normalizing we have m: -After normalizing we have m: -Before add_empty_columns m: -indices: 0,0,0,0,0,0, -After add_empty_columns m: - -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -After affineEq_vec m: -[0 0 0 0 0 0 0 ] - -Before Matrix.rref_vec x: - b: -[0 1 0 0 0 0 0 ] - -Before rref_vec we have m: -v: [0 1 0 0 0 0 0 ] - -After rref_vec, before removing zero rows, we have m: -[0 1 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 ] - -Before reduce_col 2 of m: -[0 1 0 0 0 0 0 ] - -After reduce_col 2 of m: -[0 1 0 0 0 0 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 0 ] - b: -[0 0 1 0 0 0 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 0 ] -v: [0 0 1 0 0 0 0 ] - -pivot positions are: (0,1) - -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 ] - -Before reduce_col 5 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - -After reduce_col 5 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - b: -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -v: [0 0 0 0 0 1 0 ] - -pivot positions are: (0,1)(1,2) - -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After affineEq_vec m: -[0 0 0 1 1 0 0 ] - -Before reduce_col 0 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 0 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - b: -[1 0 0 -1 -1 0 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,1)(1,2)(2,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 -1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 -1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 -1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before map2i m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] -v:[-1 0 0 0 ] - -After map2i m: -[1 0 0 -2 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before remove_row 3 of m: -[1 0 0 -2 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before keep_vals: -col_a: [-1 0 0 0 ] - col_b: [-1 0 0 0 ] - -After keep_vals: -col_a: [-1 0 0 ] - col_b: [-1 0 0 ] - -Before keep_vals: -col_a: [0 0 0 0 ] - col_b: [0 0 0 0 ] - -After keep_vals: -col_a: [0 0 0 0 ] - col_b: [0 0 0 0 ] - -join a: [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] b: [|f#303-x#301-y#302=0; i#298=0; k#299=0; x#301=0; z#300=0|] -> [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [2 0 0 -2 -2 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 2 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-2 0 0 2 2 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -2 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before dim_remove m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -Before reduce_col 0 of m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 0 of m: -[0 0 0 0 0 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 1 of m: -[0 0 0 0 0 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 1 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 2 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 2 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 3 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 3 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 4 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 4 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 5 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 5 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before del_cols cols_length=6 -m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -After dim_remove m': -Before del_cols cols_length=6 -m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before add_empty_columns m: -indices: 0,0,0,0,0,0, -After add_empty_columns m: - -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -After affineEq_vec m: -[0 0 0 0 0 0 0 ] - -Before Matrix.rref_vec x: - b: -[0 1 0 0 0 0 0 ] - -Before rref_vec we have m: -v: [0 1 0 0 0 0 0 ] - -After rref_vec, before removing zero rows, we have m: -[0 1 0 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 ] - -Before reduce_col 2 of m: -[0 1 0 0 0 0 0 ] - -After reduce_col 2 of m: -[0 1 0 0 0 0 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 0 ] - b: -[0 0 1 0 0 0 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 0 ] -v: [0 0 1 0 0 0 0 ] - -pivot positions are: (0,1) - -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - -After affineEq_vec m: -[0 0 0 0 0 0 0 ] - -Before reduce_col 5 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - -After reduce_col 5 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] - b: -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -v: [0 0 0 0 0 1 0 ] - -pivot positions are: (0,1)(1,2) - -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After affineEq_vec m: -[0 0 0 1 1 0 0 ] - -Before reduce_col 0 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 0 of m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before Matrix.rref_vec x: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - b: -[1 0 0 -1 -1 0 0 ] - -Before rref_vec we have m: -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,1)(1,2)(2,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 -1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 -1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 -1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [0 0 0 1 0 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before map2i m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] -v:[-1 0 0 0 ] - -After map2i m: -[1 0 0 -2 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before remove_row 3 of m: -[1 0 0 -2 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 1 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before keep_vals: -col_a: [-1 0 0 0 ] - col_b: [-1 0 0 0 ] - -After keep_vals: -col_a: [-1 0 0 ] - col_b: [-1 0 0 ] - -Before keep_vals: -col_a: [0 0 0 0 ] - col_b: [0 0 0 0 ] - -After keep_vals: -col_a: [0 0 0 0 ] - col_b: [0 0 0 0 ] - -join a: [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] b: [|f#303-x#301-y#302=0; i#298=0; k#299=0; x#301=0; z#300=0|] -> [|f#303-x#301-y#302=0; i#298=0; k#299=0; z#300=0|] -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [2 0 0 -2 -2 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 2 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-2 0 0 2 2 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -2 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [1 0 0 -1 -1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is 1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before rref_vec we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -v: [-1 0 0 1 1 0 0 ] - -pivot positions are: (0,0)(1,1)(2,2)(3,5) - -v_at_piv is -1 -piv row is: [1 0 0 -1 -1 0 0 ] - -scaled row is: [0 0 0 0 0 0 0 ] - -v_at_piv is 0 -v_at_piv is 0 -v_at_piv is 0 -After rref_vec, before removing zero rows, we have m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before dim_remove m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] -Before reduce_col 0 of m: -[1 0 0 -1 -1 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 0 of m: -[0 0 0 0 0 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 1 of m: -[0 0 0 0 0 0 0 ] -[0 1 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 1 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 2 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 1 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 2 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 3 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 3 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 4 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 4 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -Before reduce_col 5 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 1 0 ] - -After reduce_col 5 of m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -Before del_cols cols_length=6 -m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -After dim_remove m': -Before del_cols cols_length=6 -m: -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] -[0 0 0 0 0 0 0 ] - -[Info][Deadcode] Logical lines of code (LLoC) summary: - live: 23 - dead: 0 - total lines: 23 -[Warning][Deadcode][CWE-571] condition 'i == 0' is always true (tests/regression/63-affeq/03-guard-check.c:16:9-16:15) -[Warning][Deadcode][CWE-571] condition 'i != 1' is always true (tests/regression/63-affeq/03-guard-check.c:23:9-23:15) -[Warning][Deadcode][CWE-571] condition 'i > -1' is always true (tests/regression/63-affeq/03-guard-check.c:28:9-28:15) -[Warning][Deadcode][CWE-571] condition 'i >= -1' is always true (tests/regression/63-affeq/03-guard-check.c:35:9-35:16) -See result/index.xml diff --git a/sparse.txt b/sparse.txt deleted file mode 100644 index 4a98bd2d95..0000000000 --- a/sparse.txt +++ /dev/null @@ -1,1294 +0,0 @@ -./goblint --enable warn.debug --enable dbg.regression --set ana.activated[+] affeq --set sem.int.signed_overflow assume_none --set ana.relation.privatization top tests/regression/63-affeq/01-rel_simple.c -v -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -Matrix in Domain m: - -Switched Matrix in Domain switched_m: - -Before normalizing we have m: -After normalizing we have m: -Before add_empty_columns m: - -After add_empty_columns m: - -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -After affineEq_vec m: -[ 0 0 0 2] - -Before Matrix.rref_vec x: - b: -[ 1 0 0 2] - -Before rref_vec we have m: -v: [ 1 0 0 2] - -Before normalizing we have m: -[ 1 0 0 2] -After normalizing we have m: -[ 1 0 0 2] -After affineEq_vec m: -[ 0 0 1 5] - -Before reduce_col 1 of m: -[ 1 0 0 2] - -After reduce_col 1 of m: -[ 1 0 0 2] - -Before Matrix.rref_vec x: -[ 1 0 0 2] - b: -[ 0 1 -1 5] - -Before rref_vec we have m: -[ 1 0 0 2] -v: [ 0 1 -1 5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -After affineEq_vec m: -[ 0 0 1 5] - -Before reduce_col 1 of m: -[ 1 0 0 2] - -After reduce_col 1 of m: -[ 1 0 0 2] - -Before Matrix.rref_vec x: -[ 1 0 0 2] - b: -[ 0 1 -1 5] - -Before rref_vec we have m: -[ 1 0 0 2] -v: [ 0 1 -1 5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -Before rref_vec we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -v: [ 0 -1 0 -6] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 -1 0 -6] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 0 -1 -1] -Before rref_vec we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -v: [ 0 1 0 6] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 1 0 6] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -v: [ 0 -1 1 -5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 -1 1 -5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 0 0 0] -Before rref_vec we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -v: [ 0 1 -1 5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 1 -1 5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -[ 0 0 0 0] -After affineEq_vec m: -[ 0 0 0 3] - -Before reduce_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -After reduce_col 0 of m: -[ 0 0 0 0] -[ 0 1 -1 5] - -Before Matrix.rref_vec x: -[ 0 1 -1 5] - b: -[ 1 0 0 3] - -Before rref_vec we have m: -[ 0 1 -1 5] -v: [ 1 0 0 3] - -Before normalizing we have m: -[ 0 1 -1 5] -[ 1 0 0 3] -After normalizing we have m: -[ 1 0 0 3] -[ 0 1 -1 5] -After affineEq_vec m: -[ 0 1 0 3] - -get_col 1 of m: -[ 1 0 0 3] -[ 0 1 -1 5] - -[ 0 1] - -Before map2 we have m: -[ 1 0 0 3] -[ 0 1 -1 5] - -After map2 we have m: -[ 1 0 0 3] -[ 0 1 -1 8] - -Before normalizing we have m: -[ 1 0 0 3] -[ 0 1 -1 8] -After normalizing we have m: -[ 1 0 0 3] -[ 0 1 -1 8] -get_col 0 of m: -[ 1 0 0 3] -[ 0 1 -1 8] - -[ 1 0] - -get_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 1 0] - -get_col 1 of m: -[ 1 0 0 3] -[ 0 1 -1 8] - -[ 0 1] - -get_col 1 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 1] - -get_col 2 of m: -[ 1 0 0 3] -[ 0 1 -1 8] - -[ 0 -1] - -get_col 2 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 -1] - -Before keep_vals: -col_a: [ 0 -1] - col_b: [ 0 -1] - -After keep_vals: -col_a: [ 0 -1] - col_b: [ 0 -1] - -get_col 3 of m: -[ 1 0 0 3] -[ 0 1 -1 8] - -[ 3 8] - -get_col 3 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 2 5] - -Before keep_vals: -col_a: [ 2 5] - col_b: [ 3 8] - -After keep_vals: -col_a: [ 2 5] - col_b: [ 3 8] - -Before rev col_a: [ 2 5] - col_b: [ 3 8] - -After rev col_a: [ 5 2] - col_b: [ 8 3] - -Before multiply_by_t col_a: [ -1 -3] -Before map2i m: -[ 1 0 0 3] -[ 0 1 -1 8] -v:[ -1 -3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] - -Before multiply_by_t col_a: [ -1 -3] -Before map2i m: -[ 1 0 0 2] -[ 0 1 -1 5] -v:[ -1 -3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] - -join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|i#320-3=0; j#321-k#322-8=0|] -> [|3i#320-j#321+k#322-1=0|] -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -get_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 1 0] - -get_col 1 of m: -[ 1 -1/3 1/3 1/3] - -[ -1/3] - -get_col 1 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 1] - -Before map2i m: -[ 1 0 0 2] -[ 0 1 -1 5] -v:[ -1/3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -leq a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> true -Widen a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -get_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 1 0] - -get_col 1 of m: -[ 1 -1/3 1/3 1/3] - -[ -1/3] - -get_col 1 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 1] - -Before map2i m: -[ 1 0 0 2] -[ 0 1 -1 5] -v:[ -1/3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -After affineEq_vec m: -[ 0 0 1 5] - -Before reduce_col 1 of m: -[ 1 0 0 2] - -After reduce_col 1 of m: -[ 1 0 0 2] - -Before Matrix.rref_vec x: -[ 1 0 0 2] - b: -[ 0 1 -1 5] - -Before rref_vec we have m: -[ 1 0 0 2] -v: [ 0 1 -1 5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 1 0 0 100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 1 0 0 100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 1 1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 1 1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 -1 -1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 -1 -1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -After affineEq_vec m: -[ 1 0 0 1] - -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -Before map2 we have m: -[ 1 -1/3 1/3 1/3] - -After map2 we have m: -[ 1 -1/3 1/3 4/3] - -Before normalizing we have m: -[ 1 -1/3 1/3 4/3] -After normalizing we have m: -[ 1 -1/3 1/3 4/3] -After affineEq_vec m: -[ 0 1 0 3] - -get_col 1 of m: -[ 1 -1/3 1/3 4/3] - -[ -1/3] - -Before map2 we have m: -[ 1 -1/3 1/3 4/3] - -After map2 we have m: -[ 1 -1/3 1/3 1/3] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -get_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 1 0] - -get_col 1 of m: -[ 1 -1/3 1/3 1/3] - -[ -1/3] - -get_col 1 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 1] - -Before map2i m: -[ 1 0 0 2] -[ 0 1 -1 5] -v:[ -1/3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -join a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -leq a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -> true -Widen a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -join a: [|3i#320-j#321+k#322-1=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -After affineEq_vec m: -[ 0 0 1 5] - -Before reduce_col 1 of m: -[ 1 0 0 2] - -After reduce_col 1 of m: -[ 1 0 0 2] - -Before Matrix.rref_vec x: -[ 1 0 0 2] - b: -[ 0 1 -1 5] - -Before rref_vec we have m: -[ 1 0 0 2] -v: [ 0 1 -1 5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 1 0 0 100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 1 0 0 100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 1 1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 1 1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 -1 -1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 -1 -1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -After affineEq_vec m: -[ 1 0 0 1] - -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -Before map2 we have m: -[ 1 -1/3 1/3 1/3] - -After map2 we have m: -[ 1 -1/3 1/3 4/3] - -Before normalizing we have m: -[ 1 -1/3 1/3 4/3] -After normalizing we have m: -[ 1 -1/3 1/3 4/3] -After affineEq_vec m: -[ 0 1 0 3] - -get_col 1 of m: -[ 1 -1/3 1/3 4/3] - -[ -1/3] - -Before map2 we have m: -[ 1 -1/3 1/3 4/3] - -After map2 we have m: -[ 1 -1/3 1/3 1/3] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -get_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 1 0] - -get_col 1 of m: -[ 1 -1/3 1/3 1/3] - -[ -1/3] - -get_col 1 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 1] - -Before map2i m: -[ 1 0 0 2] -[ 0 1 -1 5] -v:[ -1/3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 1 0 0 100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 1 0 0 100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 1 1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 1 1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 -1 -1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 -1 -1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -Before dim_remove m: -[ 1 -1/3 1/3 1/3] -Before reduce_col 0 of m: -[ 1 -1/3 1/3 1/3] - -After reduce_col 0 of m: -[ 0 0 0 0] - -Before reduce_col 1 of m: -[ 0 0 0 0] - -After reduce_col 1 of m: -[ 0 0 0 0] - -Before reduce_col 2 of m: -[ 0 0 0 0] - -After reduce_col 2 of m: -[ 0 0 0 0] - -Before del_cols cols_length=3 sorted_length=3 -m: -[ 0 0 0 0] - -After dim_remove m': -Before del_cols cols_length=3 sorted_length=3 -m: -[ 0 0 0 0] - -Before add_empty_columns m: - -After add_empty_columns m: - -Before assign_var_parallel m: -⊤ -After assign_var_parallel multi_t: -⊤ -After affineEq_vec m: -[ 0 0 0 2] - -Before Matrix.rref_vec x: - b: -[ 1 0 0 2] - -Before rref_vec we have m: -v: [ 1 0 0 2] - -Before normalizing we have m: -[ 1 0 0 2] -After normalizing we have m: -[ 1 0 0 2] -After affineEq_vec m: -[ 0 0 1 5] - -Before reduce_col 1 of m: -[ 1 0 0 2] - -After reduce_col 1 of m: -[ 1 0 0 2] - -Before Matrix.rref_vec x: -[ 1 0 0 2] - b: -[ 0 1 -1 5] - -Before rref_vec we have m: -[ 1 0 0 2] -v: [ 0 1 -1 5] - -Before normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -After normalizing we have m: -[ 1 0 0 2] -[ 0 1 -1 5] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 1 0 0 100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 1 0 0 100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 1 1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 1 1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 -1 -1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 -1 -1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -[Warning][Assert] Assertion "(3 * i - j) + k == 1" is unknown. Expected: SUCCESS -> failed (tests/regression/63-affeq/01-rel_simple.c:13:9-13:44) -After affineEq_vec m: -[ 1 0 0 1] - -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -Before map2 we have m: -[ 1 -1/3 1/3 1/3] - -After map2 we have m: -[ 1 -1/3 1/3 4/3] - -Before normalizing we have m: -[ 1 -1/3 1/3 4/3] -After normalizing we have m: -[ 1 -1/3 1/3 4/3] -After affineEq_vec m: -[ 0 1 0 3] - -get_col 1 of m: -[ 1 -1/3 1/3 4/3] - -[ -1/3] - -Before map2 we have m: -[ 1 -1/3 1/3 4/3] - -After map2 we have m: -[ 1 -1/3 1/3 1/3] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -get_col 0 of m: -[ 1 -1/3 1/3 1/3] - -[ 1] - -get_col 0 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 1 0] - -get_col 1 of m: -[ 1 -1/3 1/3 1/3] - -[ -1/3] - -get_col 1 of m: -[ 1 0 0 2] -[ 0 1 -1 5] - -[ 0 1] - -Before map2i m: -[ 1 0 0 2] -[ 0 1 -1 5] -v:[ -1/3] - -After map2i m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -Before remove_row 1 of m: -[ 1 -1/3 1/3 1/3] -[ 0 1 -1 5] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 2 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -get_col 3 of m: -[ 1 -1/3 1/3 1/3] - -[ 1/3] - -Before keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -After keep_vals: -col_a: [ 1/3] - col_b: [ 1/3] - -join a: [|i#320-2=0; j#321-k#322-5=0|] b: [|3i#320-j#321+k#322-1=0|] -> [|3i#320-j#321+k#322-1=0|] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 1 0 0 100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 1 0 0 100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -1 0 0 -100] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -1 0 0 -100] -After normalizing we have m: -[ 1 -301/900 301/900 1/900] -[ 0 1/300 -1/300 299/300] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 0 0] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 0 0] -After normalizing we have m: -[ 1 -1/3 2/3 2/3] -[ 0 0 1 1] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ 3 -1 1 1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 3 -1 1 1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -Before rref_vec we have m: -[ 1 -1/3 1/3 1/3] -v: [ -3 1 -1 -1] - -Before normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ -3 1 -1 -1] -After normalizing we have m: -[ 1 -1/3 1/3 1/3] -[ 0 0 0 0] -[Warning][Assert] Assertion "(3 * i - j) + k == 1" is unknown. Expected: SUCCESS -> failed (tests/regression/63-affeq/01-rel_simple.c:17:5-17:40) -Before dim_remove m: -[ 1 -1/3 1/3 1/3] -Before reduce_col 0 of m: -[ 1 -1/3 1/3 1/3] - -After reduce_col 0 of m: -[ 0 0 0 0] - -Before reduce_col 1 of m: -[ 0 0 0 0] - -After reduce_col 1 of m: -[ 0 0 0 0] - -Before reduce_col 2 of m: -[ 0 0 0 0] - -After reduce_col 2 of m: -[ 0 0 0 0] - -Before del_cols cols_length=3 sorted_length=3 -m: -[ 0 0 0 0] - -After dim_remove m': -Before del_cols cols_length=3 sorted_length=3 -m: -[ 0 0 0 0] - -[Info][Deadcode] Logical lines of code (LLoC) summary: - live: 9 - dead: 0 - total lines: 9 -See result/index.xml From 0535677dcb85e0b6ba0d292fc44e259ee14314e4 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 13 Dec 2024 22:55:30 +0100 Subject: [PATCH 121/150] Add apply_with_c_f_preserves_zero --- .../affineEquality/arrayImplementation/arrayVector.ml | 2 ++ .../affineEquality/sparseImplementation/sparseVector.ml | 4 ++++ src/cdomains/affineEquality/vector.ml | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 0705853357..893bbda68b 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -133,4 +133,6 @@ module ArrayVector: AbstractVector = failwith "TODO / deprecated" let find_first_non_zero v = failwith "TODO" + + let apply_with_c_f_preserves_zero f c v = failwith "TODO" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index b895befc14..5294816914 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -183,6 +183,10 @@ module SparseVector: AbstractVector = if v.len <> v'.len then failwith "Unequal vector length" else of_list (List.map2 f (to_list v) (to_list v')) + let apply_with_c_f_preserves_zero f c v = + let entries' = List.filter_map (fun (idx, value) -> let new_val = f value c in if new_val =: A.zero then None else Some (idx, new_val)) v.entries in + {entries = entries'; len = v.len} + let apply_with_c f c v = (* TODO: optimize! *) of_list @@ List.map (fun value -> f value c) (to_list v) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 11b33df151..62a0229743 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -30,6 +30,8 @@ sig val apply_with_c: (num -> num -> num) -> num -> t -> t + val apply_with_c_f_preserves_zero: (num -> num -> num) -> num -> t -> t + val apply_with_c_with: (num -> num -> num) -> num -> t -> unit val zero_vec: int -> t From c776a2bd0a843f780ddf56ace28d774d0e683b9f Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Fri, 13 Dec 2024 22:58:44 +0100 Subject: [PATCH 122/150] Changed some calls in Domain to zero preserving --- src/cdomains/apron/affineEqualityDomain.apron.ml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 63f785a861..d832af53d5 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -97,17 +97,17 @@ struct | Binop (Add, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in - Vector.map2 (+:) v1 v2 + Vector.map2_f_preserves_zero (+:) v1 v2 | Binop (Sub, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in - Vector.map2 (+:) v1 (neg @@ v2) + Vector.map2_f_preserves_zero (+:) v1 (neg @@ v2) | Binop (Mul, e1, e2, _, _) -> let v1 = convert_texpr e1 in let v2 = convert_texpr e2 in begin match to_constant_opt v1, to_constant_opt v2 with - | _, Some c -> Vector.apply_with_c ( *:) c v1 - | Some c, _ -> Vector.apply_with_c ( *:) c v2 + | _, Some c -> Vector.apply_with_c_f_preserves_zero ( *:) c v1 + | Some c, _ -> Vector.apply_with_c_f_preserves_zero ( *:) c v2 | _, _ -> raise NotLinear end | Binop _ -> raise NotLinear @@ -302,10 +302,10 @@ struct let (x, y) = Vector.nth col_a i, Vector.nth col_b i in let r, diff = Vector.length col_a - (i + 1), x -: y in let a_r, b_r = Matrix.get_row a r, Matrix.get_row b r in - let col_a = Vector.map2 (-:) col_a col_b in + let col_a = Vector.map2_f_preserves_zero (-:) col_a col_b in let col_a = Vector.rev col_a in let multiply_by_t m t = - Matrix.map2i (fun i' x c -> if i' <= max then (let beta = c /: diff in Vector.map2 (fun u j -> u -: (beta *: j)) x t) else x) m col_a; + Matrix.map2i (fun i' x c -> if i' <= max then (let beta = c /: diff in Vector.map2_f_preserves_zero (fun u j -> u -: (beta *: j)) x t) else x) m col_a; in Matrix.remove_row (multiply_by_t a a_r) r, Matrix.remove_row (multiply_by_t b b_r) r, (max - 1) @@ -384,7 +384,7 @@ struct let j0 = Environment.dim_of_var env var in let a_j0 = Matrix.get_col x j0 in (*Corresponds to Axj0*) let b0 = Vector.nth b j0 in - let a_j0 = Vector.apply_with_c (/:) b0 a_j0 in (*Corresponds to Axj0/Bj0*) + let a_j0 = Vector.apply_with_c_f_preserves_zero (/:) b0 a_j0 in (*Corresponds to Axj0/Bj0*) let recalc_entries m rd_a = Matrix.map2 (fun x y -> Vector.map2i (fun j z d -> if j = j0 then y else if Vector.compare_length_with b (j + 1) > 0 then z -: y *: d From d3b18aa02d092e1df9f37d897dff241a063b6b52 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 14 Dec 2024 17:00:20 +0100 Subject: [PATCH 123/150] Change rref_matrix without append and normalize, still have to benchmark --- .../affineEquality/sparseImplementation/listMatrix.ml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 0dc0bf14ac..f0b9a08b32 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -302,11 +302,18 @@ module ListMatrix: AbstractMatrix = (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) (*TODO: OPTIMIZE!*) + (* let rref_matrix m1 m2 = let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in match normalize @@ append_matrices m1 m2 with | Some m -> let () = Printf.printf "After rref_matrix m, before removing zero rows:\n %s\n" (show m) in Some (remove_zero_rows m) | None -> let () = Printf.printf "No normalization for rref_matrix found" in None + *) + + let rref_matrix (m1 : t) (m2 : t) = + let big_m, small_m = if num_rows m1 > num_rows m2 then m1, m2 else m2, m1 in + fst @@ List.fold_while (fun acc _ -> Option.is_some acc) + (fun acc_big_m small -> rref_vec (Option.get acc_big_m) small ) (Some big_m) small_m let delete_row_with_pivots row pivots m2 = failwith "TODO" From eba9d498586c050fd2563d0ea637960972b19e3c Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 14 Dec 2024 17:12:25 +0100 Subject: [PATCH 124/150] Remove some warnings of deprecated code --- .../arrayImplementation/arrayVector.ml | 1 - .../sparseImplementation/listMatrix.ml | 38 ------------------- 2 files changed, 39 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 390ae07fdb..3d045c49aa 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -134,5 +134,4 @@ module ArrayVector: AbstractVector = let find_first_non_zero v = failwith "TODO" - end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index f0b9a08b32..7e9be147ae 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -85,9 +85,6 @@ module ListMatrix: AbstractMatrix = let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 - let sub_rows (minu : V.t) (subt : V.t) : V.t = - V.map2_f_preserves_zero (-:) minu subt - let div_row (row : V.t) (pivot : A.t) : V.t = V.map_f_preserves_zero (fun a -> a /: pivot) row @@ -174,18 +171,6 @@ module ListMatrix: AbstractMatrix = let init_with_vec v = [v] - let get_pivot_positions m = - List.mapi (fun i row -> V.findi (fun z -> z =: A.one) row) m - - let sub_rows (minu : V.t) (subt : V.t) : V.t = - V.map2_f_preserves_zero (-:) minu subt - - let div_row (row : V.t) (pivot : A.t) : V.t = - V.map_f_preserves_zero (fun a -> a /: pivot) row - - let swap_rows m j k = - List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m - let normalize m = let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in let col_count = num_cols m in @@ -287,7 +272,6 @@ module ListMatrix: AbstractMatrix = let () = Printf.printf "After rref_vec we have m:\n%s\n" (show res) in Some res - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) (*m must be in rref form and contain the same num of cols as v*) (*If m is empty then v is simply normalized and returned*) @@ -309,15 +293,11 @@ module ListMatrix: AbstractMatrix = | Some m -> let () = Printf.printf "After rref_matrix m, before removing zero rows:\n %s\n" (show m) in Some (remove_zero_rows m) | None -> let () = Printf.printf "No normalization for rref_matrix found" in None *) - let rref_matrix (m1 : t) (m2 : t) = let big_m, small_m = if num_rows m1 > num_rows m2 then m1, m2 else m2, m1 in fst @@ List.fold_while (fun acc _ -> Option.is_some acc) (fun acc_big_m small -> rref_vec (Option.get acc_big_m) small ) (Some big_m) small_m - let delete_row_with_pivots row pivots m2 = - failwith "TODO" - let is_covered_by m1 m2 = let rec is_linearly_independent_rref v m = let pivot_opt = V.findi_val_opt ((<>:) A.zero) v in @@ -369,44 +349,26 @@ module ListMatrix: AbstractMatrix = (*If m is empty then v is simply normalized and returned*) failwith "deprecated" - let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v let rref_with m = failwith "deprecated" let reduce_col_with m j = failwith "deprecated" - let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j - - - let rref_with m = Timing.wrap "rref_with" rref_with m - let normalize_with m = failwith "deprecated" - let normalize_with m = Timing.wrap "normalize_with" normalize_with m - - let set_col_with m new_col n = failwith "deprecated" - let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n - let map2_with f m v = failwith "deprecated" - let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v - let map2i_with f m v = failwith "deprecated" - let map2i_with f m v = Timing.wrap "map2i_with" (map2i_with f m) v - let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) failwith "deprecated" - - let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 - end \ No newline at end of file From dd0000eedd6e444dfae5f96517b60dbdd58c33e9 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 17 Dec 2024 15:23:45 +0100 Subject: [PATCH 125/150] Merge branch 'benchmarks' into master --- src/cdomains/affineEquality/sparseImplementation/listMatrix.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 3f910dafc0..9d951a9532 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -87,7 +87,7 @@ module ListMatrix: AbstractMatrix = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m let sub_scaled_row row1 row2 s = - V.map2_f_preserves_zero (fun x y -> x -: s *: y) row1 row2 + V.map2_f_preserves_zero (fun x y -> x -: (s *: y)) row1 row2 let reduce_col m j = if is_empty m then m From 2e80b94c1f75585a75a07d9efa1f7642518d010b Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 17 Dec 2024 15:37:32 +0100 Subject: [PATCH 126/150] removed second remove_nth --- .../sparseImplementation/sparseVector.ml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index f854bd550f..8994b2c20b 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -38,23 +38,6 @@ module SparseVector: AbstractVector = if n >= v.len then v else {entries = List.take_while (fun (idx, _) -> idx < n) v.entries; len=n} - - (* Maybe use the function below instead of this one ?*) - let remove_nth v n = - let dec_idx v = - List.map (fun (a,b) -> (a-1, b)) v - in - let rec remove_nth_vec v n = - match v with - | x::xs -> - if fst x = n then dec_idx xs else - if fst x > n then dec_idx (x::xs) else - x::(remove_nth_vec xs n) - | [] -> [] - in - if n >= v.len then v else (*could be left out but maybe performance??*) - {entries = remove_nth_vec v.entries n; len = v.len - 1} - (* TODO: Which of both remmove_nth should we use *) let remove_nth v n = if n >= v.len then failwith "Out of bounds" From 1fa998f7c947c48276e65c73d49522782112a3e8 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 17 Dec 2024 16:01:34 +0100 Subject: [PATCH 127/150] Remove deprecated _with functions from Vector and Matrix interface --- .../arrayImplementation/arrayMatrix.ml | 17 ++-------- .../arrayImplementation/arrayVector.ml | 8 ----- src/cdomains/affineEquality/matrix.ml | 14 -------- .../sparseImplementation/listMatrix.ml | 32 ------------------- .../sparseImplementation/sparseVector.ml | 25 --------------- src/cdomains/affineEquality/vector.ml | 19 +---------- 6 files changed, 4 insertions(+), 111 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index a3d1199be9..ac21c08fbe 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -265,13 +265,13 @@ module ArrayMatrix: AbstractMatrix = (*m must be in rref form and contain the same num of cols as v*) (*If m is empty then v is simply normalized and returned*) (*let v = V.to_array v in - if is_empty m then + if is_empty m then match Array.findi (fun x -> x <>: A.zero) v with | exception Not_found -> None | i -> if i = Array.length v - 1 then None else let v_i = v.(i) in Array.iteri (fun j x -> v.(j) <- x /: v_i) v; Some (init_with_vec @@ V.of_array v) - else + else let pivot_elements = get_pivot_positions m in rref_vec_helper m pivot_elements v*) normalize @@ append_row m v @@ -355,10 +355,7 @@ module ArrayMatrix: AbstractMatrix = m.(i) <- V.to_array @@ f (V.of_array m.(i)) (V.nth v i) done - (* Deprecated - let map2 f m v = - let f' x y = V.to_array @@ f (V.of_array x) y in Array.map2 f' m (V.to_array v) - *) + let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v let map2 f m v = let () = Printf.printf "Before map2 we have m:\n%s\n" (show m) in @@ -367,8 +364,6 @@ module ArrayMatrix: AbstractMatrix = let () = Printf.printf "After map2 we have m:\n%s\n" (show m') in m' - let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v - let map2i_with f m v = if num_rows m = V.length v then Array.iter2i (fun i x y -> m.(i) <- V.to_array @@ f i (V.of_array x) y) m (V.to_array v) @@ -379,12 +374,6 @@ module ArrayMatrix: AbstractMatrix = let map2i_with f m v = Timing.wrap "map2i_with" (map2i_with f m) v - (* Deprecated - let map2i f m v = - let f' x (i,y) = V.to_array @@ f i (V.of_array x) y in - let range_array = Array.init (V.length v) Fun.id in - Array.map2 f' m (Array.combine range_array (V.to_array v)) - *) let map2i f m v = let () = Printf.printf "Before map2i m:\n%sv:%s\n" (show m) (V.show v) in let m' = copy m in diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 75cfab93d5..735246ada0 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -63,8 +63,6 @@ module ArrayVector: AbstractVector = let f' i = uncurry (f i) in Array.mapi f' (Array.combine v1 v2) (* TODO: iter2i? *) - let map2i_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f i x y) v1 v2 - let find2i f v1 v2 = Array.findi (uncurry f) (Array.combine v1 v2) (* TODO: iter2i? *) @@ -72,14 +70,8 @@ module ArrayVector: AbstractVector = let of_array v = v - let apply_with_c_with f c v = Array.modify (fun x -> f x c) v - - let rev_with v = Array.rev_in_place v - let rev v = Array.rev v - let map_with f v = Array.modify f v - let map f v = Array.map f v let map2_with f v1 v2 = Array.iter2i (fun i x y -> v1.(i) <- f x y) v1 v2 diff --git a/src/cdomains/affineEquality/matrix.ml b/src/cdomains/affineEquality/matrix.ml index 3b45c12f91..0dffe8c44e 100644 --- a/src/cdomains/affineEquality/matrix.ml +++ b/src/cdomains/affineEquality/matrix.ml @@ -33,36 +33,22 @@ sig val reduce_col: t -> int -> t - val reduce_col_with: t -> int -> unit - val normalize: t -> t Option.t (*Gauss-Jordan Elimination to get matrix in reduced row echelon form (rref) + deletion of zero rows. None matrix has no solution*) - val normalize_with: t -> bool - val rref_vec: t -> vec -> t Option.t (* added to remove side effects in affineEqualityDomain*) - val rref_vec_with: t -> vec -> t Option.t - val rref_matrix: t -> t -> t Option.t (* this as well *) - val rref_matrix_with: t -> t -> t Option.t - val find_opt: (vec -> bool) -> t -> vec option val map2: (vec -> num -> vec) -> t -> vec -> t - val map2_with: (vec -> num -> vec) -> t -> vec -> unit - val map2: (vec -> num -> vec) -> t -> vec -> t (* why is this here twice??*) val map2i: (int -> vec-> num -> vec) -> t -> vec -> t - val map2i_with: (int -> vec -> num -> vec) -> t -> vec -> unit - val set_col: t -> vec -> int -> t - val set_col_with: t -> vec -> int -> t - val init_with_vec: vec -> t val remove_zero_rows: t -> t diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 9d951a9532..72fac804ea 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -307,36 +307,4 @@ module ListMatrix: AbstractMatrix = let map2 f m v = let vector_length = V.length v in List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m - - - (* ------------------------- Deprecated ------------------------*) - - let rref_vec_with m v = - (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) - (*m must be in rref form and contain the same num of cols as v*) - (*If m is empty then v is simply normalized and returned*) - failwith "deprecated" - - let rref_with m = - failwith "deprecated" - - let reduce_col_with m j = - failwith "deprecated" - - let normalize_with m = - failwith "deprecated" - - let set_col_with m new_col n = - failwith "deprecated" - - let map2_with f m v = - failwith "deprecated" - - let map2i_with f m v = - failwith "deprecated" - - let rref_matrix_with m1 m2 = - (*Similar to rref_vec_with but takes two matrices instead.*) - (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - failwith "deprecated" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 8994b2c20b..3c4a700f71 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -270,29 +270,4 @@ module SparseVector: AbstractVector = | x :: xs -> (A.to_string x) ^ " " ^ (list_str xs) in "["^list_str t^"\n" - - (* ------------------- Deprecated ------------------- *) - let mapi_with f v = - failwith "mapi_with deprecated" - - let map2i_with f v v' = - failwith "map2i_with deprecated" - - - let rev_with v = - failwith "rev_with deprecated" - - let map_with f v = - failwith "map_with deprecated" - - - let map2_with f v v' = - failwith "map2_with deprecated" - - let apply_with_c_with f m v = - failwith "apply_with_c_with deprecated" - - let set_nth_with f n num = ( - failwith "set_nth_with deprecated") - end diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 62a0229743..cf56a2da48 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -16,8 +16,6 @@ sig val set_nth: t -> int -> num -> t - val set_nth_with: t -> int -> num -> unit - val insert_val_at: int -> num -> t -> t val map_f_preserves_zero: (num -> num) -> t -> t @@ -32,8 +30,6 @@ sig val apply_with_c_f_preserves_zero: (num -> num -> num) -> num -> t -> t - val apply_with_c_with: (num -> num -> num) -> num -> t -> unit - val zero_vec: int -> t val is_zero_vec: t -> bool @@ -44,8 +40,6 @@ sig val map2: (num -> num -> num) -> t -> t -> t - val map2_with: (num -> num -> num) -> t -> t -> unit - val findi: (num -> bool) -> t -> int (* Returns optional tuple of position and value which was found*) @@ -57,8 +51,6 @@ sig val map: (num -> num) -> t -> t - val map_with: (num -> num) -> t -> unit - val map: (num -> num) -> t -> t val compare_length_with: t -> int -> int @@ -74,21 +66,12 @@ sig val exists: (num -> bool) -> t -> bool val exists2: (num -> num -> bool) -> t -> t -> bool - val rev: t -> t - - val rev_with: t -> unit - - val rev: t -> t - + val map2i: (int -> num -> num -> num) -> t -> t -> t - val map2i_with: (int -> num -> num -> num) -> t -> t -> unit - val mapi: (int -> num -> num) -> t -> t - val mapi_with: (int -> num -> num) -> t -> unit - val mapi: (int -> num -> num) -> t -> t val find2i: (num -> num -> bool) -> t -> t -> int From 1ea8040f690e464f10589fee47664a65517fdb7c Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Tue, 17 Dec 2024 16:02:15 +0100 Subject: [PATCH 128/150] Remove deprecated _with functions from Vector and Matrix interface --- src/cdomains/affineEquality/vector.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index cf56a2da48..b8f73d15b9 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -67,7 +67,7 @@ sig val exists2: (num -> num -> bool) -> t -> t -> bool val rev: t -> t - + val map2i: (int -> num -> num -> num) -> t -> t -> t val mapi: (int -> num -> num) -> t -> t @@ -88,5 +88,4 @@ sig (* Returns the part of the vector starting from index n*) val starting_from_nth : int -> t -> t - end \ No newline at end of file From fd5689abe6fbc056b823b4c5d7e82ff8e5bc204e Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 17 Dec 2024 16:23:33 +0100 Subject: [PATCH 129/150] commenting some functions --- .../sparseImplementation/listMatrix.ml | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 9d951a9532..eb46b17d3b 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -89,6 +89,7 @@ module ListMatrix: AbstractMatrix = let sub_scaled_row row1 row2 s = V.map2_f_preserves_zero (fun x y -> x -: (s *: y)) row1 row2 + (* Reduces the jth column with the last row that has a non-zero element in this column. *) let reduce_col m j = if is_empty m then m else @@ -101,7 +102,7 @@ module ListMatrix: AbstractMatrix = match (find_pivot (num_rows m - 1) (List.rev m)) with | None -> m (* column is already filled with zeroes *) | Some (row_idx, pivot) -> - let pivot_row = List.nth m row_idx in + let pivot_row = List.nth m row_idx in (* use the pivot row to reduce all entries in column j to zero, then "delete" the pivot row *) List.mapi (fun idx row -> if idx = row_idx then V.zero_vec (num_cols m) @@ -214,10 +215,12 @@ module ListMatrix: AbstractMatrix = let insert_v_according_to_piv m v piv_idx pivot_positions = match List.find_opt (fun (row_idx, piv_col) -> piv_col > piv_idx) pivot_positions with | None -> append_row m v - | Some (row_idx, _) -> let (before, after) = List.split_at row_idx m in + | Some (row_idx, _) -> let (before, after) = List.split_at row_idx m in (* TODO: Optimize *) before @ (v :: after) - let rref_vec (m : t) (v : V.t) : t option = + (* This function yields the same result as appending v to m, normalizing and removing zero rows would. *) + (* m must be in rref form and must contain the same number of columns as v *) + let rref_vec m v = if is_empty m then (* In this case, v is normalized and returned *) match V.find_first_non_zero v with | None -> None @@ -237,7 +240,7 @@ module ListMatrix: AbstractMatrix = ) v pivot_positions in match V.find_first_non_zero v_after_elim with (* now we check for contradictions and finally insert v *) - | None -> Some m (* v is zero vector and was therefore already covered by zero *) + | None -> Some m (* v is zero vector and was therefore already covered by m *) | Some (idx, value) -> if idx = (num_cols m - 1) then None @@ -245,30 +248,19 @@ module ListMatrix: AbstractMatrix = let normalized_v = V.map_f_preserves_zero (fun x -> x /: value) v_after_elim in Some (insert_v_according_to_piv m normalized_v idx pivot_positions) - (*let rref_vec m v = - match normalize @@ append_matrices m (init_with_vec v) with - | None -> None - | Some m -> Some (remove_zero_rows m) *) - let rref_vec m v = Timing.wrap "rref_vec" (rref_vec m) v - - (*Similar to rref_vec_with but takes two matrices instead.*) - (*ToDo Could become inefficient for large matrices since pivot_elements are always recalculated + many row additions*) - (*TODO: OPTIMIZE!*) - (* - let rref_matrix m1 m2 = - match normalize @@ append_matrices m1 m2 with - | Some m -> Some (remove_zero_rows m) - | None -> None - - *) + + (* This should yield the same result as appending m2 to m1, normalizing and removing zero rows. However, it is usually faster. *) + (* Both input matrices are assumed to be in rref form *) let rref_matrix (m1 : t) (m2 : t) = let big_m, small_m = if num_rows m1 > num_rows m2 then m1, m2 else m2, m1 in fst @@ List.fold_while (fun acc _ -> Option.is_some acc) - (fun acc_big_m small -> rref_vec (Option.get acc_big_m) small ) (Some big_m) small_m + (fun acc_big_m small -> rref_vec (Option.get acc_big_m) small ) (Some big_m) small_m (* TODO: pivot_positions are recalculated at each step, but since they need to be adjusted after each step it might not make sense to keep track of them here.*) let rref_matrix m1 m2 = Timing.wrap "rref_matrix" (rref_matrix m1) m2 + (* Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) + (* Both input matrices must be in rref form! *) let is_covered_by m1 m2 = let rec is_linearly_independent_rref v m = let pivot_opt = V.findi_val_opt ((<>:) A.zero) v in From 618643553ec58172ef43d4a46be7cad44b7004ca Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 17 Dec 2024 17:02:27 +0100 Subject: [PATCH 130/150] is_cons_vec --- .../arrayImplementation/arrayVector.ml | 22 ++++++++++--------- .../sparseImplementation/sparseVector.ml | 6 +++++ src/cdomains/affineEquality/vector.ml | 2 ++ .../apron/affineEqualityDomain.apron.ml | 5 ++--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 735246ada0..a95e764f16 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -57,6 +57,8 @@ module ArrayVector: AbstractVector = let is_zero_vec v = not (Array.exists (fun x -> x <>: A.zero) v) + let is_const_vec v = failwith "Never implemented!" + let nth = Array.get let map2i f v1 v2 = @@ -104,29 +106,29 @@ module ArrayVector: AbstractVector = let find_opt f v = - failwith "TODO" + failwith "Never implemented!" - let map_f_preserves_zero f v = failwith "TODO" - let map2_f_preserves_zero f v1 v2 = failwith "TODO" + let map_f_preserves_zero f v = failwith "Never implemented!" + let map2_f_preserves_zero f v1 v2 = failwith "Never implemented!" let fold_left_f_preserves_zero f acc v = - failwith "TODO" + failwith "Never implemented!" let fold_left2_f_preserves_zero f acc v v' = - failwith "TODO" + failwith "Never implemented!" let findi_val_opt f v = - failwith "TODO" + failwith "Never implemented!" let exists2 f v1 v1 = - failwith "TODO / deprecated" + failwith "Never implemented!" let starting_from_nth n v = - failwith "TODO / deprecated" + failwith "Never implemented!" let find_first_non_zero v = - failwith "TODO" + failwith "Never implemented!" let apply_with_c_f_preserves_zero f c v = - failwith "TODO" + failwith "Never implemented!" end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 3c4a700f71..6589296884 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -149,6 +149,12 @@ module SparseVector: AbstractVector = let is_zero_vec v = (v.entries = []) + let is_const_vec v = + match v.entries with + | [] -> false + | (xi,xv)::[] -> if xi = v.len - 1 then false else true + | _ -> false + let nth v n = (* Note: This exception HAS TO BE THROWN! It is expected by the domain *) if n >= v.len then raise (Invalid_argument "Cannot access vector element (out of bounds)") else diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index b8f73d15b9..61a18ff7c2 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -34,6 +34,8 @@ sig val is_zero_vec: t -> bool + val is_const_vec: t -> bool + val nth: t -> int -> num val length: t -> int diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index d832af53d5..15fc35fa59 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -66,9 +66,8 @@ struct let open Apron.Texpr1 in let exception NotLinear in let zero_vec = Vector.zero_vec @@ Environment.size t.env + 1 in - let neg v = Vector.map Mpqf.neg v in - let is_const_vec v = Vector.compare_length_with (Vector.filteri (fun i x -> (*Inefficient*) - Vector.compare_length_with v (i + 1) > 0 && x <>: Mpqf.zero) v) 1 = 0 + let neg v = Vector.map_f_preserves_zero Mpqf.neg v in + let is_const_vec = Vector.is_const_vec in let rec convert_texpr = function (*If x is a constant, replace it with its const. val. immediately*) From d42bf5fc0b8298306d177842766eed482219a414 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Tue, 17 Dec 2024 17:34:14 +0100 Subject: [PATCH 131/150] replace the last findi_val_opt --- .../affineEquality/sparseImplementation/listMatrix.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index fd073c4721..1751d364f9 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -263,12 +263,12 @@ module ListMatrix: AbstractMatrix = (* Both input matrices must be in rref form! *) let is_covered_by m1 m2 = let rec is_linearly_independent_rref v m = - let pivot_opt = V.findi_val_opt ((<>:) A.zero) v in + let pivot_opt = V.find_first_non_zero v in match pivot_opt with | None -> false (* When we found no pivot, the vector is already A.zero. *) | Some (pivot_id, pivot) -> let m' = List.drop_while (fun v2 -> - match V.findi_val_opt ((<>:) A.zero) v2 with + match V.find_first_non_zero v2 with | None -> true (* In this case, m2 only has zero rows after that *) | Some (idx', _) -> idx' < pivot_id ) m in @@ -283,7 +283,7 @@ module ListMatrix: AbstractMatrix = match m1 with | [] -> true | v1::vs1 -> - let first_non_zero = V.findi_val_opt ((<>:) A.zero) v1 in + let first_non_zero = V.find_first_non_zero v1 in match first_non_zero with | None -> true (* vs1 must also be zero-vectors because of rref *) | Some (idx, _) -> From 0088812199de5642c675c3a2ed0e5b1b313b265d Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Tue, 17 Dec 2024 17:37:08 +0100 Subject: [PATCH 132/150] ein paar maps ausgetauscht --- .../arrayImplementation/arrayVector.ml | 3 ++ .../sparseImplementation/sparseVector.ml | 34 ++++++++++++------- src/cdomains/affineEquality/vector.ml | 4 +++ .../apron/affineEqualityDomain.apron.ml | 4 +-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index a95e764f16..911e96fd4b 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -111,6 +111,9 @@ module ArrayVector: AbstractVector = let map_f_preserves_zero f v = failwith "Never implemented!" let map2_f_preserves_zero f v1 v2 = failwith "Never implemented!" + let mapi_f_preserves_zero f v = failwith "Never implemented!" + let map2i_f_preserves_zero f v v' = failwith "Never implemented!" + let fold_left_f_preserves_zero f acc v = failwith "Never implemented!" diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 6589296884..0640e31a86 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -95,6 +95,9 @@ module SparseVector: AbstractVector = ) [] v.entries in {entries = entries'; len = v.len + 1} + let map f v = + of_list (List.map f (to_list v)) + let map_f_preserves_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) let entries' = List.filter_map ( fun (idx, value) -> let new_val = f value in @@ -103,6 +106,10 @@ module SparseVector: AbstractVector = let map_f_preserves_zero f v = Timing.wrap "map_f_preserves_zero" (map_f_preserves_zero f) v + let map2 f v v' = (* TODO: Optimize! *) + if v.len <> v'.len then failwith "Unequal vector length" else + of_list (List.map2 f (to_list v) (to_list v')) + (* map for functions f such that f 0 0 = 0 since f won't be applied to if both values are zero. See also map *) let map2_f_preserves_zero f v1 v2 = let f_rem_zero acc idx e1 e2 = @@ -125,6 +132,20 @@ module SparseVector: AbstractVector = let map2_f_preserves_zero f v1 v2 = Timing.wrap "map2_f_preserves_zero" (map2_f_preserves_zero f v1) v2 + let map2i f v v' = (* TODO: optimize! *) + of_list (List.map2i f (to_list v) (to_list v')) + + let map2i_f_preserves_zero f v v' = failwith "TODO" + + let mapi f v = (* TODO: optimize! *) + of_list (List.mapi f (to_list v)) + + let mapi_f_preserves_zero f v = + let entries' = List.filter_map ( + fun (idx, value) -> let new_val = f idx value in + if new_val = A.zero then None else Some (idx, new_val)) v.entries in + {entries = entries'; len = v.len} + let fold_left_f_preserves_zero f acc v = List.fold_left (fun acc (_, value) -> f acc value) acc v.entries @@ -168,10 +189,6 @@ module SparseVector: AbstractVector = let length v = v.len - let map2 f v v' = (* TODO: Optimize! *) - if v.len <> v'.len then failwith "Unequal vector length" else - of_list (List.map2 f (to_list v) (to_list v')) - let apply_with_c_f_preserves_zero f c v = let entries' = List.filter_map (fun (idx, value) -> let new_val = f value c in if new_val =: A.zero then None else Some (idx, new_val)) v.entries in {entries = entries'; len = v.len} @@ -206,9 +223,6 @@ module SparseVector: AbstractVector = let find_first_non_zero v = Timing.wrap "find_first_non_zero" (find_first_non_zero) v - let map f v = - of_list (List.map f (to_list v)) - let compare_length_with v n = Int.compare v.len n @@ -234,12 +248,6 @@ module SparseVector: AbstractVector = let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - 1 - idx, value)) v.entries in {entries = entries'; len = v.len} - let map2i f v v' = (* TODO: optimize! *) - of_list (List.map2i f (to_list v) (to_list v')) - - let mapi f v = (* TODO: optimize! *) - of_list (List.mapi f (to_list v)) - let find2i f v v' = (* TODO: optimize! *) fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 61a18ff7c2..956c6aa1ea 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -72,8 +72,12 @@ sig val map2i: (int -> num -> num -> num) -> t -> t -> t + val map2i_f_preserves_zero: (int -> num -> num -> num) -> t -> t -> t + val mapi: (int -> num -> num) -> t -> t + val mapi_f_preserves_zero: (int -> num -> num) -> t -> t + val mapi: (int -> num -> num) -> t -> t val find2i: (num -> num -> bool) -> t -> t -> int diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 15fc35fa59..2e9676382f 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -286,7 +286,7 @@ struct if s >= Matrix.num_cols a then a else let case_two a r col_b = let a_r = Matrix.get_row a r in - let a = Matrix.map2i (fun i x y -> if i < r then Vector.map2 (fun u j -> u +: y *: j) x a_r else x) a col_b; in + let a = Matrix.map2i (fun i x y -> if i < r then Vector.map2_f_preserves_zero (fun u j -> u +: y *: j) x a_r else x) a col_b; in Matrix.remove_row a r in let case_three a b col_a col_b max = @@ -397,7 +397,7 @@ struct let assign_invertible_rels x var b env = Timing.wrap "assign_invertible" (assign_invertible_rels x var b) env in let assign_uninvertible_rel x var b env = let b_length = Vector.length b in - let b = Vector.mapi (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b in + let b = Vector.mapi_f_preserves_zero (fun i z -> if i < b_length - 1 then Mpqf.neg z else z) b in let b = Vector.set_nth b (Environment.dim_of_var env var) Mpqf.one in match Matrix.rref_vec x b with | None -> bot () From 92802e5dbe63cd43a8812049caef5846fe74a383 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Wed, 18 Dec 2024 14:47:59 +0100 Subject: [PATCH 133/150] Optimize non zero-preserving Vector.map and Vector.map2i --- .../sparseImplementation/sparseVector.ml | 37 ++++++++- .../sparseMatrixImplementationTest.ml | 83 ++++++++++++++----- 2 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index 0640e31a86..aab73454a4 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -96,7 +96,19 @@ module SparseVector: AbstractVector = {entries = entries'; len = v.len + 1} let map f v = + (* of_list (List.map f (to_list v)) + *) + let f_zero = f A.zero in + let rec map2_helper acc vec i = + match vec with + | [] when i >= v.len || f_zero =: A.zero -> List.rev acc + | [] -> map2_helper ((i, f_zero) :: acc) [] (i + 1) + | (idx, value) :: xs when idx = i -> let new_val = f value in if new_val <>: A.zero then map2_helper ((idx, new_val) :: acc) xs (i + 1) else map2_helper acc xs (i + 1) + | (idx, _) :: xs when idx > i -> if f_zero <>: A.zero then map2_helper ((i, f_zero) :: acc) vec (i + 1) else map2_helper acc vec (i + 1) + | (_, _) :: _ -> failwith "This should not happen" + in + {entries = map2_helper [] v.entries 0; len = v.len} let map_f_preserves_zero f v = (* map for functions f such that f 0 = 0 since f won't be applied to zero values. See also map *) let entries' = List.filter_map ( @@ -132,8 +144,29 @@ module SparseVector: AbstractVector = let map2_f_preserves_zero f v1 v2 = Timing.wrap "map2_f_preserves_zero" (map2_f_preserves_zero f v1) v2 - let map2i f v v' = (* TODO: optimize! *) - of_list (List.map2i f (to_list v) (to_list v')) + let map2i f v1 v2 = (* TODO: optimize! *) + if v1.len <> v2.len then raise (Invalid_argument "Unequal lengths") else + (*of_list (List.map2i f (to_list v) (to_list v'))*) + let f_rem_zero idx acc e1 e2 = + let r = f idx e1 e2 in + if r =: A.zero then acc else (idx, r)::acc + in + let rec aux acc vec1 vec2 i = + match vec1, vec2 with + | [], [] when i = v1.len -> acc + | [], [] -> aux (f_rem_zero i acc A.zero A.zero) [] [] (i + 1) + | [], (yidx, yval)::ys when i = yidx -> aux (f_rem_zero i acc A.zero yval) [] ys (i + 1) + | (xidx, xval)::xs, [] when i = xidx -> aux (f_rem_zero i acc xval A.zero) xs [] (i + 1) + | [], (_, _)::_ | (_, _)::_, [] -> aux (f_rem_zero i acc A.zero A.zero) vec1 vec2 (i + 1) (* When one vec is not zero_vec, but has implicit zeroes at front *) + | (xidx, xval)::xs, (yidx, yval)::ys -> + if xidx <> i && yidx <> i then aux (f_rem_zero i acc A.zero A.zero) vec1 vec2 (i+1) (* When both vectors have implicit zeroes at front *) + else + match xidx - yidx with (* Here at least one of the idx is i, which is the smaller one *) + | d when d < 0 -> aux (f_rem_zero i acc xval A.zero) xs vec2 (i + 1) + | d when d > 0 -> aux (f_rem_zero i acc A.zero yval) vec1 ys (i + 1) + | _ -> aux (f_rem_zero i acc xval yval) xs ys (i + 1) + in + {entries = List.rev (aux [] v1.entries v2.entries 0); len = v1.len} let map2i_f_preserves_zero f v v' = failwith "TODO" diff --git a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml index 0fe269d15e..b562760a45 100644 --- a/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml +++ b/tests/unit/cdomains/affineEqualityDomain/sparseImplementation/sparseMatrixImplementationTest.ml @@ -8,9 +8,12 @@ open SparseVector open ListMatrix open ArrayVector open ArrayMatrix +open ConvenienceOps + module D = SharedFunctions.Mpqf module Vector = SparseVector (D) module Matrix = ListMatrix (D) (SparseVector) +include ConvenienceOps(D) (** Shorthands for common functions. *) let int x = D.of_int x @@ -303,25 +306,65 @@ let int_domain_to_rational _ = in normalize_and_assert int_matrix normalized_matrix -let tests = - "SparseMatrixImplementationTest" - >::: [ - "can solve a standard normalization" >:: standard_normalize; - "does sort already reduzed" >:: does_just_sort; - "does eliminate dependent rows" >:: does_eliminate_dependent_rows; - "can handle float domain" >:: does_handle_floats; - "can handle fraction domain" >:: does_handle_fractions; - "does negate negative matrix" >:: does_negate_negative; - "does not change already normalized matrix" >:: does_not_change_normalized_matrix; - "m1 is covered by m2" >:: is_covered_by_simple; - "m1 is covered by m2 with vector in first row" >:: is_covered_by_vector_first_row; - "zero vector is covered by m2" >:: is_zero_vec_covered; - "m1 is not covered by m2" >:: is_not_covered; - "m1 is covered by m2 with big matrix" >:: is_covered_big; - "does not change an empty matrix" >:: normalize_empty; - "can correctly normalize a two column matrix" >:: normalize_two_columns; - "can handle a rational solution" >:: int_domain_to_rational; - "m1 is covered by m2 with big matrix2" >:: is_covered_big2; - ] + +let vectorMap2i _ = + let v1 = Vector.of_list [int 0; int 1; int 0; int 2; int 3; int 0; int 4; int 0; int 1] in + let v2 = Vector.of_list [int 4; int 0; int 0; int 0; int 5; int 6; int 0; int 0; int 2] in + let result = Vector.map2i (fun i x y -> (int i) *: (x +: y)) v1 v2 in + let expected = Vector.of_list [int 0; int 1; int 0; int 6; int 32; int 30; int 24; int 0; int 24] in + assert_equal expected result + + +let vectorMap2i_empty _ = + let v1 = Vector.of_list [] in + let v2 = Vector.of_list [] in + let result = Vector.map2i (fun i x y -> (int i) *: (x +: y)) v1 v2 in + let expected = Vector.of_list [] in + assert_equal expected result + +let vectorMap2i_one_zero _ = + let v1 = Vector.of_list [int 0; int 0; int 0; int 0] in + let v2 = Vector.of_list [int 1; int 2; int 3; int 4] in + let result = Vector.map2i (fun i x y -> (int i) *: (x +: y)) v1 v2 in + let expected = Vector.of_list [int 0; int 2; int 6; int 12] in + assert_equal expected result + +let vectorMap _ = + let v1 = Vector.of_list [int 0; int 1; int 2; int 0; int 0; int 3; int 4; int 0; int 0; int 5] in + let result = Vector.map (fun x -> x +: int 1) v1 in + let expected = Vector.of_list [int 1; int 2; int 3; int 1; int 1; int 4; int 5; int 1; int 1; int 6] in + assert_equal expected result + +let vectorMap_zero_preserving_normal _ = + let v1 = Vector.of_list [int 0; int 1; int 2; int 0; int 0; int 4; int 5; int 0; int 0;] in + let result = Vector.map (fun x -> x *: x) v1 in + let expected = Vector.of_list [int 0; int 1; int 4; int 0; int 0; int 16; int 25; int 0; int 0;] in + assert_equal expected result + + let tests = + "SparseMatrixImplementationTest" + >::: [ + "can solve a standard normalization" >:: standard_normalize; + "does sort already reduzed" >:: does_just_sort; + "does eliminate dependent rows" >:: does_eliminate_dependent_rows; + "can handle float domain" >:: does_handle_floats; + "can handle fraction domain" >:: does_handle_fractions; + "does negate negative matrix" >:: does_negate_negative; + "does not change already normalized matrix" >:: does_not_change_normalized_matrix; + "m1 is covered by m2" >:: is_covered_by_simple; + "m1 is covered by m2 with vector in first row" >:: is_covered_by_vector_first_row; + "zero vector is covered by m2" >:: is_zero_vec_covered; + "m1 is not covered by m2" >:: is_not_covered; + "m1 is covered by m2 with big matrix" >:: is_covered_big; + "does not change an empty matrix" >:: normalize_empty; + "can correctly normalize a two column matrix" >:: normalize_two_columns; + "can handle a rational solution" >:: int_domain_to_rational; + "m1 is covered by m2 with big matrix2" >:: is_covered_big2; + "map2i two vectors" >:: vectorMap2i; + "map2i two empty vectors" >:: vectorMap2i_empty; + "map2i one zero vector" >:: vectorMap2i_one_zero; + "map one vector" >:: vectorMap; + "map zero preserving normal" >:: vectorMap_zero_preserving_normal; + ] let () = run_test_tt_main tests From 2c8901f4fb9e61fa71d707311f4758147c4039ce Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Thu, 19 Dec 2024 10:19:33 +0100 Subject: [PATCH 134/150] added test from lin2vareq to affeq that found mistake in dim_add --- tests/regression/63-affeq/21-function_call.c | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/regression/63-affeq/21-function_call.c diff --git a/tests/regression/63-affeq/21-function_call.c b/tests/regression/63-affeq/21-function_call.c new file mode 100644 index 0000000000..723b75e14a --- /dev/null +++ b/tests/regression/63-affeq/21-function_call.c @@ -0,0 +1,21 @@ +// SKIP PARAM: --set ana.activated[+] affeq --set sem.int.signed_overflow assume_none +// This test was added from 77-lin2vareq because it found mistakes in dim_add that weren't detected by the other tests +#include + +int check_equal(int x, int y, int z) { + __goblint_check(x == y); + __goblint_check(z == y); + __goblint_check(x == z); + return 8; +} + +int main(void) { + int x, y, z; + + y = x; + z = y; + + check_equal(x, y, z); + + return 0; +} From 4411280f9fe552bc361cc3471d2ec34ff8f6b4f2 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 19 Dec 2024 15:37:19 +0100 Subject: [PATCH 135/150] Implement zero preserving Array Vector functions by calling normal functions --- .../arrayImplementation/arrayMatrix.ml | 3 ++- .../arrayImplementation/arrayVector.ml | 20 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index ac21c08fbe..af849eef0c 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -318,7 +318,8 @@ module ArrayMatrix: AbstractMatrix = let is_covered_by m1 m2 = (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) (*Both input matrices must be in rref form!*) - let () = Printf.printf "Is m1 covered by m2?\n m1:\n%sm2:\n%s" (show m1) (show m2) in + let () = Printf.printf "is_covered_by m1: \n%s " (show m1) in + let () = Printf.printf "is_covered_by m2 \n%s " (show m2) in if num_rows m1 > num_rows m2 then false else let p2 = lazy (get_pivot_positions m2) in try ( diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index 911e96fd4b..e90a5afbce 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -57,7 +57,9 @@ module ArrayVector: AbstractVector = let is_zero_vec v = not (Array.exists (fun x -> x <>: A.zero) v) - let is_const_vec v = failwith "Never implemented!" + let is_const_vec v = + compare_length_with (filteri (fun i x -> (*Inefficient*) + compare_length_with v (i + 1) > 0 && x <>: A.zero) v) 1 = 0 let nth = Array.get @@ -108,11 +110,17 @@ module ArrayVector: AbstractVector = let find_opt f v = failwith "Never implemented!" - let map_f_preserves_zero f v = failwith "Never implemented!" - let map2_f_preserves_zero f v1 v2 = failwith "Never implemented!" + let map_f_preserves_zero f v = + map f v - let mapi_f_preserves_zero f v = failwith "Never implemented!" - let map2i_f_preserves_zero f v v' = failwith "Never implemented!" + let map2_f_preserves_zero f v1 v2 = + map2 f v1 v2 + + let mapi_f_preserves_zero f v = + mapi f v + + let map2i_f_preserves_zero f v v' = + map2i f v v' let fold_left_f_preserves_zero f acc v = failwith "Never implemented!" @@ -133,5 +141,5 @@ module ArrayVector: AbstractVector = failwith "Never implemented!" let apply_with_c_f_preserves_zero f c v = - failwith "Never implemented!" + apply_with_c f c v end \ No newline at end of file From 012104f392ed1879ad8806c8b392102293bc28a6 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 19 Dec 2024 16:44:40 +0100 Subject: [PATCH 136/150] assert_rref --- .../sparseImplementation/listMatrix.ml | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 1751d364f9..6e7affc654 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -151,7 +151,7 @@ module ListMatrix: AbstractMatrix = let init_with_vec v = [v] - + let normalize m = let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = @@ -211,6 +211,25 @@ module ListMatrix: AbstractMatrix = | Some (pivot_col, _) -> (i, pivot_col) :: acc ) [] m + let assert_rref m = + let pivot_l = get_pivot_positions m in + let rec validate m i = + match m with + | [] -> () + | v::vs when (V.is_zero_vec v) -> + if List.exists (fun v -> not @@ V.is_zero_vec v) vs + then raise (Invalid_argument "Matrix not in rref: zero row!") + else () + | v::vs -> + let rec validate_vec pl = + match pivot_l with + | [] -> true + | (pr, pc)::ps -> + let target = if pr <> i then A.zero else A.one in + if V.nth v pc <> target then false else validate_vec ps + in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") + in validate m 0 + (* Inserts the vector v with pivot at piv_idx at the correct position in m. m has to be in rref form. *) let insert_v_according_to_piv m v piv_idx pivot_positions = match List.find_opt (fun (row_idx, piv_col) -> piv_col > piv_idx) pivot_positions with From 37190f4fe6ddbc6b59a6e91a29ec51fe2df2c6fa Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 19 Dec 2024 16:44:54 +0100 Subject: [PATCH 137/150] assert_rref --- .../affineEquality/sparseImplementation/listMatrix.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 6e7affc654..f5e91f092d 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -151,7 +151,7 @@ module ListMatrix: AbstractMatrix = let init_with_vec v = [v] - + let normalize m = let col_count = num_cols m in let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = @@ -268,7 +268,7 @@ module ListMatrix: AbstractMatrix = Some (insert_v_according_to_piv m normalized_v idx pivot_positions) let rref_vec m v = Timing.wrap "rref_vec" (rref_vec m) v - + (* This should yield the same result as appending m2 to m1, normalizing and removing zero rows. However, it is usually faster. *) (* Both input matrices are assumed to be in rref form *) let rref_matrix (m1 : t) (m2 : t) = From d7da9c759c9b07196fdafe1f0c125169bce8f430 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Thu, 19 Dec 2024 17:01:41 +0100 Subject: [PATCH 138/150] small bugfix assert_rref --- src/cdomains/affineEquality/sparseImplementation/listMatrix.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index f5e91f092d..263ac8addf 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -226,7 +226,7 @@ module ListMatrix: AbstractMatrix = | [] -> true | (pr, pc)::ps -> let target = if pr <> i then A.zero else A.one in - if V.nth v pc <> target then false else validate_vec ps + if V.nth v pc <>: target then false else validate_vec ps in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") in validate m 0 From bb151813d27f50ca03df1dc4204256e6a07c1e83 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 19 Dec 2024 21:09:50 +0100 Subject: [PATCH 139/150] Bugfix rref_vec using reduce_col_with_vec --- .../sparseImplementation/listMatrix.ml | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 263ac8addf..e004eb9071 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -113,16 +113,6 @@ module ListMatrix: AbstractMatrix = sub_scaled_row row pivot_row s) ) m - let reduce_col_with_vec m j v = - let pivot_element = V.nth v j in - if pivot_element = A.zero then m - else List.mapi (fun idx row -> - let row_value = V.nth row j in - if row_value =: A.zero then row - else (let s = row_value /: pivot_element in - V.map2_f_preserves_zero (fun x y -> x -: s *: y) row v) - ) m - let del_col m j = if num_cols m = 1 then empty () else @@ -202,14 +192,6 @@ module ListMatrix: AbstractMatrix = let m' = main_loop m m 0 0 in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) - (* This function return a tuple of row index and pivot position (column) in m *) - (* TODO: maybe we could use a Hashmap instead of a list? *) - let get_pivot_positions (m : t) : (int * int) list = - List.rev @@ List.fold_lefti ( - fun acc i row -> match V.find_first_non_zero row with - | None -> acc - | Some (pivot_col, _) -> (i, pivot_col) :: acc - ) [] m let assert_rref m = let pivot_l = get_pivot_positions m in @@ -230,11 +212,33 @@ module ListMatrix: AbstractMatrix = in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") in validate m 0 - (* Inserts the vector v with pivot at piv_idx at the correct position in m. m has to be in rref form. *) + (* This function return a tuple of row index and pivot position (column) in m *) + (* TODO: maybe we could use a Hashmap instead of a list? *) + let get_pivot_positions (m : t) : (int * int) list = + List.rev @@ List.fold_lefti ( + fun acc i row -> match V.find_first_non_zero row with + | None -> acc + | Some (pivot_col, _) -> (i, pivot_col) :: acc + ) [] m + + (* Sets the jth column to zero by subtracting multiples of v *) + let reduce_col_with_vec m j v = + let pivot_element = V.nth v j in + if pivot_element = A.zero then m + else List.mapi (fun idx row -> + let row_value = V.nth row j in + if row_value =: A.zero then row + else (let s = row_value /: pivot_element in + V.map2_f_preserves_zero (fun x y -> x -: (s *: y)) row v) + ) m + + (* Inserts the vector v with pivot at piv_idx at the correct position in m. m has to be in rref form and v is only <>: A.zero on piv_idx or idx not included in piv_positions *) let insert_v_according_to_piv m v piv_idx pivot_positions = + let reduced_m = reduce_col_with_vec m piv_idx v in match List.find_opt (fun (row_idx, piv_col) -> piv_col > piv_idx) pivot_positions with - | None -> append_row m v - | Some (row_idx, _) -> let (before, after) = List.split_at row_idx m in (* TODO: Optimize *) + | None -> append_row reduced_m v + | Some (row_idx, _) -> + let (before, after) = List.split_at row_idx reduced_m in (* TODO: Optimize *) before @ (v :: after) (* This function yields the same result as appending v to m, normalizing and removing zero rows would. *) From 0678f668187422405be2739484f5dc7db0cda7e3 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Thu, 19 Dec 2024 21:24:06 +0100 Subject: [PATCH 140/150] Change order of functions because of compilation error --- .../sparseImplementation/listMatrix.ml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index e004eb9071..8d80aae50a 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -193,6 +193,15 @@ module ListMatrix: AbstractMatrix = if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) + (* This function return a tuple of row index and pivot position (column) in m *) + (* TODO: maybe we could use a Hashmap instead of a list? *) + let get_pivot_positions (m : t) : (int * int) list = + List.rev @@ List.fold_lefti ( + fun acc i row -> match V.find_first_non_zero row with + | None -> acc + | Some (pivot_col, _) -> (i, pivot_col) :: acc + ) [] m + let assert_rref m = let pivot_l = get_pivot_positions m in let rec validate m i = @@ -212,15 +221,6 @@ module ListMatrix: AbstractMatrix = in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") in validate m 0 - (* This function return a tuple of row index and pivot position (column) in m *) - (* TODO: maybe we could use a Hashmap instead of a list? *) - let get_pivot_positions (m : t) : (int * int) list = - List.rev @@ List.fold_lefti ( - fun acc i row -> match V.find_first_non_zero row with - | None -> acc - | Some (pivot_col, _) -> (i, pivot_col) :: acc - ) [] m - (* Sets the jth column to zero by subtracting multiples of v *) let reduce_col_with_vec m j v = let pivot_element = V.nth v j in From 3b49ba558fe548af158450d4c8f755a0dcca8f1f Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 21 Dec 2024 10:04:28 +0100 Subject: [PATCH 141/150] Organize Vector and Matrix interface --- .../apron/affineEqualityAnalysis.apron.ml | 1 + src/cdomains/affineEquality/matrix.ml | 48 ++++++----- .../sparseImplementation/listMatrix.ml | 3 + .../sparseImplementation/sparseVector.ml | 1 - src/cdomains/affineEquality/vector.ml | 81 +++++++++---------- 5 files changed, 66 insertions(+), 68 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index 80d3b32874..fcb12606da 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -15,6 +15,7 @@ include RelationAnalysis let spec_module: (module MCPSpec) Lazy.t = lazy ( let module AD = AffineEqualityDomain.D2 (SparseVector) (ListMatrix) in + let module AD_A = AffineEqualityDomain.D2 (ArrayVector) (ArrayMatrix) in (* TODO: Remove this! Just to suppress warning *) let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct diff --git a/src/cdomains/affineEquality/matrix.ml b/src/cdomains/affineEquality/matrix.ml index 0dffe8c44e..b3433ee899 100644 --- a/src/cdomains/affineEquality/matrix.ml +++ b/src/cdomains/affineEquality/matrix.ml @@ -5,58 +5,56 @@ sig type vec type t [@@deriving eq, ord, hash] + val show: t -> string + + val copy: t -> t + val empty: unit -> t (* TODO: needs unit? *) val is_empty: t -> bool - val show: t -> string + val num_rows: t -> int - val add_empty_columns: t -> int array -> t + val num_cols: t -> int + + val init_with_vec: vec -> t val append_row: t -> vec -> t val get_row: t -> int -> vec - val del_col: t -> int -> t - - val del_cols: t -> int array -> t - val remove_row: t -> int -> t - val get_col: t -> int -> vec - - val append_matrices: t -> t -> t - - val num_rows: t -> int + val remove_zero_rows: t -> t - val num_cols: t -> int + val swap_rows: t -> int -> int -> t - val reduce_col: t -> int -> t + val add_empty_columns: t -> int array -> t - val normalize: t -> t Option.t (*Gauss-Jordan Elimination to get matrix in reduced row echelon form (rref) + deletion of zero rows. None matrix has no solution*) + val get_col: t -> int -> vec - val rref_vec: t -> vec -> t Option.t (* added to remove side effects in affineEqualityDomain*) + val set_col: t -> vec -> int -> t - val rref_matrix: t -> t -> t Option.t (* this as well *) + val del_col: t -> int -> t - val find_opt: (vec -> bool) -> t -> vec option + val del_cols: t -> int array -> t val map2: (vec -> num -> vec) -> t -> vec -> t - val map2: (vec -> num -> vec) -> t -> vec -> t (* why is this here twice??*) - val map2i: (int -> vec-> num -> vec) -> t -> vec -> t - val set_col: t -> vec -> int -> t + val find_opt: (vec -> bool) -> t -> vec option - val init_with_vec: vec -> t + val append_matrices: t -> t -> t - val remove_zero_rows: t -> t + val reduce_col: t -> int -> t - val is_covered_by: t -> t -> bool + val normalize: t -> t Option.t (*Gauss-Jordan Elimination to get matrix in reduced row echelon form (rref) + deletion of zero rows. None matrix has no solution*) - val copy: t -> t + val rref_vec: t -> vec -> t Option.t - val swap_rows: t -> int -> int -> t + val rref_matrix: t -> t -> t Option.t + + val is_covered_by: t -> t -> bool end \ No newline at end of file diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index 8d80aae50a..e8bc108d91 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -221,6 +221,9 @@ module ListMatrix: AbstractMatrix = in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") in validate m 0 + (* TODO: Remove this! Just to suppress warning *) + let () = assert_rref (empty ()) + (* Sets the jth column to zero by subtracting multiples of v *) let reduce_col_with_vec m j v = let pivot_element = V.nth v j in diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index aab73454a4..c300b22ceb 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -3,7 +3,6 @@ open RatOps open ConvenienceOps open BatList -open BatArray open Batteries module List = BatList diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 956c6aa1ea..799df35c0e 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -6,29 +6,23 @@ sig val show: t -> string - val keep_vals: t -> int -> t - - val remove_nth: t -> int -> t - - val remove_at_indices: t -> int list -> t - - val insert_zero_at_indices: t -> (int * int) list -> int -> t + val copy: t -> t - val set_nth: t -> int -> num -> t + val of_list: num list -> t - val insert_val_at: int -> num -> t -> t + val of_array: num array -> t - val map_f_preserves_zero: (num -> num) -> t -> t + val of_sparse_list: int -> (int * num) list -> t - val map2_f_preserves_zero: (num -> num -> num) -> t -> t -> t + val to_list: t -> num list - val fold_left_f_preserves_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc + val to_array: t -> num array - val fold_left2_f_preserves_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc + val to_sparse_list: t -> (int * num) list - val apply_with_c: (num -> num -> num) -> num -> t -> t + val length: t -> int - val apply_with_c_f_preserves_zero: (num -> num -> num) -> num -> t -> t + val compare_length_with: t -> int -> int val zero_vec: int -> t @@ -38,60 +32,63 @@ sig val nth: t -> int -> num - val length: t -> int - - val map2: (num -> num -> num) -> t -> t -> t + val set_nth: t -> int -> num -> t - val findi: (num -> bool) -> t -> int + val insert_val_at: int -> num -> t -> t - (* Returns optional tuple of position and value which was found*) - val findi_val_opt: (num -> bool) -> t -> (int * num) Option.t + val insert_zero_at_indices: t -> (int * int) list -> int -> t - val find_first_non_zero : t -> (int * num) option + val remove_nth: t -> int -> t - val find_opt: (num -> bool) -> t -> num Option.t + val remove_at_indices: t -> int list -> t - val map: (num -> num) -> t -> t + val keep_vals: t -> int -> t - val map: (num -> num) -> t -> t + (* Returns the part of the vector starting from index n*) + val starting_from_nth : int -> t -> t - val compare_length_with: t -> int -> int + val find_opt: (num -> bool) -> t -> num Option.t - val of_list: num list -> t + val findi: (num -> bool) -> t -> int - val to_list: t -> num list + val find2i: (num -> num -> bool) -> t -> t -> int - val filteri: (int -> num -> bool) -> t -> t + (* Returns optional tuple of position and value which was found*) + val findi_val_opt: (num -> bool) -> t -> (int * num) Option.t - val append: t -> t -> t + val find_first_non_zero : t -> (int * num) option val exists: (num -> bool) -> t -> bool val exists2: (num -> num -> bool) -> t -> t -> bool - val rev: t -> t - val map2i: (int -> num -> num -> num) -> t -> t -> t + val filteri: (int -> num -> bool) -> t -> t - val map2i_f_preserves_zero: (int -> num -> num -> num) -> t -> t -> t + val map: (num -> num) -> t -> t + + val map_f_preserves_zero: (num -> num) -> t -> t val mapi: (int -> num -> num) -> t -> t val mapi_f_preserves_zero: (int -> num -> num) -> t -> t - val mapi: (int -> num -> num) -> t -> t + val map2: (num -> num -> num) -> t -> t -> t - val find2i: (num -> num -> bool) -> t -> t -> int + val map2_f_preserves_zero: (num -> num -> num) -> t -> t -> t - val to_array: t -> num array + val map2i: (int -> num -> num -> num) -> t -> t -> t - val of_array: num array -> t + val map2i_f_preserves_zero: (int -> num -> num -> num) -> t -> t -> t - val copy: t -> t + val fold_left_f_preserves_zero: ('acc -> num -> 'acc) -> 'acc -> t -> 'acc - val of_sparse_list: int -> (int * num) list -> t + val fold_left2_f_preserves_zero: ('acc -> num -> num -> 'acc) -> 'acc -> t -> t -> 'acc - val to_sparse_list: t -> (int * num) list + val apply_with_c: (num -> num -> num) -> num -> t -> t - (* Returns the part of the vector starting from index n*) - val starting_from_nth : int -> t -> t + val apply_with_c_f_preserves_zero: (num -> num -> num) -> num -> t -> t + + val rev: t -> t + + val append: t -> t -> t end \ No newline at end of file From 93463f2008e68b2acae2546f816e823894d1fa65 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 21 Dec 2024 18:05:51 +0100 Subject: [PATCH 142/150] Bugfix Vector is_const_vec --- .../affineEquality/sparseImplementation/sparseVector.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index c300b22ceb..bf8dd6df17 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -205,7 +205,8 @@ module SparseVector: AbstractVector = let is_const_vec v = match v.entries with | [] -> false - | (xi,xv)::[] -> if xi = v.len - 1 then false else true + | (xi, xv) :: [] -> if xi = v.len - 1 then false else true + | (xi, xv) :: (const_idx, _) :: [] -> if const_idx = v.len - 1 then true else false | _ -> false let nth v n = (* Note: This exception HAS TO BE THROWN! It is expected by the domain *) From 6ae9bf167e185b3317c11bcc364bd5668846e951 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 21 Dec 2024 18:12:19 +0100 Subject: [PATCH 143/150] Remove prints in ArrayMatrix --- .../apron/affineEqualityAnalysis.apron.ml | 2 +- .../arrayImplementation/arrayMatrix.ml | 31 +++---------------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index fcb12606da..be94d389d1 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -19,7 +19,7 @@ let spec_module: (module MCPSpec) Lazy.t = let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct - include SpecFunctor (Priv) (AD) (RelationPrecCompareUtil.DummyUtil) + include SpecFunctor (Priv) (AD_A) (RelationPrecCompareUtil.DummyUtil) let name () = "affeq" end in diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml index af849eef0c..83907f29dd 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayMatrix.ml @@ -39,7 +39,6 @@ module ArrayMatrix: AbstractMatrix = let copy m = Timing.wrap "copy" (copy) m let add_empty_columns m cols = - let () = Printf.printf "Before add_empty_columns m:\n%sindices: %s\n" (show m) (Array.fold_right (fun x s -> (Int.to_string x) ^ "," ^ s) cols "") in Array.modifyi (+) cols; let nnc = Array.length cols in if is_empty m || nnc = 0 then m else @@ -52,7 +51,6 @@ module ArrayMatrix: AbstractMatrix = m'.(i).(j + !offset) <- m.(i).(j); done done; - let () = Printf.printf "After add_empty_columns m:\n%s\n" (show m') in m' let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols @@ -70,7 +68,6 @@ module ArrayMatrix: AbstractMatrix = V.of_array m.(n) let remove_row m n = - let () = Printf.printf "Before remove_row %i of m:\n%s\n" n (show m) in let new_matrix = Array.make_matrix (num_rows m - 1) (num_cols m) A.zero in if not @@ is_empty new_matrix then if n = 0 then @@ -81,7 +78,6 @@ module ArrayMatrix: AbstractMatrix = Array.blit m (n + 1) new_matrix n (num_rows new_matrix - n)); new_matrix let get_col m n = - (*let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)))) in*) V.of_array @@ Array.init (Array.length m) (fun i -> m.(i).(n)) let get_col m n = Timing.wrap "get_col" (get_col m) n @@ -90,13 +86,11 @@ module ArrayMatrix: AbstractMatrix = for i = 0 to num_rows m - 1 do m.(i).(n) <- V.nth new_col i done; - let () = Printf.printf "After set_col m:\n%s\n" (show m) in m let set_col_with m new_col n = Timing.wrap "set_col" (set_col_with m new_col) n let set_col m new_col n = - let () = Printf.printf "Before set_col m:\n%s\n" (show m) in let copy = copy m in set_col_with copy new_col n @@ -123,10 +117,8 @@ module ArrayMatrix: AbstractMatrix = let reduce_col_with m j = Timing.wrap "reduce_col_with" (reduce_col_with m) j let reduce_col m j = - let () = Printf.printf "Before reduce_col %i of m:\n%s\n" j (show m) in let copy = copy m in reduce_col_with copy j; - let () = Printf.printf "After reduce_col %i of m:\n%s\n" j (show copy) in copy let del_col m j = @@ -138,7 +130,6 @@ module ArrayMatrix: AbstractMatrix = let del_cols m cols = let n_c = Array.length cols in - let () = Printf.printf "Before del_cols cols_length=%i \nm:\n%s\n" n_c (show m) in if n_c = 0 || is_empty m then m else let m_r, m_c = num_rows m, num_cols m in @@ -210,7 +201,6 @@ module ArrayMatrix: AbstractMatrix = let reduce_col_with_vec m j v = - let () = Printf.printf "Before reduce_col_with_vec %i with vec %s of m:\n%s\n" j (V.show (V.of_array v)) (show m) in for i = 0 to num_rows m - 1 do if m.(i).(j) <>: A.zero then let beta = m.(i).(j) /: v.(j) in @@ -253,12 +243,9 @@ module ArrayMatrix: AbstractMatrix = let normalize m = let copy = copy m in - let () = Printf.printf "Before normalizing we have m:\n%s" (show m) in if normalize_with copy then - let () = Printf.printf "After normalizing we have m:\n%s" (show copy) in Some copy else - let () = Printf.printf "No normalization" in None let rref_vec_with m v = (*This function yields the same result as appending vector v to m and normalizing it afterwards would. However, it is usually faster than performing those ops manually.*) @@ -279,13 +266,11 @@ module ArrayMatrix: AbstractMatrix = let rref_vec_with m v = Timing.wrap "rref_vec_with" (rref_vec_with m) v let rref_vec m v = (* !! There was another rref_vec function that has been renamed to rref_vec_helper !!*) - let () = Printf.printf "Before rref_vec we have m:\n%sv: %s\n" (show m) (V.show v) in let m' = copy m in let v' = V.copy v in match rref_vec_with m' v' with - | Some res -> let () = Printf.printf "After rref_vec, before removing zero rows, we have m:\n%s\n" (show res) in - Some (remove_zero_rows res) - | None -> let () = Printf.printf "After rref_vec there is no normalization\n" in None + | Some res -> Some (remove_zero_rows res) + | None -> None let rref_matrix_with m1 m2 = (*Similar to rref_vec_with but takes two matrices instead.*) @@ -308,18 +293,15 @@ module ArrayMatrix: AbstractMatrix = let rref_matrix_with m1 m2 = Timing.wrap "rref_matrix_with" (rref_matrix_with m1) m2 let rref_matrix m1 m2 = - let () = Printf.printf "Before rref_matrix m1 m2\nm1: %s\nm2: %s\n" (show m1) (show m2) in let m1' = copy m1 in let m2' = copy m2 in match rref_matrix_with m1' m2' with - | Some m -> let () = Printf.printf "After rref_matrix m:\n %s\n" (show m) in Some m - | None -> let () = Printf.printf "No normalization for rref_matrix found" in None + | Some m -> Some m + | None -> None let is_covered_by m1 m2 = (*Performs a partial rref reduction to check if concatenating both matrices and afterwards normalizing them would yield a matrix <> m2 *) (*Both input matrices must be in rref form!*) - let () = Printf.printf "is_covered_by m1: \n%s " (show m1) in - let () = Printf.printf "is_covered_by m2 \n%s " (show m2) in if num_rows m1 > num_rows m2 then false else let p2 = lazy (get_pivot_positions m2) in try ( @@ -337,7 +319,6 @@ module ArrayMatrix: AbstractMatrix = if m1_i. (num_cols m1 - 1) <>: A.zero then raise Stdlib.Exit done; - (*let () = Printf.printf "m1: %sand m2: %s return true in is_covered_by.\n" (show m1') (show m2') in*) true ) with Stdlib.Exit -> false;; @@ -359,10 +340,8 @@ module ArrayMatrix: AbstractMatrix = let map2_with f m v = Timing.wrap "map2_with" (map2_with f m) v let map2 f m v = - let () = Printf.printf "Before map2 we have m:\n%s\n" (show m) in let m' = copy m in map2_with f m' v; - let () = Printf.printf "After map2 we have m:\n%s\n" (show m') in m' let map2i_with f m v = @@ -376,10 +355,8 @@ module ArrayMatrix: AbstractMatrix = let map2i_with f m v = Timing.wrap "map2i_with" (map2i_with f m) v let map2i f m v = - let () = Printf.printf "Before map2i m:\n%sv:%s\n" (show m) (V.show v) in let m' = copy m in map2i_with f m' v; - let () = Printf.printf "After map2i m:\n%s\n" (show m') in m' let swap_rows m j k = From b8ba2bbac794802073e29b94629307cbc2379297 Mon Sep 17 00:00:00 2001 From: Charlotte Brandt Date: Sat, 21 Dec 2024 19:08:15 +0100 Subject: [PATCH 144/150] reordered function in vector so that they match the interface --- .../sparseImplementation/sparseVector.ml | 320 +++++++++--------- 1 file changed, 157 insertions(+), 163 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index bf8dd6df17..a3d499f922 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -18,7 +18,19 @@ module SparseVector: AbstractVector = len: int }[@@deriving eq, ord, hash] - let to_vector e l = {entries=e; len=l} + let copy v = v + + let of_list l = + let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l + in {entries = entries'; len = List.length l} + + let of_array a = + let len' = Array.length a in + let entries' = List.rev @@ Array.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc ) [] a in + {entries = entries'; len = len'} + + let of_sparse_list col_count ls = + {entries = ls; len = col_count} let to_list v = let[@tail_mod_cons] rec extend_zero_aux i v' = @@ -29,15 +41,83 @@ module SparseVector: AbstractVector = in (extend_zero_aux 0 v.entries) - let of_list l = - let entries' = List.rev @@ List.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc) [] l - in {entries = entries'; len = List.length l} + let to_array v = + let vec = Array.make v.len A.zero in + List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; + vec - let keep_vals v n = - if n >= v.len then v else - {entries = List.take_while (fun (idx, _) -> idx < n) v.entries; len=n} + let to_sparse_list v = + v.entries + + let show v = + let t = to_list v in + let rec list_str l = + match l with + | [] -> "]" + | x :: xs -> (A.to_string x) ^ " " ^ (list_str xs) + in + "["^list_str t^"\n" + + let length v = + v.len + let compare_length_with v n = + Int.compare v.len n + + let zero_vec n = + {entries = []; len = n} + + let is_zero_vec v = (v.entries = []) + + (* Checks if exactly one variable is part of the affine equality, i.e. whether there is exactly one non-zero entry, excluding the constant at the end *) + let is_const_vec v = + match v.entries with + | [] -> false + | (idx, _) :: (const_idx , _) :: [] when const_idx = (v.len - 1) -> true + | (idx, _)::[] when idx <> v.len -1 -> true + | _ -> false + + let nth v n = (* Note: This exception HAS TO BE THROWN! It is expected by the domain *) + if n >= v.len then raise (Invalid_argument "Cannot access vector element (out of bounds)") + else + let rec nth v = match v with (* List.assoc would also work, but we use the fact that v is sorted *) + | [] -> A.zero + | (col_idx, value) :: xs when col_idx > n -> A.zero + | (col_idx, value) :: xs when col_idx = n -> value + | (col_idx, value) :: xs -> nth xs + in nth v.entries + + let set_nth v n num = (* TODO: Optimize! *) + if n >= v.len then failwith "Out of bounds" + else + let rec set_nth_helper vec acc = + match vec with + | [] -> if num <>: A.zero then List.rev ((n, num) :: acc) else List.rev acc + | (idx, value) :: xs when n = idx -> if num <>: A.zero then List.rev_append ((idx, num) :: acc) xs else List.rev_append acc xs + | (idx, value) :: xs when n < idx -> if num <>: A.zero then List.rev_append ((n, num) :: acc) vec else List.rev_append acc vec + | x :: xs -> set_nth_helper xs (x :: acc) + in + {entries = set_nth_helper v.entries []; len = v.len} + + let insert_val_at n new_val v = + if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) + let entries' = List.rev @@ List.fold_left (fun acc (idx, value) -> + if idx < n then (idx, value) :: acc + else (if new_val <>: A.zero then (idx + 1, value) :: (n, new_val) :: acc else (idx + 1, value) :: acc) + ) [] v.entries in + {entries = entries'; len = v.len + 1} + + (* Note that idx is assumed to be sorted. *) + let insert_zero_at_indices v idx count = + let rec add_indices_helper vec idx added_count acc = + match vec, idx with + | [], _ -> List.rev acc (* inserting at the end only means changing the dimension *) + | ((col_idx, value) :: xs), [] -> add_indices_helper xs [] added_count ((col_idx + added_count, value) :: acc) + | ((col_idx, value) :: xs), ((i, count) :: ys) when i = col_idx -> add_indices_helper vec ys (added_count + count) acc + | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> add_indices_helper vec ys (added_count + count) acc + | ((col_idx, value) :: xs), ((i, count) :: ys) -> add_indices_helper xs idx added_count ((col_idx + added_count, value) :: acc) + in + {entries = add_indices_helper v.entries idx 0 []; len = v.len + count} - (* TODO: Which of both remmove_nth should we use *) let remove_nth v n = if n >= v.len then failwith "Out of bounds" else @@ -63,41 +143,61 @@ module SparseVector: AbstractVector = in {entries = remove_indices_helper v.entries idx 0 []; len = v.len - List.length idx} - let insert_zero_at_indices v idx count = - let rec add_indices_helper vec idx added_count acc = - match vec, idx with - | [], _ -> List.rev acc (* inserting at the end only means changing the dimension *) - | ((col_idx, value) :: xs), [] -> add_indices_helper xs [] added_count ((col_idx + added_count, value) :: acc) - | ((col_idx, value) :: xs), ((i, count) :: ys) when i = col_idx -> add_indices_helper vec ys (added_count + count) acc - | ((col_idx, value) :: xs), ((i, count) :: ys) when i < col_idx -> add_indices_helper vec ys (added_count + count) acc - | ((col_idx, value) :: xs), ((i, count) :: ys) -> add_indices_helper xs idx added_count ((col_idx + added_count, value) :: acc) - in - {entries = add_indices_helper v.entries idx 0 []; len = v.len + count} + let keep_vals v n = + if n >= v.len then v else + {entries = List.take_while (fun (idx, _) -> idx < n) v.entries; len=n} - let set_nth v n num = (* TODO: Optimize! *) - if n >= v.len then failwith "Out of bounds" + let starting_from_nth n v = + let entries' = List.filter_map (fun (idx, value) -> if idx < n then None else Some (idx - n, value)) v.entries in + {entries = entries'; len = v.len - n} + + let find_opt f v = (* TODO: Do we need this? And optimize!!!*) + List.find_opt f (to_list v) + + let findi f v = + if f A.zero then + fst @@ List.findi (fun i (idx, value) -> if idx > i then true else f value) v.entries (* Here fst is the iteration variable i, not the tuple idx *) else - let rec set_nth_helper vec acc = - match vec with - | [] -> if num <>: A.zero then List.rev ((n, num) :: acc) else List.rev acc - | (idx, value) :: xs when n = idx -> if num <>: A.zero then List.rev_append ((idx, num) :: acc) xs else List.rev_append acc xs - | (idx, value) :: xs when n < idx -> if num <>: A.zero then List.rev_append ((n, num) :: acc) vec else List.rev_append acc vec - | x :: xs -> set_nth_helper xs (x :: acc) - in - {entries = set_nth_helper v.entries []; len = v.len} + fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) - let insert_val_at n new_val v = - if n > v.len then failwith "n too large" else (* Does this happen? Otherwise we can omit this comparison, here right now to be semantically equivalent *) - let entries' = List.rev @@ List.fold_left (fun acc (idx, value) -> - if idx < n then (idx, value) :: acc - else (if new_val <>: A.zero then (idx + 1, value) :: (n, new_val) :: acc else (idx + 1, value) :: acc) - ) [] v.entries in - {entries = entries'; len = v.len + 1} + let find2i f v v' = (* TODO: optimize! *) + fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) + + (* Returns optional of (index * value) where f value evaluated to true *) + let findi_val_opt f v = + let rec find_zero_or_val vec last_col_idx = + let f0 = f A.zero in + match vec with + | [] -> if f0 && v.len <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else None + | (idx, value) :: xs -> + if f0 && idx <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) + else if f value then Some (idx, value) + else find_zero_or_val xs idx + in find_zero_or_val v.entries (-1) + + let findi_val_opt f v = Timing.wrap "findi_val_opt" (findi_val_opt f) v + + let find_first_non_zero v = + if v.entries = [] then None + else Some (List.hd v.entries) + + let find_first_non_zero v = Timing.wrap "find_first_non_zero" (find_first_non_zero) v + + let exists f v = + let c = v.len in + let rec exists_aux at f v = + match v with + | [] -> if at = 0 then false else f A.zero + | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs + in (exists_aux c f v.entries) + + let exists2 f v1 v2 = (* TODO: optimize! *) + List.exists2 f (to_list v1) (to_list v2) + + let filteri f v = (* TODO: optimize! *) + of_list (List.filteri f (to_list v)) let map f v = - (* - of_list (List.map f (to_list v)) - *) let f_zero = f A.zero in let rec map2_helper acc vec i = match vec with @@ -117,6 +217,15 @@ module SparseVector: AbstractVector = let map_f_preserves_zero f v = Timing.wrap "map_f_preserves_zero" (map_f_preserves_zero f) v + let mapi f v = (* TODO: optimize! *) + of_list (List.mapi f (to_list v)) + + let mapi_f_preserves_zero f v = + let entries' = List.filter_map ( + fun (idx, value) -> let new_val = f idx value in + if new_val = A.zero then None else Some (idx, new_val)) v.entries in + {entries = entries'; len = v.len} + let map2 f v v' = (* TODO: Optimize! *) if v.len <> v'.len then failwith "Unequal vector length" else of_list (List.map2 f (to_list v) (to_list v')) @@ -139,7 +248,7 @@ module SparseVector: AbstractVector = | _ -> aux (f_rem_zero acc xidx xval yval) xs ys in if v1.len <> v2.len then raise (Invalid_argument "Unequal lengths") else - to_vector (List.rev (aux [] v1.entries v2.entries)) v1.len + {entries = List.rev (aux [] v1.entries v2.entries); len = v1.len} let map2_f_preserves_zero f v1 v2 = Timing.wrap "map2_f_preserves_zero" (map2_f_preserves_zero f v1) v2 @@ -160,24 +269,15 @@ module SparseVector: AbstractVector = | (xidx, xval)::xs, (yidx, yval)::ys -> if xidx <> i && yidx <> i then aux (f_rem_zero i acc A.zero A.zero) vec1 vec2 (i+1) (* When both vectors have implicit zeroes at front *) else - match xidx - yidx with (* Here at least one of the idx is i, which is the smaller one *) - | d when d < 0 -> aux (f_rem_zero i acc xval A.zero) xs vec2 (i + 1) - | d when d > 0 -> aux (f_rem_zero i acc A.zero yval) vec1 ys (i + 1) - | _ -> aux (f_rem_zero i acc xval yval) xs ys (i + 1) + match xidx - yidx with (* Here at least one of the idx is i, which is the smaller one *) + | d when d < 0 -> aux (f_rem_zero i acc xval A.zero) xs vec2 (i + 1) + | d when d > 0 -> aux (f_rem_zero i acc A.zero yval) vec1 ys (i + 1) + | _ -> aux (f_rem_zero i acc xval yval) xs ys (i + 1) in {entries = List.rev (aux [] v1.entries v2.entries 0); len = v1.len} let map2i_f_preserves_zero f v v' = failwith "TODO" - let mapi f v = (* TODO: optimize! *) - of_list (List.mapi f (to_list v)) - - let mapi_f_preserves_zero f v = - let entries' = List.filter_map ( - fun (idx, value) -> let new_val = f idx value in - if new_val = A.zero then None else Some (idx, new_val)) v.entries in - {entries = entries'; len = v.len} - let fold_left_f_preserves_zero f acc v = List.fold_left (fun acc (_, value) -> f acc value) acc v.entries @@ -196,125 +296,19 @@ module SparseVector: AbstractVector = if v.len <> v'.len then raise (Invalid_argument "Unequal lengths") else (aux acc v.entries v'.entries) - - let zero_vec n = - {entries = []; len = n} - - let is_zero_vec v = (v.entries = []) - - let is_const_vec v = - match v.entries with - | [] -> false - | (xi, xv) :: [] -> if xi = v.len - 1 then false else true - | (xi, xv) :: (const_idx, _) :: [] -> if const_idx = v.len - 1 then true else false - | _ -> false - - let nth v n = (* Note: This exception HAS TO BE THROWN! It is expected by the domain *) - if n >= v.len then raise (Invalid_argument "Cannot access vector element (out of bounds)") - else - let rec nth v = match v with (* List.assoc would also work, but we use the fact that v is sorted *) - | [] -> A.zero - | (col_idx, value) :: xs when col_idx > n -> A.zero - | (col_idx, value) :: xs when col_idx = n -> value - | (col_idx, value) :: xs -> nth xs - in nth v.entries - - let length v = - v.len + let apply_with_c f c v = (* TODO: optimize! *) + of_list @@ List.map (fun value -> f value c) (to_list v) let apply_with_c_f_preserves_zero f c v = let entries' = List.filter_map (fun (idx, value) -> let new_val = f value c in if new_val =: A.zero then None else Some (idx, new_val)) v.entries in {entries = entries'; len = v.len} - let apply_with_c f c v = (* TODO: optimize! *) - of_list @@ List.map (fun value -> f value c) (to_list v) - - let findi f v = - if f A.zero then - fst @@ List.findi (fun i (idx, value) -> if idx > i then true else f value) v.entries (* Here fst is the iteration variable i, not the tuple idx *) - else - fst @@ List.find (fun (idx, value) -> f value) v.entries (* Here fst is the idx contained in the found tuple *) - - (* Returns optional of (index * value) where f value evaluated to true *) - (*Can be optimized, dont check every zero cell*) - let findi_val_opt f v = - let rec find_zero_or_val vec last_col_idx = - let f0 = f A.zero in - match vec with - | [] -> if f0 && v.len <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) else None - | (idx, value) :: xs -> - if f0 && idx <> last_col_idx + 1 then Some (last_col_idx + 1, A.zero) - else if f value then Some (idx, value) - else find_zero_or_val xs idx - in find_zero_or_val v.entries (-1) - - let findi_val_opt f v = Timing.wrap "findi_val_opt" (findi_val_opt f) v - - let find_first_non_zero v = - if v.entries = [] then None - else Some (List.hd v.entries) - - let find_first_non_zero v = Timing.wrap "find_first_non_zero" (find_first_non_zero) v - - let compare_length_with v n = - Int.compare v.len n - - let filteri f v = (* TODO: optimize! *) - of_list (List.filteri f (to_list v)) - - let append v v' = - let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in - {entries = entries'; len = v.len + v'.len} - - let exists f v = - let c = v.len in - let rec exists_aux at f v = - match v with - | [] -> if at = 0 then false else f A.zero - | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs - in (exists_aux c f v.entries) - - let exists2 f v1 v2 = (* TODO: optimize! *) - List.exists2 f (to_list v1) (to_list v2) - let rev v = let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - 1 - idx, value)) v.entries in {entries = entries'; len = v.len} - let find2i f v v' = (* TODO: optimize! *) - fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) - - let to_array v = - let vec = Array.make v.len A.zero in - List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; - vec - - let of_array a = - let len' = Array.length a in - let entries' = List.rev @@ Array.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc ) [] a in - {entries = entries'; len = len'} - - let copy v = v - - let of_sparse_list col_count ls = - {entries = ls; len = col_count} - - let to_sparse_list v = - v.entries - - let find_opt f v = (* TODO: Do we need this? And optimize!!!*) - List.find_opt f (to_list v) - - let starting_from_nth n v = - let entries' = List.filter_map (fun (idx, value) -> if idx < n then None else Some (idx - n, value)) v.entries in - {entries = entries'; len = v.len - n} + let append v v' = + let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in + {entries = entries'; len = v.len + v'.len} - let show v = - let t = to_list v in - let rec list_str l = - match l with - | [] -> "]" - | x :: xs -> (A.to_string x) ^ " " ^ (list_str xs) - in - "["^list_str t^"\n" end From 60f7b67e471d4fbb4cffb74aab44cb91ef2b92bf Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Mon, 23 Dec 2024 11:30:16 +0100 Subject: [PATCH 145/150] Reorder listMatrix; Some renaming --- .../sparseImplementation/listMatrix.ml | 204 +++++++++--------- 1 file changed, 100 insertions(+), 104 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index e8bc108d91..c44c5e2c9b 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -21,25 +21,42 @@ module ListMatrix: AbstractMatrix = let show x = List.fold_left (^) "" (List.map (fun x -> (V.show x)) x) + let copy m = m + (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + + let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 + + let copy m = + Timing.wrap "copy" (copy) m + let empty () = [] + let is_empty = List.is_empty + let num_rows = List.length - let is_empty m = - num_rows m = 0 - (*This should be different if the implimentation is sound*) - (*m.column_count = 0*) + let num_cols m = + if m = [] then 0 else V.length (hd m) + + let init_with_vec v = + [v] - let num_cols m = if m = [] then 0 else V.length (hd m) + let append_row m row = + m @ [row] - let copy m = m - (* Lists are immutable, so this should suffice? A.t is mutuable currently, but is treated like its not in ArrayMatrix*) + let get_row = List.nth - let copy m = - Timing.wrap "copy" (copy) m + let remove_row m n = + List.remove_at n m + + let remove_zero_rows m = + List.filter (fun row -> not (V.is_zero_vec row)) m + + let swap_rows m j k = + List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m (* This only works if Array.modifyi has been removed from dim_add *) - let add_empty_columns (m : t) (cols : int array) : t = + let add_empty_columns m cols = let cols = Array.to_list cols in let sorted_cols = List.sort Stdlib.compare cols in let rec count_sorted_occ acc cols last count = @@ -55,15 +72,6 @@ module ListMatrix: AbstractMatrix = let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols - let append_row m row = - m @ [row] - - let get_row m n = - List.nth m n - - let remove_row m n = - List.remove_at n m - let get_col m n = (*let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_list @@ List.map (fun row -> V.nth row n) m)) in*) V.of_list @@ List.map (fun row -> V.nth row n) m (* builds full col including zeros, maybe use sparselist instead? *) @@ -71,24 +79,79 @@ module ListMatrix: AbstractMatrix = let get_col m n = Timing.wrap "get_col" (get_col m) n - let set_col m new_col n = + let set_col m new_col n = (* TODO: Optimize! AND CURRENTLY WRONG SEMANTICS IF VECTOR LENGTH <> NUM_ROWS! *) (* List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m *) List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) + let del_col m j = + if num_cols m = 1 then empty () + else + List.map (fun row -> V.remove_nth row j) m + + let del_cols m cols = + let cols = Array.to_list cols in (* TODO: Is it possible to use list for Apron dimchange? *) + let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification) *) + if (List.length sorted_cols) = num_cols m then empty() + else + List.map (fun row -> V.remove_at_indices row sorted_cols) m + + let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols + + let map2 f m v = + let vector_length = V.length v in + List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m + + let map2i f m v = (* TODO: Optimize! We should probably do it like in map2 *) + let rec map2i_min i acc m v = + match m, v with + | [], _ -> List.rev acc + | row :: rs, [] -> List.rev_append (row :: acc) rs + | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs + in + map2i_min 0 [] m (V.to_list v) + + let find_opt = List.find_opt + let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) m1 @ m2 - let equal m1 m2 = Timing.wrap "equal" (equal m1) m2 - let div_row (row : V.t) (pivot : A.t) : V.t = - V.map_f_preserves_zero (fun a -> a /: pivot) row - - let swap_rows m j k = - List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m + V.map_f_preserves_zero (fun a -> a /: pivot) row (* TODO: This is a case for apply_with_c *) let sub_scaled_row row1 row2 s = V.map2_f_preserves_zero (fun x y -> x -: (s *: y)) row1 row2 + (* This function return a tuple of row index and pivot position (column) in m *) + (* TODO: maybe we could use a Hashmap instead of a list? *) + let get_pivot_positions m : (int * int) list = + List.rev @@ List.fold_lefti ( + fun acc i row -> match V.find_first_non_zero row with + | None -> acc + | Some (pivot_col, _) -> (i, pivot_col) :: acc + ) [] m + + let assert_rref m = + let pivot_l = get_pivot_positions m in + let rec validate m i = + match m with + | [] -> () + | v::vs when (V.is_zero_vec v) -> + if List.exists (fun v -> not @@ V.is_zero_vec v) vs + then raise (Invalid_argument "Matrix not in rref: zero row!") + else () + | v::vs -> + let rec validate_vec pl = + match pivot_l with + | [] -> true + | (pr, pc)::ps -> + let target = if pr <> i then A.zero else A.one in + if V.nth v pc <>: target then false else validate_vec ps + in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") + in validate m 0 + + (* TODO: Remove this! Just to suppress warning *) + let () = assert_rref (empty ()) + (* Reduces the jth column with the last row that has a non-zero element in this column. *) let reduce_col m j = if is_empty m then m @@ -113,41 +176,12 @@ module ListMatrix: AbstractMatrix = sub_scaled_row row pivot_row s) ) m - let del_col m j = - if num_cols m = 1 then empty () - else - List.map (fun row -> V.remove_nth row j) m - - let del_cols m cols = - let cols = Array.to_list cols in (* TODO: Is it possible to use list for Apron dimchange? *) - let sorted_cols = List.sort_uniq Stdlib.compare cols in (* Apron Docs: Repetitions are meaningless (and are not correct specification) *) - if (List.length sorted_cols) = num_cols m then empty() - else - List.map (fun row -> V.remove_at_indices row sorted_cols) m - - let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols - - let map2i f m v = - let rec map2i_min i acc m v = - match m, v with - | [], _ -> List.rev acc - | row :: rs, [] -> List.rev_append (row :: acc) rs - | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs - in - map2i_min 0 [] m (V.to_list v) - - let remove_zero_rows m = - List.filter (fun row -> not (V.is_zero_vec row)) m - - let init_with_vec v = - [v] - let normalize m = let col_count = num_cols m in - let dec_mat_2D (m : t) (row_idx : int) (col_idx : int) : t = + let cut_front_matrix m row_idx col_idx = List.filteri_map (fun i row -> if i < row_idx then None else Some (V.starting_from_nth col_idx row)) m in - let dec_mat_2D m row_idx col_idx = Timing.wrap "dec_mat_2D" (dec_mat_2D m row_idx) col_idx in + let cut_front_matrix m row_idx col_idx = Timing.wrap "cut_front_matrix" (cut_front_matrix m row_idx) col_idx in (* Function for finding first pivot in an extracted part of the matrix (row_idx and col_idx indicate which part of the original matrix) *) (* The last column represents the constant in the affeq *) let find_first_pivot m' row_idx col_idx = @@ -158,26 +192,25 @@ module ListMatrix: AbstractMatrix = let row_first_non_zero = V.find_first_non_zero row in match row_first_non_zero with | None -> (cur_row, cur_col, cur_val) - | Some (idx, value) -> (* let () = Printf.printf "We found first non-zero at index %i in row %i\n" idx i in *) - if idx < cur_col then (i, idx, value) else (cur_row, cur_col, cur_val) - ) (num_rows m', max_piv_col_idx + 1, A.zero) m' (* Initializing with max, so num_cols m indicates that pivot is not found *) + | Some (idx, value) -> if idx < cur_col then (i, idx, value) else (cur_row, cur_col, cur_val) + ) (num_rows m', max_piv_col_idx + 1, A.zero) m' in if piv_col = (max_piv_col_idx + 1) then None else Some (row_idx + piv_row, col_idx + piv_col, piv_val) in let find_first_pivot m' row_idx col_idx = Timing.wrap "find_first_pivot" (find_first_pivot m' row_idx) col_idx in let affeq_rows_are_valid m = (* Check if the semantics of an rref-affeq matrix are correct *) let col_count = num_cols m in - let row_is_valid row = (* TODO: Vector findi_opt *) + let row_is_valid row = match V.find_first_non_zero row with | Some (idx, _) -> if idx < col_count - 1 then true else false (* If all cofactors of the affeq are zero, but the constant is non-zero, the row is invalid *) - | None -> true (* Full zero row is valid *) + | None -> true in List.for_all row_is_valid m in - let rec main_loop m m' row_idx col_idx = + let rec find_piv_and_reduce m m' row_idx col_idx = if col_idx >= (col_count - 1) then m (* In this case the whole bottom of the matrix starting from row_index is Zero, so it is normalized *) else match find_first_pivot m' row_idx col_idx with - | None -> m (* No pivot found means already normalized*) + | None -> m (* No pivot found means already normalized *) | Some (piv_row_idx, piv_col_idx, piv_val) -> ( (* let () = Printf.printf "The current matrix is: \n%s and the pivot is (%i, %i, %s)\n" (show m) piv_row_idx piv_col_idx (A.to_string piv_val) in *) let m = if piv_row_idx <> row_idx then swap_rows m row_idx piv_row_idx else m in @@ -186,44 +219,13 @@ module ListMatrix: AbstractMatrix = let subtracted_m = List.mapi (fun idx row -> if idx <> row_idx then let scale = V.nth row piv_col_idx in sub_scaled_row row piv_row scale else row) normalized_m in - let m' = dec_mat_2D subtracted_m (row_idx + 1) (piv_col_idx + 1) in - main_loop subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) + let m' = cut_front_matrix subtracted_m (row_idx + 1) (piv_col_idx + 1) in + find_piv_and_reduce subtracted_m m' (row_idx + 1) (piv_col_idx + 1)) (* We start at piv_col_idx + 1 because every other col before that is zero at the bottom*) in - let m' = main_loop m m 0 0 in + let m' = find_piv_and_reduce m m 0 0 in if affeq_rows_are_valid m' then Some m' else None (* TODO: We can check this for each row, using the helper function row_is_invalid *) - (* This function return a tuple of row index and pivot position (column) in m *) - (* TODO: maybe we could use a Hashmap instead of a list? *) - let get_pivot_positions (m : t) : (int * int) list = - List.rev @@ List.fold_lefti ( - fun acc i row -> match V.find_first_non_zero row with - | None -> acc - | Some (pivot_col, _) -> (i, pivot_col) :: acc - ) [] m - - let assert_rref m = - let pivot_l = get_pivot_positions m in - let rec validate m i = - match m with - | [] -> () - | v::vs when (V.is_zero_vec v) -> - if List.exists (fun v -> not @@ V.is_zero_vec v) vs - then raise (Invalid_argument "Matrix not in rref: zero row!") - else () - | v::vs -> - let rec validate_vec pl = - match pivot_l with - | [] -> true - | (pr, pc)::ps -> - let target = if pr <> i then A.zero else A.one in - if V.nth v pc <>: target then false else validate_vec ps - in if validate_vec pivot_l then validate vs (i+1) else raise (Invalid_argument "Matrix not in rref: pivot column not empty!") - in validate m 0 - - (* TODO: Remove this! Just to suppress warning *) - let () = assert_rref (empty ()) - (* Sets the jth column to zero by subtracting multiples of v *) let reduce_col_with_vec m j v = let pivot_element = V.nth v j in @@ -319,10 +321,4 @@ module ListMatrix: AbstractMatrix = let is_covered_by m1 m2 = Timing.wrap "is_covered_by" (is_covered_by m1) m2 - let find_opt f m = - List.find_opt f m - - let map2 f m v = - let vector_length = V.length v in - List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m end \ No newline at end of file From 8c931a7b82d64963332818f3ce6755062f0a017d Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Mon, 23 Dec 2024 12:37:00 +0100 Subject: [PATCH 146/150] Optimize get_col for sparse; Some timing_wraps for matrix --- src/analyses/apron/affineEqualityAnalysis.apron.ml | 2 +- .../sparseImplementation/listMatrix.ml | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/analyses/apron/affineEqualityAnalysis.apron.ml b/src/analyses/apron/affineEqualityAnalysis.apron.ml index be94d389d1..fcb12606da 100644 --- a/src/analyses/apron/affineEqualityAnalysis.apron.ml +++ b/src/analyses/apron/affineEqualityAnalysis.apron.ml @@ -19,7 +19,7 @@ let spec_module: (module MCPSpec) Lazy.t = let module Priv = (val RelationPriv.get_priv ()) in let module Spec = struct - include SpecFunctor (Priv) (AD_A) (RelationPrecCompareUtil.DummyUtil) + include SpecFunctor (Priv) (AD) (RelationPrecCompareUtil.DummyUtil) let name () = "affeq" end in diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index c44c5e2c9b..a43167daff 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -72,9 +72,10 @@ module ListMatrix: AbstractMatrix = let add_empty_columns m cols = Timing.wrap "add_empty_cols" (add_empty_columns m) cols - let get_col m n = - (*let () = Printf.printf "get_col %i of m:\n%s\n%s\n" n (show m) (V.show (V.of_list @@ List.map (fun row -> V.nth row n) m)) in*) - V.of_list @@ List.map (fun row -> V.nth row n) m (* builds full col including zeros, maybe use sparselist instead? *) + let get_col m n = (* TODO: is this optimal? *) + (* V.of_list @@ List.map (fun row -> V.nth row n) m (* builds full col including zeros, maybe use sparselist instead? *) *) + V.of_sparse_list (num_rows m) @@ List.filteri_map (fun i row -> let value = V.nth row n in if value <>: A.zero then Some (i, value) else None) m + let get_col m n = Timing.wrap "get_col" (get_col m) n @@ -83,6 +84,8 @@ module ListMatrix: AbstractMatrix = (* List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m *) List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) + let set_col m new_col n = Timing.wrap "set_col" (set_col m) new_col n + let del_col m j = if num_cols m = 1 then empty () else @@ -101,6 +104,8 @@ module ListMatrix: AbstractMatrix = let vector_length = V.length v in List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m + let map2 f m v = Timing.wrap "Matrix.map2" (map2 f m) v + let map2i f m v = (* TODO: Optimize! We should probably do it like in map2 *) let rec map2i_min i acc m v = match m, v with @@ -110,6 +115,8 @@ module ListMatrix: AbstractMatrix = in map2i_min 0 [] m (V.to_list v) + let map2i f m v = Timing.wrap "Matrix.map2i" (map2i f m) v + let find_opt = List.find_opt let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) From de6acc71cadc84f89826927de465c28a08a6dcec Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Mon, 23 Dec 2024 13:52:47 +0100 Subject: [PATCH 147/150] Fix semantics Matrix.map2, changed Matrix.map2i but might still have to optimize --- src/cdomains/affineEquality/matrix.ml | 8 ++-- .../sparseImplementation/listMatrix.ml | 44 +++++++++++-------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/cdomains/affineEquality/matrix.ml b/src/cdomains/affineEquality/matrix.ml index b3433ee899..13bf12a4b6 100644 --- a/src/cdomains/affineEquality/matrix.ml +++ b/src/cdomains/affineEquality/matrix.ml @@ -29,6 +29,10 @@ sig val swap_rows: t -> int -> int -> t + val map2: (vec -> num -> vec) -> t -> vec -> t + + val map2i: (int -> vec-> num -> vec) -> t -> vec -> t + val add_empty_columns: t -> int array -> t val get_col: t -> int -> vec @@ -39,10 +43,6 @@ sig val del_cols: t -> int array -> t - val map2: (vec -> num -> vec) -> t -> vec -> t - - val map2i: (int -> vec-> num -> vec) -> t -> vec -> t - val find_opt: (vec -> bool) -> t -> vec option val append_matrices: t -> t -> t diff --git a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml index a43167daff..c35e8b02f9 100644 --- a/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml +++ b/src/cdomains/affineEquality/sparseImplementation/listMatrix.ml @@ -55,6 +55,28 @@ module ListMatrix: AbstractMatrix = let swap_rows m j k = List.mapi (fun i row -> if i = j then List.nth m k else if i = k then List.nth m j else row) m + let map2 f m v = + let vector_length = V.length v in + List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m + + let map2 f m v = Timing.wrap "Matrix.map2" (map2 f m) v + + let map2i f m v = (* TODO: Optimize! We should probably do it like in map2 *) + (* + let map2i f m v = (* TODO: Optimize! We should probably do it like in map2 *) + let rec map2i_min i acc m v = + match m, v with + | [], _ -> List.rev acc + | row :: rs, [] -> List.rev_append (row :: acc) rs + | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs + in + map2i_min 0 [] m (V.to_list v + *) + let vector_length = V.length v in + List.mapi (fun index row -> if index < vector_length then f index row (V.nth v index) else row ) m + + let map2i f m v = Timing.wrap "Matrix.map2i" (map2i f m) v + (* This only works if Array.modifyi has been removed from dim_add *) let add_empty_columns m cols = let cols = Array.to_list cols in @@ -80,9 +102,10 @@ module ListMatrix: AbstractMatrix = let get_col m n = Timing.wrap "get_col" (get_col m) n - let set_col m new_col n = (* TODO: Optimize! AND CURRENTLY WRONG SEMANTICS IF VECTOR LENGTH <> NUM_ROWS! *) + let set_col m new_col n = (* TODO: Optimize! The two commented methods have wrong semantics for wrong vector length *) (* List.mapi (fun row_idx row -> V.set_nth row n (V.nth new_col row_idx)) m *) - List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) + (* List.map2 (fun row value -> V.set_nth row n value) m (V.to_list new_col) *) + map2 (fun row value -> V.set_nth row n value) m new_col let set_col m new_col n = Timing.wrap "set_col" (set_col m) new_col n @@ -100,23 +123,6 @@ module ListMatrix: AbstractMatrix = let del_cols m cols = Timing.wrap "del_cols" (del_cols m) cols - let map2 f m v = - let vector_length = V.length v in - List.mapi (fun index row -> if index < vector_length then f row (V.nth v index) else row ) m - - let map2 f m v = Timing.wrap "Matrix.map2" (map2 f m) v - - let map2i f m v = (* TODO: Optimize! We should probably do it like in map2 *) - let rec map2i_min i acc m v = - match m, v with - | [], _ -> List.rev acc - | row :: rs, [] -> List.rev_append (row :: acc) rs - | row :: rs, value :: vs -> map2i_min (i + 1) (f i row value :: acc) rs vs - in - map2i_min 0 [] m (V.to_list v) - - let map2i f m v = Timing.wrap "Matrix.map2i" (map2i f m) v - let find_opt = List.find_opt let append_matrices m1 m2 = (* keeps dimensions of first matrix, what if dimensions differ?*) From c01b62743940f5737682d2184e49acb5cc5a6e18 Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Fri, 27 Dec 2024 23:45:35 +0100 Subject: [PATCH 148/150] comments --- .../sparseImplementation/sparseVector.ml | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index a3d499f922..bc357e0325 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -311,4 +311,55 @@ module SparseVector: AbstractVector = let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in {entries = entries'; len = v.len + v'.len} + let exists f v = (*TODO: optimize!; maybe we shouldn't if exists is never called with a =: A.zero*) + let c = v.len in + let rec exists_aux at f v = + match v with + | [] -> if at = 0 then false else f A.zero + | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs + in (exists_aux c f v.entries) + + let exists2 f v1 v2 = (* TODO: optimize! *) + List.exists2 f (to_list v1) (to_list v2) + + let rev v = + let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - 1 - idx, value)) v.entries in + {entries = entries'; len = v.len} + + let find2i f v v' = (* TODO: optimize! *) (*"Franzisco should do this!":~Franzisco*) + fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) + + let to_array v = + let vec = Array.make v.len A.zero in + List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; + vec + + let of_array a = + let len' = Array.length a in + let entries' = List.rev @@ Array.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc ) [] a in + {entries = entries'; len = len'} + + let copy v = v + + let of_sparse_list col_count ls = + {entries = ls; len = col_count} + + let to_sparse_list v = + v.entries + + let find_opt f v = (* TODO: Do we need this? And optimize!!!*) + List.find_opt f (to_list v) + + let starting_from_nth n v = + let entries' = List.filter_map (fun (idx, value) -> if idx < n then None else Some (idx - n, value)) v.entries in + {entries = entries'; len = v.len - n} + + let show v = + let t = to_list v in + let rec list_str l = + match l with + | [] -> "]" + | x :: xs -> (A.to_string x) ^ " " ^ (list_str xs) + in + "["^list_str t^"\n" end From 1a33f5599aae7a768e1c46ac932df532c1f60f4e Mon Sep 17 00:00:00 2001 From: CopperCableIsolator Date: Sat, 28 Dec 2024 00:13:14 +0100 Subject: [PATCH 149/150] findi_f_false_at_zero --- .../sparseImplementation/sparseVector.ml | 19 +++++++++++++++++-- src/cdomains/affineEquality/vector.ml | 2 ++ .../apron/affineEqualityDomain.apron.ml | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index bc357e0325..b085eb6f5a 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -252,7 +252,7 @@ module SparseVector: AbstractVector = let map2_f_preserves_zero f v1 v2 = Timing.wrap "map2_f_preserves_zero" (map2_f_preserves_zero f v1) v2 - let map2i f v1 v2 = (* TODO: optimize! *) + let map2i f v1 v2 = (*might more memory efficient, but definitly not faster (asymptotically)*) if v1.len <> v2.len then raise (Invalid_argument "Unequal lengths") else (*of_list (List.map2i f (to_list v) (to_list v'))*) let f_rem_zero idx acc e1 e2 = @@ -326,9 +326,24 @@ module SparseVector: AbstractVector = let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - 1 - idx, value)) v.entries in {entries = entries'; len = v.len} - let find2i f v v' = (* TODO: optimize! *) (*"Franzisco should do this!":~Franzisco*) + let find2i f v v' = fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) + let find2i_f_false_at_zero f v v' = (*Very welcome to change the name*) + let rec aux v1 v2 = + match v1, v2 with + | [], [] -> raise Not_found + | [], (yidx, yval)::ys -> if f A.zero yval then yidx else aux [] ys + | (xidx, xval)::xs, [] -> if f xval A.zero then xidx else aux xs [] + | (xidx, xval)::xs, (yidx, yval)::ys -> + match xidx - yidx with + | d when d < 0 -> if f xval A.zero then xidx else aux xs v2 + | d when d > 0 -> if f A.zero yval then yidx else aux v1 ys + | _ -> if f xval yval then xidx else aux xs ys + in + if v.len <> v'.len then raise (Invalid_argument "Unequal lengths") else + aux v.entries v'.entries + let to_array v = let vec = Array.make v.len A.zero in List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; diff --git a/src/cdomains/affineEquality/vector.ml b/src/cdomains/affineEquality/vector.ml index 799df35c0e..a72bb7a78b 100644 --- a/src/cdomains/affineEquality/vector.ml +++ b/src/cdomains/affineEquality/vector.ml @@ -53,6 +53,8 @@ sig val find2i: (num -> num -> bool) -> t -> t -> int + val find2i_f_false_at_zero: (num -> num -> bool) -> t -> t -> int + (* Returns optional tuple of position and value which was found*) val findi_val_opt: (num -> bool) -> t -> (int * num) Option.t diff --git a/src/cdomains/apron/affineEqualityDomain.apron.ml b/src/cdomains/apron/affineEqualityDomain.apron.ml index 2e9676382f..9ea34bbb2e 100644 --- a/src/cdomains/apron/affineEqualityDomain.apron.ml +++ b/src/cdomains/apron/affineEqualityDomain.apron.ml @@ -297,7 +297,7 @@ struct ( let col_a = Vector.rev col_a in let col_b = Vector.rev col_b in - let i = Vector.find2i (<>:) col_a col_b in + let i = Vector.find2i_f_false_at_zero (<>:) col_a col_b in let (x, y) = Vector.nth col_a i, Vector.nth col_b i in let r, diff = Vector.length col_a - (i + 1), x -: y in let a_r, b_r = Matrix.get_row a r, Matrix.get_row b r in From aaadeaa22b5c8d9b4ccdf05a383c58aa63452647 Mon Sep 17 00:00:00 2001 From: Kevin Adameit Date: Sat, 28 Dec 2024 13:55:16 +0100 Subject: [PATCH 150/150] Add find2i_f_false_at_zero to ArrayVector and remove duplicate code from sparseVector --- .../arrayImplementation/arrayVector.ml | 5 +- .../sparseImplementation/sparseVector.ml | 82 ++++--------------- 2 files changed, 19 insertions(+), 68 deletions(-) diff --git a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml index e90a5afbce..954a051dcc 100644 --- a/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml +++ b/src/cdomains/affineEquality/arrayImplementation/arrayVector.ml @@ -59,7 +59,7 @@ module ArrayVector: AbstractVector = let is_const_vec v = compare_length_with (filteri (fun i x -> (*Inefficient*) - compare_length_with v (i + 1) > 0 && x <>: A.zero) v) 1 = 0 + compare_length_with v (i + 1) > 0 && x <>: A.zero) v) 1 = 0 let nth = Array.get @@ -70,6 +70,9 @@ module ArrayVector: AbstractVector = let find2i f v1 v2 = Array.findi (uncurry f) (Array.combine v1 v2) (* TODO: iter2i? *) + let find2i_f_false_at_zero f v v' = + find2i f v v' + let to_array v = v let of_array v = v diff --git a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml index b085eb6f5a..10c62bc180 100644 --- a/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml +++ b/src/cdomains/affineEquality/sparseImplementation/sparseVector.ml @@ -163,6 +163,21 @@ module SparseVector: AbstractVector = let find2i f v v' = (* TODO: optimize! *) fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) + let find2i_f_false_at_zero f v v' = (*Very welcome to change the name*) + let rec aux v1 v2 = + match v1, v2 with + | [], [] -> raise Not_found + | [], (yidx, yval)::ys -> if f A.zero yval then yidx else aux [] ys + | (xidx, xval)::xs, [] -> if f xval A.zero then xidx else aux xs [] + | (xidx, xval)::xs, (yidx, yval)::ys -> + match xidx - yidx with + | d when d < 0 -> if f xval A.zero then xidx else aux xs v2 + | d when d > 0 -> if f A.zero yval then yidx else aux v1 ys + | _ -> if f xval yval then xidx else aux xs ys + in + if v.len <> v'.len then raise (Invalid_argument "Unequal lengths") else + aux v.entries v'.entries + (* Returns optional of (index * value) where f value evaluated to true *) let findi_val_opt f v = let rec find_zero_or_val vec last_col_idx = @@ -310,71 +325,4 @@ module SparseVector: AbstractVector = let append v v' = let entries' = v.entries @ List.map (fun (idx, value) -> (idx + v.len), value) v'.entries in {entries = entries'; len = v.len + v'.len} - - let exists f v = (*TODO: optimize!; maybe we shouldn't if exists is never called with a =: A.zero*) - let c = v.len in - let rec exists_aux at f v = - match v with - | [] -> if at = 0 then false else f A.zero - | (xi, xv)::xs -> if f xv then true else exists_aux (at - 1) f xs - in (exists_aux c f v.entries) - - let exists2 f v1 v2 = (* TODO: optimize! *) - List.exists2 f (to_list v1) (to_list v2) - - let rev v = - let entries' = List.rev @@ List.map (fun (idx, value) -> (v.len - 1 - idx, value)) v.entries in - {entries = entries'; len = v.len} - - let find2i f v v' = - fst @@ List.findi (fun _ (val1, val2) -> (uncurry f) (val1, val2)) (List.combine (to_list v) (to_list v')) - - let find2i_f_false_at_zero f v v' = (*Very welcome to change the name*) - let rec aux v1 v2 = - match v1, v2 with - | [], [] -> raise Not_found - | [], (yidx, yval)::ys -> if f A.zero yval then yidx else aux [] ys - | (xidx, xval)::xs, [] -> if f xval A.zero then xidx else aux xs [] - | (xidx, xval)::xs, (yidx, yval)::ys -> - match xidx - yidx with - | d when d < 0 -> if f xval A.zero then xidx else aux xs v2 - | d when d > 0 -> if f A.zero yval then yidx else aux v1 ys - | _ -> if f xval yval then xidx else aux xs ys - in - if v.len <> v'.len then raise (Invalid_argument "Unequal lengths") else - aux v.entries v'.entries - - let to_array v = - let vec = Array.make v.len A.zero in - List.iter (fun (idx, value) -> vec.(idx) <- value) v.entries; - vec - - let of_array a = - let len' = Array.length a in - let entries' = List.rev @@ Array.fold_lefti (fun acc i x -> if x <> A.zero then (i, x) :: acc else acc ) [] a in - {entries = entries'; len = len'} - - let copy v = v - - let of_sparse_list col_count ls = - {entries = ls; len = col_count} - - let to_sparse_list v = - v.entries - - let find_opt f v = (* TODO: Do we need this? And optimize!!!*) - List.find_opt f (to_list v) - - let starting_from_nth n v = - let entries' = List.filter_map (fun (idx, value) -> if idx < n then None else Some (idx - n, value)) v.entries in - {entries = entries'; len = v.len - n} - - let show v = - let t = to_list v in - let rec list_str l = - match l with - | [] -> "]" - | x :: xs -> (A.to_string x) ^ " " ^ (list_str xs) - in - "["^list_str t^"\n" end