diff --git a/src_colibri2/core/datastructure.ml b/src_colibri2/core/datastructure.ml index e28c7200245e7a5f647b837d5daa074646e99d14..f5f416cc99adf9364f780ecaeb078a7645eacf6d 100644 --- a/src_colibri2/core/datastructure.ml +++ b/src_colibri2/core/datastructure.ml @@ -87,3 +87,4 @@ module Hashtbl(S:Colibri2_popop_lib.Popop_stdlib.Datatype) : Sig with type key : end module HNode = Hashtbl(Nodes.Node) +module HTermConst = Hashtbl(Expr.Term.Const) diff --git a/src_colibri2/core/datastructure.mli b/src_colibri2/core/datastructure.mli index 86dd3cf6b61f6735117ab2743daefe7213f5e58f..f9bb3ee6e3219e579bef38c7bfbde32b0f89b45b 100644 --- a/src_colibri2/core/datastructure.mli +++ b/src_colibri2/core/datastructure.mli @@ -34,3 +34,4 @@ end module Hashtbl (S:Colibri2_popop_lib.Popop_stdlib.Datatype) : Sig with type key := S.t module HNode : Sig with type key := Nodes.Node.t +module HTermConst : Sig with type key := Expr.Term.Const.t diff --git a/src_colibri2/core/structures/expr.ml b/src_colibri2/core/structures/expr.ml index d6b5be6b667047dc406e443cffde02a5627932d1..70062664e9da5f5250bbe9733e4ec44655026fb7 100644 --- a/src_colibri2/core/structures/expr.ml +++ b/src_colibri2/core/structures/expr.ml @@ -32,5 +32,13 @@ module Term = struct include Dolmen_std.Expr.Term.Const let pp fmt (t:t) = Dolmen_std.Expr.Id.print fmt t let hash_fold_t state t = Base.Hash.fold_int state (hash 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 + end) end end diff --git a/src_colibri2/core/synTerm.ml b/src_colibri2/core/synTerm.ml index 9a053bfc13522777a92b2c19d4560949d9234957..a266f15f9c111c2b8b86acb754a1ccd3dfd0c74b 100644 --- a/src_colibri2/core/synTerm.ml +++ b/src_colibri2/core/synTerm.ml @@ -34,6 +34,41 @@ module ThTerm = RegisterThTerm(struct let node_of_term x = ThTerm.node (ThTerm.index x) +(** Definitions *) +module Defs = struct + + type fundef = { + tyl: Expr.Ty.Var.t list; + tvl: Expr.Term.Var.t list; + body: Expr.Term.t + } + + let pp_fundef _ _ = () + + let fundefs = Datastructure.HTermConst.create pp_fundef "SynTerm.fundefs" + + let add d tc tyl tvl body = + Datastructure.HTermConst.set fundefs d tc {tyl;tvl;body} + + let converter d (v:Expr.Term.t) cl = + match v with + | { descr = App(tc,tyl,tvl); _ } -> + begin match Datastructure.HTermConst.find fundefs d tc with + | exception Not_found -> () + | fundef -> + let mk_subst vl l = + List.fold_left2 + (fun subst var v -> Expr.Subst.Var.bind subst var v) + Expr.Subst.empty vl l + in + let subst_ty = mk_subst fundef.tyl tyl in + let subst_term = mk_subst fundef.tvl tvl in + let body = Expr.Term.subst subst_ty subst_term fundef.body in + Egraph.set_thterm d cl (ThTerm.thterm (ThTerm.index body)) + end + | _ -> () +end + type env = { converters: (Egraph.t -> Expr.Term.t -> Node.t -> unit) list; } @@ -74,7 +109,8 @@ module DaemonConvertTerm = struct | _ -> let cl = ThTerm.node thterm in let iter conv = conv d v cl in - List.iter iter e.converters + List.iter iter e.converters; + Defs.converter d v cl in handle v end with Exit -> () end @@ -84,10 +120,13 @@ end module RDaemonConvertTerm = Demon.Fast.Register(DaemonConvertTerm) +(* Not added in default theories because Solver.input requires it. So scheduler + always add it *) let init env = Egraph.set_env env converters {converters=[]}; RDaemonConvertTerm.init env; Demon.Fast.attach env - DaemonConvertTerm.key [Demon.Create.EventRegSem(ThTerm.key,())]; + DaemonConvertTerm.key [Demon.Create.EventRegSem(ThTerm.key,())] + include ThTerm diff --git a/src_colibri2/core/synTerm.mli b/src_colibri2/core/synTerm.mli index 7645b601a631094720f3e2f95a932f1cd7ac40bd..837449fd3f21d12541285abfac41781fd2b1cb96 100644 --- a/src_colibri2/core/synTerm.mli +++ b/src_colibri2/core/synTerm.mli @@ -36,3 +36,14 @@ val register_converter: (Egraph.t -> Expr.Term.t -> Node.t -> unit) -> unit (** register converters between syntactic terms *) + +module Defs: sig + + val add: + Egraph.t -> + Expr.Term.Const.t -> + Expr.Ty.Var.t list -> + Expr.Term.Var.t list -> + Expr.Term.t -> + unit +end diff --git a/src_colibri2/solver/input.ml b/src_colibri2/solver/input.ml index 4d5d445056a7fa7f45cbfd91e17eaa103c9f16fc..9d3a19a83220d02ba4caeab05759772aa0bfcf9c 100644 --- a/src_colibri2/solver/input.ml +++ b/src_colibri2/solver/input.ml @@ -172,7 +172,13 @@ let debug_pipe st c = Dolmen.Std.Statement.print c; st, c -let def _st _d = invalid_arg "unimplemented" +let def st (d:Typer.def) = + match d with + | `Type_def _ -> () (* handled by dolmen *) + | `Term_def (_, tc, tyl, tvl, b) -> + Scheduler.add_assertion st.scheduler (fun d -> + SynTerm.Defs.add d tc tyl tvl b + ) let set_term_true ~set_true d t = let t = SynTerm.node_of_term t in diff --git a/src_colibri2/tests/solve/smt_uf/unsat/dune.inc b/src_colibri2/tests/solve/smt_uf/unsat/dune.inc index 5e8a4d4979f43fd9dfb437d3e29e112d73b3b150..36caad8d4996674d751b573dd3356a18f400638e 100644 --- a/src_colibri2/tests/solve/smt_uf/unsat/dune.inc +++ b/src_colibri2/tests/solve/smt_uf/unsat/dune.inc @@ -13,6 +13,8 @@ (rule (alias runtest) (action (diff oracle eq_diamond2.smt2.res))) (rule (action (with-stdout-to equality_norm_set.smt2.res (run %{bin:colibri2} --max-step 1000 %{dep:equality_norm_set.smt2})))) (rule (alias runtest) (action (diff oracle equality_norm_set.smt2.res))) +(rule (action (with-stdout-to fundef.smt2.res (run %{bin:colibri2} --max-step 1000 %{dep:fundef.smt2})))) +(rule (alias runtest) (action (diff oracle fundef.smt2.res))) (rule (action (with-stdout-to get_repr_at__instead_of__equal_CRepr.smt2.res (run %{bin:colibri2} --max-step 1000 %{dep:get_repr_at__instead_of__equal_CRepr.smt2})))) (rule (alias runtest) (action (diff oracle get_repr_at__instead_of__equal_CRepr.smt2.res))) (rule (action (with-stdout-to many_distinct.smt2.res (run %{bin:colibri2} --max-step 1000 %{dep:many_distinct.smt2})))) diff --git a/src_colibri2/tests/solve/smt_uf/unsat/fundef.smt2 b/src_colibri2/tests/solve/smt_uf/unsat/fundef.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..99ba9585229d92cf32a438d296d60c3bc51ab324 --- /dev/null +++ b/src_colibri2/tests/solve/smt_uf/unsat/fundef.smt2 @@ -0,0 +1,7 @@ +(set-logic ALL) + +(define-fun foo ((x Int)) Bool (= x 1)) + +(assert (foo 0)) + +(check-sat)