diff --git a/src_colibri2/core/colibri2_core.mli b/src_colibri2/core/colibri2_core.mli index f4611fd2572f033c9bb30e1b82a7150785bb22df..9d739358ec0804e3dd9d1b848b9ee056948d9f16 100644 --- a/src_colibri2/core/colibri2_core.mli +++ b/src_colibri2/core/colibri2_core.mli @@ -1225,11 +1225,16 @@ module Debug : sig Info flags are set by --debug-all and must not change the behaviour. *) val dprintf0 : - ?nobox:unit -> flag -> (unit, Format.formatter, unit) format -> unit + ?nobox:unit -> + ?ct:unit -> + flag -> + (unit, Format.formatter, unit) format -> + unit (** Print only if the flag is set *) val dprintf1 : ?nobox:unit -> + ?ct:unit -> flag -> ('a -> unit, Format.formatter, unit) format -> 'a -> @@ -1238,6 +1243,7 @@ module Debug : sig val dprintf2 : ?nobox:unit -> + ?ct:unit -> flag -> ('b -> 'a -> unit, Format.formatter, unit) format -> 'b -> @@ -1247,6 +1253,7 @@ module Debug : sig val dprintf3 : ?nobox:unit -> + ?ct:unit -> flag -> ('c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'c -> @@ -1257,6 +1264,7 @@ module Debug : sig val dprintf4 : ?nobox:unit -> + ?ct:unit -> flag -> ('d -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'd -> @@ -1268,6 +1276,7 @@ module Debug : sig val dprintf5 : ?nobox:unit -> + ?ct:unit -> flag -> ('e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'e -> @@ -1280,6 +1289,7 @@ module Debug : sig val dprintf6 : ?nobox:unit -> + ?ct:unit -> flag -> ('f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'f -> @@ -1293,6 +1303,7 @@ module Debug : sig val dprintf7 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, @@ -1310,6 +1321,7 @@ module Debug : sig val dprintf8 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, @@ -1328,6 +1340,7 @@ module Debug : sig val dprintf9 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, @@ -1347,6 +1360,7 @@ module Debug : sig val dprintf10 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, @@ -1367,6 +1381,7 @@ module Debug : sig val dprintf11 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, @@ -1388,6 +1403,7 @@ module Debug : sig val dprintf12 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'l -> 'k -> @@ -1422,6 +1438,7 @@ module Debug : sig val dprintf13 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'm -> 'l -> @@ -1458,6 +1475,7 @@ module Debug : sig val dprintf14 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'n -> 'm -> @@ -1496,6 +1514,7 @@ module Debug : sig val dprintf15 : ?nobox:unit -> + ?ct:unit -> flag -> ( 'o -> 'n -> @@ -1536,6 +1555,7 @@ module Debug : sig val dprintfn : ?nobox:unit -> + ?ct:unit -> flag -> ( 'o -> 'n -> diff --git a/src_colibri2/core/dune b/src_colibri2/core/dune index 2709e1eb32e3118144f1a3b502c865a9be1b09fa..b258dddedc50d2f414b7bc6226c13296f5ea3605 100644 --- a/src_colibri2/core/dune +++ b/src_colibri2/core/dune @@ -2,7 +2,7 @@ (name colibri2_core) (public_name colibri2.core) (synopsis "core for colibri2, e.g. trail, egraph") - (libraries containers ocamlgraph str colibri2.stdlib colibri2.popop_lib dolmen.std) + (libraries containers ocamlgraph str colibri2.stdlib colibri2.popop_lib dolmen.std dolmen_loop) (preprocess (pps ppx_deriving.std ppx_hash)) (flags :standard -w +a-4-42-44-48-50-58-60-40-9@8 -color always -open diff --git a/src_colibri2/core/egraph.ml b/src_colibri2/core/egraph.ml index 2c2f38b969e55b7a1093ca39fc329f6d006ad470..7f32eb13351b20adcc7dfc46539f9b2ec964fdc4 100644 --- a/src_colibri2/core/egraph.ml +++ b/src_colibri2/core/egraph.ml @@ -396,8 +396,9 @@ let output_graph filename t = match Only_for_solver.sem_of_node thterm with | Only_for_solver.ThTerm(sem,v) -> let (module S) = Nodes.get_thterm sem in + let v = S.sem v in Format.fprintf fmt "| {%a | %s}" - ThTermKind.pp sem (escape_for_dot S.pp v) + ThTermKind.pp sem (escape_for_dot S.SD.pp v) end | _ -> () in @@ -962,8 +963,9 @@ module Delayed = struct set_value_pending d node nodevalue let set_dom d dom node v = - Debug.dprintf4 debug_few - "[Egraph] @[set_dom for %a with %a@]" + Debug.dprintf6 debug_few + "[Egraph] @[set_dom %a for %a with %a@]" + DomKind.pp dom Node.pp node (print_dom dom) v; set_dom_pending d dom node (Some v) diff --git a/src_colibri2/core/structures/expr.ml b/src_colibri2/core/structures/expr.ml index b5c34015fcfd3e4398682819d3321f4ff41b4a41..f4674eb6cd6412727eb8f3677b72f6dc3d8d1c09 100644 --- a/src_colibri2/core/structures/expr.ml +++ b/src_colibri2/core/structures/expr.ml @@ -26,28 +26,38 @@ module Ty = struct let pp = print - include Colibri2_popop_lib.Popop_stdlib.MkDatatype(struct + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (struct + type nonrec t = t + + let equal = equal + + let compare = compare + + let hash = hash + + let pp = pp + + let hash_fold_t s t = Base.Hash.fold_int s (hash t) + end) + + module Var = struct + include Dolmen_std.Expr.Ty.Var + + let pp = Dolmen_std.Expr.Print.ty_var + + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (struct type nonrec t = t + let equal = equal + let compare = compare + let hash = hash + let pp = pp + let hash_fold_t s t = Base.Hash.fold_int s (hash t) end) - - module Var = struct - include Dolmen_std.Expr.Ty.Var - - let pp = Dolmen_std.Expr.Print.ty_var - - include Colibri2_popop_lib.Popop_stdlib.MkDatatype(struct - type nonrec t = t - let equal = equal - let compare = compare - let hash = hash - let pp = pp - let hash_fold_t s t = Base.Hash.fold_int s (hash t) - end) end let rec free_vars acc (t : t) = @@ -56,117 +66,160 @@ module Ty = struct | TyApp (_, l) -> List.fold_left free_vars acc l | Arrow (args, ret) -> List.fold_left free_vars (free_vars acc ret) args | Pi (vars, body) -> - let fv = free_vars Var.S.empty body in - let fv = List.fold_left (fun acc v -> Var.S.remove v acc) fv vars in - Var.S.union fv acc + let fv = free_vars Var.S.empty body in + let fv = List.fold_left (fun acc v -> Var.S.remove v acc) fv vars in + Var.S.union fv acc module Const = struct include Dolmen_std.Expr.Ty.Const - let pp fmt (t:t) = Dolmen_std.Expr.Id.print fmt t - - include Colibri2_popop_lib.Popop_stdlib.MkDatatype(struct - type nonrec t = t - let equal = equal - let compare = compare - let hash = hash - let pp = pp - let hash_fold_t s t = Base.Hash.fold_int s (hash t) - end) - end -end + let pp fmt (t : t) = Dolmen_std.Expr.Id.print fmt t -module Term = struct - include Dolmen_std.Expr.Term - let pp = print - - include Colibri2_popop_lib.Popop_stdlib.MkDatatype(struct + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (struct type nonrec t = t + let equal = equal + let compare = compare + let hash = hash + let pp = pp + let hash_fold_t s t = Base.Hash.fold_int s (hash t) end) + end +end - module Const = struct +module Term = struct + include Dolmen_std.Expr.Term + + let pp = print + + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (struct + type nonrec t = t + + let equal = equal + let compare = compare + + let hash = hash + + let pp = pp + + let hash_fold_t s t = Base.Hash.fold_int s (hash t) + end) + + module Const = struct module D = struct - include Dolmen_std.Expr.Term.Const - let pp fmt (t:t) = Dolmen_std.Expr.Id.print fmt t - include Colibri2_popop_lib.Popop_stdlib.MkDatatype(struct + include Dolmen_std.Expr.Term.Const + + let pp fmt (t : t) = Dolmen_std.Expr.Id.print fmt t + + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (struct type nonrec t = t + let equal = equal + let compare = compare + let hash = hash + let pp = pp + let hash_fold_t s t = Base.Hash.fold_int s (hash t) end) end include D - - module HC = Datastructure.Hashtbl(D) - + module HC = Datastructure.Hashtbl (D) end module Var = struct include Dolmen_std.Expr.Term.Var - let pp fmt (t:t) = Dolmen_std.Expr.Id.print fmt t - include Colibri2_popop_lib.Popop_stdlib.MkDatatype(struct - type nonrec t = t - let equal = equal - let compare = compare - let hash = hash - let pp = pp - let hash_fold_t s t = Base.Hash.fold_int s (hash t) + let pp fmt (t : t) = Dolmen_std.Expr.Id.print fmt t + + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (struct + type nonrec t = t + + let equal = equal + + let compare = compare + + let hash = hash + + let pp = pp + + let hash_fold_t s t = Base.Hash.fold_int s (hash t) end) end - let rec free_vars ((acc_ty,acc_term) as acc) (t : t) = match t.term_descr with - | Var v -> (Ty.free_vars acc_ty v.id_ty,Var.S.add v acc_term) + let rec free_vars ((acc_ty, acc_term) as acc) (t : t) = + match t.term_descr with + | Var v -> (Ty.free_vars acc_ty v.id_ty, Var.S.add v acc_term) | Cst _ -> acc | App (f, tys, ts) -> - let acc_ty, acc_term = free_vars acc f in - List.fold_left free_vars ( - List.fold_left Ty.free_vars acc_ty tys, acc_term - ) ts + let acc_ty, acc_term = free_vars acc f in + List.fold_left free_vars + (List.fold_left Ty.free_vars acc_ty tys, acc_term) + ts | Binder ((Lambda (tys, ts) | Exists (tys, ts) | Forall (tys, ts)), body) -> - let (fty,fv) = free_vars (Ty.Var.S.empty,Var.S.empty) body in - let fty = List.fold_left (fun acc ty -> Ty.Var.S.remove ty acc) fty tys in - let fv = List.fold_left (fun acc t -> Var.S.remove t acc) fv ts in - (Ty.Var.S.union acc_ty fty, Var.S.union acc_term fv) + let fty, fv = free_vars (Ty.Var.S.empty, Var.S.empty) body in + let fty = + List.fold_left (fun acc ty -> Ty.Var.S.remove ty acc) fty tys + in + let fv = List.fold_left (fun acc t -> Var.S.remove t acc) fv ts in + (Ty.Var.S.union acc_ty fty, Var.S.union acc_term fv) | Binder (Let_seq l, body) -> - let (acc_ty,fv) = free_vars (acc_ty,Var.S.empty) body in - let (acc_ty,fv) = List.fold_right (fun (v, t) (acc_ty,fv) -> - let fv = Var.S.remove v fv in - let (acc_ty,fv) = free_vars (acc_ty,fv) t in - let acc_ty = Ty.free_vars acc_ty v.id_ty in - (acc_ty,fv) - ) l (acc_ty,fv) in - (acc_ty, Var.S.union acc_term fv) + let acc_ty, fv = free_vars (acc_ty, Var.S.empty) body in + let acc_ty, fv = + List.fold_right + (fun (v, t) (acc_ty, fv) -> + let fv = Var.S.remove v fv in + let acc_ty, fv = free_vars (acc_ty, fv) t in + let acc_ty = Ty.free_vars acc_ty v.id_ty in + (acc_ty, fv)) + l (acc_ty, fv) + in + (acc_ty, Var.S.union acc_term fv) | Binder (Let_par l, body) -> - let (acc_ty,fv) = free_vars (acc_ty,Var.S.empty) body in - let fv = List.fold_right (fun (v, _) fv -> - let fv = Var.S.remove v fv in - fv - ) l fv in - let (acc_ty,fv) = List.fold_right (fun (v, t) (acc_ty,fv) -> - let (acc_ty,fv) = free_vars (acc_ty,fv) t in - let acc_ty = Ty.free_vars acc_ty v.id_ty in - (acc_ty,fv) - ) l (acc_ty,fv) in - (acc_ty, Var.S.union acc_term fv) + let acc_ty, fv = free_vars (acc_ty, Var.S.empty) body in + let fv = + List.fold_right + (fun (v, _) fv -> + let fv = Var.S.remove v fv in + fv) + l fv + in + let acc_ty, fv = + List.fold_right + (fun (v, t) (acc_ty, fv) -> + let acc_ty, fv = free_vars (acc_ty, fv) t in + let acc_ty = Ty.free_vars acc_ty v.id_ty in + (acc_ty, fv)) + l (acc_ty, fv) + in + (acc_ty, Var.S.union acc_term fv) | Match (scrutinee, branches) -> - let acc = free_vars (acc_ty,acc_term) scrutinee in - List.fold_left (fun (acc_ty,acc_term) (pat, body) -> - let (acc_ty,freet) = free_vars (acc_ty,Var.S.empty) body in - let (acc_ty,boundt) = free_vars (acc_ty,Var.S.empty) pat in - let bound = Var.S.diff freet boundt in - (acc_ty, Var.S.union acc_term bound) - ) acc branches - + let acc = free_vars (acc_ty, acc_term) scrutinee in + List.fold_left + (fun (acc_ty, acc_term) (pat, body) -> + let acc_ty, freet = free_vars (acc_ty, Var.S.empty) body in + let acc_ty, boundt = free_vars (acc_ty, Var.S.empty) pat in + let bound = Var.S.diff freet boundt in + (acc_ty, Var.S.union acc_term bound)) + acc branches end -let foo = 1 +let add_builtins, additional_builtins = + let q : Dolmen_loop.Typer.T.builtin_symbols Base.Queue.t = + Base.Queue.create () + in + ( Base.Queue.enqueue q, + fun e t -> + let o = + Base.Queue.find_map q ~f:(fun f -> + match f e t with `Not_found -> None | x -> Some x) + in + Option.value ~default:`Not_found o ) diff --git a/src_colibri2/popop_lib/debug.ml b/src_colibri2/popop_lib/debug.ml index 8105a1b88c91628c6066936e66de15983dba45d0..61ff438d466a846b4c9470ac86f843abf3f44c94 100644 --- a/src_colibri2/popop_lib/debug.ml +++ b/src_colibri2/popop_lib/debug.ml @@ -99,7 +99,7 @@ let get_debug_formatter () = !formatter let () = set_debug_formatter Format.err_formatter -let real_dprintf ?nobox s = +let real_dprintf ?nobox ?ct s = let box = match nobox with None -> true | Some () -> false in if box then begin Format.pp_print_cut !formatter (); @@ -109,60 +109,83 @@ let real_dprintf ?nobox s = (fun fmt -> if box then begin Format.pp_close_box fmt (); Format.pp_print_flush fmt (); - end + end; + if Option.is_some ct then + let b = Base.Backtrace.get ~at_most_num_frames:7 () in + let l = match (Base.Backtrace.to_string_list b) with + | _::_::_::l -> l + | l -> l + in Fmt.(pf !formatter "@.%a" (vbox ~indent:1 (list ~sep:cut (box lines))) l) ) !formatter s +[@@ inline never] -let dprintf0 ?nobox flag s = - if !flag then real_dprintf ?nobox s +let dprintf0 ?nobox ?ct flag s = + if !flag then real_dprintf ?nobox ?ct s +[@@ inline always] -let dprintf1 ?nobox flag s a1 = - if !flag then real_dprintf ?nobox s a1 +let dprintf1 ?nobox ?ct flag s a1 = + if !flag then real_dprintf ?nobox ?ct s a1 +[@@ inline always] -let dprintf2 ?nobox flag s a1 a2 = - if !flag then real_dprintf ?nobox s a1 a2 +let dprintf2 ?nobox ?ct flag s a1 a2 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 +[@@ inline always] -let dprintf3 ?nobox flag s a1 a2 a3 = - if !flag then real_dprintf ?nobox s a1 a2 a3 +let dprintf3 ?nobox ?ct flag s a1 a2 a3 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 +[@@ inline always] -let dprintf4 ?nobox flag s a1 a2 a3 a4 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 +let dprintf4 ?nobox ?ct flag s a1 a2 a3 a4 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 +[@@ inline always] -let dprintf5 ?nobox flag s a1 a2 a3 a4 a5 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 +let dprintf5 ?nobox ?ct flag s a1 a2 a3 a4 a5 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 +[@@ inline always] -let dprintf6 ?nobox flag s a1 a2 a3 a4 a5 a6 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 +let dprintf6 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 +[@@ inline always] -let dprintf7 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 +let dprintf7 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 +[@@ inline always] -let dprintf8 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 +let dprintf8 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 +[@@ inline always] -let dprintf9 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 +let dprintf9 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 +[@@ inline always] -let dprintf10 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 +let dprintf10 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 +[@@ inline always] -let dprintf11 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 +let dprintf11 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 +[@@ inline always] -let dprintf12 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 +let dprintf12 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 +[@@ inline always] -let dprintf13 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 +let dprintf13 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 +[@@ inline always] -let dprintf14 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 +let dprintf14 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 +[@@ inline always] -let dprintf15 ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 +let dprintf15 ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 +[@@ inline always] -let dprintfn ?nobox flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 = - if !flag then real_dprintf ?nobox s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 +let dprintfn ?nobox ?ct flag s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 = + if !flag then real_dprintf ?nobox ?ct s a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 else (* ifprintf take too many times for computing the format *) let rec aux = fun _ -> Obj.magic aux in diff --git a/src_colibri2/popop_lib/debug.mli b/src_colibri2/popop_lib/debug.mli index 55580a1e05a6e4a036a3c4d9e0affa198f1efa5a..54cbd4d25a90d2060665b1c48dccf1a4c5e4afe9 100644 --- a/src_colibri2/popop_lib/debug.mli +++ b/src_colibri2/popop_lib/debug.mli @@ -55,95 +55,95 @@ val set_debug_formatter : Format.formatter -> unit val get_debug_formatter : unit -> Format.formatter (** Get the formatter used when printing debug material *) -val dprintf0 : ?nobox:unit -> flag -> (unit, +val dprintf0 : ?nobox:unit -> ?ct:unit -> flag -> (unit, Format.formatter, unit) format -> unit (** Print only if the flag is set *) -val dprintf1 : ?nobox:unit -> flag -> ('a -> unit, +val dprintf1 : ?nobox:unit -> ?ct:unit -> flag -> ('a -> unit, Format.formatter, unit) format -> 'a -> unit (** Print only if the flag is set *) -val dprintf2 : ?nobox:unit -> flag -> ('b -> 'a -> unit, +val dprintf2 : ?nobox:unit -> ?ct:unit -> flag -> ('b -> 'a -> unit, Format.formatter, unit) format -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf3 : ?nobox:unit -> flag -> ('c -> 'b -> 'a -> unit, +val dprintf3 : ?nobox:unit -> ?ct:unit -> flag -> ('c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf4 : ?nobox:unit -> flag -> ('d -> 'c -> 'b -> 'a -> unit, +val dprintf4 : ?nobox:unit -> ?ct:unit -> flag -> ('d -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf5 : ?nobox:unit -> flag -> ('e -> 'd -> 'c -> 'b -> 'a -> unit, +val dprintf5 : ?nobox:unit -> ?ct:unit -> flag -> ('e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf6 : ?nobox:unit -> flag -> +val dprintf6 : ?nobox:unit -> ?ct:unit -> flag -> ('f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf7 : ?nobox:unit -> flag -> +val dprintf7 : ?nobox:unit -> ?ct:unit -> flag -> ('g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf8 : ?nobox:unit -> flag -> +val dprintf8 : ?nobox:unit -> ?ct:unit -> flag -> ('h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf9 : ?nobox:unit -> flag -> +val dprintf9 : ?nobox:unit -> ?ct:unit -> flag -> ('i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf10 : ?nobox:unit -> flag -> +val dprintf10 : ?nobox:unit -> ?ct:unit -> flag -> ('j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf11 : ?nobox:unit -> flag -> +val dprintf11 : ?nobox:unit -> ?ct:unit -> flag -> ('k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf12 : ?nobox:unit -> flag -> +val dprintf12 : ?nobox:unit -> ?ct:unit -> flag -> ('l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf13 : ?nobox:unit -> flag -> +val dprintf13 : ?nobox:unit -> ?ct:unit -> flag -> ('m -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf14 : ?nobox:unit -> flag -> +val dprintf14 : ?nobox:unit -> ?ct:unit -> flag -> ('n -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'n -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintf15 : ?nobox:unit -> flag -> +val dprintf15 : ?nobox:unit -> ?ct:unit -> flag -> ('o -> 'n -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit, Format.formatter, unit) format -> 'o -> 'n -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> unit (** Print only if the flag is set *) -val dprintfn : ?nobox:unit -> flag -> +val dprintfn : ?nobox:unit -> ?ct:unit -> flag -> ('o -> 'n -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> 'z, Format.formatter, unit) format -> 'o -> 'n -> 'm -> 'l -> 'k -> 'j -> 'i -> 'h -> 'g -> 'f -> 'e -> 'd -> 'c -> 'b -> 'a -> 'z diff --git a/src_colibri2/solver/input.ml b/src_colibri2/solver/input.ml index 07ed927216150b2a36ac409fb7e13fbed9ef6827..a5cab114417c344e821fdfb4256b0eaf420e9892 100644 --- a/src_colibri2/solver/input.ml +++ b/src_colibri2/solver/input.ml @@ -63,6 +63,8 @@ module Typer = struct Dolmen_loop.Typer.Pipe (Dolmen.Std.Expr) (Dolmen.Std.Expr.Print) (State) (T) end +let () = Typer.additional_builtins := Colibri2_core.Expr.additional_builtins + let split_input = function | `Stdin -> (Sys.getcwd (), `Stdin) | `File f -> (Filename.dirname f, `File (Filename.basename f)) diff --git a/src_colibri2/solver/scheduler.ml b/src_colibri2/solver/scheduler.ml index 2f46a03e276c2a8f0751f49aae1c0e29c1fd3f78..e3dbfbd530a2b7c02cf113663ec962257fb92cea 100644 --- a/src_colibri2/solver/scheduler.ml +++ b/src_colibri2/solver/scheduler.ml @@ -161,7 +161,7 @@ let new_solver ~learning () = in let sched_daemon att = incr daemon_count; - Debug.dprintf0 debug "[Scheduler] New waiting daemon"; + (* Debug.dprintf0 debug "[Scheduler] New waiting daemon"; *) match get_event_priority att with | Immediate -> assert false (* absurd *) | Delayed_by offset -> Context.TimeWheel.add t.daemons att offset @@ -170,7 +170,7 @@ let new_solver ~learning () = Context.Ref.set t.fixing_model (att :: Context.Ref.get t.fixing_model) and sched_decision dec = incr dec_count; - Debug.dprintf1 debug "[Scheduler] New possible decisions prio:%i" !dec_count; + (* Debug.dprintf1 debug "[Scheduler] New possible decisions prio:%i" !dec_count; *) t.choices <- Prio.insert t.decprio (Att.Decision (!dec_count, dec)) t.choices in diff --git a/src_colibri2/tests/generate_tests/.ocamlformat b/src_colibri2/tests/generate_tests/.ocamlformat new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src_colibri2/tests/generate_tests/generate_dune_tests.ml b/src_colibri2/tests/generate_tests/generate_dune_tests.ml index f7aa4779b9b28bcbd36c2d3c2ecc5e65492ef68f..2df700bb6e2661f8ccd3eccef6bec9bbd796cb88 100644 --- a/src_colibri2/tests/generate_tests/generate_dune_tests.ml +++ b/src_colibri2/tests/generate_tests/generate_dune_tests.ml @@ -22,7 +22,7 @@ let dir = Sys.argv.(1) let result = if Array.length Sys.argv >= 3 then Some Sys.argv.(2) else None -let cmd = "%{bin:colibri2} --size=10M --time=30s --max-steps 3500" +let cmd = "%{bin:colibri2} --size=15M --time=30s --max-steps 3500" let print_test cout file = match result with diff --git a/src_colibri2/tests/solve/all/sat/div_abs.smt2 b/src_colibri2/tests/solve/all/sat/div_abs.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..8d12bd08eab028c0908826f33cf79720c817b109 --- /dev/null +++ b/src_colibri2/tests/solve/all/sat/div_abs.smt2 @@ -0,0 +1,11 @@ +(set-logic ALL) +(set-info :smt-lib-version 2.6) +(declare-const x Real) +(declare-const y Real) + +(assert (< y 0.0)) + +(assert + (= (colibri_abs_real (/ x y)) + (/ (colibri_abs_real x) (colibri_abs_real y)))) +(check-sat) diff --git a/src_colibri2/tests/solve/all/sat/div_abs2.smt2 b/src_colibri2/tests/solve/all/sat/div_abs2.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..e0871e29c8248bfe8dc6af411ef25607a5dc8cbb --- /dev/null +++ b/src_colibri2/tests/solve/all/sat/div_abs2.smt2 @@ -0,0 +1,9 @@ +(set-logic ALL) +(set-info :smt-lib-version 2.6) +(declare-const x Real) +(declare-const y Real) + +(assert + (not (= (colibri_abs_real (/ x y)) + (/ (colibri_abs_real x) (colibri_abs_real y))))) +(check-sat) diff --git a/src_colibri2/tests/solve/all/sat/dune b/src_colibri2/tests/solve/all/sat/dune new file mode 100644 index 0000000000000000000000000000000000000000..137bdf589269179a3ae42355c4024e65ca273535 --- /dev/null +++ b/src_colibri2/tests/solve/all/sat/dune @@ -0,0 +1,13 @@ +(include dune.inc) + +(rule + (alias runtest) + (deps + (glob_files *.cnf) + (glob_files *.smt2) + (glob_files *.psmt2)) + (action + (with-stdout-to + dune.inc + (run %{exe:../../../generate_tests/generate_dune_tests.exe} . sat))) + (mode promote)) diff --git a/src_colibri2/tests/solve/all/sat/dune.inc b/src_colibri2/tests/solve/all/sat/dune.inc new file mode 100644 index 0000000000000000000000000000000000000000..aca73444f0d4e5534f76b17b6ead8815ff6700e6 --- /dev/null +++ b/src_colibri2/tests/solve/all/sat/dune.inc @@ -0,0 +1,6 @@ +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat +--dont-print-result %{dep:div_abs.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:div_abs.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat +--dont-print-result %{dep:div_abs2.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:div_abs2.smt2}))) diff --git a/src_colibri2/tests/solve/all/steplimitreached/dune.inc b/src_colibri2/tests/solve/all/steplimitreached/dune.inc index a63167f0516d0604ff19723247bde91df3d2f69d..98b899ea73a26e035e0584d4b0ce4aaedad0905e 100644 --- a/src_colibri2/tests/solve/all/steplimitreached/dune.inc +++ b/src_colibri2/tests/solve/all/steplimitreached/dune.inc @@ -1,3 +1,3 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status steplimitreached +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status steplimitreached --dont-print-result %{dep:bag-BagImpl-addqtvc.psmt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status steplimitreached --learning --dont-print-result %{dep:bag-BagImpl-addqtvc.psmt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status steplimitreached --learning --dont-print-result %{dep:bag-BagImpl-addqtvc.psmt2}))) diff --git a/src_colibri2/tests/solve/all/unsat/div_abs.smt2 b/src_colibri2/tests/solve/all/unsat/div_abs.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..62465424103aee5dc8b9348d373fcaca57fc879e --- /dev/null +++ b/src_colibri2/tests/solve/all/unsat/div_abs.smt2 @@ -0,0 +1,11 @@ +(set-logic ALL) +(set-info :smt-lib-version 2.6) +(declare-const x Real) +(declare-const y Real) + +(assert (< y 0.0)) + +(assert + (not (= (colibri_abs_real (/ x y)) + (/ (colibri_abs_real x) (colibri_abs_real y))))) +(check-sat) diff --git a/src_colibri2/tests/solve/all/unsat/dune.inc b/src_colibri2/tests/solve/all/unsat/dune.inc index 8a470e8f41631aa1b4faa594a48387da1cf0a2cd..0c02372cf204487ed05c2de668ff6475ca9d257b 100644 --- a/src_colibri2/tests/solve/all/unsat/dune.inc +++ b/src_colibri2/tests/solve/all/unsat/dune.inc @@ -1,12 +1,18 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:bag-BagImpl-createqtvc.psmt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:bag-BagImpl-createqtvc.psmt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:bag-BagImpl-createqtvc.psmt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat +--dont-print-result %{dep:div_abs.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_abs.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:fact-FactRecursive-fact_recqtvc.psmt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:fact-FactRecursive-fact_recqtvc.psmt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:fact-FactRecursive-fact_recqtvc.psmt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:interval-Convexe-exists_memqtvc_1.psmt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:interval-Convexe-exists_memqtvc_1.psmt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:interval-Convexe-exists_memqtvc_1.psmt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:interval-Convexe-exists_memqtvc_2.psmt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:interval-Convexe-exists_memqtvc_2.psmt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:interval-Convexe-exists_memqtvc_2.psmt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat +--dont-print-result %{dep:mul_abs.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_abs.smt2}))) diff --git a/src_colibri2/tests/solve/all/unsat/mul_abs.smt2 b/src_colibri2/tests/solve/all/unsat/mul_abs.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..4799c11cbd5ca98d795b9feb11f45fef750d385a --- /dev/null +++ b/src_colibri2/tests/solve/all/unsat/mul_abs.smt2 @@ -0,0 +1,8 @@ +(set-logic ALL) + +(declare-fun a () Real) +(declare-fun b () Real) + +(assert (not (= (* (colibri_abs_real a) (colibri_abs_real b)) (colibri_abs_real (* a b))))) + +(check-sat) diff --git a/src_colibri2/tests/solve/dimacs/sat/dune.inc b/src_colibri2/tests/solve/dimacs/sat/dune.inc index 9a3098f1bed7ae73d9df3a42047d9765d4bafd0f..3a8a918a67df7e466836bcb7c234e24ee7fcdd91 100644 --- a/src_colibri2/tests/solve/dimacs/sat/dune.inc +++ b/src_colibri2/tests/solve/dimacs/sat/dune.inc @@ -1,33 +1,33 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:anomaly_agetooold.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:anomaly_agetooold.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:anomaly_agetooold.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:anomaly_agetooold2.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:anomaly_agetooold2.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:anomaly_agetooold2.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:assertion_fail.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:assertion_fail.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:assertion_fail.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:fuzzing1.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:fuzzing1.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:fuzzing1.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:fuzzing2.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:fuzzing2.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:fuzzing2.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:par8-1-c.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:par8-1-c.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:par8-1-c.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:pigeon-2.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:pigeon-2.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:pigeon-2.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:pigeon-3.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:pigeon-3.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:pigeon-3.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:pigeon-4.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:pigeon-4.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:pigeon-4.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:quinn.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:quinn.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:quinn.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:simple_v3_c2.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_v3_c2.cnf}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_v3_c2.cnf}))) diff --git a/src_colibri2/tests/solve/dimacs/unsat/dune.inc b/src_colibri2/tests/solve/dimacs/unsat/dune.inc index 33634441266451e5d7912d9b29154467bb4f83e2..a4da599a19b005f9759869cda3cddbc91e8a27fd 100644 --- a/src_colibri2/tests/solve/dimacs/unsat/dune.inc +++ b/src_colibri2/tests/solve/dimacs/unsat/dune.inc @@ -1,18 +1,18 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:anomaly_agetooold.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:anomaly_agetooold.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:anomaly_agetooold.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:modus_ponens.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:modus_ponens.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:modus_ponens.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:pigeon-1.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-1.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-1.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:pigeon-2.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-2.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-2.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:pigeon-3.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-3.cnf}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-3.cnf}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:pigeon-4.cnf}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-4.cnf}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:pigeon-4.cnf}))) diff --git a/src_colibri2/tests/solve/models/abs_real.smt2 b/src_colibri2/tests/solve/models/abs_real.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..509d830f5ba39243715e097c66dd9bba0efe3cf2 --- /dev/null +++ b/src_colibri2/tests/solve/models/abs_real.smt2 @@ -0,0 +1,13 @@ +(set-logic ALL) +(set-info :status-colibri2 sat) + +(declare-fun a () Int) +(declare-fun b () Real) + +(assert (< a 0)) +(assert (< b 0)) + +(check-sat) +(get-model) +(get-value ((abs a))) +(get-value ((colibri_abs_real b))) diff --git a/src_colibri2/tests/solve/models/abs_real.smt2.oracle b/src_colibri2/tests/solve/models/abs_real.smt2.oracle new file mode 100644 index 0000000000000000000000000000000000000000..7b5c3b712725c9a9c61f70e38539c108d694ce1f --- /dev/null +++ b/src_colibri2/tests/solve/models/abs_real.smt2.oracle @@ -0,0 +1,4 @@ +sat +((a -1)(b -1)) +((abs a 1)) +((colibri_abs_real b 1)) diff --git a/src_colibri2/tests/solve/models/dune.inc b/src_colibri2/tests/solve/models/dune.inc index ff2aa261caace0ce331feaf9636f1c0dc0c42fcf..c9eaba0f3712b7401bd9cbf990aa709bdf7bc93d 100644 --- a/src_colibri2/tests/solve/models/dune.inc +++ b/src_colibri2/tests/solve/models/dune.inc @@ -1,2 +1,4 @@ -(rule (action (with-stdout-to get_value.smt2.res (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 %{dep:get_value.smt2})))) +(rule (action (with-stdout-to abs_real.smt2.res (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 %{dep:abs_real.smt2})))) +(rule (alias runtest) (action (diff abs_real.smt2.oracle abs_real.smt2.res))) +(rule (action (with-stdout-to get_value.smt2.res (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 %{dep:get_value.smt2})))) (rule (alias runtest) (action (diff get_value.smt2.oracle get_value.smt2.res))) diff --git a/src_colibri2/tests/solve/smt_adt/sat/dune.inc b/src_colibri2/tests/solve/smt_adt/sat/dune.inc index 48f0c472b8b8532231719bc3b27ade36cb3ca8b5..8e7e09be40b1350daabfd7868cad647e76b43834 100644 --- a/src_colibri2/tests/solve/smt_adt/sat/dune.inc +++ b/src_colibri2/tests/solve/smt_adt/sat/dune.inc @@ -1,18 +1,18 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:enum.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:enum.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:enum.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:list0.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:list0.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:list0.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:list1.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:list1.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:list1.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:tree1.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:tree1.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:tree1.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:tree2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:tree2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:tree2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:tree3.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:tree3.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:tree3.smt2}))) diff --git a/src_colibri2/tests/solve/smt_adt/unsat/dune.inc b/src_colibri2/tests/solve/smt_adt/unsat/dune.inc index 0879b8f097646a2d3482d13052461b9e038108db..76424e820adb599eb4103225c0826c56eaddfbc3 100644 --- a/src_colibri2/tests/solve/smt_adt/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_adt/unsat/dune.inc @@ -1,24 +1,24 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:enum.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:enum.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:enum.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:enum2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:enum2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:enum2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:list0.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list0.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list0.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:list1.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list1.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list1.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:list2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:list3.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list3.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list3.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:list4.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list4.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:list4.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:parlist0.psmt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:parlist0.psmt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:parlist0.psmt2}))) diff --git a/src_colibri2/tests/solve/smt_fp/dune.inc b/src_colibri2/tests/solve/smt_fp/dune.inc index 43a2e25af1e4cfe582d32fa8fe29372adc07f0da..3df67fbfaa78aeed8624cc20b8b429a4cdd6f680 100644 --- a/src_colibri2/tests/solve/smt_fp/dune.inc +++ b/src_colibri2/tests/solve/smt_fp/dune.inc @@ -1,2 +1,2 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:rm_universal.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:rm_universal.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:rm_universal.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:rm_universal.smt2}))) diff --git a/src_colibri2/tests/solve/smt_fp/sat/dune.inc b/src_colibri2/tests/solve/smt_fp/sat/dune.inc index f0216026c8d36e97ea490cf09e2b42bc28de066b..a37aae0c7467a9349b619a24789a534a76c4ae72 100644 --- a/src_colibri2/tests/solve/smt_fp/sat/dune.inc +++ b/src_colibri2/tests/solve/smt_fp/sat/dune.inc @@ -1,45 +1,45 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:exists_eq_not_fp_eq.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:exists_eq_not_fp_eq.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:exists_eq_not_fp_eq.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:inf_pos_neg_neq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:inf_pos_neg_neq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:inf_pos_neg_neq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:infm_eq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:infm_eq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:infm_eq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:infp_eq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:infp_eq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:infp_eq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:nan_neq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:nan_neq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:nan_neq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:recognize_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:recognize_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:recognize_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:recognize_rounding_mode.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:recognize_rounding_mode.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:recognize_rounding_mode.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:rm_instanciation.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:rm_instanciation.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:rm_instanciation.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:simple_add_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_add_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_add_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:simple_eq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_eq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_eq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:simple_mul_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_mul_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:simple_mul_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:to_fp_eq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:to_fp_eq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:to_fp_eq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:zero_pos_neg_neq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zero_pos_neg_neq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zero_pos_neg_neq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:zerom_eq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zerom_eq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zerom_eq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:zerop_eq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zerop_eq_float32.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zerop_eq_float32.smt2}))) diff --git a/src_colibri2/tests/solve/smt_fp/unsat/dune.inc b/src_colibri2/tests/solve/smt_fp/unsat/dune.inc index 5d8594119d983e5c74dfa5044d3723bcca6d6187..df78d2aeadad850713c9ff0c4205176e2eba52aa 100644 --- a/src_colibri2/tests/solve/smt_fp/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_fp/unsat/dune.inc @@ -1,12 +1,12 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:eq_fp_eq.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:eq_fp_eq.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:eq_fp_eq.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:inf_pos_neg_neq.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:inf_pos_neg_neq.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:inf_pos_neg_neq.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:nan_neq_float32.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:nan_neq_float32.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:nan_neq_float32.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:propagate_le_ge.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:propagate_le_ge.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:propagate_le_ge.smt2}))) diff --git a/src_colibri2/tests/solve/smt_lra/sat/dune.inc b/src_colibri2/tests/solve/smt_lra/sat/dune.inc index 2c2e89ded6d45c4ab64d12a0fa8452bac48de0bf..c2743209c79e5a0af1b4f715e7ddb0361c8f8466 100644 --- a/src_colibri2/tests/solve/smt_lra/sat/dune.inc +++ b/src_colibri2/tests/solve/smt_lra/sat/dune.inc @@ -1,99 +1,102 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_CombiRepr_normalize.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_CombiRepr_normalize.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_CombiRepr_normalize.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_conflict_add_disequality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_conflict_add_disequality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_conflict_add_disequality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_conpoly.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_conpoly.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_conpoly.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_decide_must_test_is_dis_equal.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_decide_must_test_is_dis_equal.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_decide_must_test_is_dis_equal.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_init_always_merge_itself.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_init_always_merge_itself.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_init_always_merge_itself.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_init_and_propa_must_be_ordered.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_init_and_propa_must_be_ordered.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_init_and_propa_must_be_ordered.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_case1.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_case1.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_case1.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_case_4.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_case_4.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_case_4.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_case_4_bis.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_case_4_bis.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_case_4_bis.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_itself_coef_of_repr_is_one.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_itself_coef_of_repr_is_one.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_itself_coef_of_repr_is_one.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_itself_last_case.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_itself_last_case.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_itself_last_case.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_itself_pivot_not_in_p12.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_itself_pivot_not_in_p12.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_itself_pivot_not_in_p12.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_merge_must_use_find.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_must_use_find.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_merge_must_use_find.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_mult_explication.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_mult_explication.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_mult_explication.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_mult_not_linear_in_conflict.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_mult_not_linear_in_conflict.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_mult_not_linear_in_conflict.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_normalize_use_find_def.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_normalize_use_find_def.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_normalize_use_find_def.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_own_repr.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_own_repr.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_own_repr.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_propacl.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_propacl.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_propacl.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_subst_and_conflict_add.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_subst_and_conflict_add.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_subst_and_conflict_add.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:arith_zero_dom.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_zero_dom.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:arith_zero_dom.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:attach_only_when_dom_present.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:attach_only_when_dom_present.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:attach_only_when_dom_present.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:init_not_repr.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:init_not_repr.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:init_not_repr.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:le.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:le.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:le.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:le2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:le2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:le2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:mul.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:sem_invariant_in_learnt_dec.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:sem_invariant_in_learnt_dec.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:sem_invariant_in_learnt_dec.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:solver_add_pexp_cl.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_add_pexp_cl.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_add_pexp_cl.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:solver_arith_homogeneous_dist_sign.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_arith_homogeneous_dist_sign.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_arith_homogeneous_dist_sign.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:solver_merge_itself_repr_inside.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_merge_itself_repr_inside.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_merge_itself_repr_inside.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:solver_set_pending_merge_expsameexp.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_set_pending_merge_expsameexp.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_set_pending_merge_expsameexp.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:solver_subst_eventdom_find.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_subst_eventdom_find.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:solver_subst_eventdom_find.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:to_real.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:to_real.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:to_real.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:to_real2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:to_real2.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:to_real2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat +--dont-print-result %{dep:zero_should_not_be_simplified.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:zero_should_not_be_simplified.smt2}))) diff --git a/src_colibri2/tests/solve/smt_lra/sat/zero_should_not_be_simplified.smt2 b/src_colibri2/tests/solve/smt_lra/sat/zero_should_not_be_simplified.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..04165ac26b0adb32064b9d750fa86de6ea05985a --- /dev/null +++ b/src_colibri2/tests/solve/smt_lra/sat/zero_should_not_be_simplified.smt2 @@ -0,0 +1,23 @@ +(set-logic ALL) +(declare-fun v0 () Real) +(assert + (let ((?n12 0.0)) + (let ((?n13 0.0)) + (let ((?n15 0.0)) + (let ((?n26 true)) + (let ((?n28 true)) + (let ((?n29 false)) + (let ((?n30 0.0)) + (let ((?n31 (* 0.0 ?n13))) + (let ((?n32 (= ?n30 ?n31))) + (let ((?n33 (ite ?n32 v0 ?n15))) + (let ((?n34 (ite ?n29 ?n33 ?n12))) + (let ((?n37 0.0)) + (let ((?n38 (= ?n34 ?n37))) + (let ((?n42 true)) + (let ((?n43 (xor ?n38 ?n42))) + (let ((?n44 (xor ?n28 ?n43))) + (let ((?n45 (or ?n26 ?n44))) ?n45 +)))))))))))))))))) +(check-sat) +(exit) diff --git a/src_colibri2/tests/solve/smt_lra/unsat/dune.inc b/src_colibri2/tests/solve/smt_lra/unsat/dune.inc index 32098dbe065e4c8236e9953029f2e4dee7575d88..148c56f234b5deb1bad0a638588d467da421fd0f 100644 --- a/src_colibri2/tests/solve/smt_lra/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_lra/unsat/dune.inc @@ -1,33 +1,33 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:arith_ExpMult_by_zero.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:arith_ExpMult_by_zero.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:arith_ExpMult_by_zero.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:arith_merge_case2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:arith_merge_case2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:arith_merge_case2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:le.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:le.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:le.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:le2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:le2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:le2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:mul.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:repr_and_poly.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:repr_and_poly.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:repr_and_poly.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:repr_fourier.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:repr_fourier.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:repr_fourier.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:solver_merge_itself_repr_empty.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:solver_merge_itself_repr_empty.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:solver_merge_itself_repr_empty.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:solver_set_sem_merge_sign.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:solver_set_sem_merge_sign.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:solver_set_sem_merge_sign.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:to_real.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:to_real.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:to_real.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:to_real2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:to_real2.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:to_real2.smt2}))) diff --git a/src_colibri2/tests/solve/smt_nra/sat/dune.inc b/src_colibri2/tests/solve/smt_nra/sat/dune.inc index b0533db1e786e849483d576da545bf09427eb908..c73a28514ac43c5079afe957dbae5b47804a2ca1 100644 --- a/src_colibri2/tests/solve/smt_nra/sat/dune.inc +++ b/src_colibri2/tests/solve/smt_nra/sat/dune.inc @@ -1,21 +1,21 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:ceil.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:ceil.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:ceil.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:div_pos.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:div_pos.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:div_pos.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:div_pos_lt.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:div_pos_lt.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:div_pos_lt.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:mul_commut.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_commut.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_commut.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:mul_commut2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_commut2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_commut2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:mul_pos.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_pos.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_pos.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:mul_pos_lt.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_pos_lt.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:mul_pos_lt.smt2}))) diff --git a/src_colibri2/tests/solve/smt_nra/unsat/dune.inc b/src_colibri2/tests/solve/smt_nra/unsat/dune.inc index fdc03088e9ccf54610f6b382332c93ed58aa07bb..e25ae6b8c2aa2a031c4271477e527e4d1a5499d4 100644 --- a/src_colibri2/tests/solve/smt_nra/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_nra/unsat/dune.inc @@ -1,30 +1,30 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:ceil.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:ceil.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:ceil.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:div_pos.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_pos.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_pos.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:div_pos_lt.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_pos_lt.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_pos_lt.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:div_pos_lt_to_real.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_pos_lt_to_real.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:div_pos_lt_to_real.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:floor.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:floor.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:floor.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:mul_commut.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_commut.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_commut.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:mul_commut2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_commut2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_commut2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:mul_pos.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_pos.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_pos.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:mul_pos_lt.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_pos_lt.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_pos_lt.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:mul_pos_zero_le.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_pos_zero_le.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:mul_pos_zero_le.smt2}))) diff --git a/src_colibri2/tests/solve/smt_quant/dune.inc b/src_colibri2/tests/solve/smt_quant/dune.inc index 94c44726ffa9cfb365197972f70c954968c1bf33..7ff5d8dec7552006dcfca2c9198ccdf8fa613f12 100644 --- a/src_colibri2/tests/solve/smt_quant/dune.inc +++ b/src_colibri2/tests/solve/smt_quant/dune.inc @@ -1,6 +1,6 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:forall0.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:forall0.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:forall3.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:forall3.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:forall4.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:forall4.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:forall0.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:forall0.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:forall3.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:forall3.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result %{dep:forall4.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status colibri2 --dont-print-result --learning %{dep:forall4.smt2}))) diff --git a/src_colibri2/tests/solve/smt_quant/sat/dune.inc b/src_colibri2/tests/solve/smt_quant/sat/dune.inc index d888d22476695e087a41697346133e75a6296291..d33efa7a088a3f513006663b225c230b89037e1d 100644 --- a/src_colibri2/tests/solve/smt_quant/sat/dune.inc +++ b/src_colibri2/tests/solve/smt_quant/sat/dune.inc @@ -1,3 +1,3 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:exists.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:exists.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:exists.smt2}))) diff --git a/src_colibri2/tests/solve/smt_quant/unsat/dune.inc b/src_colibri2/tests/solve/smt_quant/unsat/dune.inc index fcea32050f0ee3ba5b20f8dcfcf30ba4fd2de59e..517624de8395acfd45a3e1d50c99aa837e6ae91b 100644 --- a/src_colibri2/tests/solve/smt_quant/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_quant/unsat/dune.inc @@ -1,33 +1,33 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:exists.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:exists.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:exists.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:exists2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:exists2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:exists2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall0.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall0.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall0.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall1.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall1.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall1.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall3.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall3.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall3.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall4.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall4.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall4.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall5.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall5.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall5.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall6.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall6.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall6.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall7.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall7.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall7.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:forall8.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall8.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:forall8.smt2}))) diff --git a/src_colibri2/tests/solve/smt_uf/sat/dune.inc b/src_colibri2/tests/solve/smt_uf/sat/dune.inc index 9872a6d3060efdca446859d6b939b45fa4cf283c..1ab95cb3d0d149b7b713ddcd730c5553dd02d7d1 100644 --- a/src_colibri2/tests/solve/smt_uf/sat/dune.inc +++ b/src_colibri2/tests/solve/smt_uf/sat/dune.inc @@ -1,63 +1,63 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:bad_conflict.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bad_conflict.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bad_conflict.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:bcp_dont_like_duplicate.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bcp_dont_like_duplicate.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bcp_dont_like_duplicate.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:bool_not_propa.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bool_not_propa.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bool_not_propa.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:boolexpup.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:boolexpup.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:boolexpup.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:clause_normalization.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:clause_normalization.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:clause_normalization.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:clmerge.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:clmerge.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:clmerge.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:conflict_complete_needed_cl.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:conflict_complete_needed_cl.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:conflict_complete_needed_cl.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:directdom_not.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:directdom_not.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:directdom_not.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:dis_dom_before_first_age.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:dis_dom_before_first_age.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:dis_dom_before_first_age.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:dom_merge_equality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:dom_merge_equality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:dom_merge_equality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:equality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:equality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:equality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:equality_condis.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:equality_condis.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:equality_condis.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:equality_get_sem.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:equality_get_sem.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:equality_get_sem.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:exp_sem_equality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:exp_sem_equality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:exp_sem_equality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:explimit_cl_equality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:explimit_cl_equality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:explimit_cl_equality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:implication.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:implication.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:implication.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:intmap_set_disjoint.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:intmap_set_disjoint.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:intmap_set_disjoint.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:is_equal_not_propagated.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:is_equal_not_propagated.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:is_equal_not_propagated.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:ite_sem_bool.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:ite_sem_bool.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:ite_sem_bool.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:polyeq_genequality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:polyeq_genequality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:polyeq_genequality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --dont-print-result %{dep:substupfalse_equality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:substupfalse_equality.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:substupfalse_equality.smt2}))) diff --git a/src_colibri2/tests/solve/smt_uf/unsat/dune.inc b/src_colibri2/tests/solve/smt_uf/unsat/dune.inc index 7003c0e59b3715b4f75dcb76be45ff7b7648a64b..e29ac13dd0c6f2ef96e2ee757bc02792782d5fd6 100644 --- a/src_colibri2/tests/solve/smt_uf/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_uf/unsat/dune.inc @@ -1,39 +1,39 @@ -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:NEQ004_size4__decide_eq_us.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:NEQ004_size4__decide_eq_us.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:NEQ004_size4__decide_eq_us.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:deltaed0.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:deltaed0.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:deltaed0.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:diff_to_value_for_bool.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:diff_to_value_for_bool.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:diff_to_value_for_bool.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:diff_value_substupfalse.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:diff_value_substupfalse.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:diff_value_substupfalse.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:distinct.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:distinct.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:distinct.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:eq_diamond2.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:eq_diamond2.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:eq_diamond2.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:equality_norm_set.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:equality_norm_set.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:equality_norm_set.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:fundef.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:fundef.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:fundef.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:get_repr_at__instead_of__equal_CRepr.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:get_repr_at__instead_of__equal_CRepr.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:get_repr_at__instead_of__equal_CRepr.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:many_distinct.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:many_distinct.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:many_distinct.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:polyeq_genequality.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:polyeq_genequality.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:polyeq_genequality.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:polyeq_genequality_deltaed.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:polyeq_genequality_deltaed.smt2}))) -(rule (alias runtest) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:polyeq_genequality_deltaed.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --dont-print-result %{dep:xor.smt2}))) -(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=10M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:xor.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=15M --time=30s --max-steps 3500 --check-status unsat --learning --dont-print-result %{dep:xor.smt2}))) diff --git a/src_colibri2/theories/FP/dom_interval.ml b/src_colibri2/theories/FP/dom_interval.ml index 0551468dd3241f2e8e59170cfaa87cbcebd5edf2..7c14b026c2471385a06a017f2f33485ebef30c1b 100644 --- a/src_colibri2/theories/FP/dom_interval.ml +++ b/src_colibri2/theories/FP/dom_interval.ml @@ -113,4 +113,4 @@ let init env = Egraph.set_dom d dom (Float32.node value) s end ) - \ No newline at end of file + diff --git a/src_colibri2/theories/LRA/.ocamlformat b/src_colibri2/theories/LRA/.ocamlformat new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src_colibri2/theories/LRA/dom_interval.ml b/src_colibri2/theories/LRA/dom_interval.ml index e9613f9ba0bfa29b6c97cbab8d0b70af5379cfcd..60cbf361ba62c7852ee914f5eb11687dcbf1dcc9 100644 --- a/src_colibri2/theories/LRA/dom_interval.ml +++ b/src_colibri2/theories/LRA/dom_interval.ml @@ -22,29 +22,40 @@ open Colibri2_popop_lib open Colibri2_core open Colibri2_stdlib.Std -let debug = Debug.register_info_flag - ~desc:"for intervals for the arithmetic theory" - "LRA.interval" +let debug = + Debug.register_info_flag ~desc:"for intervals for the arithmetic theory" + "LRA.interval" module D = Colibri2_theories_LRA_stages.Interval_domain -let dom = Dom.Kind.create (module struct type t = D.t let name = "ARITH" end) +let dom = + Dom.Kind.create + (module struct + type t = D.t -include (Dom.Lattice(struct - include D - let key = dom - let inter _ d1 d2 = inter d1 d2 - let is_singleton _ d = - Option.map (fun x -> RealValue.nodevalue @@ RealValue.index x) (is_singleton d) - end -)) + let name = "ARITH" + end) + +include Dom.Lattice (struct + include D + + let key = dom + + let inter _ d1 d2 = inter d1 d2 + + let is_singleton _ d = + Option.map + (fun x -> RealValue.nodevalue @@ RealValue.index x) + (is_singleton d) +end) let is_zero_or_positive d n = match Egraph.get_dom d dom n with | None -> false - | Some p -> match D.is_comparable D.zero p with - | D.Le | D.Lt -> true - | D.Ge | D.Gt | D.Uncomparable -> false + | Some p -> ( + match D.is_comparable D.zero p with + | D.Le | D.Lt | D.Eq -> true + | D.Ge | D.Gt | D.Uncomparable -> false) let is_not_zero d n = match Egraph.get_dom d dom n with @@ -54,59 +65,57 @@ let is_not_zero d n = let is_strictly_positive d n = match Egraph.get_dom d dom n with | None -> false - | Some p -> match D.is_comparable D.zero p with - | D.Lt -> true - | D.Le | D.Ge | D.Gt | D.Uncomparable -> false + | Some p -> ( + match D.is_comparable D.zero p with + | D.Lt -> true + | D.Eq | D.Le | D.Ge | D.Gt | D.Uncomparable -> false) let is_strictly_negative d n = match Egraph.get_dom d dom n with | None -> false - | Some p -> match D.is_comparable D.zero p with - | D.Gt -> true - | D.Le | D.Ge | D.Lt | D.Uncomparable -> false + | Some p -> ( + match D.is_comparable D.zero p with + | D.Gt -> true + | D.Eq | D.Le | D.Ge | D.Lt | D.Uncomparable -> false) -let is_integer d n = +let assume_negative d n = upd_dom d n (D.lt Q.zero) + +let assume_positive d n = upd_dom d n (D.gt Q.zero) + +let zero_is d n = match Egraph.get_dom d dom n with - | None -> false - | Some p -> D.is_integer p + | None -> D.Uncomparable + | Some p -> D.is_comparable D.zero p +let is_integer d n = + match Egraph.get_dom d dom n with None -> false | Some p -> D.is_integer p module ChoLRA = struct let make_decision node v env = - Debug.dprintf4 Debug.decision - "[LRA] decide %a on %a" D.pp v Node.pp node; + Debug.dprintf4 Debug.decision "[LRA] decide %a on %a" D.pp v Node.pp node; set_dom env node v let choose_decision node env = let v = Opt.get_def D.reals (Egraph.get_dom env dom node) in - match D.split_heuristic v with - | Singleton _ -> Choice.DecNo - | Splitted (v1,v2) -> - DecTodo (List.map (make_decision node) (Shuffle.shufflel [v1;v2])) - | NotSplitted -> - DecTodo [make_decision node (D.singleton (D.choose v))] - - let choice n = { - Choice.prio = 1; - choice = choose_decision n; - print_cho = "Decision made by dom_interval.ml"; + match D.split_heuristic v with + | Singleton _ -> Choice.DecNo + | Splitted (v1, v2) -> + DecTodo (List.map (make_decision node) (Shuffle.shufflel [ v1; v2 ])) + | NotSplitted -> DecTodo [ make_decision node (D.singleton (D.choose v)) ] + + let choice n = + { + Choice.prio = 1; + choice = choose_decision n; + print_cho = "Decision made by dom_interval.ml"; } - end let choice = ChoLRA.choice -let neg_cmp = function - | `Lt -> `Ge - | `Le -> `Gt - | `Ge -> `Lt - | `Gt -> `Le +let neg_cmp = function `Lt -> `Ge | `Le -> `Gt | `Ge -> `Lt | `Gt -> `Le -let com_cmp = function - | `Lt -> `Gt - | `Le -> `Ge - | `Ge -> `Le - | `Gt -> `Lt +let com_cmp = function `Lt -> `Gt | `Le -> `Ge | `Ge -> `Le | `Gt -> `Lt let backward = function | `Lt -> D.lt' @@ -115,7 +124,7 @@ let backward = function | `Ge -> D.ge' (** {2 Initialization} *) -let converter d (f:Ground.t) = +let converter d (f : Ground.t) = let r = Ground.node f in let reg n = Egraph.register d n in let open Monad in @@ -124,67 +133,103 @@ let converter d (f:Ground.t) = let set = updd upd_dom in let get = getd dom in let cmp test cmp a b = - reg a; reg b; - attach d ( - setb r (let* va = get a and+ vb = get b in - test (D.is_comparable va vb)) && - set b (let+ va = get a and+ vr = getb r in - backward (if vr then (com_cmp cmp) else (com_cmp (neg_cmp cmp))) va) && - set a (let+ vb = get b and+ vr = getb r in - backward (if vr then cmp else (neg_cmp cmp)) vb) - ); + reg a; + reg b; + attach d + (setb r + (let* va = get a and+ vb = get b in + test (D.is_comparable va vb)) + && set b + (let+ va = get a and+ vr = getb r in + backward (if vr then com_cmp cmp else com_cmp (neg_cmp cmp)) va) + && set a + (let+ vb = get b and+ vr = getb r in + backward (if vr then cmp else neg_cmp cmp) vb)) in match Ground.sem f with - | { app = {builtin = Expr.Base; _ }; tyargs = _; args = _; ty } + | { app = { builtin = Expr.Base; _ }; tyargs = _; args = _; ty } when Ground.Ty.equal ty Ground.Ty.real -> - (* Egraph.register_decision d (ChoLRA.choice r) *) (* not useful for now *) - () - | { app = {builtin = Expr.Base; _ }; tyargs = _; args = _; ty } + (* Egraph.register_decision d (ChoLRA.choice r) *) + (* not useful for now *) + () + | { app = { builtin = Expr.Base; _ }; tyargs = _; args = _; ty } when Ground.Ty.equal ty Ground.Ty.int -> - upd_dom d r D.integers - | { app = {builtin = Expr.Add}; tyargs = []; args; _ } -> - let (a,b) = IArray.extract2_exn args in - reg a; reg b; - attach d ( - set r (let+ va = get a and+ vb = get b in D.add va vb) && - set a (let+ vb = get b and+ vr = get r in D.minus vr vb) && - set b (let+ va = get a and+ vr = get r in D.minus vr va) - ); - | { app = {builtin = Expr.Sub}; tyargs = []; args; _ } -> - let (a,b) = IArray.extract2_exn args in - reg a; reg b; - attach d ( - set r (let+ va = get a and+ vb = get b in D.minus va vb) && - set a (let+ vb = get b and+ vr = get r in D.add vr vb) && - set b (let+ va = get a and+ vr = get r in D.minus va vr) - ); - | { app = {builtin = Expr.Minus}; tyargs = []; args; _ } -> - let a = IArray.extract1_exn args in - reg a; - attach d ( - set r (let+ va = get a in D.mult_cst Q.minus_one va) && - set a (let+ vr = get r in D.mult_cst Q.minus_one vr) - ); - | { app = {builtin = Expr.Lt}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp (function | Uncomparable | Le -> None | Lt -> Some true | Ge | Gt -> Some false) `Lt a b - | { app = {builtin = Expr.Leq}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp (function | Uncomparable | Ge -> None | Lt | Le -> Some true | Gt -> Some false) `Le a b - | { app = {builtin = Expr.Geq}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp (function | Uncomparable | Le -> None | Lt -> Some false | Ge | Gt -> Some true) `Ge a b - | { app = {builtin = Expr.Gt}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp (function | Uncomparable | Ge -> None | Lt | Le -> Some false | Gt -> Some true) `Gt a b + upd_dom d r D.integers + | { app = { builtin = Expr.Add }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + attach d + (set r + (let+ va = get a and+ vb = get b in + D.add va vb) + && set a + (let+ vb = get b and+ vr = get r in + D.minus vr vb) + && set b + (let+ va = get a and+ vr = get r in + D.minus vr va)) + | { app = { builtin = Expr.Sub }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + attach d + (set r + (let+ va = get a and+ vb = get b in + D.minus va vb) + && set a + (let+ vb = get b and+ vr = get r in + D.add vr vb) + && set b + (let+ va = get a and+ vr = get r in + D.minus va vr)) + | { app = { builtin = Expr.Minus }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + attach d + (set r + (let+ va = get a in + D.mult_cst Q.minus_one va) + && set a + (let+ vr = get r in + D.mult_cst Q.minus_one vr)) + | { app = { builtin = Expr.Lt }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp + (function + | Uncomparable | Le -> None + | Lt -> Some true + | Eq | Ge | Gt -> Some false) + `Lt a b + | { app = { builtin = Expr.Leq }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp + (function + | Uncomparable | Ge -> None + | Eq | Lt | Le -> Some true + | Gt -> Some false) + `Le a b + | { app = { builtin = Expr.Geq }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp + (function + | Uncomparable | Le -> None + | Eq | Lt -> Some false + | Ge | Gt -> Some true) + `Ge a b + | { app = { builtin = Expr.Gt }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp + (function + | Uncomparable | Ge -> None + | Eq | Lt | Le -> Some false + | Gt -> Some true) + `Gt a b | _ -> () let init env = - Daemon.attach_reg_value env - RealValue.key - (fun d value -> - let v = RealValue.value value in - let s = D.singleton v in - Egraph.set_dom d dom (RealValue.node value) s - ); + Daemon.attach_reg_value env RealValue.key (fun d value -> + let v = RealValue.value value in + let s = D.singleton v in + Egraph.set_dom d dom (RealValue.node value) s); Ground.register_converter env converter diff --git a/src_colibri2/theories/LRA/dom_interval.mli b/src_colibri2/theories/LRA/dom_interval.mli index 4a7f75404698ceb723de8b98028a1fcce513e116..fa4cd42d3038c849ef084502c515955ec7fb0e1a 100644 --- a/src_colibri2/theories/LRA/dom_interval.mli +++ b/src_colibri2/theories/LRA/dom_interval.mli @@ -18,14 +18,28 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (*************************************************************************) -val init: Egraph.wt -> unit +val init : Egraph.wt -> unit -module D: sig type t end +module D : sig + type t + + type is_comparable = Gt | Lt | Ge | Le | Eq | Uncomparable +end val dom : D.t Dom.Kind.t -val is_zero_or_positive: _ Egraph.t -> Node.t -> bool -val is_not_zero: _ Egraph.t -> Node.t -> bool -val is_strictly_positive: _ Egraph.t -> Node.t -> bool -val is_strictly_negative: _ Egraph.t -> Node.t -> bool -val is_integer: _ Egraph.t -> Node.t -> bool +val is_zero_or_positive : _ Egraph.t -> Node.t -> bool + +val is_not_zero : _ Egraph.t -> Node.t -> bool + +val is_strictly_positive : _ Egraph.t -> Node.t -> bool + +val is_strictly_negative : _ Egraph.t -> Node.t -> bool + +val is_integer : _ Egraph.t -> Node.t -> bool + +val zero_is : _ Egraph.t -> Node.t -> D.is_comparable + +val assume_positive : Egraph.wt -> Node.t -> unit + +val assume_negative : Egraph.wt -> Node.t -> unit diff --git a/src_colibri2/theories/LRA/dom_polynome.ml b/src_colibri2/theories/LRA/dom_polynome.ml index 4ee192231889c6f459e7dc0d7625bf69ca796f0b..9217b959115067fa3f85e4b26ecf018574b564fa 100644 --- a/src_colibri2/theories/LRA/dom_polynome.ml +++ b/src_colibri2/theories/LRA/dom_polynome.ml @@ -22,205 +22,118 @@ open Colibri2_popop_lib open Colibri2_core open Colibri2_stdlib.Std -let debug = Debug.register_info_flag - ~desc:"for the arithmetic theory of polynome" - "LRA.polynome" - -let dom = Dom.Kind.create (module struct type t = Polynome.t let name = "ARITH_POLY" end) +let debug = + Debug.register_info_flag ~desc:"for the arithmetic theory of polynome" + "LRA.polynome" module T = struct include Polynome + let name = "SARITH_POLY" end -module ThE = ThTerm.Register(T) - -let node_of_polynome t = ThE.node (ThE.index t) - -let used_in_poly : Node.t Bag.t Node.HC.t = Node.HC.create (Bag.pp Pp.semi Node.pp) "used_in_poly" - -let set_poly d cl p = - Egraph.set_dom d dom cl p; - match Polynome.is_one_node p with - | None -> Egraph.set_thterm d cl (ThE.thterm (ThE.index p)) - | Some cl' -> Egraph.merge d cl cl' - -let add_used d cl' new_cl = - Node.M.iter (fun used _ -> - Node.HC.change (function - | Some b -> Some (Bag.append b cl') - | None -> - begin match Egraph.get_dom d dom used with - | None -> - (** If a used node have no polynome associated, we set it to - itself. This allows to be warned when this node is merged. It - is the reason why this module doesn't specifically wait for - representative change *) - Egraph.set_dom d dom used (Polynome.monome Q.one used) - | Some p -> - assert (Polynome.equal (Polynome.monome Q.one used) p) - end; - Some (Bag.elt cl') - ) used_in_poly d used - ) new_cl - -let subst_doms d cl (p:Polynome.t) = - let b = match Node.HC.find used_in_poly d cl with - | exception Not_found -> Bag.empty - | b -> b - in - Bag.iter (fun cl' -> - match Egraph.get_dom d dom cl' with - | None -> assert false (** absurd: can't be used and absent *) - | Some q -> - let new_cl = Node.M.set_diff p.poly q.poly in - let q, _ = Polynome.subst q cl p in - add_used d cl' new_cl; - set_poly d cl' q - ) b; - add_used d cl p.poly; - set_poly d cl p - -module Th = struct +module ThE = ThTerm.Register (T) + +module Table = struct + module H = Datastructure.Hashtbl (T) + + let h = H.create Node.pp "HARITH_POLY" + + let set ~old_ ~new_ n d = + (match old_ with + | None -> () + | Some old_ -> if not (Polynome.equal old_ new_) then H.remove h d old_); + H.change + (function + | None -> Some n + | Some n' as s -> + Egraph.merge d n n'; + s) + h d new_ + + let new_ d p = + match H.find_opt h d p with + | Some n -> n + | None -> + let n = ThE.node (ThE.index p) in + H.set h d p n; + n +end + +let node_of_polynome d p = + match Polynome.is_cst p with + | None -> Table.new_ d p + | Some q -> RealValue.node (RealValue.index q) + +include Pivot.Total (struct include Polynome - let merged v1 v2 = - match v1,v2 with - | None, None -> true - | Some v', Some v -> equal v' v - | _ -> false - - let norm_dom cl = function - | None -> - let r = monome Q.one cl in - r - | Some p -> - p - - let add_itself d cl norm = - add_used d cl norm.poly; - Egraph.set_dom d dom cl norm - - let merge d ((p1o,cl1) as a1) ((p2o,cl2) as a2) inv = - assert (not (Egraph.is_equal d cl1 cl2)); - assert (not (Option.is_none p1o && Option.is_none p2o)); - let (pother, other), (prepr, repr) = if inv then a2,a1 else a1,a2 in - let other = Egraph.find d other in - let repr = Egraph.find d repr in - let p1 = norm_dom other pother in - let p2 = norm_dom repr prepr in - let diff = sub p1 p2 in - (* 0 = other - repr = p1 - p2 = diff *) - Debug.dprintf2 debug "[Arith] @[solve 0=%a@]" pp diff; - begin match Polynome.extract diff with - | Zero -> (** no new equality already equal *) - begin - match pother, prepr with - | Some _, Some _ | None, None -> - assert false (** absurd: no need of merge *) - | Some p, None -> - (** p = repr *) - add_itself d repr p - | None, Some p -> - (** p = other *) - add_itself d other p - end - | Cst c -> - (* 0 = cst <> 0 *) - Debug.dprintf6 Debug.contradiction - "[LRA/Poly] Found 0 = %a when merging %a and %a" - Q.pp c - Node.pp cl1 Node.pp cl2; - Egraph.contradiction d - | Var(q,x,p') -> - (** diff = qx + p' *) - assert ( not (Q.equal Q.zero q) ); - Debug.dprintf2 debug "[Arith] @[pivot %a@]" Node.pp x; - let add_if_default n norm = function - | Some _ -> () - | None -> - add_itself d n norm - in - add_if_default other p1 pother; - add_if_default repr p2 prepr; - subst_doms d x (Polynome.mult_cst (Q.div Q.one (Q.neg q)) p') - end; - assert (Option.compare Polynome.compare - (Egraph.get_dom d dom repr) - (Egraph.get_dom d dom other) = 0) - - let solve_one d cl p1 = - match Egraph.get_dom d dom cl with - | None -> - subst_doms d cl p1 - | Some p2 -> - let diff = Polynome.sub p1 p2 in - (* 0 = p1 - p2 = diff *) - Debug.dprintf8 debug "[Arith] @[solve in init %a 0=(%a)-(%a)=%a@]" - Node.pp cl Polynome.pp p1 Polynome.pp p2 Polynome.pp diff; - begin match Polynome.extract diff with - | Zero -> () - | Cst c -> - (* 0 = cst <> 0 *) - Debug.dprintf4 Debug.contradiction - "[LRA/Poly] Found 0 = %a when updating %a" - Q.pp c - Node.pp cl; - Egraph.contradiction d - | Var(q,x,p') -> - (** diff = qx + p' *) - assert ( not (Q.equal Q.zero q) ); - Debug.dprintf2 debug "[Arith] @[pivot %a@]" Node.pp x; - subst_doms d x (Polynome.mult_cst (Q.div Q.one (Q.neg q)) p') - end - - let key = dom -end + let name = "LRA.polynome" + + type data = Q.t + + let nodes p = p.poly -let () = Dom.register(module Th) + let of_one_node n = monome Q.one n -let norm d (p:Polynome.t) = - let add acc cl c = - let cl = Egraph.find_def d cl in - match Egraph.get_dom d dom cl with - | None -> Polynome.add acc (Polynome.monome c cl) - | Some p -> Polynome.x_p_cy acc c p - in - Polynome.fold add (Polynome.cst p.cst) p + let subst p n q = fst (subst p n q) -let assume_poly_equality d n (p:Polynome.t) = - (* Debug.dprintf4 debug "assume1: %a = %a" Node.pp n Polynome.pp p; *) - let n = Egraph.find_def d n in - let p = norm d p in - (* Debug.dprintf4 debug "assume2: %a = %a" Node.pp n Polynome.pp p; *) - Th.solve_one d n p + let normalize p ~f = + let add acc cl c = Polynome.x_p_cy acc c (f cl) in + Polynome.fold add (Polynome.cst p.cst) p + + let set d cl ~old_ ~new_ = + match is_one_node new_ with + | None -> ( + match Polynome.is_cst new_ with + | None -> Table.set ~old_ ~new_ cl d + | Some q -> + Egraph.set_value d cl (RealValue.nodevalue (RealValue.index q))) + | Some cl' -> Egraph.merge d cl cl' + + let solve p1 p2 : _ Pivot.solve_total = + let diff = sub p1 p2 in + (* 0 = other - repr = p1 - p2 = diff *) + Debug.dprintf2 debug "[Arith] @[solve 0=%a@]" pp diff; + match Polynome.extract diff with + | Zero -> Pivot.AlreadyEqual + | Cst c -> + (* 0 = cst <> 0 *) + Debug.dprintf2 Debug.contradiction + "[LRA/Poly] Found 0 = %a when merging" Q.pp c; + Contradiction + | Var (q, x, p') -> + assert (not (Q.equal Q.zero q)); + (* diff = qx + p' *) + Subst (x, Polynome.mult_cst (Q.div Q.one (Q.neg q)) p') +end) (** {2 Initialization} *) -let converter d (f:Ground.t) = - let res = Ground.node f in +let converter d (f : Ground.t) = + let res = Ground.node f in let reg n = Egraph.register d n in match Ground.sem f with - | { app = {builtin = Expr.Add}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; - assume_poly_equality d res (Polynome.of_list Q.zero [a,Q.one;b,Q.one]) - | { app = {builtin = Expr.Sub}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; - assume_poly_equality d res (Polynome.of_list Q.zero [a,Q.one;b,Q.minus_one]) - | { app = {builtin = Expr.Minus}; tyargs = []; args; _ } -> - let a = IArray.extract1_exn args in - reg a; - assume_poly_equality d res (Polynome.of_list Q.zero [a,Q.minus_one]) + | { app = { builtin = Expr.Add }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + assume_equality d res (Polynome.of_list Q.zero [ (a, Q.one); (b, Q.one) ]) + | { app = { builtin = Expr.Sub }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + assume_equality d res + (Polynome.of_list Q.zero [ (a, Q.one); (b, Q.minus_one) ]) + | { app = { builtin = Expr.Minus }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + assume_equality d res (Polynome.of_list Q.zero [ (a, Q.minus_one) ]) | _ -> () let init env = - Daemon.attach_reg_value env - RealValue.key - (fun d value -> - let v = RealValue.value value in - let cl = RealValue.node value in - let p1 = Polynome.of_list v [] in - assume_poly_equality d cl p1 - ); - Ground.register_converter env converter + Daemon.attach_reg_value env RealValue.key (fun d value -> + let v = RealValue.value value in + let cl = RealValue.node value in + let p1 = Polynome.of_list v [] in + assume_equality d cl p1); + Ground.register_converter env converter diff --git a/src_colibri2/theories/LRA/dom_polynome.mli b/src_colibri2/theories/LRA/dom_polynome.mli index ef3a5d7b07be91f7b2dd8afbc9f027b1f9a6804a..f9051653d763eb6f3334453952509a396b0e2ab0 100644 --- a/src_colibri2/theories/LRA/dom_polynome.mli +++ b/src_colibri2/theories/LRA/dom_polynome.mli @@ -18,12 +18,18 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (*************************************************************************) -val assume_poly_equality: Egraph.wt -> Node.t -> Polynome.t -> unit +val assume_equality : Egraph.wt -> Node.t -> Polynome.t -> unit -val dom: Polynome.t Dom.Kind.t +val get_repr : _ Egraph.t -> Node.t -> Polynome.t option -val init: Egraph.wt -> unit +val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit -val node_of_polynome: Polynome.t -> Node.t +val events_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.rt -> Node.t -> Events.enqueue) -> unit -val norm: _ Egraph.t -> Polynome.t -> Polynome.t +val init : Egraph.wt -> unit + +val node_of_polynome : _ Egraph.t -> Polynome.t -> Node.t + +val normalize : _ Egraph.t -> Polynome.t -> Polynome.t diff --git a/src_colibri2/theories/LRA/dom_product.ml b/src_colibri2/theories/LRA/dom_product.ml index 989a8d47540dabbb47b31e840c1559d28e1315c3..c726fd0ddc59e524be6ae4e1266dd9218041c88a 100644 --- a/src_colibri2/theories/LRA/dom_product.ml +++ b/src_colibri2/theories/LRA/dom_product.ml @@ -22,387 +22,380 @@ open Colibri2_popop_lib open Colibri2_core open Colibri2_stdlib.Std -let debug = Debug.register_info_flag - ~desc:"for the arithmetic theory of product of variable" - "LRA.product" +let debug = + Debug.register_info_flag + ~desc:"for the arithmetic theory of product of variable" "LRA.product" -type t = { - repr: Product.t; - (** When a pivot is not possible because the equality can be null, the other - product are waiting on the side, they are also normalized *) - eqs: Product.S.t; -}[@@deriving ord,eq] +module T = struct + module T = struct + type t = { abs : Product.t; sign : Sign_product.t } + [@@deriving eq, ord, hash, show] -let pp fmt t = - Fmt.pf fmt "%a,%a" Product.pp t.repr Product.S.pp t.eqs + let name = "SARITH_PROD" + end -let dom = Dom.Kind.create (module struct type nonrec t = t let name = "ARITH_PROD" end) + include T + include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T) +end -module T = struct - include Product - let name = "SARITH_PROD" +module ThE = ThTerm.Register (T) + +module Table = struct + module H = Datastructure.Hashtbl (T) + + let h = H.create Node.pp "HARITH_PRODUCT" + + let set ~old_ ~new_ d n = + if not (T.equal old_ new_) then H.remove h d old_; + H.change + (function + | None -> Some n + | Some n' as s -> + Egraph.merge d n n'; + s) + h d new_ + + let new_ d p = + match H.find_opt h d p with + | Some n -> n + | None -> + let n = ThE.node (ThE.index p) in + H.set h d p n; + n end -module ThE = ThTerm.Register(T) - -let node_of_product t = ThE.node (ThE.index t) - -let used_in_poly : Node.S.t Node.HC.t = Node.HC.create Node.S.pp "used_in_poly" - -let set_poly d cl p chg = - Egraph.set_dom d dom cl p; - List.iter (fun p -> - match Product.is_one_node p with - | None -> Egraph.set_thterm d cl (ThE.thterm (ThE.index p)) - | Some cl' -> Egraph.merge d cl cl') chg - -let add_used_product d cl' new_cls = - Node.M.iter (fun used _ -> - Node.HC.change (function - | Some b -> Some (Node.S.add cl' b) - | None -> - begin match Egraph.get_dom d dom used with - | None -> - (** If a used node have no polynome associated, we set it to - itself. This allows to be warned when this node is merged. It - is the reason why this module doesn't specifically wait for - representative change *) - Egraph.set_dom d dom used - {repr = Product.monome used Q.one; eqs = Product.S.empty }; - Some (Node.S.of_list [cl';used]) - | Some p -> - assert (Product.equal (Product.monome used Q.one) p.repr); - assert false - end - ) used_in_poly d used - ) new_cls - -let add_used_t d cl' t = - add_used_product d cl' t.repr.poly; - Product.S.iter (fun p -> add_used_product d cl' p.poly) t.eqs - -let subst_doms d cl p = - let b = match Node.HC.find used_in_poly d cl with - | exception Not_found -> Node.S.empty - | b -> b - in - Node.S.iter (fun cl' -> - match Egraph.get_dom d dom cl' with - | None -> assert false (** absurd: can't be used and absent *) - | Some q -> - let fold (new_cl,acc,chg) (q:Product.t) = - let new_cl = Node.M.set_union new_cl (Node.M.set_diff p.Product.poly q.poly) in - let q, c = Product.subst q cl p in - (new_cl, Product.S.add q acc, if Q.sign c = 0 then chg else q::chg) - in - let (new_cl,acc,chg) = fold (Node.M.empty, Product.S.empty, []) q.repr in - let repr = Product.S.choose acc in - let (new_cl,acc,chg) = Product.S.fold_left fold (new_cl,acc,chg) q.eqs in - let eqs = Product.S.remove repr acc in - add_used_product d cl' new_cl; - set_poly d cl' { repr; eqs } chg - ) b - -let norm_product d p = - let add acc cl c = - let cl = Egraph.find d cl in - match Egraph.get_dom d dom cl with - | None -> Product.mul acc (Product.monome cl c) - | Some p -> Product.x_m_yc acc p.repr c - in - Product.fold add Product.one p +let node_of_product d abs sign = + let t = { T.abs; sign } in + Table.new_ d t +let set d cl ~old_abs ~old_sign abs sign = + if Sign_product.equal Sign_product.zero sign then + Egraph.merge d cl RealValue.zero + else + let aux () = + Table.set d cl + ~old_:{ T.abs = old_abs; sign = old_sign } + ~new_:{ T.abs; sign } + in + match Product.is_one_node abs with + | None -> aux () + | Some cl' -> ( + match Sign_product.is_one_node sign with + | Some cl'' when Egraph.is_equal d cl' cl'' -> Egraph.merge d cl cl' + | _ -> aux ()) -module Th = struct - let merged v1 v2 = - Base.phys_equal v1 v2 || - match v1,v2 with - | None, None -> true - | Some v', Some v -> equal v' v - | _ -> false +module rec SolveAbs : sig + val assume_equality : Egraph.wt -> Node.t -> Product.t -> unit - let norm_dom cl = function - | None -> - let r = Product.monome cl Q.one in - { repr = r; eqs = Product.S.empty } - | Some p -> - p - - let add_itself d cl norm = - add_used_t d cl norm; - Egraph.set_dom d dom cl norm - - let rec merge d (_,cl1) (_,cl2) _inv = - let cl1 = Egraph.find d cl1 in - let cl2 = Egraph.find d cl2 in - assert (not (Egraph.is_equal d cl1 cl2)); - merge_aux d cl1 cl2 - - and merge_aux d cl1 cl2 = - let p1o = Egraph.get_dom d dom cl1 in - let p2o = Egraph.get_dom d dom cl2 in - assert (not (Option.is_none p1o && Option.is_none p2o)); - match p1o, p2o with - | None, None -> assert false (* absurd: no need to merge *) - | Some p, None -> - assert ( Option.is_none (Node.HC.find_opt used_in_poly d cl2) ); - add_itself d cl2 p - | None, Some p -> - assert ( Option.is_none (Node.HC.find_opt used_in_poly d cl1) ); - add_itself d cl1 p - | Some p1, Some p2 -> - match solve d - ( Lists.product - (part d (p1.repr::(Product.S.elements p1.eqs))) - (part d (p2.repr::(Product.S.elements p2.eqs))) - ) - with - | `Solved -> - (** The domains have been subsituted, and possibly recursively *) - merge_aux d cl1 cl2 - | `Not_solved -> - (** nothing to solve *) - let repr = - match Product.is_one_node p1.repr, Product.is_one_node p2.repr with - | None, None -> p1.repr (* arbitrary *) - | Some _, None -> p1.repr - | None, Some _ -> p2.repr - | Some cl1', Some cl2' -> - assert ( Node.equal cl1' cl2' ); - p1.repr - in - let eqs = p1.eqs - |> Product.S.add p1.repr - |> Product.S.union p2.eqs - |> Product.S.add p2.repr - |> Product.S.remove repr - in - let p = { repr; eqs } in - Egraph.set_dom d dom cl1 p; - Egraph.set_dom d dom cl2 p - - and merge_one_new_eq d cl eq = - let po = Egraph.get_dom d dom cl in - match po with - | None -> - add_used_product d cl eq.Product.poly; - set_poly d cl { repr = eq; eqs = Product.S.empty } [eq] - | Some p -> - if not (Product.S.mem eq p.eqs) && not (Product.equal eq p.repr) then - match solve d - (Lists.product - (part d (p.repr::(Product.S.elements p.eqs))) - (part d [eq]) - ) - with - | `Solved -> - (** The domains have been subsituted, and possibly recursively *) - let eq = norm_product d eq in - merge_one_new_eq d cl eq - | `Not_solved -> - (** nothing to solve *) - let repr = p.repr in - let eqs = p.eqs - |> Product.S.add eq - |> Product.S.remove repr - in - let p = { repr; eqs } in - add_used_product d cl eq.poly; - set_poly d cl p [eq] - - and subst d cl eq = - Debug.dprintf4 debug "[Product] subst %a with %a" Node.pp cl Product.pp eq; - let po = Egraph.get_dom d dom cl in - match po with - | None -> - let p = { repr = eq; eqs = Product.S.empty } in - add_used_product d cl eq.poly; - set_poly d cl p [eq] - | Some p -> - assert (Product.equal p.repr (Product.monome cl Q.one)); - subst_doms d cl eq; - assert (Product.equal eq (Opt.get (Egraph.get_dom d dom cl)).repr); - merge_one_new_eq d cl eq - - and part d l = - let part m = - let spos,other = Node.M.partition (fun k _ -> Dom_interval.is_strictly_positive d k) - m.Product.poly - in - let notz,other = Node.M.partition (fun k _ -> Dom_interval.is_not_zero d k) - other in - spos,notz,other,m - in - List.map part l - - and solve d l = - let exception Solved of Node.t * Product.t in - let criteria ((_,notz1,unk1,p1) as i1) ((_,notz2,unk2,p2) as i2) = - if Node.M.is_empty notz1 && Node.M.is_empty unk1 && - Node.M.is_empty notz2 && Node.M.is_empty unk2 then - (** all (strictly) positive: can use root *) - let p = Product.div p1 p2 in - match Product.extract p with - | One -> () - | Var(q,n,p) -> - let p = Product.power_cst (Q.inv (Q.neg q)) p in - raise (Solved (n,p)) - else - let aux (_,_,unk1,p1) (_,_,unk2,p2) = - if Node.M.is_empty unk1 then - (** side 1 with all different from zero *) - Node.M.iter (fun n q1 -> - let q2 = Node.M.find_def Q.zero n p2.Product.poly in - if Q.equal (Q.sub q1 q2) Q.one then - let p = Product.div p2 p1 in - assert (Q.equal (Node.M.find n p.poly) Q.minus_one); - let p = Product.remove n p in - raise (Solved(n,p)) - ) p1.Product.poly - else if Node.M.is_num_elt 1 unk1 then - let (n,q) = Node.M.choose unk1 in - if Q.equal q Q.one && not (Node.M.mem n unk2) then - let p = Product.div p2 (Product.remove n p1) in - raise (Solved(n,p)) - in - aux i1 i2; aux i2 i1 - in - match - List.iter (fun (a,b) -> criteria a b) l - with - | exception Solved (n,p) -> - subst d n p; - `Solved - | () -> - `Not_solved - - let key = dom - - type nonrec t = t - let pp = pp -end + val init : Egraph.wt -> unit -let () = Dom.register(module Th) - -let get_repr d n = - let open CCOpt in - let+ p = Egraph.get_dom d dom n in - p.repr - -let assume_poly_equality d n (p:Product.t) = - (* Debug.dprintf4 debug "assume1: %a = %a" Node.pp n Product.pp p; *) - let n = Egraph.find d n in - let p = norm_product d p in - (* Debug.dprintf4 debug "assume2: %a = %a" Node.pp n Product.pp p; *) - Th.merge_one_new_eq d n p - -module ChangePos = struct - type runable = Node.S.t - let print_runable = Node.S.pp - let run d ns = - Node.S.iter (fun n -> - let p = Opt.get @@ Egraph.get_dom d dom n in - let l = Th.part d (p.repr::Product.S.elements p.eqs) in - let l = Lists.product l l in - ignore (Th.solve d l)) - ns - let delay = Events.Delayed_by 10 - let key = Events.Dem.create (module struct type t = Node.S.t - let name = "Dom_product.ChangePos" end) - - let init d = - Events.attach_any_dom d Dom_interval.dom - (fun d n -> - match Node.HC.find_opt used_in_poly d n with - | Some ns -> Events.EnqRun (key,ns,None) - | None -> Events.EnqAlready) + val get_repr : _ Egraph.t -> Node.t -> Product.t option -end + val iter_eqs : _ Egraph.t -> Node.t -> f:(Product.t -> unit) -> unit -let () = Events.register (module ChangePos) + val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit -let factorize res a coef b d _ = - match Egraph.get_dom d dom a, Egraph.get_dom d dom b with - | Some pa, Some pb -> - let common = Node.M.inter (fun _ a b -> - Q.none_zero (Q.min (Q.floor a) (Q.floor b))) - pa.repr.poly pb.repr.poly in - if not (Node.M.is_empty common) then - let (cst,l) = List.fold_left (fun (cst,acc) (p,v) -> - let p = Product.of_map (Node.M.diff (fun _ a b -> Q.none_zero (Q.sub a b)) p.Product.poly common) in - match Product.classify p with - | ONE -> - (Q.add v cst,acc) - | NODE n -> - (cst,(n,v)::acc) - | PRODUCT -> - let n = node_of_product p in - Egraph.register d n; - (Q.add Q.one cst,(n,v)::acc) - ) (Q.zero,[]) [pa.repr,Q.one;pb.repr,coef] in - let p = Polynome.of_list cst l in - let n = Dom_polynome.node_of_polynome p in - Egraph.register d n; - Dom_polynome.assume_poly_equality d n p; - assume_poly_equality d res (Product.of_map (Node.M.add n Q.one common)) - | _ -> () + val attach_eqs_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit +end = Pivot.WithUnsolved (struct + let name = "ARITH_ABS" + include Product + + let pp fmt p = Fmt.pf fmt "|%a|" pp p + + let of_one_node _ n = Product.monome n Q.one + + let subst p n q = + let p, c = subst p n q in + if Q.is_zero c then None else Some p + + let set d cl ~old_ ~new_ = + SolveSign.iter_eqs d cl ~f:(fun sign -> + set d cl ~old_abs:old_ ~old_sign:sign new_ sign) + + type data = Q.t + + let nodes p = p.Product.poly + + let normalize p ~f = + let add acc cl c = + let q = f cl in + Product.x_m_yc acc q c + in + Product.fold add Product.one p + + type info = data Node.M.t * data Node.M.t * data Node.M.t * Product.t + + let info d m = + let spos, other = + Node.M.partition + (fun k _ -> Dom_interval.is_strictly_positive d k) + m.Product.poly + in + let notz, other = + Node.M.partition (fun k _ -> Dom_interval.is_not_zero d k) other + in + (spos, notz, other, m) + + let attach_info_change d f = Events.attach_any_dom d Dom_interval.dom f + + let solve (_, notz1, unk1, p1) (_, notz2, unk2, p2) : + _ Pivot.solve_with_unsolved = + let exception Solved of Node.t * Product.t in + try + (if + Node.M.is_empty notz1 && Node.M.is_empty unk1 && Node.M.is_empty notz2 + && Node.M.is_empty unk2 + then + (* all (strictly) positive: can use root *) + let p = Product.div p1 p2 in + match Product.extract p with + | One -> () + | Var (q, n, p) -> + let p = Product.power_cst (Q.inv (Q.neg q)) p in + raise (Solved (n, p)) + else if Node.M.is_empty unk1 then + (* side 1 with all different from zero *) + Node.M.iter + (fun n q1 -> + let q2 = Node.M.find_def Q.zero n p2.Product.poly in + if Q.equal (Q.sub q1 q2) Q.one then ( + let p = Product.div p2 p1 in + assert (Q.equal (Node.M.find n p.poly) Q.minus_one); + let p = Product.remove n p in + raise (Solved (n, p)))) + p1.Product.poly + else if Node.M.is_num_elt 1 unk1 then + let n, q = Node.M.choose unk1 in + if Q.equal q Q.one && not (Node.M.mem n unk2) then + let p = Product.div p2 (Product.remove n p1) in + raise (Solved (n, p))); + Unsolved + with Solved (n, p) -> Subst (n, p) +end) + +and SolveSign : sig + val assume_equality : Egraph.wt -> Node.t -> Sign_product.t -> unit + + val init : Egraph.wt -> unit + + val get_repr : _ Egraph.t -> Node.t -> Sign_product.t option + + val iter_eqs : _ Egraph.t -> Node.t -> f:(Sign_product.t -> unit) -> unit + + val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val attach_eqs_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val reshape : + Egraph.wt -> Node.t -> f:(Sign_product.t -> Sign_product.t option) -> unit +end = Pivot.WithUnsolved (struct + let name = "ARITH_SIGN" + + include Sign_product + + let of_one_node d n = + if Dom_interval.is_not_zero d n then Sign_product.of_one_node_non_zero n + else Sign_product.of_one_node n + + let attach_info_change d f = Events.attach_any_dom d Dom_interval.dom f + + let set d cl ~old_ ~new_ = + SolveAbs.iter_eqs d cl ~f:(fun abs -> + set d cl ~old_abs:abs ~old_sign:old_ abs new_) + + type info = Sign_product.presolve * Sign_product.t + + let info _ m : info = (Sign_product.presolve m, m) + + let solve ((info1, p1) : info) ((_, p2) : info) : _ Pivot.solve_with_unsolved + = + match info1 with + | Zero -> Unsolved + | NonZero -> ( + (* all non_zero *) + let p = Sign_product.mul p2 p1 in + match Sign_product.extract p with + | Plus_one -> AlreadyEqual + | Minus_one -> Contradiction + | Zero -> Contradiction + | Var (n, p) -> Subst (n, p) + | NoNonZero -> Unsolved) + | OneNonZero n -> + if not (Node.M.mem n (Sign_product.nodes p2)) then + let p = Sign_product.mul p2 (Sign_product.remove n p1) in + Subst (n, p) + else Unsolved + | Other -> Unsolved +end) + +let factorize res a coef b d _ = + if + (not (Egraph.is_equal d RealValue.zero res)) + && (not (Egraph.is_equal d RealValue.zero a)) + && not (Egraph.is_equal d RealValue.zero b) + then + match + ( SolveAbs.get_repr d a, + SolveAbs.get_repr d b, + SolveSign.get_repr d a, + SolveSign.get_repr d b ) + with + | Some pa, Some pb, Some sa, Some sb -> + let common_abs = Product.common pa pb in + let common_sign = Sign_product.common sa sb in + if + not + (Product.equal Product.one common_abs + && Sign_product.equal Sign_product.one common_sign) + then ( + let cst, l = + List.fold_left + (fun (cst, acc) (abs, sign, v) -> + let abs = Product.div abs common_abs in + let sign = Sign_product.mul sign common_sign in + match (Product.classify abs, Sign_product.classify sign) with + | ONE, PLUS_ONE -> (Q.add v cst, acc) + | ONE, MINUS_ONE -> (Q.sub v cst, acc) + | NODE n, NODE n' when Egraph.is_equal d n n' -> + (cst, (n, v) :: acc) + | _ -> + let n = node_of_product d abs sign in + Egraph.register d n; + (cst, (n, v) :: acc)) + (Q.zero, []) + [ (pa, sa, Q.one); (pb, sb, coef) ] + in + let p = Polynome.of_list cst l in + let n = Dom_polynome.node_of_polynome d p in + let pp_coef fmt coef = + if Q.equal Q.one coef then Fmt.pf fmt "+" else Fmt.pf fmt "-" + in + Debug.dprintf10 debug "[Factorize] %a = %a %a %a into %a" Node.pp res + Node.pp a pp_coef coef Node.pp b Polynome.pp p; + Egraph.register d n; + Dom_polynome.assume_equality d n p; + let abs = Product.mul (Product.monome n Q.one) common_abs in + let sign = + Sign_product.mul (Sign_product.of_one_node n) common_sign + in + SolveAbs.assume_equality d res abs; + SolveSign.assume_equality d res sign) + | _ -> () (** {2 Initialization} *) -let converter d (f:Ground.t) = +let converter d (f : Ground.t) = let res = Ground.node f in let reg n = Egraph.register d n in match Ground.sem f with - | { app = {builtin = Expr.Mul}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; - assume_poly_equality d res (Product.of_list [a,Q.one;b,Q.one]) - | { app = {builtin = Expr.Div}; tyargs = []; args; _ } -> - let num,den = IArray.extract2_exn args in - reg num; reg den; - Daemon.attach_dom d den Dom_interval.dom - (fun d _ -> - if Dom_interval.is_not_zero d den then - assume_poly_equality d num (Product.of_list [res,Q.one;den,Q.one]) - ) - | { app = {builtin = Expr.Add}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; - List.iter (fun x -> Daemon.attach_dom d x dom (factorize res a Q.one b)) [a;b] - | { app = {builtin = Expr.Sub}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; - List.iter (fun x -> Daemon.attach_dom d x dom (factorize res a Q.minus_one b)) [a;b] + | { app = { builtin = Expr.Mul }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + SolveAbs.assume_equality d res + (Product.of_list [ (a, Q.one); (b, Q.one) ]); + SolveSign.assume_equality d res + (Sign_product.mul + (Sign_product.of_one_node a) + (Sign_product.of_one_node b)) + | { app = { builtin = Expr.Div }; tyargs = []; args; _ } -> + let num, den = IArray.extract2_exn args in + reg num; + reg den; + Daemon.attach_dom d den Dom_interval.dom (fun d _ -> + if Dom_interval.is_not_zero d den then ( + (* num = res * den *) + SolveAbs.assume_equality d num + (Product.of_list [ (res, Q.one); (den, Q.one) ]); + SolveSign.assume_equality d num + (Sign_product.mul + (Sign_product.of_one_node res) + (Sign_product.of_one_node den)))) + | { app = { builtin = Expr.Add }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + List.iter + (fun node -> + SolveAbs.attach_repr_change d ~node (factorize res a Q.one b); + SolveSign.attach_repr_change d ~node (factorize res a Q.one b)) + [ a; b ] + | { app = { builtin = Expr.Sub }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + List.iter + (fun node -> + SolveAbs.attach_repr_change d ~node (factorize res a Q.minus_one b); + SolveSign.attach_repr_change d ~node (factorize res a Q.minus_one b)) + [ a; b ] + | { + app = { builtin = Expr.Abs | RealValue.Builtin.Abs_real }; + tyargs = []; + args; + _; + } -> + let a = IArray.extract1_exn args in + reg a; + SolveAbs.assume_equality d res (Product.of_list [ (a, Q.one) ]); + SolveSign.assume_equality d res Sign_product.one | _ -> () +let reshape_non_zero d n = + let q = Sign_product.of_one_node_non_zero n in + SolveSign.reshape d n ~f:(fun p -> Sign_product.subst p n q) + let init env = - Daemon.attach_any_dom env - Dom_polynome.dom - (fun d n -> - match Egraph.get_dom d Dom_polynome.dom n with - | None -> () - | Some p -> - if Q.equal p.cst Q.zero && Node.M.is_num_elt 1 p.poly then - let (cl,q) = Node.M.choose p.poly in - if Q.equal q Q.one then - let p1 = Product.of_list [cl,Q.one] in - assume_poly_equality d n p1 - ); - Daemon.attach_any_dom env - Dom_polynome.dom - (fun d n -> - match Egraph.get_dom d dom n with - | None -> () - | Some p -> - let aux (p:Product.t) = - if Node.M.is_num_elt 1 p.poly then - let (cl,q) = Node.M.choose p.poly in - if Q.equal q Q.one then - let p1 = Polynome.of_list Q.zero [cl,Q.one] in - Dom_polynome.assume_poly_equality d n p1 - in - aux p.repr; - Product.S.iter aux p.eqs - ); - Ground.register_converter env converter; - ChangePos.init env + SolveAbs.init env; + Dom_polynome.attach_repr_change env (fun d n -> + match Dom_polynome.get_repr d n with + | None -> () + | Some p -> + if Q.equal p.cst Q.zero && Node.M.is_num_elt 1 p.poly then + let cl, q = Node.M.choose p.poly in + if Q.equal q Q.one then ( + let p1 = Product.of_list [ (cl, Q.one) ] in + Debug.dprintf4 debug "[Polynome->Product] propagate %a is %a" + Node.pp n Node.pp cl; + SolveAbs.assume_equality d n p1; + SolveSign.assume_equality d n (Sign_product.of_one_node cl))); + let product_polynome d n = + (* todo more efficient *) + SolveAbs.iter_eqs d n ~f:(fun p -> + match Product.is_one_node p with + | None -> () + | Some cl -> + SolveSign.iter_eqs d n ~f:(fun p -> + match Sign_product.is_one_node p with + | Some cl' when Egraph.is_equal d cl cl' -> + let p1 = Polynome.of_list Q.zero [ (cl, Q.one) ] in + Debug.dprintf4 debug + "[Product->Polynome] propagate %a is %a" Node.pp n Node.pp + cl; + Dom_polynome.assume_equality d n p1 + | _ -> ())) + in + SolveAbs.attach_eqs_change env product_polynome; + SolveSign.attach_eqs_change env product_polynome; + DaemonWithFilter.attach_any_dom env Dom_interval.dom (fun d n -> + match Dom_interval.zero_is d n with + | Eq -> Some (fun d -> SolveSign.assume_equality d n Sign_product.zero) + | Lt -> Some (fun d -> SolveSign.assume_equality d n Sign_product.one) + | Gt -> + Some (fun d -> SolveSign.assume_equality d n Sign_product.minus_one) + | Le | Ge | Uncomparable -> + if Dom_interval.is_not_zero d n then + Some (fun d -> reshape_non_zero d n) + else None); + SolveSign.attach_eqs_change env (fun d n -> + SolveSign.iter_eqs d n ~f:(fun s -> + match Sign_product.classify s with + | Sign_product.PLUS_ONE -> Dom_interval.assume_positive d n + | Sign_product.MINUS_ONE -> Dom_interval.assume_negative d n + | Sign_product.ZERO -> Egraph.merge d n RealValue.zero + | _ -> ())); + Ground.register_converter env converter diff --git a/src_colibri2/theories/LRA/dom_product.mli b/src_colibri2/theories/LRA/dom_product.mli index ab1a2f86d7ca0b07ee2effd430ec40604bef6f32..df0dd22e7fdc3529ee9c42a1ff72ce98189a6166 100644 --- a/src_colibri2/theories/LRA/dom_product.mli +++ b/src_colibri2/theories/LRA/dom_product.mli @@ -18,14 +18,16 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (*************************************************************************) -val assume_poly_equality: Egraph.wt -> Node.t -> Product.t -> unit +(* val assume_equality : Egraph.wt -> Node.t -> Product.t -> unit *) -val node_of_product: Product.t -> Node.t +val node_of_product : _ Egraph.t -> Product.t -> Sign_product.t -> Node.t -type t +module SolveAbs : sig + val get_repr : _ Egraph.t -> Node.t -> Product.t option +end -val dom: t Dom.Kind.t +module SolveSign : sig + val get_repr : _ Egraph.t -> Node.t -> Sign_product.t option +end -val get_repr: _ Egraph.t -> Node.t -> Product.t option - -val init: Egraph.wt -> unit +val init : Egraph.wt -> unit diff --git a/src_colibri2/theories/LRA/fourier.ml b/src_colibri2/theories/LRA/fourier.ml index 672d8571a9ef125ad5420dba02ac143900cca103..311f557d44dc168c0b6750453c40371c05958330 100644 --- a/src_colibri2/theories/LRA/fourier.ml +++ b/src_colibri2/theories/LRA/fourier.ml @@ -22,218 +22,240 @@ open Colibri2_popop_lib open Colibri2_core let comparisons = Datastructure.Push.create Ground.pp "LRA.fourier.comparisons" -let scheduled = Datastructure.Ref.create Base.Bool.pp "LRA.fourier.scheduled" false -let debug = Debug.register_info_flag ~desc:"Reasoning about <= < in LRA" "fourier" +let scheduled = + Datastructure.Ref.create Base.Bool.pp "LRA.fourier.scheduled" false -let stats_run = Debug.register_stats_int ~name:"Fourier.run" ~init:0 +let debug = + Debug.register_info_flag ~desc:"Reasoning about <= < in LRA" "fourier" +let stats_run = Debug.register_stats_int ~name:"Fourier.run" ~init:0 -type eq = { p: Polynome.t; bound: Bound.t; origins: Ground.S.t } +type eq = { p : Polynome.t; bound : Bound.t; origins : Ground.S.t } [@@deriving show] (** p <= 0 or p < 0 *) -let divide d (p:Polynome.t) = +let divide d (p : Polynome.t) = try - begin match Polynome.is_cst p with - | None -> () - | Some _ -> raise Exit - end; + (match Polynome.is_cst p with None -> () | Some _ -> raise Exit); if Q.sign p.cst <> 0 then raise Exit; let l = Node.M.bindings p.poly in - let l = List.fold_left (fun acc (e,q) -> - match Dom_product.get_repr d e with - | None when Egraph.is_equal d RealValue.zero e -> acc - | None -> raise Exit - | Some p -> (p,q)::acc) [] l in - Debug.dprintf4 debug "@[eq:%a@ %a@]" - Polynome.pp p Fmt.(list ~sep:(any "+") (using CCPair.swap (pair Q.pp Product.pp))) l; + let l = + List.fold_left + (fun acc (e, q) -> + match + ( Dom_product.SolveAbs.get_repr d e, + Dom_product.SolveSign.get_repr d e ) + with + | None, _ when Egraph.is_equal d RealValue.zero e -> acc + | None, _ | _, None -> raise Exit + | Some abs, Some sign -> (abs, sign, q) :: acc) + [] l + in + (* Debug.dprintf4 debug "@[eq:%a@ %a@]" Polynome.pp p + * Fmt.(list ~sep:(any "+") (using CCPair.swap (pair Q.pp Product.pp))) + * l; *) match l with | [] -> raise Exit - | (hd,_)::_ -> - let common = List.fold_left (fun acc (p,_) -> - Node.M.inter (fun _ a b -> if Q.equal a b then Some a else None) acc p.Product.poly) - hd.Product.poly l in - let common, pos = Node.M.fold_left - (fun (acc,pos) n v -> - if Dom_interval.is_strictly_positive d n - then (Node.M.add n v acc,pos) - else if Dom_interval.is_strictly_negative d n - then (Node.M.add n v acc,not pos) - else (acc,pos) - ) (Node.M.empty,true) common - in - if Node.M.is_empty common then raise Exit; - Debug.dprintf4 debug "[Fourier] found possible division: %a / %a" - Polynome.pp p (Node.M.pp Q.pp) common; - let (cst,l) = List.fold_left (fun (cst,acc) (p,v) -> - let p = Product.of_map (Node.M.set_diff p.Product.poly common) in - - let v = if pos then v else Q.neg v in - match Product.classify p with - | ONE -> - (Q.add v cst,acc) - | NODE n -> - (cst,(n,v)::acc) - | PRODUCT -> - let n = Dom_product.node_of_product p in - (Q.add Q.one cst,(n,v)::acc) - ) (Q.zero,[]) l in - Some (Polynome.of_list cst l,common,pos) - with Exit -> - None + | (hd, __, _) :: _ -> + let common = + List.fold_left + (fun acc (abs, _, _) -> + Node.M.inter + (fun _ a b -> if Q.equal a b then Some a else None) + acc abs.Product.poly) + hd.Product.poly l + in + let common = + Node.M.fold_left + (fun acc abs v -> + if Dom_interval.is_not_zero d abs then Node.M.add abs v acc + else acc) + Node.M.empty common + in + if Node.M.is_empty common then raise Exit; + let common = Product.of_map common in + Debug.dprintf4 debug "[Fourier] found possible division: %a / |%a|" + Polynome.pp p Product.pp common; + let cst, l = + List.fold_left + (fun (cst, acc) (abs, sign, v) -> + let abs = Product.div abs common in + let pos, sign = Sign_product.extract_cst sign in + let v = + match pos with Zero -> Q.zero | Pos -> v | Neg -> Q.neg v + in + match (Product.classify abs, Sign_product.classify sign) with + | _, MINUS_ONE -> assert false + | ONE, PLUS_ONE -> (Q.add v cst, acc) + | NODE n, NODE n' when Egraph.is_equal d n n' -> + (cst, (n, v) :: acc) + | _ -> + let n = Dom_product.node_of_product d abs sign in + (cst, (n, v) :: acc)) + (Q.zero, []) l + in + Some (Polynome.of_list cst l, common) + with Exit -> None let delta d eq = (* add info to delta *) if Node.M.is_num_elt 2 eq.p.poly then match Node.M.bindings eq.p.poly with - | [src,a;dst,b] when Q.equal Q.one a && Q.equal Q.minus_one b -> - Delta.add d src (Q.neg eq.p.cst) eq.bound dst - | [dst,b;src,a] when Q.equal Q.one a && Q.equal Q.minus_one b -> - Delta.add d src (Q.neg eq.p.cst) eq.bound dst + | [ (src, a); (dst, b) ] when Q.equal Q.one a && Q.equal Q.minus_one b -> + Delta.add d src (Q.neg eq.p.cst) eq.bound dst + | [ (dst, b); (src, a) ] when Q.equal Q.one a && Q.equal Q.minus_one b -> + Delta.add d src (Q.neg eq.p.cst) eq.bound dst | _ -> () let apply d ~f truth g = let aux d bound a b = - let bound = if truth then bound else match bound with | Bound.Large -> Strict | Strict -> Large in - let a,b = if truth then a,b else b,a in - f d bound a b + let bound = + if truth then bound + else match bound with Bound.Large -> Strict | Strict -> Large + in + let a, b = if truth then (a, b) else (b, a) in + f d bound a b in match Ground.sem g with - | { app = {builtin = Expr.Lt}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - aux d Bound.Strict a b - | { app = {builtin = Expr.Leq}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - aux d Large a b - | { app = {builtin = Expr.Geq}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - aux d Large b a - | { app = {builtin = Expr.Gt}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - aux d Strict b a + | { app = { builtin = Expr.Lt }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + aux d Bound.Strict a b + | { app = { builtin = Expr.Leq }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + aux d Large a b + | { app = { builtin = Expr.Geq }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + aux d Large b a + | { app = { builtin = Expr.Gt }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + aux d Strict b a | _ -> assert false - let add_eq d eqs p bound origins = - match Polynome.is_cst p, bound with + match (Polynome.is_cst p, bound) with | None, _ -> - let eq = { p; bound; origins } in - delta d eq; - eq::eqs + let eq = { p; bound; origins } in + delta d eq; + eq :: eqs | Some p, Bound.Large when Q.sign p = 0 -> - Ground.S.iter (fun g -> - let truth = Base.Option.value_exn (Boolean.is d (Ground.node g)) in - apply d truth g ~f:(fun d bound a b -> - match bound with - | Strict when Dom_interval.is_integer d a && Dom_interval.is_integer d b -> - Dom_polynome.assume_poly_equality d a (Polynome.of_list Q.minus_one [b,Q.one]) - | Large -> - Dom_polynome.assume_poly_equality d a (Polynome.monome Q.one b) - | Strict -> - assert false - )) origins; - eqs + Ground.S.iter + (fun g -> + let truth = Base.Option.value_exn (Boolean.is d (Ground.node g)) in + apply d truth g ~f:(fun d bound a b -> + match bound with + | Strict + when Dom_interval.is_integer d a && Dom_interval.is_integer d b + -> + Dom_polynome.assume_equality d a + (Polynome.of_list Q.minus_one [ (b, Q.one) ]) + | Large -> + Dom_polynome.assume_equality d a (Polynome.monome Q.one b) + | Strict -> assert false)) + origins; + eqs | Some p, _ when Q.sign p < 0 -> - Debug.dprintf2 debug "[Fourier] discard %a" Ground.S.pp origins; - eqs + Debug.dprintf2 debug "[Fourier] discard %a" Ground.S.pp origins; + eqs | Some p, bound -> - Debug.dprintf4 Debug.contradiction - "[LRA/Fourier] Found %a%a0" - Q.pp p Bound.pp bound; - Egraph.contradiction d + Debug.dprintf4 Debug.contradiction "[LRA/Fourier] Found %a%a0" Q.pp p + Bound.pp bound; + Egraph.contradiction d let mk_eq d bound a b = - let (!) n = - match Egraph.get_dom d Dom_polynome.dom n with + let ( ! ) n = + match Dom_polynome.get_repr d n with | None -> Polynome.monome Q.one (Egraph.find_def d n) - | Some p -> p in - let p,bound' = + | Some p -> p + in + let p, bound' = match bound with - | Bound.Strict when Dom_interval.is_integer d a && Dom_interval.is_integer d b -> - Polynome.add_cst (Polynome.sub (!a) (!b)) Q.one, Bound.Large - | _ -> Polynome.sub (!a) (!b), bound + | Bound.Strict + when Dom_interval.is_integer d a && Dom_interval.is_integer d b -> + (Polynome.add_cst (Polynome.sub !a !b) Q.one, Bound.Large) + | _ -> (Polynome.sub !a !b, bound) in - p,bound', - Polynome.sub (Polynome.monome Q.one a) (Polynome.monome Q.one b), bound + ( p, + bound', + Polynome.sub (Polynome.monome Q.one a) (Polynome.monome Q.one b), + bound ) -let make_equations d (eqs,vars) g = +let make_equations d (eqs, vars) g = Debug.dprintf2 debug "[Fourier] %a" Ground.pp g; match Boolean.is d (Ground.node g) with - | None -> - (eqs,vars) - | Some truth -> - let p,bound,p_non_norm,bound_non_norm = - apply d ~f:mk_eq truth g - in - Debug.dprintf6 debug "[Fourier] %a(%a)%a0" Polynome.pp p Polynome.pp p_non_norm Bound.pp bound; - let eqs, vars = - (add_eq d eqs p bound (Ground.S.singleton g), - Node.M.union_merge (fun _ _ _ -> Some ()) vars p.Polynome.poly) - in - match divide d p_non_norm with - | Some (p',_,_) -> - let p' = Dom_polynome.norm d p' in - (add_eq d eqs p' bound_non_norm Ground.S.empty, - Node.M.union_merge (fun _ _ _ -> Some ()) vars p'.Polynome.poly) - | None -> eqs, vars + | None -> (eqs, vars) + | Some truth -> ( + let p, bound, p_non_norm, bound_non_norm = apply d ~f:mk_eq truth g in + Debug.dprintf6 debug "[Fourier] %a(%a)%a0" Polynome.pp p Polynome.pp + p_non_norm Bound.pp bound; + let eqs, vars = + ( add_eq d eqs p bound (Ground.S.singleton g), + Node.M.union_merge (fun _ _ _ -> Some ()) vars p.Polynome.poly ) + in + match divide d p_non_norm with + | Some (p', _) -> + let p' = Dom_polynome.normalize d p' in + ( add_eq d eqs p' bound_non_norm Ground.S.empty, + Node.M.union_merge (fun _ _ _ -> Some ()) vars p'.Polynome.poly ) + | None -> (eqs, vars)) -let fm (d:Egraph.wt) = +let fm (d : Egraph.wt) = Debug.dprintf0 debug "[Fourier]"; Debug.incr stats_run; Datastructure.Ref.set scheduled d false; - let eqs, vars = Datastructure.Push.fold comparisons d - ~f:(make_equations d) ~init:([],Node.S.empty) + let eqs, vars = + Datastructure.Push.fold comparisons d ~f:(make_equations d) + ~init:([], Node.S.empty) in let rec split n positive negative absent = function - | [] -> (positive,negative,absent) - | eq::l -> - match Node.M.find_opt n eq.p.poly with - | None -> split n positive negative (eq::absent) l - | Some q -> - if Q.sign q > 0 then - split n ((q,eq)::positive) negative absent l - else split n positive ((q,eq)::negative) absent l + | [] -> (positive, negative, absent) + | eq :: l -> ( + match Node.M.find_opt n eq.p.poly with + | None -> split n positive negative (eq :: absent) l + | Some q -> + if Q.sign q > 0 then split n ((q, eq) :: positive) negative absent l + else split n positive ((q, eq) :: negative) absent l) in let rec aux eqs vars = match Node.S.choose vars with | exception Not_found -> () - | n -> - let vars = Node.S.remove n vars in - let positive, negative, absent = split n [] [] [] eqs in - match positive, negative with - | [], _ | _ , [] -> aux absent vars - | _, _ -> - let eqs = - Lists.fold_product (fun eqs (pq,peq) (nq,neq) -> - let q = Q.div pq (Q.neg nq) in - let p = Polynome.cx_p_cy Q.one peq.p q neq.p in - let bound = - match peq.bound, neq.bound with - | Large, Large -> Bound.Large - | _ -> Bound.Strict in - add_eq d eqs p bound (Ground.S.union peq.origins neq.origins) - ) absent positive negative - in - aux eqs vars + | n -> ( + let vars = Node.S.remove n vars in + let positive, negative, absent = split n [] [] [] eqs in + match (positive, negative) with + | [], _ | _, [] -> aux absent vars + | _, _ -> + let eqs = + Lists.fold_product + (fun eqs (pq, peq) (nq, neq) -> + let q = Q.div pq (Q.neg nq) in + let p = Polynome.cx_p_cy Q.one peq.p q neq.p in + let bound = + match (peq.bound, neq.bound) with + | Large, Large -> Bound.Large + | _ -> Bound.Strict + in + add_eq d eqs p bound (Ground.S.union peq.origins neq.origins)) + absent positive negative + in + aux eqs vars) in aux eqs vars module Daemon = struct let key = Events.Dem.create - ( module struct + (module struct type t = unit + let name = "LRA.fourier" - end ) + end) let enqueue d _ = - if Datastructure.Ref.get scheduled d - then Events.EnqAlready - else begin + if Datastructure.Ref.get scheduled d then Events.EnqAlready + else ( Datastructure.Ref.set scheduled d true; - Events.EnqRun (key,(),None) - end + Events.EnqRun (key, (), None)) let delay = Events.Delayed_by 64 @@ -246,21 +268,24 @@ end let () = Events.register (module Daemon) - (** {2 Initialization} *) -let converter d (f:Ground.t) = +let converter d (f : Ground.t) = match Ground.sem f with - | { app = {builtin = (Expr.Lt|Expr.Leq|Expr.Geq|Expr.Gt)}; tyargs = []; args } -> - let attach n = - Events.attach_dom d n Dom_polynome.dom Daemon.enqueue; - Events.attach_repr d n Daemon.enqueue; - in - IArray.iter ~f:attach args; - Events.attach_value d (Ground.node f) Boolean.dom (fun d n _ -> Daemon.enqueue d n); - Datastructure.Push.push comparisons d f; - Events.new_pending_daemon d Daemon.key (); - Choice.register d (Boolean.chobool (Ground.node f)) + | { + app = { builtin = Expr.Lt | Expr.Leq | Expr.Geq | Expr.Gt }; + tyargs = []; + args; + } -> + let attach n = + Dom_polynome.events_repr_change d ~node:n Daemon.enqueue; + Events.attach_repr d n Daemon.enqueue + in + IArray.iter ~f:attach args; + Events.attach_value d (Ground.node f) Boolean.dom (fun d n _ -> + Daemon.enqueue d n); + Datastructure.Push.push comparisons d f; + Events.new_pending_daemon d Daemon.key (); + Choice.register d (Boolean.chobool (Ground.node f)) | _ -> () -let init env = - Ground.register_converter env converter +let init env = Ground.register_converter env converter diff --git a/src_colibri2/theories/LRA/mul.ml b/src_colibri2/theories/LRA/mul.ml index 2d078b586480accbd5f4adbdb065c903fa07151e..c59c0dfc175cd9379b0e9e4aa17ce40126b72d20 100644 --- a/src_colibri2/theories/LRA/mul.ml +++ b/src_colibri2/theories/LRA/mul.ml @@ -18,23 +18,20 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (*************************************************************************) -let attach d n (mul,other) = - Daemon.attach_value d n - RealValue.key - (fun d _ q -> - Dom_polynome.assume_poly_equality d mul (Polynome.monome (RealValue.value q) other) - ) +let attach d n (mul, other) = + Daemon.attach_value d n RealValue.key (fun d _ q -> + Dom_polynome.assume_equality d mul + (Polynome.monome (RealValue.value q) other)) -let converter d (f:Ground.t) = +let converter d (f : Ground.t) = let res = Ground.node f in match Ground.sem f with - | { app = {builtin = Expr.Mul}; tyargs = []; args; _ } -> begin - let arg1,arg2 = Colibri2_popop_lib.IArray.extract2_exn args in - Egraph.register d arg1; Egraph.register d arg2; - attach d arg1 (res,arg2); - attach d arg2 (res,arg1) - end + | { app = { builtin = Expr.Mul }; tyargs = []; args; _ } -> + let arg1, arg2 = Colibri2_popop_lib.IArray.extract2_exn args in + Egraph.register d arg1; + Egraph.register d arg2; + attach d arg1 (res, arg2); + attach d arg2 (res, arg1) | _ -> () -let init env = - Ground.register_converter env converter +let init env = Ground.register_converter env converter diff --git a/src_colibri2/theories/LRA/pivot.ml b/src_colibri2/theories/LRA/pivot.ml new file mode 100644 index 0000000000000000000000000000000000000000..100d4f5ddf2e07f3072b044ec4bc47921022734e --- /dev/null +++ b/src_colibri2/theories/LRA/pivot.ml @@ -0,0 +1,600 @@ +(*************************************************************************) +(* This file is part of Colibri2. *) +(* *) +(* Copyright (C) 2014-2021 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(*************************************************************************) + +let debug = + Debug.register_info_flag ~desc:"for the normalization by pivoting" "LRA.pivot" + +type 'a solve_with_unsolved = + | AlreadyEqual + | Contradiction + | Unsolved + | Subst of Node.t * 'a + +module WithUnsolved (P : sig + type t + + val name : string + + include Colibri2_popop_lib.Popop_stdlib.Datatype with type t := t + + val of_one_node : _ Egraph.t -> Node.t -> t + + val is_one_node : t -> Node.t option + + val subst : t -> Node.t -> t -> t option + + val normalize : t -> f:(Node.t -> t) -> t + + type data + + val nodes : t -> data Node.M.t + + type info + + val info : _ Egraph.t -> t -> info + + val attach_info_change : + Egraph.wt -> (Egraph.rt -> Node.t -> Events.enqueue) -> unit + + val solve : info -> info -> t solve_with_unsolved + + val set : Egraph.wt -> Node.t -> old_:t -> new_:t -> unit +end) : sig + val assume_equality : Egraph.wt -> Node.t -> P.t -> unit + + val init : Egraph.wt -> unit + + val get_repr : _ Egraph.t -> Node.t -> P.t option + + val iter_eqs : _ Egraph.t -> Node.t -> f:(P.t -> unit) -> unit + + val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val attach_eqs_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val reshape : Egraph.wt -> Node.t -> f:(P.t -> P.t option) -> unit +end = struct + type t = { + repr : P.t; + (** When a pivot is not possible because the equality can be null, the other + product are waiting on the side, they are also normalized *) + eqs : P.S.t; + } + [@@deriving ord, eq] + + let pp fmt t = Fmt.pf fmt "%a,%a" P.pp t.repr P.S.pp t.eqs + + let dom = + Dom.Kind.create + (module struct + type nonrec t = t + + let name = P.name + end) + + let used_in_poly : Node.S.t Node.HC.t = + Node.HC.create Node.S.pp (P.name ^ "_used_in_poly") + + let set_poly d cl p chg = + Egraph.set_dom d dom cl p; + List.iter (fun (old_, new_) -> P.set d cl ~old_ ~new_) chg + + let add_used_product d cl' new_cls = + Node.M.iter + (fun used _ -> + Node.HC.change + (function + | Some b -> Some (Node.S.add cl' b) + | None -> ( + match Egraph.get_dom d dom used with + | None -> + (* If a used node have no polynome associated, we set it to + itself. This allows to be warned when this node is merged. It + is the reason why this module doesn't specifically wait for + representative change *) + Egraph.set_dom d dom used + { repr = P.of_one_node d used; eqs = P.S.empty }; + Some (Node.S.of_list [ cl'; used ]) + | Some p -> + assert ( + Option.equal Node.equal (P.is_one_node p.repr) (Some used)); + assert false)) + used_in_poly d used) + new_cls + + let add_used_t d cl' t = + add_used_product d cl' (P.nodes t.repr); + P.S.iter (fun p -> add_used_product d cl' (P.nodes p)) t.eqs + + let norm_product d p = + P.normalize p ~f:(fun cl -> + let cl = Egraph.find d cl in + match Egraph.get_dom d dom cl with + | None -> P.of_one_node d cl + | Some p -> p.repr) + + module Th = struct + let merged v1 v2 = + Base.phys_equal v1 v2 + || + match (v1, v2) with + | None, None -> true + | Some v', Some v -> equal v' v + | _ -> false + + let add_itself d cl norm = + add_used_t d cl norm; + Egraph.set_dom d dom cl norm + + let rec merge d (_, cl1) (_, cl2) _inv = + let cl1 = Egraph.find d cl1 in + let cl2 = Egraph.find d cl2 in + assert (not (Egraph.is_equal d cl1 cl2)); + merge_aux d cl1 cl2 + + and merge_aux d cl1 cl2 = + let p1o = Egraph.get_dom d dom cl1 in + let p2o = Egraph.get_dom d dom cl2 in + assert (not (Option.is_none p1o && Option.is_none p2o)); + match (p1o, p2o) with + | None, None -> assert false (* absurd: no need to merge *) + | Some p, None -> + assert (Option.is_none (Node.HC.find_opt used_in_poly d cl2)); + add_itself d cl2 p + | None, Some p -> + assert (Option.is_none (Node.HC.find_opt used_in_poly d cl1)); + add_itself d cl1 p + | Some p1, Some p2 -> ( + match + solve d + (Base.List.cartesian_product + (part d (p1.repr :: P.S.elements p1.eqs)) + (part d (p2.repr :: P.S.elements p2.eqs))) + with + | `Solved -> + (* The domains have been substituted, and possibly recursively *) + merge_aux d cl1 cl2 + | `Not_solved -> + (* nothing to solve *) + let repr = + match (P.is_one_node p1.repr, P.is_one_node p2.repr) with + | None, None -> p1.repr (* arbitrary *) + | Some _, None -> p1.repr + | None, Some _ -> p2.repr + | Some cl1', Some cl2' -> + assert (Node.equal cl1' cl2'); + p1.repr + in + let eqs = + p1.eqs |> P.S.add p1.repr |> P.S.union p2.eqs |> P.S.add p2.repr + |> P.S.remove repr + in + let p = { repr; eqs } in + Egraph.set_dom d dom cl1 p; + Egraph.set_dom d dom cl2 p) + + and merge_one_new_eq d cl eq = + let po = Egraph.get_dom d dom cl in + match po with + | None -> + add_used_product d cl (P.nodes eq); + set_poly d cl { repr = eq; eqs = P.S.empty } [ (eq, eq) ] + | Some p -> ( + if (not (P.S.mem eq p.eqs)) && not (P.equal eq p.repr) then + match + solve d + (Base.List.cartesian_product + (part d (p.repr :: P.S.elements p.eqs)) + (part d [ eq ])) + with + | `Solved -> + (* The domains have been substituted, and possibly recursively *) + let eq = norm_product d eq in + merge_one_new_eq d cl eq + | `Not_solved -> + (* nothing to solve *) + let repr = p.repr in + let eqs = p.eqs |> P.S.add eq |> P.S.remove repr in + let p = { repr; eqs } in + add_used_product d cl (P.nodes eq); + set_poly d cl p [ (eq, eq) ]) + + and subst d cl eq = + Debug.dprintf4 debug "[Pivot] subst %a with %a" Node.pp cl P.pp eq; + let po = Egraph.get_dom d dom cl in + match po with + | None -> + let p = { repr = eq; eqs = P.S.empty } in + add_used_product d cl (P.nodes eq); + set_poly d cl p [ (eq, eq) ] + | Some p -> + assert (Option.equal Node.equal (P.is_one_node p.repr) (Some cl)); + subst_doms d cl eq; + let eq = norm_product d eq in + assert ( + P.equal eq (Base.Option.value_exn (Egraph.get_dom d dom cl)).repr); + merge_one_new_eq d cl eq + + and subst_doms d cl p = + let b = + match Node.HC.find used_in_poly d cl with + | exception Not_found -> Node.S.empty + | b -> b + in + let touched = Node.H.create 10 in + Node.S.iter + (fun cl' -> + match Egraph.get_dom d dom cl' with + | None -> assert false (* absurd: can't be used and absent *) + | Some q -> + let fold (new_cl, acc, chg) (q : P.t) = + let new_cl = + Node.M.set_union new_cl + (Node.M.set_diff (P.nodes p) (P.nodes q)) + in + match P.subst q cl p with + | None -> (new_cl, P.S.add q acc, chg) + | Some q' -> + Node.H.replace touched cl' (); + (new_cl, P.S.add q' acc, (q, q') :: chg) + in + let new_cl, acc, chg = + fold (Node.M.empty, P.S.empty, []) q.repr + in + let repr = P.S.choose acc in + let new_cl, acc, chg = + P.S.fold_left fold (new_cl, acc, chg) q.eqs + in + let eqs = P.S.remove repr acc in + add_used_product d cl' new_cl; + set_poly d cl' { repr; eqs } chg) + b; + Node.H.iter (recheck d) touched + + and part d l = List.map (fun p -> P.info d p) l + + and solve d l = + let exception Solved of Node.t * P.t in + let criteria i1 i2 = + let aux i1 i2 = + match P.solve i1 i2 with + | AlreadyEqual -> () + | Contradiction -> Egraph.contradiction d + | Unsolved -> () + | Subst (n, p) -> raise (Solved (n, p)) + in + aux i1 i2; + aux i2 i1 + in + match List.iter (fun (a, b) -> criteria a b) l with + | exception Solved (n, p) -> + subst d n p; + `Solved + | () -> `Not_solved + + and recheck d n () = + match Egraph.get_dom d dom n with + | None -> assert false (* absurd: can't be used and absent *) + | Some p -> ( + match + solve d + (Base.List.cartesian_product + (part d (p.repr :: P.S.elements p.eqs)) + (part d (p.repr :: P.S.elements p.eqs))) + with + | `Solved -> recheck d n () + | `Not_solved -> ()) + + let key = dom + + type nonrec t = t + + let pp = pp + end + + let () = Dom.register (module Th) + + let get_repr d n = + let open CCOpt in + let+ p = Egraph.get_dom d dom n in + p.repr + + let iter_eqs d n ~f = + match Egraph.get_dom d dom n with + | None -> () + | Some p -> + f p.repr; + P.S.iter f p.eqs + + let assume_equality d n (p : P.t) = + Debug.dprintf5 debug "[Pivot %s] assume %a = %a" P.name Node.pp n P.pp p; + let n = Egraph.find d n in + let p = norm_product d p in + Th.merge_one_new_eq d n p + + let reshape d cl ~(f : P.t -> P.t option) = + match Node.HC.find used_in_poly d cl with + | exception Not_found -> () + | b -> + let touched = Node.H.create 10 in + Node.S.iter + (fun cl' -> + match Egraph.get_dom d dom cl' with + | None -> assert false (* absurd: can't be used and absent *) + | Some q -> + let replace p = + match f p with + | None -> p + | Some p -> + Node.H.replace touched cl' (); + p + in + let eqs = + P.S.fold + (fun p acc -> P.S.add (replace p) acc) + q.eqs P.S.empty + in + let q' = { repr = replace q.repr; eqs } in + Egraph.set_dom d dom cl' q'; + let l = Th.part d (q'.repr :: P.S.elements q'.eqs) in + let l = Base.List.cartesian_product l l in + ignore (Th.solve d l)) + b; + Node.H.iter (Th.recheck d) touched + + module ChangeInfo = struct + type runable = Node.S.t + + let print_runable = Node.S.pp + + let run d ns = + Node.S.iter + (fun n -> + let p = Base.Option.value_exn (Egraph.get_dom d dom n) in + let l = Th.part d (p.repr :: P.S.elements p.eqs) in + let l = Base.List.cartesian_product l l in + ignore (Th.solve d l)) + ns + + let delay = Events.Delayed_by 10 + + let key = + Events.Dem.create + (module struct + type t = Node.S.t + + let name = "Dom_product.ChangePos" + end) + + let init d = + P.attach_info_change d (fun d n -> + match Node.HC.find_opt used_in_poly d n with + | Some ns -> Events.EnqRun (key, ns, None) + | None -> Events.EnqAlready) + end + + let () = Events.register (module ChangeInfo) + + let init d = ChangeInfo.init d + + let attach_eqs_change d ?node f = + match node with + | Some x -> Daemon.attach_dom d x dom f + | None -> Daemon.attach_any_dom d dom f + + let attach_repr_change = attach_eqs_change +end + +type 'a solve_total = AlreadyEqual | Contradiction | Subst of Node.t * 'a + +module Total (P : sig + type t + + val name : string + + include Colibri2_popop_lib.Popop_stdlib.Datatype with type t := t + + val of_one_node : Node.t -> t + + val is_one_node : t -> Node.t option + + val subst : t -> Node.t -> t -> t + + val normalize : t -> f:(Node.t -> t) -> t + + type data + + val nodes : t -> data Node.M.t + + val solve : t -> t -> t solve_total + + val set : Egraph.wt -> Node.t -> old_:t option -> new_:t -> unit +end) : sig + val assume_equality : Egraph.wt -> Node.t -> P.t -> unit + + val init : Egraph.wt -> unit + + val get_repr : _ Egraph.t -> Node.t -> P.t option + + val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val events_repr_change : + _ Egraph.t -> + ?node:Node.t -> + (Egraph.rt -> Node.t -> Events.enqueue) -> + unit + + val normalize : _ Egraph.t -> P.t -> P.t +end = struct + open Colibri2_popop_lib + + let dom = + Dom.Kind.create + (module struct + type t = P.t + + let name = P.name + end) + + let used_in_poly : Node.t Bag.t Node.HC.t = + Node.HC.create (Bag.pp Pp.semi Node.pp) "used_in_poly" + + let set_poly d cl old_ new_ = + Egraph.set_dom d dom cl new_; + P.set d cl ~old_ ~new_ + + let add_used d cl' new_cl = + Node.M.iter + (fun used _ -> + Node.HC.change + (function + | Some b -> Some (Bag.append b cl') + | None -> + (match Egraph.get_dom d dom used with + | None -> + (* If a used node have no polynome associated, we set it to + itself. This allows to be warned when this node is merged. It + is the reason why this module doesn't specifically wait for + representative change *) + Egraph.set_dom d dom used (P.of_one_node used) + | Some p -> assert (P.equal (P.of_one_node used) p)); + Some (Bag.elt cl')) + used_in_poly d used) + new_cl + + let subst_doms d cl (p : P.t) = + let b = + match Node.HC.find used_in_poly d cl with + | exception Not_found -> Bag.empty + | b -> b + in + Bag.iter + (fun cl' -> + match Egraph.get_dom d dom cl' with + | None -> assert false (* absurd: can't be used and absent *) + | Some q -> + let new_cl = Node.M.set_diff (P.nodes p) (P.nodes q) in + let q_new = P.subst q cl p in + add_used d cl' new_cl; + set_poly d cl' (Some q) q_new) + b; + add_used d cl (P.nodes p); + set_poly d cl None p + + module Th = struct + include P + + let merged v1 v2 = + match (v1, v2) with + | None, None -> true + | Some v', Some v -> equal v' v + | _ -> false + + let norm_dom cl = function + | None -> + let r = P.of_one_node cl in + r + | Some p -> p + + let add_itself d cl norm = + add_used d cl (P.nodes norm); + Egraph.set_dom d dom cl norm + + let merge d ((p1o, cl1) as a1) ((p2o, cl2) as a2) inv = + assert (not (Egraph.is_equal d cl1 cl2)); + assert (not (Option.is_none p1o && Option.is_none p2o)); + let (pother, other), (prepr, repr) = if inv then (a2, a1) else (a1, a2) in + let other = Egraph.find d other in + let repr = Egraph.find d repr in + let p1 = norm_dom other pother in + let p2 = norm_dom repr prepr in + (match P.solve p1 p2 with + | AlreadyEqual -> ( + (* no new equality already equal *) + match (pother, prepr) with + | Some _, Some _ | None, None -> + assert false (* absurd: no need of merge *) + | Some p, None -> + (* p = repr *) + add_itself d repr p + | None, Some p -> + (* p = other *) + add_itself d other p) + | Contradiction -> Egraph.contradiction d + | Subst (x, p) -> + Debug.dprintf2 debug "[Arith] @[pivot %a@]" Node.pp x; + let add_if_default n norm = function + | Some _ -> () + | None -> add_itself d n norm + in + add_if_default other p1 pother; + add_if_default repr p2 prepr; + subst_doms d x p); + assert ( + Option.compare P.compare + (Egraph.get_dom d dom repr) + (Egraph.get_dom d dom other) + = 0) + + let solve_one d cl p1 = + match Egraph.get_dom d dom cl with + | None -> subst_doms d cl p1 + | Some p2 -> ( + match P.solve p1 p2 with + | AlreadyEqual -> () + | Contradiction -> Egraph.contradiction d + | Subst (x, p) -> + Debug.dprintf2 debug "[Arith] @[pivot %a@]" Node.pp x; + subst_doms d x p) + + let key = dom + end + + let () = Dom.register (module Th) + + let normalize d (p : P.t) = + P.normalize p ~f:(fun cl -> + let cl = Egraph.find_def d cl in + match Egraph.get_dom d dom cl with + | None -> P.of_one_node cl + | Some p -> p) + + let assume_equality d n (p : P.t) = + let n = Egraph.find_def d n in + let p = normalize d p in + Th.solve_one d n p + + let get_repr d cl = Egraph.get_dom d dom cl + + let attach_repr_change d ?node f = + match node with + | Some x -> Daemon.attach_dom d x dom f + | None -> Daemon.attach_any_dom d dom f + + let events_repr_change d ?node f = + match node with + | Some x -> Events.attach_dom d x dom f + | None -> Events.attach_any_dom d dom f + + let init _ = () +end diff --git a/src_colibri2/theories/LRA/pivot.mli b/src_colibri2/theories/LRA/pivot.mli new file mode 100644 index 0000000000000000000000000000000000000000..1112944c7f41b68a5ebcfcd04bec5d092270119c --- /dev/null +++ b/src_colibri2/theories/LRA/pivot.mli @@ -0,0 +1,152 @@ +(*************************************************************************) +(* This file is part of Colibri2. *) +(* *) +(* Copyright (C) 2014-2021 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(*************************************************************************) + +(** Normalization of equations generic in the shape of the terms *) + +type 'a solve_with_unsolved = + | AlreadyEqual + | Contradiction + | Unsolved + | Subst of Node.t * 'a + +module WithUnsolved (P : sig + type t + (** Normalizable terms *) + + val name : string + + include Colibri2_popop_lib.Popop_stdlib.Datatype with type t := t + + val of_one_node : _ Egraph.t -> Node.t -> t + (** Build a value that represent one node *) + + val is_one_node : t -> Node.t option + (** Test if a value represents one node *) + + val subst : t -> Node.t -> t -> t option + (** [subst p n q] substitute [n] by [q] in [p], if [n] is not in [p] None is + returned, otherwise the substitution is returned *) + + val normalize : t -> f:(Node.t -> t) -> t + (** [norm p ~f] normalize [p] using [f] *) + + type data + (** An abstract type to avoid translating the map to sets in {!nodes} *) + + val nodes : t -> data Node.M.t + (** [nodes t] returns the node which are present in [t] *) + + type info + (** Additional information useful for solving the equation *) + + val info : _ Egraph.t -> t -> info + (** [info d t] returns the information for the given normalized term *) + + val attach_info_change : + Egraph.wt -> (Egraph.rt -> Node.t -> Events.enqueue) -> unit + (** [attach_info_change f] should call the given function when information + used for the computation of [info] changed. All unsolved equation which + contains, [nodes t], the given node will be looked again. *) + + val solve : info -> info -> t solve_with_unsolved + (** [solve t1 t2] solve the equation [t1 = t2] by returning a substitution. + Return Unsolved if the equation can't be yet solved *) + + val set : Egraph.wt -> Node.t -> old_:t -> new_:t -> unit + (** Called a new term equal to this node is found *) +end) : sig + val assume_equality : Egraph.wt -> Node.t -> P.t -> unit + (** [assume_equality d n p] assumes the equality [n = p] *) + + val init : Egraph.wt -> unit + (** Initialize the data-structure needed. *) + + val get_repr : _ Egraph.t -> Node.t -> P.t option + + val iter_eqs : _ Egraph.t -> Node.t -> f:(P.t -> unit) -> unit + + val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val attach_eqs_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val reshape : Egraph.wt -> Node.t -> f:(P.t -> P.t option) -> unit + (** Apply the given function to all the normalized form which contains this node. + The resulting normalized form should contain the same or less nodes than before. + *) +end + +type 'a solve_total = AlreadyEqual | Contradiction | Subst of Node.t * 'a + +module Total (P : sig + type t + (** Normalizable terms *) + + val name : string + + include Colibri2_popop_lib.Popop_stdlib.Datatype with type t := t + + val of_one_node : Node.t -> t + (** Build a value that represent one node *) + + val is_one_node : t -> Node.t option + (** Test if a value represents one node *) + + val subst : t -> Node.t -> t -> t + (** [subst p n q] return the result of the substitution of [n] by [q] in [p] *) + + val normalize : t -> f:(Node.t -> t) -> t + (** [norm p ~f] normalize [p] using [f] *) + + type data + (** An abstract type to avoid translating the map to sets in {!nodes} *) + + val nodes : t -> data Node.M.t + (** [nodes t] returns the node which are present in [t] *) + + val solve : t -> t -> t solve_total + (** [solve t1 t2] solve the equation [t1 = t2] by returning a substitution. *) + + val set : Egraph.wt -> Node.t -> old_:t option -> new_:t -> unit + (** Called a new term equal to this node is found *) +end) : sig + val assume_equality : Egraph.wt -> Node.t -> P.t -> unit + (** [assume_equality d n p] assumes the equality [n = p] *) + + val init : Egraph.wt -> unit + (** Initialize the data-structure needed. *) + + val get_repr : _ Egraph.t -> Node.t -> P.t option + + val attach_repr_change : + _ Egraph.t -> ?node:Node.t -> (Egraph.wt -> Node.t -> unit) -> unit + + val events_repr_change : + _ Egraph.t -> + ?node:Node.t -> + (Egraph.rt -> Node.t -> Events.enqueue) -> + unit + + val normalize : _ Egraph.t -> P.t -> P.t +end + +(* LocalWords: Normalizable + *) diff --git a/src_colibri2/theories/LRA/product.ml b/src_colibri2/theories/LRA/product.ml index c971e576b0faca9c954ba11e49eb8ac4bb2630ca..87cef75a21c1dea5ab8e0afbcf0bfcbce4a64eb4 100644 --- a/src_colibri2/theories/LRA/product.ml +++ b/src_colibri2/theories/LRA/product.ml @@ -22,8 +22,7 @@ open Colibri2_popop_lib open Colibri2_core module T = struct - type t = { (* cst : Q.t; *) poly : Q.t Node.M.t} - [@@deriving eq,ord,hash] + type t = { (* cst : Q.t; *) poly : Q.t Node.M.t } [@@deriving eq, ord, hash] let pp_exposant fmt q = if Z.equal q.Q.den Z.one && Z.fits_int q.Q.num then @@ -48,12 +47,12 @@ module T = struct else Fmt.pf fmt "@[%a@]" (* print_not_one v.cst *) - Fmt.(iter_bindings Node.M.iter (pair ~sep:nop Node.pp pp_exposant)) v.poly - + Fmt.(iter_bindings Node.M.iter (pair ~sep:nop Node.pp pp_exposant)) + v.poly end include T -include Popop_stdlib.MkDatatype(T) +include Popop_stdlib.MkDatatype (T) (** different invariant *) @@ -61,48 +60,45 @@ let invariant p = (* not (Q.equal p.cst Q.zero && Node.M.is_empty p.poly) && *) Node.M.for_all (fun _ q -> not (Q.equal q Q.zero)) p.poly -(** constructor *) (* let cst q = assert (not (Q.equal q Q.zero)); {cst = q; poly = Node.M.empty} * (\* let zero = cst Q.zero *\) *) + +(** constructor *) let one = { poly = Node.M.empty } (* * let is_cst p = if Node.M.is_empty p.poly then Some p.cst else None * (\* let is_zero p = Q.equal p.cst Q.zero && Node.M.is_empty p.poly *\) * let is_one p = Q.equal p.cst Q.one && Node.M.is_empty p.poly *) -type extract = One | Var of Q.t * Node.t * t +type extract = One | Var of Q.t * Node.t * t + let extract p = - if Node.M.is_empty p.poly then - (* if Q.equal p.cst Q.one then *) One + if Node.M.is_empty p.poly then (* if Q.equal p.cst Q.one then *) One (* else Cst p.cst *) else - let x,q = Shuffle.chooseb Node.M.choose Node.M.choose_rnd p.poly in - let p' = {(* p with *)poly = Node.M.remove x p.poly} in - Var(q,x,p') + let x, q = Shuffle.chooseb Node.M.choose Node.M.choose_rnd p.poly in + let p' = { (* p with *) poly = Node.M.remove x p.poly } in + Var (q, x, p') let remove n p = { poly = Node.M.remove n p.poly } type kind = ONE | NODE of Node.t | PRODUCT + let classify p = - if Node.M.is_empty p.poly then - ONE - else - if Node.M.is_num_elt 1 p.poly then - let node,k = Node.M.choose p.poly in - if Q.equal Q.one k then NODE node - else PRODUCT + if Node.M.is_empty p.poly then ONE + else if Node.M.is_num_elt 1 p.poly then + let node, k = Node.M.choose p.poly in + if Q.equal Q.one k then NODE node else PRODUCT else PRODUCT - let monome x c = - if Q.equal Q.zero c then one - else {poly = Node.M.singleton x c} + if Q.equal Q.zero c then one else { poly = Node.M.singleton x c } -let is_one_node p = (** cst = 0 and one empty monome *) +let is_one_node p = + (* cst = 0 and one empty monome *) if (* Q.equal Q.zero p.cst && *) Node.M.is_num_elt 1 p.poly then - let node,k = Node.M.choose p.poly in - if Q.equal Q.one k then Some node - else None + let node, k = Node.M.choose p.poly in + if Q.equal Q.one k then Some node else None else None (* let mult_cst c p1 = @@ -113,9 +109,9 @@ let power_cst c p1 = if Q.equal Q.zero c then one else if Q.equal Q.one c then p1 else - let poly_mult c m = Node.M.map (fun c1 -> Q.mul c c1) m in - if Q.equal Q.zero c then one - else {(* cst = Q.mul c p1.cst; *) poly = poly_mult c p1.poly} + let poly_mult c m = Node.M.map (fun c1 -> Q.mul c c1) m in + if Q.equal Q.zero c then one + else { (* cst = Q.mul c p1.cst; *) poly = poly_mult c p1.poly } (** Warning Node.M.union can be used only for defining an operation [op] that verifies [op 0 p = p] and [op p 0 = p] *) @@ -123,76 +119,88 @@ let mul p1 p2 = let poly_add m1 m2 = Node.M.union (fun _ c1 c2 -> Q.none_zero (Q.add c1 c2)) m1 m2 in - {(* cst = Q.mul p1.cst p2.cst; *) poly = poly_add p1.poly p2.poly} + { (* cst = Q.mul p1.cst p2.cst; *) poly = poly_add p1.poly p2.poly } let div p1 p2 = let poly_sub m1 m2 = - Node.M.union_merge (fun _ c1 c2 -> - match c1 with - | None -> Some (Q.neg c2) - | Some c1 -> Q.none_zero (Q.sub c1 c2)) - m1 m2 in - {(* cst = Q.div p1.cst p2.cst; *) poly = poly_sub p1.poly p2.poly} + Node.M.union_merge + (fun _ c1 c2 -> + match c1 with + | None -> Some (Q.neg c2) + | Some c1 -> Q.none_zero (Q.sub c1 c2)) + m1 m2 + in + { (* cst = Q.div p1.cst p2.cst; *) poly = poly_sub p1.poly p2.poly } let x_m_yc p1 p2 c = assert (not (Q.equal c Q.zero)); let f a b = Q.add a (Q.mul c b) in let poly m1 m2 = - Node.M.union_merge (fun _ c1 c2 -> - match c1 with - | None -> Some (Q.mul c c2) - | Some c1 -> Q.none_zero (f c1 c2)) - m1 m2 in - {(* cst = Q.mul p1.cst (Q. p2.cst; *) poly = poly p1.poly p2.poly} - + Node.M.union_merge + (fun _ c1 c2 -> + match c1 with + | None -> Some (Q.mul c c2) + | Some c1 -> Q.none_zero (f c1 c2)) + m1 m2 + in + { (* cst = Q.mul p1.cst (Q. p2.cst; *) poly = poly p1.poly p2.poly } let xc_m_yc p1 c1 p2 c2 = let c1_iszero = Q.equal c1 Q.zero in let c2_iszero = Q.equal c2 Q.zero in if c1_iszero && c2_iszero then one - else if c1_iszero - then p2 - else if c2_iszero - then p1 + else if c1_iszero then p2 + else if c2_iszero then p1 else let f e1 e2 = Q.add (Q.mul c1 e1) (Q.mul c2 e2) in let poly m1 m2 = - Node.M.merge (fun _ e1 e2 -> - match e1, e2 with + Node.M.merge + (fun _ e1 e2 -> + match (e1, e2) with | None, None -> assert false | None, Some e2 -> Some (Q.mul c2 e2) | Some e1, None -> Some (Q.mul c1 e1) - | Some e1, Some e2 -> - Q.none_zero (f e1 e2)) - m1 m2 in - {(* cst = f p1.cst p2.cst; *) poly = poly p1.poly p2.poly} + | Some e1, Some e2 -> Q.none_zero (f e1 e2)) + m1 m2 + in + { (* cst = f p1.cst p2.cst; *) poly = poly p1.poly p2.poly } let subst_node p x y = - let poly,qo = Node.M.find_remove x p.poly in + let poly, qo = Node.M.find_remove x p.poly in match qo with - | None -> p, Q.zero + | None -> (p, Q.zero) | Some q -> - let poly = Node.M.change (function - | None -> qo - | Some q' -> Q.none_zero (Q.add q q') - ) y poly in - {poly}, q + let poly = + Node.M.change + (function None -> qo | Some q' -> Q.none_zero (Q.add q q')) + y poly + in + ({ poly }, q) let subst p x s = - let poly,q = Node.M.find_remove x p.poly in - match q with - | None -> p, Q.zero - | Some q -> x_m_yc {poly} s q, q + let poly, q = Node.M.find_remove x p.poly in + match q with None -> (p, Q.zero) | Some q -> (x_m_yc { poly } s q, q) let fold f acc p = Node.M.fold_left f acc p.poly + let iter f p = Node.M.iter f p.poly -let of_list (* cst *)l = - let fold acc (node,q) = Node.M.change (function - | None -> Some q - | Some q' -> Q.none_zero (Q.add q q')) node acc in - {(* cst; *)poly= List.fold_left fold Node.M.empty l} +let of_list (* cst *) l = + let fold acc (node, q) = + Node.M.change + (function None -> Some q | Some q' -> Q.none_zero (Q.add q q')) + node acc + in + { (* cst; *) poly = List.fold_left fold Node.M.empty l } let of_map m = - assert ( Node.M.for_all (fun _ v -> Q.sign v <> 0) m ); + assert (Node.M.for_all (fun _ v -> Q.sign v <> 0) m); { poly = m } + +let common pa pb = + { + poly = + Node.M.inter + (fun _ a b -> Q.none_zero (Q.min (Q.floor a) (Q.floor b))) + pa.poly pb.poly; + } diff --git a/src_colibri2/theories/LRA/product.mli b/src_colibri2/theories/LRA/product.mli index dfca11762cac524ef13d534df3469072cad08f74..32c5916cf3f6f2a293eba5fe6227ca6259bb2fc2 100644 --- a/src_colibri2/theories/LRA/product.mli +++ b/src_colibri2/theories/LRA/product.mli @@ -19,45 +19,55 @@ (*************************************************************************) open Colibri2_popop_lib + open Colibri2_core (** Polynome *) -type t = private { (* cst : Q.t; *)poly : Q.t Node.M.t} +type t = private { (* cst : Q.t; *) poly : Q.t Node.M.t } + include Popop_stdlib.Datatype with type t := t -val invariant: t -> bool +val invariant : t -> bool -val one: t +val one : t -val monome: Node.t -> Q.t -> t -val is_one_node: t -> Node.t option +val monome : Node.t -> Q.t -> t -val remove: Node.t -> t -> t +val is_one_node : t -> Node.t option + +val remove : Node.t -> t -> t type extract = - | One (** p = 1 *) - | Var of Q.t * Node.t * t (** p = x^q * p' *) + | One (** p = 1 *) + | Var of Q.t * Node.t * t (** p = x^q * p' *) val extract : t -> extract type kind = ONE | NODE of Node.t | PRODUCT + val classify : t -> kind -val power_cst: Q.t -> t -> t +val power_cst : Q.t -> t -> t -val of_list: (Node.t * Q.t) list -> t +val of_list : (Node.t * Q.t) list -> t -val mul: t -> t -> t -val div: t -> t -> t +val mul : t -> t -> t -val x_m_yc: t -> t -> Q.t -> t +val div : t -> t -> t -val xc_m_yc: t -> Q.t -> t -> Q.t -> t +val x_m_yc : t -> t -> Q.t -> t -val subst: t -> Node.t -> t -> t * Q.t -val subst_node: t -> Node.t -> Node.t -> t * Q.t +val xc_m_yc : t -> Q.t -> t -> Q.t -> t -val fold: ('a -> Node.t -> Q.t -> 'a) -> 'a -> t -> 'a -val iter: (Node.t -> Q.t -> unit) -> t -> unit +val subst : t -> Node.t -> t -> t * Q.t + +val subst_node : t -> Node.t -> Node.t -> t * Q.t + +val fold : ('a -> Node.t -> Q.t -> 'a) -> 'a -> t -> 'a + +val iter : (Node.t -> Q.t -> unit) -> t -> unit val of_map : Q.t Node.M.t -> t + +val common : t -> t -> t +(** Return the common part *) diff --git a/src_colibri2/theories/LRA/realValue.ml b/src_colibri2/theories/LRA/realValue.ml index 3e9d7818b661a8b79fdddfe80bd2c93b4a5cf989..ff7d8c648b2490e41edecd3177642249a2e764e1 100644 --- a/src_colibri2/theories/LRA/realValue.ml +++ b/src_colibri2/theories/LRA/realValue.ml @@ -22,238 +22,325 @@ open Colibri2_core open Colibri2_popop_lib open Colibri2_stdlib.Std -module RealValue = Value.Register(struct - include Q - let name = "Q" - end) +module Builtin = struct + type _ Expr.t += Abs_real + + let abs_real = + Expr.Id.mk ~name:"colibri_abs_real" ~builtin:Abs_real "Abs" + (Expr.Ty.arrow [ Expr.Ty.real ] Expr.Ty.real) + + let () = + Expr.add_builtins (fun env s -> + match s with + | Dolmen_loop.Typer.T.Id { ns = Term; name = "colibri_abs_real" } -> + `Term + (Dolmen_type.Base.term_app1 + (module Dolmen_loop.Typer.T) + env "colibri_abs_real" + (fun a -> Expr.Term.apply_cst abs_real [] [ a ])) + | _ -> `Not_found) +end + +module RealValue = Value.Register (struct + include Q + + let name = "Q" +end) include RealValue -let () = Interp.Register.print_value_smt RealValue.key - (fun _ fmt v -> - let v = RealValue.value v in - if Z.equal v.den Z.one then - Z.pp_print fmt v.num - else - Fmt.pf fmt "(/ %a %a)" Z.pp_print v.num Z.pp_print v.den - ) +let () = + Interp.Register.print_value_smt RealValue.key (fun _ fmt v -> + let v = RealValue.value v in + if Z.equal v.den Z.one then Z.pp_print fmt v.num + else Fmt.pf fmt "(/ %a %a)" Z.pp_print v.num Z.pp_print v.den) let cst' c = index ~basename:(Format.asprintf "%aR" Q.pp c) c + let cst c = node (cst' c) let zero = cst Q.zero + let one = cst Q.one let int_sequence_without_zero = let open Base.Sequence.Generator in let rec loop i = - yield i >>= fun () -> yield (Z.neg i) >>= (fun () -> loop (Z.succ i)) + yield i >>= fun () -> + yield (Z.neg i) >>= fun () -> loop (Z.succ i) in run (loop Z.one) -let int_sequence = - Base.Sequence.shift_right int_sequence_without_zero Z.zero +let int_sequence = Base.Sequence.shift_right int_sequence_without_zero Z.zero let init_ty d = Interp.Register.ty d (fun d ty -> match ty with - | {app={builtin = Expr.Int;_};_} -> - Some (Interp.SeqLim.map (Interp.SeqLim.of_seq d int_sequence) - ~f:(fun i -> nodevalue (cst' (Q.of_bigint i))) - ) - | {app={builtin = Expr.Real;_};_} -> - let seq = - let open Interp.SeqLim in - let+ num = of_seq d int_sequence - and* den = of_seq d int_sequence_without_zero in - (Q.make num den) - in - let seq = Interp.SeqLim.unfold_with seq ~init:Q.S.empty - ~f:(fun s v -> if Q.S.mem v s then Skip s - else Yield(nodevalue (cst' v),Q.S.add v s)) in - Some seq + | { app = { builtin = Expr.Int; _ }; _ } -> + Some + (Interp.SeqLim.map (Interp.SeqLim.of_seq d int_sequence) + ~f:(fun i -> nodevalue (cst' (Q.of_bigint i)))) + | { app = { builtin = Expr.Real; _ }; _ } -> + let seq = + let open Interp.SeqLim in + let+ num = of_seq d int_sequence + and* den = of_seq d int_sequence_without_zero in + Q.make num den + in + let seq = + Interp.SeqLim.unfold_with seq ~init:Q.S.empty ~f:(fun s v -> + if Q.S.mem v s then Skip s + else Yield (nodevalue (cst' v), Q.S.add v s)) + in + Some seq | _ -> None) module Check = struct let interp d n = Opt.get_exn Impossible (Egraph.get_value d n) + let compute_ground d t = - let (!>) t = RealValue.value (RealValue.coerce_nodevalue (interp d t)) in - let (!<) v = `Some (RealValue.nodevalue (RealValue.index v)) in - let (!<<) b = - let r = if b then Boolean.values_true else Boolean.values_false in - `Some r - in - match Ground.sem t with - | { app = {builtin = Expr.Coercion}; - tyargs = - ( [{app={builtin = (Expr.Int|Expr.Rat);_};_};{app={builtin = Expr.Real;_};_}] - | [{app={builtin = Expr.Int;_};_};{app={builtin = Expr.Rat;_};_}] - ); - args } -> + let ( !> ) t = RealValue.value (RealValue.coerce_nodevalue (interp d t)) in + let ( !< ) v = `Some (RealValue.nodevalue (RealValue.index v)) in + let ( !<< ) b = + let r = if b then Boolean.values_true else Boolean.values_false in + `Some r + in + match Ground.sem t with + | { + app = { builtin = Expr.Coercion }; + tyargs = + ( [ + { app = { builtin = Expr.Int | Expr.Rat; _ }; _ }; + { app = { builtin = Expr.Real; _ }; _ }; + ] + | [ + { app = { builtin = Expr.Int; _ }; _ }; + { app = { builtin = Expr.Rat; _ }; _ }; + ] ); + args; + } -> let a = IArray.extract1_exn args in - !< (!> a) - | { app = {builtin = Expr.Integer s}; tyargs = []; args; ty = _ } -> - assert ( IArray.is_empty args); - !< (Q.of_string s) - | { app = {builtin = Expr.Decimal s}; tyargs = []; args; ty = _ } -> - assert ( IArray.is_empty args); - !< (Q.of_string_decimal s) - | { app = {builtin = Expr.Rational s}; tyargs = []; args; ty = _ } -> - assert ( IArray.is_empty args); - !< (Q.of_string_decimal s) - | { app = {builtin = Expr.Add}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !< (Q.add !>a !>b) - | { app = {builtin = Expr.Sub}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !< (Q.sub !>a !>b) - | { app = {builtin = Expr.Minus}; tyargs = []; args; ty = _ } -> + !<(!>a) + | { app = { builtin = Expr.Integer s }; tyargs = []; args; ty = _ } -> + assert (IArray.is_empty args); + !<(Q.of_string s) + | { app = { builtin = Expr.Decimal s }; tyargs = []; args; ty = _ } -> + assert (IArray.is_empty args); + !<(Q.of_string_decimal s) + | { app = { builtin = Expr.Rational s }; tyargs = []; args; ty = _ } -> + assert (IArray.is_empty args); + !<(Q.of_string_decimal s) + | { app = { builtin = Expr.Add }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<(Q.add !>a !>b) + | { app = { builtin = Expr.Sub }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<(Q.sub !>a !>b) + | { app = { builtin = Expr.Minus }; tyargs = []; args; ty = _ } -> let a = IArray.extract1_exn args in - !< (Q.neg !>a) - | { app = {builtin = Expr.Mul}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !< (Q.mul !>a !>b) - | { app = {builtin = Expr.Div}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - if Q.is_zero !>b then `Uninterp - else !< (Q.div !>a !>b) - | { app = {builtin = Expr.Lt}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !<< (Q.lt !>a !>b) - | { app = {builtin = Expr.Leq}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !<< (Q.leq !>a !>b) - | { app = {builtin = Expr.Gt}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !<< (Q.gt !>a !>b) - | { app = {builtin = Expr.Geq}; tyargs = []; args; ty = _ } -> - let a,b = IArray.extract2_exn args in - !<< (Q.geq !>a !>b) - | { app = {builtin = Expr.Floor}; tyargs = []; args; _ } -> + !<(Q.neg !>a) + | { app = { builtin = Expr.Mul }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<(Q.mul !>a !>b) + | { app = { builtin = Expr.Div }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + if Q.is_zero !>b then `Uninterp else !<(Q.div !>a !>b) + | { app = { builtin = Expr.Lt }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<<(Q.lt !>a !>b) + | { app = { builtin = Expr.Leq }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<<(Q.leq !>a !>b) + | { app = { builtin = Expr.Gt }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<<(Q.gt !>a !>b) + | { app = { builtin = Expr.Geq }; tyargs = []; args; ty = _ } -> + let a, b = IArray.extract2_exn args in + !<<(Q.geq !>a !>b) + | { app = { builtin = Expr.Floor }; tyargs = []; args; _ } -> let a = IArray.extract1_exn args in - !< (Q.floor (!> a)) - | _ -> `None + !<(Q.floor !>a) + | { app = { builtin = Expr.Abs | Builtin.Abs_real }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + !<(Q.abs !>a) + | _ -> `None let init d = Interp.Register.check d (fun d t -> - let check r = - Value.equal r (interp d (Ground.node t)) - in + let check r = Value.equal r (interp d (Ground.node t)) in match compute_ground d t with | `None -> NA | `Some v -> Interp.check_of_bool (check v) - | `Uninterp -> Interp.check_of_bool (Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain.check d t) - ); + | `Uninterp -> + Interp.check_of_bool + (Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain + .check d t)); Interp.Register.compute d (fun d t -> match compute_ground d t with | `None -> NA | `Some v -> Value v - | `Uninterp -> Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain.compute d t - ) + | `Uninterp -> + Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain + .compute d t) let attach d g = let f d g = match compute_ground d g with | `None -> raise Impossible | `Some v -> Egraph.set_value d (Ground.node g) v - | `Uninterp -> Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain.propagate d g + | `Uninterp -> + Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain + .propagate d g in Interp.WatchArgs.create d f g end -let wait_for_this_node_get_a_value d n = - Daemon.attach_value d n RealValue.key +let wait_for_this_node_get_a_value d n = Daemon.attach_value d n RealValue.key - (** {2 Initialization} *) -let converter d (f:Ground.t) = +(** {2 Initialization} *) +let converter d (f : Ground.t) = let r = Ground.node f in let reg n = Egraph.register d n in - let merge n = Egraph.register d n; Egraph.merge d r n in + let merge n = + Egraph.register d n; + Egraph.merge d r n + in let open Monad in let cmp cmp a b = - reg a; reg b; - attach d ( - setv Boolean.dom r (let+ va = getv key a and+ vb = getv key b in cmp va vb) - ); + reg a; + reg b; + attach d + (setv Boolean.dom r + (let+ va = getv key a and+ vb = getv key b in + cmp va vb)) in let set = setv key in let get = getv key in match Ground.sem f with - | { app = {builtin = Expr.Coercion}; - tyargs = - ( [{app={builtin = (Expr.Int|Expr.Rat);_};_};{app={builtin = Expr.Real;_};_}] - | [{app={builtin = Expr.Int;_};_};{app={builtin = Expr.Rat;_};_}] - ); - args } -> - let a = IArray.extract1_exn args in - merge a; Check.attach d f - | { app = {builtin = Expr.Integer s}; tyargs = []; args; _ } -> - assert ( IArray.is_empty args); - merge (cst (Q.of_string s)) - | { app = {builtin = Expr.Decimal s}; tyargs = []; args; _ } -> -assert ( IArray.is_empty args); - merge (cst (Q.of_string_decimal s)) - | { app = {builtin = Expr.Rational s}; tyargs = []; args; _ } -> -assert ( IArray.is_empty args); - merge (cst (Q.of_string_decimal s)) - | { app = {builtin = Expr.Add}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; Check.attach d f; - attach d ( - set r (let+ va = get a and+ vb = get b in Q.add va vb) && - set a (let+ vb = get b and+ vr = get r in Q.sub vr vb) && - set b (let+ va = get a and+ vr = get r in Q.sub vr va) - ); - | { app = {builtin = Expr.Sub}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; Check.attach d f; - attach d ( - set r (let+ va = get a and+ vb = get b in Q.sub va vb) && - set a (let+ vb = get b and+ vr = get r in Q.add vr vb) && - set b (let+ va = get a and+ vr = get r in Q.sub va vr) - ) - | { app = {builtin = Expr.Mul}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; Check.attach d f; - attach d ( - set r (let+ va = get a and+ vb = get b in Q.mul va vb) && - set a (let* vb = get b and+ vr = get r in if Q.is_zero vb then None else Some (Q.div vr vb)) && - set b (let* va = get a and+ vr = get r in if Q.is_zero va then None else Some (Q.div vr va)) - ) - | { app = {builtin = Expr.Div}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - reg a; reg b; Check.attach d f; - attach d ( - set r (let* va = get a and+ vb = get b in if Q.is_zero vb then None else Some (Q.div va vb)) && - set a (let* vb = get b and+ vr = get r in if Q.is_zero vb then None else Some (Q.mul vr vb)) && - (* if va is 0, and vr is not 0, b can't be not zero because vr would be 0. So b is 0. *) - set b (let* va = get a and+ vr = get r in if Q.is_zero vr then None else Some (Q.div va vr)) - ); - | { app = {builtin = Expr.Minus}; tyargs = []; args; _ } -> - let a = IArray.extract1_exn args in - reg a; Check.attach d f; - attach d ( - set r (let+ va = get a in Q.neg va) && - set a (let+ vr = get r in Q.neg vr) - ); - | { app = {builtin = Expr.Lt}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp Q.lt a b; Check.attach d f; - | { app = {builtin = Expr.Leq}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp Q.le a b; Check.attach d f; - | { app = {builtin = Expr.Gt}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp Q.gt a b; Check.attach d f; - | { app = {builtin = Expr.Geq}; tyargs = []; args; _ } -> - let a,b = IArray.extract2_exn args in - cmp Q.ge a b; Check.attach d f; - | { app = {builtin = Expr.Floor}; tyargs = []; args; _ } -> - let a = IArray.extract1_exn args in - reg a; Check.attach d f; + | { + app = { builtin = Expr.Coercion }; + tyargs = + ( [ + { app = { builtin = Expr.Int | Expr.Rat; _ }; _ }; + { app = { builtin = Expr.Real; _ }; _ }; + ] + | [ + { app = { builtin = Expr.Int; _ }; _ }; + { app = { builtin = Expr.Rat; _ }; _ }; + ] ); + args; + } -> + let a = IArray.extract1_exn args in + merge a; + Check.attach d f + | { app = { builtin = Expr.Integer s }; tyargs = []; args; _ } -> + assert (IArray.is_empty args); + merge (cst (Q.of_string s)) + | { app = { builtin = Expr.Decimal s }; tyargs = []; args; _ } -> + assert (IArray.is_empty args); + merge (cst (Q.of_string_decimal s)) + | { app = { builtin = Expr.Rational s }; tyargs = []; args; _ } -> + assert (IArray.is_empty args); + merge (cst (Q.of_string_decimal s)) + | { app = { builtin = Expr.Add }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f; + attach d + (set r + (let+ va = get a and+ vb = get b in + Q.add va vb) + && set a + (let+ vb = get b and+ vr = get r in + Q.sub vr vb) + && set b + (let+ va = get a and+ vr = get r in + Q.sub vr va)) + | { app = { builtin = Expr.Sub }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f; + attach d + (set r + (let+ va = get a and+ vb = get b in + Q.sub va vb) + && set a + (let+ vb = get b and+ vr = get r in + Q.add vr vb) + && set b + (let+ va = get a and+ vr = get r in + Q.sub va vr)) + | { app = { builtin = Expr.Mul }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f; + attach d + (set r + (let+ va = get a and+ vb = get b in + Q.mul va vb) + && set a + (let* vb = get b and+ vr = get r in + if Q.is_zero vb then None else Some (Q.div vr vb)) + && set b + (let* va = get a and+ vr = get r in + if Q.is_zero va then None else Some (Q.div vr va))) + | { app = { builtin = Expr.Div }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f; + attach d + (set r + (let* va = get a and+ vb = get b in + if Q.is_zero vb then None else Some (Q.div va vb)) + && set a + (let* vb = get b and+ vr = get r in + if Q.is_zero vb then None else Some (Q.mul vr vb)) + && (* if va is 0, and vr is not 0, b can't be not zero because vr would be 0. So b is 0. *) + set b + (let* va = get a and+ vr = get r in + if Q.is_zero vr then None else Some (Q.div va vr))) + | { app = { builtin = Expr.Minus }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f; + attach d + (set r + (let+ va = get a in + Q.neg va) + && set a + (let+ vr = get r in + Q.neg vr)) + | { app = { builtin = Expr.Lt }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp Q.lt a b; + Check.attach d f + | { app = { builtin = Expr.Leq }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp Q.le a b; + Check.attach d f + | { app = { builtin = Expr.Gt }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp Q.gt a b; + Check.attach d f + | { app = { builtin = Expr.Geq }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + cmp Q.ge a b; + Check.attach d f + | { app = { builtin = Expr.Floor }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Abs | Builtin.Abs_real }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f | _ -> () - let init env = Ground.register_converter env converter; init_ty env; diff --git a/src_colibri2/theories/LRA/realValue.mli b/src_colibri2/theories/LRA/realValue.mli index bf72dac0e0133877e5cb29ce40e9abbeb33dcaae..c2862ae8aecb795c3673802d740f334f4c547623 100644 --- a/src_colibri2/theories/LRA/realValue.mli +++ b/src_colibri2/theories/LRA/realValue.mli @@ -18,11 +18,18 @@ (* for more details (enclosed in the file licenses/LGPLv2.1). *) (*************************************************************************) +module Builtin : sig + type _ Expr.t += Abs_real + + val abs_real : Colibri2_core.Expr.Term.Const.t +end + include Value.S with type s = Q.t -val cst': Q.t -> t -val cst: Q.t -> Node.t +val cst' : Q.t -> t + +val cst : Q.t -> Node.t -val zero: Node.t +val zero : Node.t -val init: Egraph.wt -> unit +val init : Egraph.wt -> unit diff --git a/src_colibri2/theories/LRA/sign_product.ml b/src_colibri2/theories/LRA/sign_product.ml new file mode 100644 index 0000000000000000000000000000000000000000..7ef561b8a77da8297dfa1eddf7775571daa39705 --- /dev/null +++ b/src_colibri2/theories/LRA/sign_product.ml @@ -0,0 +1,193 @@ +(*************************************************************************) +(* This file is part of Colibri2. *) +(* *) +(* Copyright (C) 2014-2021 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(*************************************************************************) + +(** Product of node sign with one constant 1 or -1 *) + +module T = struct + type cst = Pos | Neg [@@deriving eq, ord, hash] + + type power = Odd | Even | OddNonZero (** the node can't be zero*) + [@@deriving eq, ord, hash] + + type t = NZ of { poly : power Node.M.t; cst : cst } | Zero + [@@deriving eq, ord, hash] + + let pp_exposant fmt q = + match q with + | OddNonZero -> () + | Even -> Fmt.string fmt "²" + | Odd -> Fmt.string fmt "³" + + let pp fmt = function + | Zero -> Fmt.pf fmt "0" + | NZ v -> + Fmt.pf fmt "@[%s%a@]" + (match v.cst with Pos -> "+" | Neg -> "-") + (* print_not_one v.cst *) + Fmt.(iter_bindings Node.M.iter (pair Node.pp pp_exposant)) + v.poly +end + +include T +include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T) + +let of_one_node cl = NZ { poly = Node.M.singleton cl Odd; cst = Pos } + +let of_one_node_non_zero cl = + NZ { poly = Node.M.singleton cl OddNonZero; cst = Pos } + +let is_one_node = function + | Zero -> None + | NZ t -> + if Node.M.is_num_elt 1 t.poly && T.equal_cst t.cst Pos then + match Node.M.choose t.poly with + | _, Even -> None + | n, (Odd | OddNonZero) -> Some n + else None + +let one = NZ { cst = Pos; poly = Node.M.empty } + +let minus_one = NZ { cst = Neg; poly = Node.M.empty } + +let zero = Zero + +let mul_cst c1 c2 = + match (c1, c2) with Pos, Pos | Neg, Neg -> Pos | Neg, Pos | Pos, Neg -> Neg + +let mul p1 p2 = + match (p1, p2) with + | Zero, _ | _, Zero -> Zero + | NZ p1, NZ p2 -> + let poly m1 m2 = + Node.M.union + (fun _ c1 c2 -> + match (c1, c2) with + | Odd, Odd -> Some Even + | (OddNonZero | Odd), (OddNonZero | Odd) -> None + | Even, v | v, Even -> Some v) + m1 m2 + in + NZ { cst = mul_cst p1.cst p2.cst; poly = poly p1.poly p2.poly } + +let subst p x s = + match p with + | Zero -> None + | NZ p -> ( + let poly, q = Node.M.find_remove x p.poly in + match q with + | None -> None + | Some (Odd | OddNonZero) -> Some (mul (NZ { cst = p.cst; poly }) s) + | Some Even -> Some (mul (mul (NZ { cst = p.cst; poly }) s) s)) + +let normalize p ~f = + match p with + | Zero -> Zero + | NZ p -> + let add acc cl v = + let q = f cl in + match v with Odd | OddNonZero -> mul acc q | Even -> mul (mul acc q) q + in + Node.M.fold_left add (NZ { cst = p.cst; poly = Node.M.empty }) p.poly + +type data = power + +let nodes = function Zero -> Node.M.empty | NZ p -> p.poly + +type extracted = Plus_one | Minus_one | Zero | Var of Node.t * t | NoNonZero + +let extract : t -> extracted = function + | Zero -> Zero + | NZ p -> ( + if Node.M.is_empty p.poly then + match p.cst with Pos -> Plus_one | Neg -> Minus_one + else + match + Node.M.fold_left + (fun acc c v -> + match acc with + | Some _ -> acc + | None -> ( + match v with Odd | Even -> None | OddNonZero -> Some c)) + None p.poly + with + | None -> NoNonZero + | Some x -> + let p' = NZ { p with poly = Node.M.remove x p.poly } in + Var (x, p')) + +type presolve = Zero | NonZero | OneNonZero of Node.t | Other + +let presolve : t -> presolve = function + | Zero -> Zero + | NZ p -> + Node.M.fold_left + (fun acc c -> function + | Odd | Even -> ( + match acc with + | NonZero -> OneNonZero c + | OneNonZero _ | Zero | Other -> Other) + | OddNonZero -> acc) + NonZero p.poly + +type extract_cst = Pos | Neg | Zero + +let extract_cst : t -> extract_cst * t = function + | Zero -> (Zero, Zero) + | NZ t as t' -> ( + match t.cst with Pos -> (Pos, t') | Neg -> (Neg, NZ { t with cst = Pos })) + +let remove n = function + | T.Zero -> T.Zero + | NZ p -> NZ { p with poly = Node.M.remove n p.poly } + +let common pa pb = + match (pa, pb) with + | T.Zero, T.Zero -> T.Zero + | Zero, p | p, Zero -> p + | NZ pa, NZ pb -> + NZ + { + poly = + Node.M.inter + (fun _ v1 v2 -> + match (v1, v2) with + | Odd, Odd -> Some Odd + | (Odd | OddNonZero), (Odd | OddNonZero) -> Some OddNonZero + | Odd, Even | Even, Odd -> Some Odd + | OddNonZero, Even | Even, OddNonZero -> Some OddNonZero + | Even, Even -> Some Even) + pa.poly pb.poly; + cst = + (match (pa.cst, pb.cst) with + | Neg, Neg -> Neg + | Pos, Pos | Neg, Pos | Pos, Neg -> Pos); + } + +type kind = PLUS_ONE | MINUS_ONE | ZERO | NODE of Node.t | PRODUCT + +let classify = function + | T.Zero -> ZERO + | T.NZ p -> + if Node.M.is_empty p.poly then + match p.cst with Pos -> PLUS_ONE | Neg -> MINUS_ONE + else if T.equal_cst Pos p.cst && Node.M.is_num_elt 1 p.poly then + let node, v = Node.M.choose p.poly in + match v with Even -> PRODUCT | Odd | OddNonZero -> NODE node + else PRODUCT diff --git a/src_colibri2/theories/LRA/sign_product.mli b/src_colibri2/theories/LRA/sign_product.mli new file mode 100644 index 0000000000000000000000000000000000000000..9f3515e62e833a6581f52fa31615b331241049f7 --- /dev/null +++ b/src_colibri2/theories/LRA/sign_product.mli @@ -0,0 +1,76 @@ +(*************************************************************************) +(* This file is part of Colibri2. *) +(* *) +(* Copyright (C) 2014-2021 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(*************************************************************************) + +(** Product of node sign with one constant 1 or -1 *) + +type t + +include Colibri2_popop_lib.Popop_stdlib.Datatype with type t := t + +val of_one_node : Node.t -> t +(** Build a value that represent one node *) + +val of_one_node_non_zero : Node.t -> t +(** Build a value that represent one node when it is known to be non-zero *) + +val is_one_node : t -> Node.t option +(** Test if a value represents one node *) + +val subst : t -> Node.t -> t -> t option +(** [subst p n q] substitute [n] by [q] in [p], if [n] is not in [p] None is + returned, otherwise the result of the substitution is returned *) + +val normalize : t -> f:(Node.t -> t) -> t +(** [norm p ~f] normalize [p] using [f] *) + +type data +(** An abstract type to avoid translating the map to sets in {!nodes} *) + +val nodes : t -> data Node.M.t +(** [nodes t] returns the node which are present in [t] *) + +val mul : t -> t -> t + +type extracted = Plus_one | Minus_one | Zero | Var of Node.t * t | NoNonZero + +val extract : t -> extracted + +type extract_cst = Pos | Neg | Zero + +val extract_cst : t -> extract_cst * t + +val remove : Node.t -> t -> t + +val common : t -> t -> t +(** Return the common part *) + +val one : t + +val minus_one : t + +val zero : t + +type kind = PLUS_ONE | MINUS_ONE | ZERO | NODE of Node.t | PRODUCT + +val classify : t -> kind + +type presolve = Zero | NonZero | OneNonZero of Node.t | Other + +val presolve : t -> presolve diff --git a/src_colibri2/theories/LRA/stages/interval_sig.ml b/src_colibri2/theories/LRA/stages/interval_sig.ml index 1715ca252c8d5844ba6d6e2f69f1997493b16561..cff021537f139003c2f8b2beb45221d6a4972ed1 100644 --- a/src_colibri2/theories/LRA/stages/interval_sig.ml +++ b/src_colibri2/theories/LRA/stages/interval_sig.ml @@ -23,76 +23,81 @@ open Colibri2_popop_lib module type S = sig include Popop_stdlib.Datatype - val is_distinct: t -> t -> bool - type is_comparable = - | Gt - | Lt - | Ge - | Le - | Uncomparable - - val is_comparable: t -> t -> is_comparable - val is_included: t -> t -> bool - - val mult_cst: Q.t -> t -> t + val is_distinct : t -> t -> bool + + type is_comparable = Gt | Lt | Ge | Le | Eq | Uncomparable + + val is_comparable : t -> t -> is_comparable + + val is_included : t -> t -> bool + + val mult_cst : Q.t -> t -> t + val add_cst : Q.t -> t -> t - val add: t -> t -> t - val minus: t -> t -> t - val mem: Q.t -> t -> bool + val add : t -> t -> t + val minus : t -> t -> t + + val mem : Q.t -> t -> bool + + val singleton : Q.t -> t (** from Q.t *) - val singleton: Q.t -> t - val is_singleton: t -> Q.t option - val except: t -> Q.t -> t option + val is_singleton : t -> Q.t option + + val except : t -> Q.t -> t option + + type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted - type split_heuristic = - | Singleton of Q.t - | Splitted of t * t - | NotSplitted + val split_heuristic : t -> split_heuristic - val split_heuristic: t -> split_heuristic + val absent : Q.t -> t -> bool - val absent: Q.t -> t -> bool - val is_integer: t -> bool - val integers: t + val is_integer : t -> bool - val gt: Q.t -> t - val ge: Q.t -> t - val lt: Q.t -> t - val le: Q.t -> t + val integers : t + + val gt : Q.t -> t + + val ge : Q.t -> t + + val lt : Q.t -> t + + val le : Q.t -> t (** > q, >= q, < q, <= q *) - val le': t -> t - val lt': t -> t - val ge': t -> t - val gt': t -> t + val le' : t -> t - val union: t -> t -> t + val lt' : t -> t + + val ge' : t -> t + + val gt' : t -> t + + val union : t -> t -> t (** union set *) - val inter: t -> t -> t option + val inter : t -> t -> t option (** intersection set. if the two arguments are equals, return the second *) + val zero : t - val zero: t - val reals: t + val reals : t + val is_reals : t -> bool (** R *) - val is_reals: t -> bool - val choose: t -> Q.t + val choose : t -> Q.t (** Nothing smart in this choosing *) - val invariant: t -> bool + val invariant : t -> bool (* val choose_rnd : (int -> int) -> t -> Q.t * (\** choose an element randomly (but non-uniformly), the given function is * the random generator *\) * * val get_convexe_hull: t -> (Q.t * bound) option * (Q.t * bound) option *) - end diff --git a/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml b/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml index 69981140f7b9381b9a17cd76b713885f705bdd10..33178987e69acdb4aa9a968e78f6cdec55bdeb48 100644 --- a/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml +++ b/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml @@ -24,75 +24,95 @@ open Base module T = struct type t = { - noninteger: bool; (** true: maybe negative, false: never negative *) - sign: Sign_domain.t; + noninteger : bool; (** true: maybe negative, false: never negative *) + sign : Sign_domain.t; } [@@deriving ord, eq, hash] - let pp fmt t = - let prefix s = if t.noninteger then s else "â„•"^s in - Fmt.string fmt @@ - match t.sign.neg, t.sign.zero, t.sign.pos with - | true, true, true -> if t.noninteger then "â„" else "â„•" + let prefix s = if t.noninteger then s else "â„•" ^ s in + Fmt.string fmt + @@ + match (t.sign.neg, t.sign.zero, t.sign.pos) with + | true, true, true -> if t.noninteger then "â„" else "â„•" | true, false, true -> prefix "≠0" | false, true, false -> prefix "=0" | true, true, false -> prefix "≤0" - | true, false, false -> prefix "<0" - | false, false, false -> prefix "∅" + | true, false, false -> prefix "<0" + | false, false, false -> prefix "∅" | false, false, true -> prefix ">0" | false, true, true -> prefix "≥0" - end include T -include Colibri2_popop_lib.Popop_stdlib.MkDatatype(T) +include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T) let invariant t = Sign_domain.invariant t.sign -type split_heuristic = - | Singleton of Q.t - | Splitted of t * t - | NotSplitted +type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted let split_heuristic t = match Sign_domain.split_heuristic t.sign with | Singleton q -> Singleton q - | Splitted (t1,t2) -> Splitted ({ noninteger = t.noninteger; sign = t1 }, - { noninteger = t.noninteger; sign = t2 }) + | Splitted (t1, t2) -> + Splitted + ( { noninteger = t.noninteger; sign = t1 }, + { noninteger = t.noninteger; sign = t2 } ) | NotSplitted -> NotSplitted let absent q t = - (not t.noninteger && not (Q.is_integer q)) || - Sign_domain.absent q t.sign + ((not t.noninteger) && not (Q.is_integer q)) || Sign_domain.absent q t.sign + +let le' t = { noninteger = true; sign = Sign_domain.le' t.sign } -let le' t = { noninteger = true; sign = Sign_domain.le' t.sign; } -let lt' t = { noninteger = true; sign = Sign_domain.lt' t.sign; } -let ge' t = { noninteger = true; sign = Sign_domain.ge' t.sign; } -let gt' t = { noninteger = true; sign = Sign_domain.gt' t.sign; } +let lt' t = { noninteger = true; sign = Sign_domain.lt' t.sign } + +let ge' t = { noninteger = true; sign = Sign_domain.ge' t.sign } + +let gt' t = { noninteger = true; sign = Sign_domain.gt' t.sign } let is_distinct t1 t2 = Sign_domain.is_distinct t1.sign t2.sign -type is_comparable = Sign_domain.is_comparable = Gt | Lt | Ge | Le | Uncomparable +type is_comparable = Sign_domain.is_comparable = + | Gt + | Lt + | Ge + | Le + | Eq + | Uncomparable let is_comparable t1 t2 = Sign_domain.is_comparable t1.sign t2.sign + let is_included t1 t2 = - (not t1.noninteger || t2.noninteger) && - Sign_domain.is_included t1.sign t2.sign - -let mult_cst q t = { noninteger = t.noninteger && Q.is_not_zero q; - sign = Sign_domain.mult_cst q t.sign } -let add_cst q t = { noninteger = t.noninteger; - sign = Sign_domain.add_cst q t.sign } -let add t1 t2 = { noninteger = t1.noninteger || t2.noninteger; - sign = Sign_domain.add t1.sign t2.sign } -let minus t1 t2 = { noninteger = t1.noninteger || t2.noninteger; - sign = Sign_domain.minus t1.sign t2.sign } -let mem q t = - (Q.is_integer q || t.noninteger) && - Sign_domain.mem q t.sign - -let singleton q = { noninteger = not (Q.is_integer q); sign = Sign_domain.singleton q } + ((not t1.noninteger) || t2.noninteger) + && Sign_domain.is_included t1.sign t2.sign + +let mult_cst q t = + { + noninteger = t.noninteger && Q.is_not_zero q; + sign = Sign_domain.mult_cst q t.sign; + } + +let add_cst q t = + { noninteger = t.noninteger; sign = Sign_domain.add_cst q t.sign } + +let add t1 t2 = + { + noninteger = t1.noninteger || t2.noninteger; + sign = Sign_domain.add t1.sign t2.sign; + } + +let minus t1 t2 = + { + noninteger = t1.noninteger || t2.noninteger; + sign = Sign_domain.minus t1.sign t2.sign; + } + +let mem q t = (Q.is_integer q || t.noninteger) && Sign_domain.mem q t.sign + +let singleton q = + { noninteger = not (Q.is_integer q); sign = Sign_domain.singleton q } + let is_singleton t = Sign_domain.is_singleton t.sign let except t q = @@ -101,25 +121,32 @@ let except t q = | Some sign -> Some { noninteger = t.noninteger; sign } let gt q = { noninteger = true; sign = Sign_domain.gt q } + let ge q = { noninteger = true; sign = Sign_domain.ge q } + let lt q = { noninteger = true; sign = Sign_domain.lt q } + let le q = { noninteger = true; sign = Sign_domain.le q } -let union t1 t2 = { noninteger = t1.noninteger || t2.noninteger; - sign = Sign_domain.union t1.sign t2.sign - } +let union t1 t2 = + { + noninteger = t1.noninteger || t2.noninteger; + sign = Sign_domain.union t1.sign t2.sign; + } let inter t1 t2 = match Sign_domain.inter t1.sign t2.sign with - | Some sign -> - Some { noninteger = t1.noninteger && t2.noninteger; sign; } + | Some sign -> Some { noninteger = t1.noninteger && t2.noninteger; sign } | None -> None let zero = { noninteger = false; sign = Sign_domain.zero } + let reals = { noninteger = true; sign = Sign_domain.reals } + let integers = { noninteger = false; sign = Sign_domain.reals } + let is_reals t = t.noninteger && Sign_domain.is_reals t.sign let choose t = Sign_domain.choose t.sign -let is_integer t = not (t.noninteger) +let is_integer t = not t.noninteger diff --git a/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml b/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml index ce6a596796bdb474a2be414896d8aea88d495992..7d5db0e4f9ca73b288cba1e26a99804c1fe84044 100644 --- a/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml +++ b/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml @@ -19,55 +19,65 @@ (*************************************************************************) (** Sign domain: abstraction of integer numerical values by their signs. *) + (** From frama-c *) open Base module T = struct type t = { - pos: bool; (** true: maybe positive, false: never positive *) - zero: bool; (** true: maybe zero, false: never zero *) - neg: bool; (** true: maybe negative, false: never negative *) + pos : bool; (** true: maybe positive, false: never positive *) + zero : bool; (** true: maybe zero, false: never zero *) + neg : bool; (** true: maybe negative, false: never negative *) } [@@deriving ord, eq, hash] - let pp fmt t = - Fmt.string fmt @@ - match t.neg, t.zero, t.pos with - | true, true, true -> "â„" + Fmt.string fmt + @@ + match (t.neg, t.zero, t.pos) with + | true, true, true -> "â„" | true, false, true -> "≠0" | false, true, false -> "=0" | true, true, false -> "≤0" - | true, false, false -> "<0" - | false, false, false -> "∅" + | true, false, false -> "<0" + | false, false, false -> "∅" | false, false, true -> ">0" | false, true, true -> "≥0" - end include T -include Colibri2_popop_lib.Popop_stdlib.MkDatatype(T) - +include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T) let invariant t = t.neg || t.zero || t.pos -let top = { pos = true; zero = true; neg = true } -let pos_or_zero = { pos = true; zero = true; neg = false } -let pos = { pos = true; zero = false; neg = false } -let neg_or_zero = { pos = false; zero = true; neg = true } -let neg = { pos = false; zero = false; neg = true } -let zero = { pos = false; zero = true; neg = false } -let one = { pos = true; zero = false; neg = false } -let non_zero = { pos = true; zero = false; neg = true } +let top = { pos = true; zero = true; neg = true } + +let pos_or_zero = { pos = true; zero = true; neg = false } + +let pos = { pos = true; zero = false; neg = false } + +let neg_or_zero = { pos = false; zero = true; neg = true } + +let neg = { pos = false; zero = false; neg = true } + +let zero = { pos = false; zero = true; neg = false } + +let one = { pos = true; zero = false; neg = false } + +let non_zero = { pos = true; zero = false; neg = true } + let ge_zero v = not v.neg + let le_zero v = not v.pos (* Bottom is a special value (`Bottom) in Eva, and need not be part of the lattice. Here, we have a value which is equivalent to it, defined there only for commodity. *) let empty = { pos = false; zero = false; neg = false } + let is_empty t = equal t empty + let is_reals t = equal t top (* Inclusion: test inclusion of each field. *) @@ -76,41 +86,37 @@ let is_included v1 v2 = bincl v1.pos v2.pos && bincl v1.zero v2.zero && bincl v1.neg v2.neg (* Join of the lattice: pointwise logical or. *) -let join v1 v2 = { - pos = v1.pos || v2.pos; - zero = v1.zero || v2.zero; - neg = v1.neg || v2.neg; -} +let join v1 v2 = + { pos = v1.pos || v2.pos; zero = v1.zero || v2.zero; neg = v1.neg || v2.neg } (* Meet of the lattice (called 'narrow' in Eva for historical reasons). We detect the case where the values have incompatible concretization, and report this as `Bottom. *) let narrow v1 v2 = - let r = { - pos = v1.pos && v2.pos; - zero = v1.zero && v2.zero; - neg = v1.neg && v2.neg; - } in + let r = + { + pos = v1.pos && v2.pos; + zero = v1.zero && v2.zero; + neg = v1.neg && v2.neg; + } + in if is_empty r then None else Some r let mem q v = let c = Q.sign q in - c = 0 && v.zero || c < 0 && v.neg || c > 0 && v.pos + (c = 0 && v.zero) || (c < 0 && v.neg) || (c > 0 && v.pos) let absent q v = let c = Q.sign q in - c = 0 && not v.zero || c < 0 && not v.neg || c > 0 && not v.pos + (c = 0 && not v.zero) || (c < 0 && not v.neg) || (c > 0 && not v.pos) let reals = top (* [singleton] creates an abstract value corresponding to the singleton [i]. *) let singleton i = - if Q.lt i Q.zero then neg - else if Q.gt i Q.zero then pos - else zero + if Q.lt i Q.zero then neg else if Q.gt i Q.zero then pos else zero -let is_singleton v = - if equal v zero then Some Q.zero else None +let is_singleton v = if equal v zero then Some Q.zero else None (** {2 Forward transfer functions} *) @@ -129,14 +135,15 @@ let add v1 v2 = let same_sign v1 v2 = (le_zero v1 && le_zero v2) || (ge_zero v1 && ge_zero v2) in - let zero = not (same_sign v1 v2) || (v1.zero && v2.zero) in + let zero = (not (same_sign v1 v2)) || (v1.zero && v2.zero) in { neg; pos; zero } let add_cst q v = let c = Q.sign q in if c = 0 then v - else if c > 0 then { neg = v.neg; zero = v.zero && v.neg ; pos = v.pos || v.zero || v.neg } - else { neg = v.neg || v.zero || v.pos; zero = v.zero && v.pos ; pos = v.pos } + else if c > 0 then + { neg = v.neg; zero = v.zero && v.neg; pos = v.pos || v.zero || v.neg } + else { neg = v.neg || v.zero || v.pos; zero = v.zero && v.pos; pos = v.pos } let mul v1 v2 = let pos = (v1.pos && v2.pos) || (v1.neg && v2.neg) in @@ -144,20 +151,19 @@ let mul v1 v2 = let zero = v1.zero || v2.zero in { neg; pos; zero } -let minus v1 v2 = - add v1 { neg = v2.pos; zero = v2.zero; pos = v2.neg } +let minus v1 v2 = add v1 { neg = v2.pos; zero = v2.zero; pos = v2.neg } let mult_cst q v = let c = Q.sign q in if c = 0 then zero else if c > 0 then v - else { neg = v.pos; zero = v.zero; pos = v.neg } - + else { neg = v.pos; zero = v.zero; pos = v.neg } let div v1 v2 = let pos = (v1.pos && v2.pos) || (v1.neg && v2.neg) in let neg = (v1.pos && v2.neg) || (v1.neg && v2.pos) in - let zero = true in (* zero can appear with large enough v2 *) + let zero = true in + (* zero can appear with large enough v2 *) { neg; pos; zero } (* The implementation of the bitwise operators below relies on this table @@ -194,8 +200,7 @@ let bitwise_xor v1 v2 = || (v1.neg && v2.neg) in let neg = - (v1.neg && (v2.pos || v2.zero)) || - (v2.neg && (v1.pos || v1.zero)) + (v1.neg && (v2.pos || v2.zero)) || (v2.neg && (v1.pos || v1.zero)) in let zero = (v1.zero && v2.zero) || (v1.pos && v2.pos) || (v1.neg && v2.neg) in { neg; pos; zero } @@ -284,46 +289,55 @@ let backward_cast ~src_typ:_ ~dst_typ:_ ~src_val:_ ~dst_val:_ = `Value None let is_distinct a b = Bool.(a.neg <> b.neg) && Bool.(a.zero <> b.zero) && Bool.(a.pos <> b.pos) -type is_comparable = - | Gt - | Lt - | Ge - | Le - | Uncomparable +type is_comparable = Gt | Lt | Ge | Le | Eq | Uncomparable let is_comparable x y = - match x, y with - | {pos=false; zero=false;neg=false},_ | _, {pos=false; zero=false;neg=false} - | {pos=true; neg = true;_}, _ | _, {pos=true; neg = true;_} -> Uncomparable - | {pos=true; _ }, {pos = true; _} - | {neg=true; _ }, {neg = true; _} -> Uncomparable - | {neg=true; zero=false; pos = false }, {neg=false; zero=_; pos=_} - | {neg=true; zero=true; pos = false }, {neg=false; zero=false; pos=true} - | {neg=false; zero=true; pos = false }, {neg=false; zero=false; pos=true} - -> Lt - | {neg=true; zero=true; pos = false }, {neg=false; zero=true; pos=_} - | {neg=false; zero=true; pos = false }, {neg=false; zero=true; pos=_} - -> Le - | {neg=false; zero=_; pos=_}, {neg=true; zero=false; pos = false } - | {neg=false; zero=false; pos=true}, {neg=true; zero=true; pos = false } - | {neg=false; zero=false; pos=true}, {neg=false; zero=true; pos = false } - -> Gt - | {neg=false; zero=true; pos=_}, {neg=true; zero=true; pos = false } - | {neg=false; zero=true; pos=true}, {neg=false; zero=true; pos = false } - -> Ge + match (x, y) with + | { pos = false; zero = false; neg = false }, _ + | _, { pos = false; zero = false; neg = false } + | { pos = true; neg = true; _ }, _ + | _, { pos = true; neg = true; _ } -> + Uncomparable + | { pos = true; _ }, { pos = true; _ } | { neg = true; _ }, { neg = true; _ } + -> + Uncomparable + | ( { neg = false; zero = true; pos = false }, + { neg = false; zero = true; pos = false } ) -> + Eq + | ( { neg = true; zero = false; pos = false }, + { neg = false; zero = _; pos = _ } ) + | ( { neg = true; zero = true; pos = false }, + { neg = false; zero = false; pos = true } ) + | ( { neg = false; zero = true; pos = false }, + { neg = false; zero = false; pos = true } ) -> + Lt + | ( { neg = true; zero = true; pos = false }, + { neg = false; zero = true; pos = _ } ) + | ( { neg = false; zero = true; pos = false }, + { neg = false; zero = true; pos = _ } ) -> + Le + | ( { neg = false; zero = _; pos = _ }, + { neg = true; zero = false; pos = false } ) + | ( { neg = false; zero = false; pos = true }, + { neg = true; zero = true; pos = false } ) + | ( { neg = false; zero = false; pos = true }, + { neg = false; zero = true; pos = false } ) -> + Gt + | ( { neg = false; zero = true; pos = _ }, + { neg = true; zero = true; pos = false } ) + | ( { neg = false; zero = true; pos = true }, + { neg = false; zero = true; pos = false } ) -> + Ge let is_included x y = (* <= is like implication on booleans *) Bool.(x.neg <= y.neg && x.zero <= y.zero && x.pos <= y.pos) let union = join -let inter = narrow +let inter = narrow -type split_heuristic = - | Singleton of Q.t - | Splitted of t * t - | NotSplitted +type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted let split_heuristic _ = NotSplitted @@ -333,56 +347,34 @@ let except t x = if is_empty t then None else Some t else Some t -let choose t = - if t.zero then Q.zero - else if t.pos then Q.one - else Q.minus_one +let choose t = if t.zero then Q.zero else if t.pos then Q.one else Q.minus_one let le q = let c = Q.sign q in - if c < 0 then neg - else if c = 0 then neg_or_zero - else top + if c < 0 then neg else if c = 0 then neg_or_zero else top let lt q = let c = Q.sign q in - if c <= 0 then neg - else top + if c <= 0 then neg else top let ge q = let c = Q.sign q in - if c < 0 then top - else if c = 0 then pos_or_zero - else pos + if c < 0 then top else if c = 0 then pos_or_zero else pos let gt q = let c = Q.sign q in - if c >= 0 then pos - else top + if c >= 0 then pos else top let le' v = - { neg = v.neg || v.zero || v.pos; - zero = v.zero || v.pos; - pos = v.pos - } + { neg = v.neg || v.zero || v.pos; zero = v.zero || v.pos; pos = v.pos } -let lt' v = - { neg = v.neg || v.zero || v.pos; - zero = v.pos; - pos = v.pos - } +let lt' v = { neg = v.neg || v.zero || v.pos; zero = v.pos; pos = v.pos } let ge' v = - { neg = v.neg; - zero = v.zero || v.neg ; - pos = v.pos || v.zero || v.neg; - } + { neg = v.neg; zero = v.zero || v.neg; pos = v.pos || v.zero || v.neg } -let gt' v = - { neg = v.neg; - zero = v.neg ; - pos = v.pos || v.zero || v.neg; - } +let gt' v = { neg = v.neg; zero = v.neg; pos = v.pos || v.zero || v.neg } let integers = reals + let is_integer _ = false diff --git a/src_common/interval.mlw b/src_common/interval.mlw index a97b41139949b1accb3fc098ed9d91e9321d41dc..70bb62789babf34b5d3767a4a1210a009afcc1a0 100644 --- a/src_common/interval.mlw +++ b/src_common/interval.mlw @@ -116,6 +116,7 @@ module Convexe | Lt | Ge | Le + | Eq | Uncomparable use q.Ord as Ord @@ -128,6 +129,7 @@ module Convexe | Gt -> forall q1 q2. mem q1 e1 -> mem q2 e2 -> q1 >. q2 | Le -> forall q1 q2. mem q1 e1 -> mem q2 e2 -> q1 <=. q2 | Ge -> forall q1 q2. mem q1 e1 -> mem q2 e2 -> q1 >=. q2 + | Eq -> forall q1 q2. mem q1 e1 -> mem q2 e2 -> q1 = q2 end } = @@ -163,6 +165,7 @@ module Convexe end | Finite v1 b1 v1' b1', Finite v2 b2 v2' b2' -> match Q.compare v1' v2, Q.compare v1 v2' with + | Ord.Eq, Ord.Eq -> Eq | Ord.Eq, _ -> match b1', b2 with | Large, Large -> Le diff --git a/src_common/interval__Convexe.ml b/src_common/interval__Convexe.ml index d552b1acd86f9f4bbad3563ad8be2ba976bb29fb..2a6402b6d0e3492315af77134b4544012c73230d 100644 --- a/src_common/interval__Convexe.ml +++ b/src_common/interval__Convexe.ml @@ -74,6 +74,7 @@ type is_comparable = | Lt | Ge | Le + | Eq | Uncomparable let is_comparable (e1: t') (e2: t') : is_comparable = @@ -117,6 +118,7 @@ let is_comparable (e1: t') (e2: t') : is_comparable = v2', b2')) -> begin match ((Q_extra.compare v1' v2), (Q_extra.compare v1 v2')) with + | (Ord.Eq, Ord.Eq) -> Eq | (Ord.Eq, _) -> begin match (b1', b2) with diff --git a/src_common/q/why3session.xml b/src_common/q/why3session.xml index 6ef2aa09b442a13a6d5ad85b6c0b3b0f1456d368..0d13e6466775d9fe18669fc6fe9687bc71f5f5f8 100644 --- a/src_common/q/why3session.xml +++ b/src_common/q/why3session.xml @@ -2,7 +2,7 @@ <!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN" "http://why3.lri.fr/why3session.dtd"> <why3session shape_version="6"> -<prover id="3" name="Colibri2" version="0.1" timelimit="5" steplimit="0" memlimit="1000"/> +<prover id="3" name="Colibri2" version="n/a" timelimit="5" steplimit="0" memlimit="1000"/> <file format="whyml" proved="true"> <path name=".."/><path name="q.mlw"/> <theory name="QWithInf" proved="true">