From 99a6aaa79043dbd745406c2a16f4e3df386753b8 Mon Sep 17 00:00:00 2001 From: "Hichem R. A" <hichem.ait-el-hara@ocamlpro.com> Date: Tue, 11 Apr 2023 14:20:59 +0200 Subject: [PATCH] [Array] Added memoization of some RW rules --- colibri2/theories/array/Id.ml | 12 +- colibri2/theories/array/RWRules.ml | 407 +++++++++++++++++++---------- colibri2/theories/array/WEGraph.ml | 208 +++++++-------- colibri2/theories/array/common.ml | 165 +++++++++--- colibri2/theories/array/common.mli | 49 +++- 5 files changed, 524 insertions(+), 317 deletions(-) diff --git a/colibri2/theories/array/Id.ml b/colibri2/theories/array/Id.ml index d082659bf..b77cf3420 100644 --- a/colibri2/theories/array/Id.ml +++ b/colibri2/theories/array/Id.ml @@ -20,19 +20,13 @@ (*************************************************************************) module Array = Common.MkIdDom (struct - let n1 = "Array.Id.Array.merge_hooks" - let n2 = "Array.Id" - let n3 = "Array.Id.Array.new_id_hooks" + let name = "Array.Id" end) module Index = Common.MkIdDom (struct - let n1 = "Array.Id.Index.merge_hooks" - let n2 = "Array.Index_id" - let n3 = "Array.Id.Index.new_id_hooks" + let name = "Array.Index.Id" end) module Value = Common.MkIdDom (struct - let n1 = "Array.Id.Value.merge_hooks" - let n2 = "Array.Value_id" - let n3 = "Array.Id.Value.new_id_hooks" + let name = "Array.Value.Id" end) diff --git a/colibri2/theories/array/RWRules.ml b/colibri2/theories/array/RWRules.ml index 0f791f261..5a67c8d58 100644 --- a/colibri2/theories/array/RWRules.ml +++ b/colibri2/theories/array/RWRules.ml @@ -27,6 +27,63 @@ open Colibri2_theories_quantifiers module GHT = Datastructure.Hashtbl (Ground) module GTHT = Datastructure.Hashtbl (Ground.Ty) +(** disjunction 1: (a,b,i,j) -> (i = j) \/ (a[j] = b[j]) *) +module D1db = + SHT + (struct + include I4 + + let sort (a, b, i, j, ty1, ty2) = + let a, b = if a <= b then (a, b) else (b, a) in + let i, j = if i <= j then (i, j) else (j, i) in + (a, b, i, j, ty1, ty2) + end) + (struct + type t = unit + + let name = "D1db" + let pp = Pp.unit + end) + +(** disjunction 2: (a,b) -> (a = b) ⋠(a[k] ≠b[k]) *) +module D2db = + SHT + (struct + include I2 + + let sort (a, b, ty1, ty2) = + let a, b = if a <= b then (a, b) else (b, a) in + (a, b, ty1, ty2) + end) + (struct + type t = unit + + let name = "D2db" + let pp = Pp.unit + end) + +let get_ss_nodes env (subst : Ground.Subst.t) = + let b_n = Expr.Term.Var.M.find STV.vb subst.term in + let i_n = Expr.Term.Var.M.find STV.vi subst.term in + let j_n = Expr.Term.Var.M.find STV.vj subst.term in + let ind_gty = Expr.Ty.Var.M.find STV.ind_ty_var subst.ty in + let val_gty = Expr.Ty.Var.M.find STV.val_ty_var subst.ty in + let a_n = + try Expr.Term.Var.M.find STV.va subst.term + with Not_found -> + let v_n = Expr.Term.Var.M.find STV.vv subst.term in + ground_apply env Expr.Term.Const.Array.store [ ind_gty; val_gty ] + [ b_n; i_n; v_n ] + in + (a_n, b_n, i_n, j_n, ind_gty, val_gty) + +(* let get_ext_nodes (subst : Ground.Subst.t) = + let a_n = Expr.Term.Var.M.find STV.va subst.term in + let b_n = Expr.Term.Var.M.find STV.vb subst.term in + let ind_gty = Expr.Ty.Var.M.find STV.ind_ty_var subst.ty in + let val_gty = Expr.Ty.Var.M.find STV.val_ty_var subst.ty in + (a_n, b_n, ind_gty, val_gty) *) + type size = Inf | Finite of { num : int; size : int } [@@deriving show] let check_gty_num_size = @@ -52,24 +109,40 @@ let check_gty_num_size = (* ⇓: a ≡ b[i <- v], a[j] |> (i = j) \/ a[j] = b[j] *) let adown_pattern, adown_run = - let a = mk_store_term STV.tb STV.ti STV.tv in - let term = mk_select_term a STV.tj in + (* (a,b,i,j) *) + let a_term = mk_store_term STV.tb STV.ti STV.tv in + let term = mk_select_term a_term STV.tj in let adown_pattern = Pattern.of_term_exn ~subst:Ground.Subst.empty term in let adown_run env subst = Debug.dprintf2 debug "Found adown with %a" Ground.Subst.pp subst; - let n = convert ~subst env term in - let v = - convert ~subst env - (Expr.Term._or - [ - Expr.Term.eq STV.ti STV.tj; - Expr.Term.eq (mk_select_term a STV.tj) - (mk_select_term STV.tb STV.tj); - ]) - in - Egraph.register env n; - Egraph.register env v; - Boolean.set_true env v + let a_n, b_n, i_n, j_n, ind_gty, val_gty = get_ss_nodes env subst in + match + let a_id = Id.Array.get_id env a_n in + let b_id = Id.Array.get_id env b_n in + let i_id = Id.Index.get_id env i_n in + let j_id = Id.Index.get_id env j_n in + D1db.find_opt env (a_id, b_id, i_id, j_id, ind_gty, val_gty) + with + | Some () -> () + | None | (exception NoIdFound _) -> + let v = + convert ~subst env + (Expr.Term._or + [ + Expr.Term.eq STV.ti STV.tj; + Expr.Term.eq + (mk_select_term a_term STV.tj) + (mk_select_term STV.tb STV.tj); + ]) + in + Egraph.register env v; + Boolean.set_true env v; + Id.Array.set_id env a_n; + let a_id = Id.Array.get_id env a_n in + let b_id = Id.Array.get_id env b_n in + let i_id = Id.Index.get_id env i_n in + let j_id = Id.Index.get_id env j_n in + D1db.set env (a_id, b_id, i_id, j_id, ind_gty, val_gty) () in (adown_pattern, adown_run) @@ -85,19 +158,36 @@ let aup_pattern, aup_run = let aup_pattern_bis = Pattern.of_term_exn ~subst term_bis in let aup_run_bis env subst_bis = let subst = Ground.Subst.distinct_union subst_bis subst in + (* (a,b,i,j) *) Debug.dprintf2 debug "Found aup2 with %a" Ground.Subst.pp subst; - let v = - convert ~subst env - (Expr.Term._or - [ - Expr.Term.eq STV.ti STV.tj; - Expr.Term.eq - (mk_select_term term STV.tj) - (mk_select_term STV.tb STV.tj); - ]) - in - Egraph.register env v; - Boolean.set_true env v + let a_n, b_n, i_n, j_n, ind_gty, val_gty = get_ss_nodes env subst in + match + let a_id = Id.Array.get_id env a_n in + let b_id = Id.Array.get_id env b_n in + let i_id = Id.Index.get_id env i_n in + let j_id = Id.Index.get_id env j_n in + D1db.find_opt env (a_id, b_id, i_id, j_id, ind_gty, val_gty) + with + | Some () -> () + | None | (exception NoIdFound _) -> + let v = + convert ~subst env + (Expr.Term._or + [ + Expr.Term.eq STV.ti STV.tj; + Expr.Term.eq + (mk_select_term term STV.tj) + (mk_select_term STV.tb STV.tj); + ]) + in + Egraph.register env v; + Boolean.set_true env v; + Id.Array.set_id env a_n; + let a_id = Id.Array.get_id env a_n in + let b_id = Id.Array.get_id env b_n in + let i_id = Id.Index.get_id env i_n in + let j_id = Id.Index.get_id env j_n in + D1db.set env (a_id, b_id, i_id, j_id, ind_gty, val_gty) () in InvertedPath.add_callback env aup_pattern_bis aup_run_bis in @@ -105,6 +195,7 @@ let aup_pattern, aup_run = (* ⇑ᵣ: a ≡ b[i <- v], b[j], b ∈ non-linear |> (i = j) \/ a[j] = b[j] *) let raup_pattern, raup_run = + (* (a,b,i,j) *) let term = mk_store_term STV.tb STV.ti STV.tv in let raup_pattern = Pattern.of_term_exn ~subst:Ground.Subst.empty term in let raup_run env subst = @@ -116,25 +207,41 @@ let raup_pattern, raup_run = let raup_run_bis env subst_bis = let subst = Ground.Subst.distinct_union subst_bis subst in Debug.dprintf2 debug "Found raup2 with %a" Ground.Subst.pp subst; - let bn = convert ~subst env STV.tb in - match Egraph.get_dom env Linearity_dom.key bn with - | Some NonLinear -> - let v = - convert ~subst env - (Expr.Term._or - [ - Expr.Term.eq STV.ti STV.tj; - Expr.Term.eq - (mk_select_term term STV.tj) - (mk_select_term STV.tb STV.tj); - ]) - in - Debug.dprintf2 debug "Apply raup2: set %a to true" Node.pp v; - Egraph.register env v; - Boolean.set_true env v - | _ -> - Debug.dprintf2 debug "Do not apply raup2: %a is not non-linear" - Node.pp bn + let a_n, b_n, i_n, j_n, ind_gty, val_gty = get_ss_nodes env subst in + match + let a_id = Id.Array.get_id env a_n in + let b_id = Id.Array.get_id env b_n in + let i_id = Id.Index.get_id env i_n in + let j_id = Id.Index.get_id env j_n in + D1db.find_opt env (a_id, b_id, i_id, j_id, ind_gty, val_gty) + with + | Some () -> () + | None | (exception NoIdFound _) -> ( + let bn = convert ~subst env STV.tb in + match Egraph.get_dom env Linearity_dom.key bn with + | Some NonLinear -> + let v = + convert ~subst env + (Expr.Term._or + [ + Expr.Term.eq STV.ti STV.tj; + Expr.Term.eq + (mk_select_term term STV.tj) + (mk_select_term STV.tb STV.tj); + ]) + in + Debug.dprintf2 debug "Apply raup2: set %a to true" Node.pp v; + Egraph.register env v; + Boolean.set_true env v; + Id.Array.set_id env a_n; + let a_id = Id.Array.get_id env a_n in + let b_id = Id.Array.get_id env b_n in + let i_id = Id.Index.get_id env i_n in + let j_id = Id.Index.get_id env j_n in + D1db.set env (a_id, b_id, i_id, j_id, ind_gty, val_gty) () + | _ -> + Debug.dprintf2 debug "Do not apply raup2: %a is not non-linear" + Node.pp bn) in InvertedPath.add_callback env raup_pattern_bis raup_run_bis in @@ -152,84 +259,93 @@ let const_read_pattern, const_read_run = in (const_read_pattern, const_read_run) -let apply_res_ext_1_1_aux _env ind_gty val_gty l tyvt = +let apply_res_ext_1_1_aux env ind_gty val_gty l = Debug.dprintf2 debug "Application of the res-ext-1-1 rule on %a" (Fmt.list ~sep:Fmt.comma Node.pp) l; - let rec aux tnl = - match tnl with - | (nterm, _) :: t -> - let nterms = - List.fold_left - (fun acc (oterm, _) -> distinct_arrays_term nterm oterm :: acc) - [] t - in - List.rev_append nterms (aux t) - | [] -> [] - in - let _, tsubst, tnl = - List.fold_left - (fun (cnt, tsubst, tns) node -> - let anv = Expr.Term.Var.mk (Format.sprintf "a%d" cnt) tyvt in - let anvt = Expr.Term.of_var anv in - (cnt + 1, (anv, node) :: tsubst, (anvt, node) :: tns)) - (0, [], []) l + let rec aux l = + match l with + | [] -> () + | n1 :: t -> + List.iter + (fun n2 -> + (* (a,b) *) + let id1 = Id.Array.get_id env n1 in + let id2 = Id.Array.get_id env n2 in + match D2db.find_opt env (id1, id2, ind_gty, val_gty) with + | Some () -> () + | None -> + let diseq = mk_distinct_arrays env n1 n2 ind_gty val_gty in + Egraph.register env diseq; + Boolean.set_true env diseq; + D2db.set env (id1, id2, ind_gty, val_gty) ()) + t; + aux t in - let tysubst = [ (STV.ind_ty_var, ind_gty); (STV.val_ty_var, val_gty) ] in - let subst = mk_subst tsubst tysubst in - (aux tnl, subst) + aux l -let apply_res_ext_1_2_aux env ind_gty val_gty l tyvt = +let apply_res_ext_1_2_aux env ind_gty val_gty l = Debug.dprintf2 debug "Application of the res-ext-1-2 rule on %a" (Fmt.list ~sep:Fmt.comma Node.pp) l; - let rec aux (tnl : (Expr.term * int) list) = - match tnl with - | (nterm, idn) :: t -> ( - match WEGraph.WEG.find_opt env idn with + let rec aux2 l = + match l with + | [] -> () + | (n1, id1) :: t -> ( + match WEGraph.WEG.find_opt env id1 with + | None -> aux2 t | Some (_, m) -> - let nterms = - List.fold_left - (fun acc (oterm, oid) -> - if DInt.M.mem oid m then - distinct_arrays_term nterm oterm :: acc - else acc) - [] t - in - List.rev_append nterms (aux t) - | None -> aux t) - | [] -> [] + List.iter + (fun (n2, id2) -> + if DInt.M.mem id2 m then + (* (a,b) *) + match D2db.find_opt env (id1, id2, ind_gty, val_gty) with + | Some () -> () + | None -> + let diseq = + mk_distinct_arrays env n1 n2 ind_gty val_gty + in + Egraph.register env diseq; + Boolean.set_true env diseq; + D2db.set env (id1, id2, ind_gty, val_gty) ()) + t) in - let _, tsubst, tnl = - List.fold_left - (fun (cnt, tsubst, tns) node -> - let anv = Expr.Term.Var.mk (Format.sprintf "a%d" cnt) tyvt in - let anvt = Expr.Term.of_var anv in - (cnt + 1, (anv, node) :: tsubst, (anvt, Id.Array.get_id env node) :: tns)) - (0, [], []) l + let rec aux1 l = + match l with + | [] -> () + | n1 :: t -> ( + let id1 = Id.Array.get_id env n1 in + match WEGraph.WEG.find_opt env id1 with + | Some (_, m) -> + let t' = + List.rev_map + (fun n2 -> + let id2 = Id.Array.get_id env n2 in + (if DInt.M.mem id2 m then + (* (a,b) *) + match D2db.find_opt env (id1, id2, ind_gty, val_gty) with + | Some () -> () + | None -> + let diseq = + mk_distinct_arrays env n1 n2 ind_gty val_gty + in + Egraph.register env diseq; + Boolean.set_true env diseq; + D2db.set env (id1, id2, ind_gty, val_gty) ()); + (n2, id2)) + t + in + aux2 t' + | None -> aux1 t) in - let tysubst = [ (STV.ind_ty_var, ind_gty); (STV.val_ty_var, val_gty) ] in - let subst = mk_subst tsubst tysubst in - (aux tnl, subst) + aux1 l (* (a = b) ≡ false |> (a[k] ≠b[k]) *) let apply_res_ext_1_1, apply_res_ext_1_2 = let apply_res_ext_1 f env s = let l = Node.S.elements s in match get_array_gty_args env (List.hd l) with - | ind_gty, val_gty -> ( - let tyvt = Expr.Ty.array STV.ind_ty STV.val_ty in - let l, subst = f env ind_gty val_gty l tyvt in - match l with - | [] -> () - | [ t ] -> - let n = convert ~subst env t in - Egraph.register env n; - Boolean.set_true env n - | l -> - let n = convert ~subst env (Expr.Term._and l) in - Egraph.register env n; - Boolean.set_true env n) + | ind_gty, val_gty -> f env ind_gty val_gty l | exception Not_An_Array _ -> () in let apply_res_ext_1_1 = apply_res_ext_1 apply_res_ext_1_1_aux in @@ -248,34 +364,38 @@ let get_foreign_neighbours env a arr_set = else acc) arr_set Node.S.empty -let apply_ext env a b = - let ind_gty, val_gty = array_gty_args (get_array_gty env a) in - let eq = Equality.equality env [ a; b ] in - let diseq = mk_distinct_arrays env a b ind_gty val_gty in - Debug.dprintf4 debug "Application of the extensionality rule on %a and %a" - Node.pp a Node.pp b; - Egraph.register env eq; - Egraph.register env diseq; - Choice.register_global env - { - print_cho = "Decision from extensionality application."; - prio = 1; - choice = - (fun env -> - match (Boolean.is env eq, Boolean.is env diseq) with - | Some true, _ -> DecNo - | _, Some true -> DecNo - | _ -> - DecTodo - [ - (fun env -> - Boolean.set_true env eq; - Boolean.set_false env diseq); - (fun env -> - Boolean.set_false env eq; - Boolean.set_true env diseq); - ]); - } +let apply_ext env (a, id1) (b, id2) ind_gty val_gty = + (* (a,b) *) + match D2db.find_opt env (id1, id2, ind_gty, val_gty) with + | Some () -> () + | None -> + let eq = Equality.equality env [ a; b ] in + let diseq = mk_distinct_arrays env a b ind_gty val_gty in + Debug.dprintf4 debug "Application of the extensionality rule on %a and %a" + Node.pp a Node.pp b; + Egraph.register env eq; + Egraph.register env diseq; + Choice.register_global env + { + print_cho = "Decision from extensionality application."; + prio = 1; + choice = + (fun env -> + match (Boolean.is env eq, Boolean.is env diseq) with + | Some true, _ -> DecNo + | _, Some true -> DecNo + | _ -> + DecTodo + [ + (fun env -> + Boolean.set_true env eq; + Boolean.set_false env diseq); + (fun env -> + Boolean.set_false env eq; + Boolean.set_true env diseq); + ]); + }; + D2db.set env (id1, id2, ind_gty, val_gty) () (* a, b, {a,b} ⊆ foreign |> (a = b) ⋠(a[k] ≠b[k]) *) let apply_res_ext_2_1, apply_res_ext_2_2 = @@ -300,14 +420,27 @@ let apply_res_ext_2_1, apply_res_ext_2_2 = let apply_res_ext_2_1 env aty a = Debug.dprintf2 debug "Application of the res-ext-2-1 rule on %a" Node.pp a; apply_res_ext_2 - (fun env a fa_set -> Node.S.iter (apply_ext env a) fa_set) + (fun env a fa_set -> + let ind_gty, val_gty = array_gty_args (get_array_gty env a) in + let id1 = Id.Array.get_id env a in + Node.S.iter + (fun b -> + let id2 = Id.Array.get_id env b in + apply_ext env (a, id1) (b, id2) ind_gty val_gty) + fa_set) env aty a in let apply_res_ext_2_2 env aty a = Debug.dprintf2 debug "Application of the res-ext-2-2 rule on %a" Node.pp a; apply_res_ext_2 (fun env a fa_set -> - Node.S.iter (apply_ext env a) (get_foreign_neighbours env a fa_set)) + let ind_gty, val_gty = array_gty_args (get_array_gty env a) in + let id1 = Id.Array.get_id env a in + Node.S.iter + (fun b -> + let id2 = Id.Array.get_id env b in + apply_ext env (a, id1) (b, id2) ind_gty val_gty) + (get_foreign_neighbours env a fa_set)) env aty a in (apply_res_ext_2_1, apply_res_ext_2_2) diff --git a/colibri2/theories/array/WEGraph.ml b/colibri2/theories/array/WEGraph.ml index 5f5f64d37..8a1946443 100644 --- a/colibri2/theories/array/WEGraph.ml +++ b/colibri2/theories/array/WEGraph.ml @@ -24,39 +24,15 @@ open Colibri2_popop_lib open Popop_stdlib open Common -module EHT = MkIHT (struct +module ITN = MkIHT (struct type t = Node.t let pp = Node.pp - let name = "WEGraph.Edges.Nodes" + let name = "WEGraph.IdsToNodes" end) -module VHT = MkIHT (struct - type t = Node.t - - let pp = Node.pp - let name = "WEGraph.Vertices.Nodes" -end) - -module ValHT = MkIHT (struct - type t = Node.t - - let pp = Node.pp - let name = "WEGraph.Values.Nodes" -end) - -let pp_eid env fmt i = - match EHT.find_opt env i with - | Some n -> Format.fprintf fmt "%a{id = %d}" Node.pp n i - | None -> Format.fprintf fmt "Not_found{id = %d}" i - -let pp_vid env fmt i = - match VHT.find_opt env i with - | Some n -> Format.fprintf fmt "%a{id = %d}" Node.pp n i - | None -> Format.fprintf fmt "Not_found{id = %d}" i - -let pp_val_id env fmt i = - match ValHT.find_opt env i with +let pp_nid env fmt i = + match ITN.find_opt env i with | Some n -> Format.fprintf fmt "%a{id = %d}" Node.pp n i | None -> Format.fprintf fmt "Not_found{id = %d}" i @@ -152,26 +128,26 @@ module Values = struct let check_store env a b i v = Debug.dprintf8 debug "WEGraph.Values.check_store: a=%a b=%a i=%a v=%a" - (pp_eid env) a (pp_eid env) b (pp_vid env) i (pp_val_id env) v; + (pp_nid env) a (pp_nid env) b (pp_nid env) i (pp_nid env) v; Option.iter (fun (_, s2) -> if a <> b && IDS.mem (v, b) s2 then ( Debug.dprintf8 debug "WEGraph.Values.do_mk_eq1: a=%a b=%a (v=%a i=%a)" - (pp_eid env) a (pp_eid env) b (pp_val_id env) v (pp_vid env) i; - do_mk_eq env (EHT.find env a) (EHT.find env b))) + (pp_nid env) a (pp_nid env) b (pp_nid env) v (pp_nid env) i; + do_mk_eq env (ITN.find env a) (ITN.find env b))) (VIHT.find_opt env i) let check_select env u c j = Debug.dprintf6 debug "WEGraph.Values.check_select: u=%a c=%a j=%a" - (pp_val_id env) u (pp_eid env) c (pp_vid env) j; + (pp_nid env) u (pp_nid env) c (pp_nid env) j; Option.iter (fun (s1, _) -> ITS.iter (* find a way not to iterate *) (fun (a, b, i) -> if a <> b && b = c && a = c && j = i then ( Debug.dprintf8 debug "WEGraph.Values.do_mk_eq2: %a %a (%a %a)" - (pp_eid env) a (pp_eid env) b (pp_val_id env) u (pp_vid env) j; - do_mk_eq env (EHT.find env a) (EHT.find env b))) + (pp_nid env) a (pp_nid env) b (pp_nid env) u (pp_nid env) j; + do_mk_eq env (ITN.find env a) (ITN.find env b))) s1) (VHT.find_opt env u) @@ -180,11 +156,11 @@ module Values = struct | Some (s, _) when ITS.mem (a, i, v) s -> Debug.dprintf8 debug "WEGraph.Values.add_store: a=%a b=%a i=%a v=%a (Already present)" - (pp_eid env) a (pp_eid env) b (pp_vid env) i (pp_val_id env) v; + (pp_nid env) a (pp_nid env) b (pp_nid env) i (pp_nid env) v; () | _ -> Debug.dprintf8 debug "WEGraph.Values.add_store: a=%a b=%a i=%a v=%a" - (pp_eid env) a (pp_eid env) b (pp_vid env) i (pp_val_id env) v; + (pp_nid env) a (pp_nid env) b (pp_nid env) i (pp_nid env) v; A1HT.add_store env b (a, i, v); VHT.add_store env v (a, b, i); VIHT.add_store env i (a, b, v); @@ -196,11 +172,11 @@ module Values = struct | Some (_, s) when IDS.mem (u, j) s -> Debug.dprintf6 debug "WEGraph.Values.add_select: u=%a c=%a j=%a (Already present)" - (pp_val_id env) u (pp_eid env) c (pp_vid env) j; + (pp_nid env) u (pp_nid env) c (pp_nid env) j; () | _ -> Debug.dprintf6 debug "WEGraph.Values.add_select: u=%a c=%a j=%a" - (pp_val_id env) u (pp_eid env) c (pp_vid env) j; + (pp_nid env) u (pp_nid env) c (pp_nid env) j; A1HT.add_select env c (u, j); VHT.add_select env u (c, j); VIHT.add_select env j (u, c); @@ -209,8 +185,8 @@ module Values = struct let subst_kr kid rid aid = if aid = rid then Some kid else None let eq_arrays_norm env kid rid = - Debug.dprintf4 debug "WEGraph.Values.eq_arrays_norm: %a %a " (pp_eid env) - kid (pp_eid env) rid; + Debug.dprintf4 debug "WEGraph.Values.eq_arrays_norm: %a %a " (pp_nid env) + kid (pp_nid env) rid; (* res-arrays *) Option.iter (fun rm -> @@ -290,8 +266,8 @@ module Values = struct (A1HT.find_opt env rid) let eq_indices_norm env kid rid = - Debug.dprintf4 debug "WEGraph.Values.eq_indices_norm: %a %a " (pp_vid env) - kid (pp_vid env) rid; + Debug.dprintf4 debug "WEGraph.Values.eq_indices_norm: %a %a " (pp_nid env) + kid (pp_nid env) rid; Option.iter (fun (rsto, rsel) -> let ksto, ksel = @@ -339,8 +315,8 @@ module Values = struct (VIHT.find_opt env rid) let eq_values_norm env kid rid = - Debug.dprintf4 debug "WEGraph.Values.eq_values_norm: %a %a " (pp_val_id env) - kid (pp_val_id env) rid; + Debug.dprintf4 debug "WEGraph.Values.eq_values_norm: %a %a " (pp_nid env) + kid (pp_nid env) rid; Option.iter (fun (rsto, rsel) -> let ksto, ksel = @@ -455,20 +431,20 @@ module WEG = struct let rec aux (m : DInt.t DInt.M.t DInt.M.t) = match DInt.M.min_binding m with | nid, mnp when DInt.M.is_empty mnp -> - Format.fprintf fmt " \"%a\";@." Node.pp (EHT.find env nid); + Format.fprintf fmt " \"%a\";@." Node.pp (ITN.find env nid); aux (DInt.M.remove nid m) | nid, mnp -> - let nidn = EHT.find env nid in + let nidn = ITN.find env nid in aux @@ DInt.M.fold (fun inid (kid : DInt.t) (nm : DInt.t DInt.M.t DInt.M.t) -> - let inidn = EHT.find env inid in - let k = VHT.find env kid in + let inidn = ITN.find env inid in + let k = ITN.find env kid in match DInt.M.find_opt inid nm with | Some inpm -> ( match DInt.M.find_opt nid inpm with | Some kid' -> - let k' = VHT.find env kid' in + let k' = ITN.find env kid' in if Egraph.is_equal env k k' then ( pp_arrow fmt nidn inidn k ~options:[ ("dir", "both") ]; @@ -653,7 +629,7 @@ module KnownValues = struct Debug.dprintf6 debug "Adding (%a) the known values of %a (and its neighbours excluding \ %a)" - (DInt.M.pp Node.pp) ppg (pp_eid env) src_id (Opt.pp DInt.pp) except; + (DInt.M.pp Node.pp) ppg (pp_nid env) src_id (Opt.pp DInt.pp) except; let new_ppg = add_kvs env src_id ppg in ppg_neighbours env ?except src_id new_ppg @@ -663,18 +639,18 @@ module KnownValues = struct let ns = match except with Some e -> DInt.M.remove e ns | None -> ns in Debug.dprintf8 debug "Propagating (%a) over the neighbours (%a) of %a (excluding %a)" - (DInt.M.pp Node.pp) ppg (DInt.M.pp DInt.pp) ns (pp_eid env) src_id + (DInt.M.pp Node.pp) ppg (DInt.M.pp DInt.pp) ns (pp_nid env) src_id (Opt.pp DInt.pp) except; DInt.M.iter (fun dest_id dest_ind_id -> - let n_vrt = VHT.find env dest_ind_id in + let n_vrt = ITN.find env dest_ind_id in let dest_ppg = DInt.M.filter (fun ppg_ind ppg_val -> if is_nppg env dest_ind_id ppg_ind then false else if (not (is_already_ppg env dest_id ppg_ind ppg_val)) - && Equality.is_disequal env (VHT.find env ppg_ind) n_vrt + && Equality.is_disequal env (ITN.find env ppg_ind) n_vrt then true else ( add_nppg env dest_ind_id ppg_ind; @@ -712,10 +688,10 @@ module KnownValues = struct | None, None -> () let split_nppgs env ind s = - let indn = VHT.find env ind in + let indn = ITN.find env ind in DInt.S.fold (fun iid (acc1, acc2) -> - let iidn = VHT.find env iid in + let iidn = ITN.find env iid in if Equality.is_disequal env indn iidn then (DInt.S.add iid acc1, acc2) else (acc1, DInt.S.add iid acc2)) s @@ -819,7 +795,7 @@ module KnownValues = struct let ppg_s = match (NP.find_opt env ind1, NP.find_opt env ind2) with | Some nps1, Some nps2 -> - let ind1n, ind2n = (VHT.find env ind1, VHT.find env ind2) in + let ind1n, ind2n = (ITN.find env ind1, ITN.find env ind2) in let ppg_s, nnps = DInt.S.fold (fun iid (acc1, acc2) -> @@ -828,7 +804,7 @@ module KnownValues = struct (acc1, acc2)) else if DInt.S.mem iid nps2 then (acc1, DInt.S.add iid acc2) else - let iidn = VHT.find env iid in + let iidn = ITN.find env iid in if Equality.is_disequal env ind2n iidn then ( rm_np_id env iid ind1; (DInt.S.add iid acc1, acc2)) @@ -844,7 +820,7 @@ module KnownValues = struct else if DInt.S.mem iid nps1 then (* it was already added in the fold over nps1 *) (acc1, acc2) else - let iidn = VHT.find env iid in + let iidn = ITN.find env iid in if Equality.is_disequal env ind1n iidn then (DInt.S.add iid acc1, acc2) else ( @@ -856,12 +832,12 @@ module KnownValues = struct NP.remove env ind2; ppg_s | None, Some nps2 -> - let ind1n = VHT.find env ind1 in + let ind1n = ITN.find env ind1 in let ppg_s, _nnps = DInt.S.fold (fun iid (acc1, acc2) -> rm_np_id env iid ind2; - let iidn = VHT.find env iid in + let iidn = ITN.find env iid in if Equality.is_disequal env ind1n iidn then (DInt.S.add iid acc1, acc2) else ( @@ -873,11 +849,11 @@ module KnownValues = struct NP.remove env ind2; ppg_s | Some nps1, None -> - let ind2n = VHT.find env ind2 in + let ind2n = ITN.find env ind2 in let ppg_s, _nnps = DInt.S.fold (fun iid (acc1, acc2) -> - let iidn = VHT.find env iid in + let iidn = ITN.find env iid in if Equality.is_disequal env ind2n iidn then ( rm_np_id env iid ind1; (DInt.S.add iid acc1, acc2)) @@ -925,7 +901,7 @@ let are_neighbours env id1 id2 = | Some (_, m) -> DInt.M.mem id2 m let rm_neighbour env (kid, knode) (rid, rnode) iid = - let ind = VHT.find env iid in + let ind = ITN.find env iid in WEG.change env kid ~f:(function | None -> raise (Not_a_neighbour (knode, rnode, ind)) | Some (m1, m2) -> @@ -943,7 +919,7 @@ let rm_neighbour env (kid, knode) (rid, rnode) iid = DInt.M.change (function | Some iid' -> - let ind' = VHT.find env iid' in + let ind' = ITN.find env iid' in assert (Egraph.is_equal env ind ind'); None | None -> raise (Not_a_neighbour (knode, rnode, ind))) @@ -979,15 +955,15 @@ let add_neighbour vid aid = function DInt.M.add aid vid m2 ) let add_edge_aux env (a, aid) (b, bid) (i, iid) ind_gty val_gty = - Debug.dprintf6 debug "WEGraph: add_edge_aux %a between %a and %a" (pp_vid env) - iid (pp_eid env) aid (pp_eid env) bid; + Debug.dprintf6 debug "WEGraph: add_edge_aux %a between %a and %a" (pp_nid env) + iid (pp_nid env) aid (pp_nid env) bid; match DInt.M.find_opt bid (snd (WEG.find env aid)) with | Some jid when iid = jid -> () | None -> WEG.change env aid ~f:(add_neighbour iid bid); WEG.change env bid ~f:(add_neighbour iid aid) | Some jid -> - let j = VHT.find env jid in + let j = ITN.find env jid in let ij_eq = Equality.equality env [ i; j ] in let ij_neq = Equality.disequality env [ i; j ] in Egraph.register env ij_eq; @@ -1052,20 +1028,20 @@ let add_edge ?from_merge env aid bid iid = as a neighbour to all the nodes in the complete graph formed by all the array nodes which differ on the same index k. *) Debug.dprintf6 debug "WEGraph: adding the edge %a between %a and %a" - (pp_vid env) iid (pp_eid env) aid (pp_eid env) bid; + (pp_nid env) iid (pp_nid env) aid (pp_nid env) bid; if aid <> bid (* && not (are_k_neighbours env aid bid iid) *) then ( let ind_gty, val_gty = - array_gty_args (get_node_ty env (EHT.find env aid)) + array_gty_args (get_node_ty env (ITN.find env aid)) in let ank = get_k_neighbours env aid iid in let bnk = get_k_neighbours env bid iid in - let ind = VHT.find env iid in + let ind = ITN.find env iid in DInt.S.iter (fun id1 -> DInt.S.iter (fun id2 -> - let n1 = EHT.find env id1 in - let n2 = EHT.find env id2 in + let n1 = ITN.find env id1 in + let n2 = ITN.find env id2 in if (not (are_neighbours env id1 id2)) && id1 <> id2 then ( Vertices.change env iid ~f:(function | Some s -> Some (Vertex.S.add (id1, id2) s) @@ -1080,22 +1056,22 @@ let add_edge ?from_merge env aid bid iid = ~msg: (Fmt.str "_merge_neighbours %a %a\\n add edge between %a and %a with %a" - (pp_eid env) kid (pp_eid env) rid (pp_eid env) aid (pp_eid env) - bid Node.pp (VHT.find env iid)) + (pp_nid env) kid (pp_nid env) rid (pp_nid env) aid (pp_nid env) + bid Node.pp (ITN.find env iid)) env () | None -> WEG.pp_dot_wegraph ~msg: - (Fmt.str "Add edge between %a and %a with %a" (pp_eid env) aid - (pp_eid env) bid Node.pp (VHT.find env iid)) + (Fmt.str "Add edge between %a and %a with %a" (pp_nid env) aid + (pp_nid env) bid Node.pp (ITN.find env iid)) env ()) let rm_edge ?from_merge env aid bid iid = - Debug.dprintf6 debug "WEGraph: rm_edge %a between %a and %a" (pp_vid env) iid - (pp_eid env) aid (pp_eid env) bid; + Debug.dprintf6 debug "WEGraph: rm_edge %a between %a and %a" (pp_nid env) iid + (pp_nid env) aid (pp_nid env) bid; if aid <> bid then ( - let an = EHT.find env aid in - let bn = EHT.find env bid in + let an = ITN.find env aid in + let bn = ITN.find env bid in Vertices.change env iid ~f:(function | Some s -> Some (Vertex.S.remove (aid, bid) s) | None -> None (* should be unreachable *)); @@ -1109,28 +1085,28 @@ let rm_edge ?from_merge env aid bid iid = (Fmt.str "_merge_neighbours %a to %a\\n remove the edge %a between %a \ and %a" - (pp_eid env) kid (pp_eid env) rid (pp_vid env) iid (pp_eid env) - aid (pp_eid env) bid) + (pp_nid env) kid (pp_nid env) rid (pp_nid env) iid (pp_nid env) + aid (pp_nid env) bid) env () | None -> WEG.pp_dot_wegraph ~msg: - (Fmt.str " remove the edge %a between %a and %a" (pp_vid env) iid - (pp_eid env) aid (pp_eid env) bid) + (Fmt.str " remove the edge %a between %a and %a" (pp_nid env) iid + (pp_nid env) aid (pp_nid env) bid) env ()) let merge_neigbours_aux env (a, aid) (_, bid) nid kk_opt kr_opt () = match (kk_opt, kr_opt) with | Some iid, Some jid -> - let i = VHT.find env iid in - let j = VHT.find env jid in + let i = ITN.find env iid in + let j = ITN.find env jid in Debug.dprintf6 debug "WEGraph: _merge_neigbours_aux: iter1: found the neighbour %a through \ %a and %a" - (pp_eid env) nid (pp_vid env) iid (pp_vid env) jid; + (pp_nid env) nid (pp_nid env) iid (pp_nid env) jid; if not (Egraph.is_equal env i j) then ( let ijeq = Equality.equality env [ i; j ] in - let aneq = Equality.equality env [ a; EHT.find env nid ] in + let aneq = Equality.equality env [ a; ITN.find env nid ] in Egraph.register env ijeq; Egraph.register env aneq; Choice.register_global env @@ -1153,14 +1129,14 @@ let merge_neigbours_aux env (a, aid) (_, bid) nid kk_opt kr_opt () = Debug.dprintf4 debug "WEGraph: _merge_neigbours_aux: iter2: found the neighbour %a through \ %a" - (pp_eid env) nid (pp_vid env) iid; + (pp_nid env) nid (pp_nid env) iid; rm_edge ~from_merge:(aid, bid) env nid bid iid; add_edge ~from_merge:(aid, bid) env nid aid iid | _ -> () let merge_neighbours env (kn, kid) (rn, rid) b = Debug.dprintf5 debug "WEGraph: _merge_neighbours %b [kn=%a; rn=%a]" b - (pp_eid env) kid (pp_eid env) rid; + (pp_nid env) kid (pp_nid env) rid; (* Add all the neighbours of rnode to knp, removes rnode as a neighbour from the others and adds knp as a neighbour to them if it isn't already. *) (match (WEG.find_opt env kid, WEG.find_opt env rid) with @@ -1178,7 +1154,7 @@ let merge_neighbours env (kn, kid) (rn, rid) b = WEG.pp_dot_wegraph ~msg: (Fmt.str "_merge_neighbours %b | %a | %a\\n remove %a" b - (pp_eid env) kid (pp_eid env) rid (pp_eid env) rid) + (pp_nid env) kid (pp_nid env) rid (pp_nid env) rid) env () | None, Some (_, rnm) -> let rnm = DInt.M.remove kid rnm in @@ -1187,34 +1163,34 @@ let merge_neighbours env (kn, kid) (rn, rid) b = Debug.dprintf4 debug "WEGraph: _merge_neighbours: iter3: found the neighbour %a through \ %a" - (pp_eid env) nid (pp_vid env) iid; + (pp_nid env) nid (pp_nid env) iid; rm_edge ~from_merge:(kid, rid) env nid rid iid; add_edge ~from_merge:(kid, rid) env nid kid iid) rnm | _ -> ()); if not b then ( - EHT.set env kid rn; + ITN.set env kid rn; if Debug.test_flag WEG.wegraph_opt then WEG.pp_dot_wegraph ~msg: (Fmt.str "_merge_neighbours %b | %a | %a\\n replace %a <- %a" b - (pp_eid env) kid (pp_eid env) rid (pp_eid env) kid (pp_eid env) rid) + (pp_nid env) kid (pp_nid env) rid (pp_nid env) kid (pp_nid env) rid) env ()) let eq_arrays_norm env (kn, kid) (rn, rid) b = - Debug.dprintf4 debug "WEGraph: eq_arrays_norm_ %a %a" (pp_eid env) kid - (pp_eid env) rid; + Debug.dprintf4 debug "WEGraph: eq_arrays_norm_ %a %a" (pp_nid env) kid + (pp_nid env) rid; Values.eq_arrays_norm env kid rid; KnownValues.eq_arrays_norm env kid rid; merge_neighbours env (kn, kid) (rn, rid) b; if Debug.test_flag WEG.wegraph_opt then WEG.pp_dot_wegraph - ~msg:(Fmt.str "eq_arrays_norm_ %a %a" (pp_eid env) kid (pp_eid env) rid) + ~msg:(Fmt.str "eq_arrays_norm_ %a %a" (pp_nid env) kid (pp_nid env) rid) env () let eq_indices_norm env (_kn, kid) (rn, rid) b = - Debug.dprintf4 debug "WEGraph: eq_indices_norm_ %a %a" (pp_vid env) kid - (pp_vid env) rid; + Debug.dprintf4 debug "WEGraph: eq_indices_norm_ %a %a" (pp_nid env) kid + (pp_nid env) rid; Values.eq_indices_norm env kid rid; let ppg_s = KnownValues.eq_indices_norm env kid rid in (match (Vertices.find_opt env kid, Vertices.find_opt env rid) with @@ -1225,23 +1201,23 @@ let eq_indices_norm env (_kn, kid) (rn, rid) b = add_edge env aid bid kid) sr | _ -> ()); - VHT.remove env rid; - if not b then VHT.set env kid rn; + ITN.remove env rid; + if not b then ITN.set env kid rn; DInt.S.iter (KnownValues.reppg env kid) ppg_s; if Debug.test_flag WEG.wegraph_opt then WEG.pp_dot_wegraph - ~msg:(Fmt.str "_eq_indices_norm %a %a" (pp_vid env) kid (pp_vid env) rid) + ~msg:(Fmt.str "_eq_indices_norm %a %a" (pp_nid env) kid (pp_nid env) rid) env () let eq_values_norm env (_, kid) (_, rid) _b = - Debug.dprintf4 debug "WEGraph: eq_values_norm_ %a %a" (pp_val_id env) kid - (pp_val_id env) rid; + Debug.dprintf4 debug "WEGraph: eq_values_norm_ %a %a" (pp_nid env) kid + (pp_nid env) rid; Values.eq_values_norm env kid rid; - if not _b then ValHT.set env kid (ValHT.find env rid); - ValHT.remove env rid + if not _b then ITN.set env kid (ITN.find env rid); + ITN.remove env rid let ineq_indices_norm env s = - Debug.dprintf2 debug "WEGraph: ineq_indices_norm_: %a" KnownValues.HT.pp env; + Debug.dprintf2 debug "WEGraph: ineq_indices_norm_: %a" Node.S.pp s; let ns = List.filter_map (fun n -> @@ -1257,15 +1233,15 @@ let new_store env a b ind v = let bid = Id.Array.get_id env b in let iid = Id.Index.get_id env ind in let vid = Id.Value.get_id env v in - Debug.dprintf8 debug "WEGraph.new_store: %a %a %a %a" (pp_eid env) aid - (pp_eid env) bid (pp_vid env) iid (pp_val_id env) vid; + Debug.dprintf8 debug "WEGraph.new_store: %a %a %a %a" (pp_nid env) aid + (pp_nid env) bid (pp_nid env) iid (pp_nid env) vid; Values.add_store env aid bid iid vid; add_edge env aid bid iid; KnownValues.directed_ppg env aid (DInt.M.singleton iid v); if Debug.test_flag WEG.wegraph_opt then WEG.pp_dot_wegraph ~msg: - (Fmt.str "WEGraph.update: %a %a %a" (pp_eid env) aid (pp_eid env) bid + (Fmt.str "WEGraph.update: %a %a %a" (pp_nid env) aid (pp_nid env) bid Node.pp ind) env () @@ -1273,8 +1249,8 @@ let new_select env r a i = let aid = Id.Array.get_id env a in let iid = Id.Index.get_id env i in let rid = Id.Value.get_id env r in - Debug.dprintf6 debug "WEGraph.new_select: %a %a %a" (pp_val_id env) rid - (pp_eid env) aid (pp_vid env) iid; + Debug.dprintf6 debug "WEGraph.new_select: %a %a %a" (pp_nid env) rid + (pp_nid env) aid (pp_nid env) iid; Values.add_select env rid aid iid; match KnownValues.HT.find_opt env aid with | None -> () @@ -1301,20 +1277,20 @@ let get_neighbours env nid = let new_id_hook env id n = WEG.set env id (DInt.M.empty, DInt.M.empty); - EHT.set env id n + ITN.set env id n let new_index_id_hook env id n = Vertices.set env id Vertex.S.empty; - VHT.set env id n + ITN.set env id n let get_array_kvs env n = match KnownValues.HT.find_opt env (Id.Array.get_id env n) with | Some kv -> DInt.M.fold (fun i v acc -> - let indn = VHT.find env i in + let indn = ITN.find env i in Node.M.add indn v acc) kv Node.M.empty | None -> Node.M.empty -let new_value_id_hook env id n = ValHT.set env id n +let new_value_id_hook env id n = ITN.set env id n diff --git a/colibri2/theories/array/common.ml b/colibri2/theories/array/common.ml index 4e35ab627..0596c8286 100644 --- a/colibri2/theories/array/common.ml +++ b/colibri2/theories/array/common.ml @@ -81,6 +81,29 @@ exception NoIdFound of string * Node.t exception Not_a_neighbour of (Node.t * Node.t * Node.t) exception Empty_neighbour_set of (Node.t * Node.t * Node.t) +let () = + Printexc.register_printer (function + | Not_An_Array n -> Some (Fmt.str "%a is not an array!" Node.pp n) + | Not_An_Array_gty gty -> + Some (Fmt.str "%a is not an array ground type!" Ground.Ty.pp gty) + | Not_An_Array_ty ty -> + Some (Fmt.str "%a is not an array type!" Expr.Ty.pp ty) + | Type_Not_Set n -> + Some (Fmt.str "the type of the node %a was not set!" Node.pp n) + | NoIdFound (s, n) -> + Some (Fmt.str "get_id(%s) of %a: No Id found!" s Node.pp n) + | Not_a_neighbour (kn, rn, k) -> + Some + (Fmt.str "%a was expected to be a neighbour of %a through %a" Node.pp + rn Node.pp kn Node.pp k) + | Empty_neighbour_set (kn, rn, k) -> + Some + (Fmt.str + "%a was expected to be a neighbour of %a through %a, but %a's \ + neighbour set is empty" + Node.pp rn Node.pp kn Node.pp k Node.pp kn) + | _ -> None) + module STV = struct let ind_ty_var = Expr.Ty.Var.mk "ind_ty" let val_ty_var = Expr.Ty.Var.mk "val_ty" @@ -351,16 +374,16 @@ let do_mk_eq_if_neq env a b = if not (Egraph.is_equal env a b) then do_mk_eq env a b module type HTS = sig + type key type t - val set : Egraph.wt -> int -> t -> unit - val find : Egraph.wt -> int -> t - val find_opt : Egraph.wt -> int -> t option - val change : f:(t option -> t option) -> Egraph.wt -> int -> unit - val remove : Egraph.wt -> int -> unit - val iter : f:(int -> t -> unit) -> Egraph.wt -> unit - val fold : (int -> t -> 'a -> 'a) -> Egraph.wt -> 'a -> 'a - val filter_map_inplace : (int -> t -> t option) -> 'a Egraph.t -> unit + val set : Egraph.wt -> key -> t -> unit + val find : Egraph.wt -> key -> t + val find_opt : Egraph.wt -> key -> t option + val change : f:(t option -> t option) -> Egraph.wt -> key -> unit + val remove : Egraph.wt -> key -> unit + val iter : f:(key -> t -> unit) -> Egraph.wt -> unit + val fold : (key -> t -> 'a -> 'a) -> Egraph.wt -> 'a -> 'a val pp : Format.formatter -> Egraph.wt -> unit end @@ -369,7 +392,8 @@ module MkIHT (V : sig val pp : t Pp.pp val name : string -end) : HTS with type t = V.t = struct +end) : HTS with type key = int and type t = V.t = struct + type key = int type t = V.t let db = HT.create V.pp V.name @@ -380,7 +404,6 @@ end) : HTS with type t = V.t = struct let remove (env : Egraph.wt) i = HT.remove db env i let iter = HT.iter db let fold f env acc = HT.fold f db env acc - let filter_map_inplace f env = HT.filter_map_inplace f db env let pp fmt env = Fmt.pf fmt "%s:[%a]" V.name @@ -402,35 +425,13 @@ module type IdDomSig = sig val get_id : Egraph.wt -> Node.t -> int end -let () = - Printexc.register_printer (function - | Not_An_Array n -> Some (Fmt.str "%a is not an array!" Node.pp n) - | Not_An_Array_gty gty -> - Some (Fmt.str "%a is not an array ground type!" Ground.Ty.pp gty) - | Not_An_Array_ty ty -> - Some (Fmt.str "%a is not an array type!" Expr.Ty.pp ty) - | Type_Not_Set n -> - Some (Fmt.str "the type of the node %a was not set!" Node.pp n) - | NoIdFound (s, n) -> - Some (Fmt.str "get_id(%s) of %a: No Id found!" s Node.pp n) - | Not_a_neighbour (kn, rn, k) -> - Some - (Fmt.str "%a was expected to be a neighbour of %a through %a" Node.pp - rn Node.pp kn Node.pp k) - | Empty_neighbour_set (kn, rn, k) -> - Some - (Fmt.str - "%a was expected to be a neighbour of %a through %a, but %a's \ - neighbour set is empty" - Node.pp rn Node.pp kn Node.pp k Node.pp kn) - | _ -> None) +(** Global Id counter *) +let id_counter = ref 0 module MkIdDom (N : sig - val n1 : string - val n2 : string - val n3 : string + val name : string end) : IdDomSig = struct - let merge_hooks = Datastructure.Push.create Fmt.nop N.n1 + let merge_hooks = Datastructure.Push.create Fmt.nop (N.name ^ ".merge_hooks") let register_merge_hook env (f : Egraph.wt -> 'a -> 'a -> bool -> unit) = Datastructure.Push.push merge_hooks env f @@ -448,7 +449,7 @@ end) : IdDomSig = struct (module struct type nonrec t = t - let name = N.n2 + let name = N.name ^ ".DOM" end) let inter _ v _ = Some v @@ -469,28 +470,108 @@ end) : IdDomSig = struct end let () = Dom.register (module D) - let new_id_hooks = Datastructure.Push.create Fmt.nop N.n3 + let new_id_hooks = Datastructure.Push.create Fmt.nop (N.name ^ ".new_id_hooks") let register_new_id_hook env (f : Egraph.wt -> int -> Node.t -> unit) = Datastructure.Push.push new_id_hooks env f let set_id, get_id = - let id_counter = ref 0 in let set_id env n = match Egraph.get_dom env D.key n with | None -> incr id_counter; - Debug.dprintf4 debug "set_id(%s) of %a: none -> %d" N.n2 Node.pp n + Debug.dprintf4 debug "set_id(%s) of %a: none -> %d" N.name Node.pp n !id_counter; D.set_dom env n !id_counter; Datastructure.Push.iter new_id_hooks env ~f:(fun new_id_hook -> new_id_hook env !id_counter n) - | Some id -> Debug.dprintf4 debug "set_id(%s) of %a: %d" N.n2 Node.pp n id + | Some id -> + Debug.dprintf4 debug "set_id(%s) of %a: %d" N.name Node.pp n id in + let get_id env n = match Egraph.get_dom env D.key n with | Some id -> id - | None -> raise (NoIdFound (N.n2, n)) + | None -> raise (NoIdFound (N.name, n)) in (set_id, get_id) end + +module SHT (K : sig + include Datatype + + val sort : t -> t + val pp : t Pp.pp +end) (V : sig + type t + + val name : string + val pp : t Pp.pp +end) : HTS with type key = K.t and type t = V.t = struct + type key = K.t + type t = V.t + + module HT = Datastructure.Hashtbl (K) + + let db = HT.create V.pp V.name + let aux f env k = f db env (K.sort k) + let remove = aux HT.remove + let set = aux HT.set + let find = aux HT.find + let find_opt = aux HT.find_opt + let mem = aux HT.mem + let change ~f = aux (HT.change f) + let iter = HT.iter db + let fold f env acc = HT.fold f db env acc + + let pp fmt env = + Fmt.pf fmt "%s:[%a]" V.name + (fun fmt () -> + iter env ~f:(fun i v -> Fmt.pf fmt "(%a -> %a);@ " K.pp i V.pp v)) + () +end + +module I4 = struct + module T = struct + type t = DInt.t * DInt.t * DInt.t * DInt.t * Ground.Ty.t * Ground.Ty.t + [@@deriving eq, ord, hash, show] + end + + include T + include MkDatatype (T) +end + +module I3 = struct + module T = struct + type t = DInt.t * DInt.t * DInt.t * Ground.Ty.t * Ground.Ty.t + [@@deriving eq, ord, hash, show] + end + + include T + include MkDatatype (T) +end + +module I2 = struct + module T = struct + type t = DInt.t * DInt.t * Ground.Ty.t * Ground.Ty.t + [@@deriving eq, ord, hash, show] + end + + include T + include MkDatatype (T) +end + +module I1 = struct + module T = struct + type t = DInt.t * Ground.Ty.t * Ground.Ty.t [@@deriving eq, ord, hash, show] + end + + include T + include MkDatatype (T) +end + +(* (id1,id2,id3,id4,ty1,ty2) *) +(* (id1,id2,ty1,ty2) *) + +(* id1 -> (id2,id3,id4,ty1,ty2) *) +(* id1 -> (id2,ty1,ty2) *) diff --git a/colibri2/theories/array/common.mli b/colibri2/theories/array/common.mli index 101a6a0ef..81fc6144d 100644 --- a/colibri2/theories/array/common.mli +++ b/colibri2/theories/array/common.mli @@ -19,6 +19,9 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (*************************************************************************) +open Colibri2_popop_lib +open Popop_stdlib + val no_wegraph : bool Options.t val no_res_ext : bool Options.t val no_res_aup : bool Options.t @@ -140,25 +143,25 @@ val do_mk_eq : Egraph.wt -> Node.t -> Node.t -> unit val do_mk_eq_if_neq : Egraph.wt -> Node.t -> Node.t -> unit module type HTS = sig + type key type t - val set : Egraph.wt -> int -> t -> unit - val find : Egraph.wt -> int -> t - val find_opt : Egraph.wt -> int -> t option - val change : f:(t option -> t option) -> Egraph.wt -> int -> unit - val remove : Egraph.wt -> int -> unit - val iter : f:(int -> t -> unit) -> Egraph.wt -> unit - val fold : (int -> t -> 'a -> 'a) -> Egraph.wt -> 'a -> 'a - val filter_map_inplace : (int -> t -> t option) -> 'a Egraph.t -> unit + val set : Egraph.wt -> key -> t -> unit + val find : Egraph.wt -> key -> t + val find_opt : Egraph.wt -> key -> t option + val change : f:(t option -> t option) -> Egraph.wt -> key -> unit + val remove : Egraph.wt -> key -> unit + val iter : f:(key -> t -> unit) -> Egraph.wt -> unit + val fold : (key -> t -> 'a -> 'a) -> Egraph.wt -> 'a -> 'a val pp : Format.formatter -> Egraph.wt -> unit end module MkIHT (V : sig type t - val pp : t Colibri2_popop_lib.Pp.pp + val pp : t Pp.pp val name : string -end) : HTS with type t = V.t +end) : HTS with type key = int and type t = V.t module type IdDomSig = sig val register_merge_hook : @@ -174,7 +177,27 @@ module type IdDomSig = sig end module MkIdDom (_ : sig - val n1 : string - val n2 : string - val n3 : string + val name : string end) : IdDomSig + +module SHT (K : sig + include Datatype + + val sort : t -> t + val pp : t Pp.pp +end) (V : sig + type t + + val name : string + val pp : t Pp.pp +end) : HTS with type key = K.t and type t = V.t + +module I4 : + Datatype + with type t = DInt.t * DInt.t * DInt.t * DInt.t * Ground.Ty.t * Ground.Ty.t + +module I3 : + Datatype with type t = DInt.t * DInt.t * DInt.t * Ground.Ty.t * Ground.Ty.t + +module I2 : Datatype with type t = DInt.t * DInt.t * Ground.Ty.t * Ground.Ty.t +module I1 : Datatype with type t = DInt.t * Ground.Ty.t * Ground.Ty.t -- GitLab