mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 03:05:31 -05:00
Added uninterpreted functions to mcsat solver
This commit is contained in:
parent
4fae86c81d
commit
1656995097
5 changed files with 93 additions and 10 deletions
|
|
@ -494,7 +494,8 @@ module Make
|
||||||
l.assigned <- Some value;
|
l.assigned <- Some value;
|
||||||
l.l_level <- lvl;
|
l.l_level <- lvl;
|
||||||
Vec.push env.elt_queue (of_lit l);
|
Vec.push env.elt_queue (of_lit l);
|
||||||
()
|
Log.debugf 20 "Enqueue (%d): %a"
|
||||||
|
(fun k -> k (Vec.size env.elt_queue) pp_lit l)
|
||||||
|
|
||||||
(* evaluate an atom for MCsat, if it's not assigned
|
(* evaluate an atom for MCsat, if it's not assigned
|
||||||
by boolean propagation/decision *)
|
by boolean propagation/decision *)
|
||||||
|
|
|
||||||
|
|
@ -282,14 +282,14 @@ module McMake (E : Expr_intf.S)(Dummy : sig end) = struct
|
||||||
|
|
||||||
let pp_assign out = function
|
let pp_assign out = function
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some t -> Format.fprintf out " ->@ %a" E.Term.print t
|
| Some t -> Format.fprintf out " ->@ @[<hov>%a@]" E.Term.print t
|
||||||
|
|
||||||
let pp_lit out v =
|
let pp_lit out v =
|
||||||
Format.fprintf out "%d [lit:%a%a]"
|
Format.fprintf out "%d [lit:@[<hov>%a%a@]]"
|
||||||
(v.lid+1) E.Term.print v.term pp_assign v.assigned
|
(v.lid+1) E.Term.print v.term pp_assign v.assigned
|
||||||
|
|
||||||
let pp_atom out a =
|
let pp_atom out a =
|
||||||
Format.fprintf out "%s%d%s[atom:%a]@ "
|
Format.fprintf out "%s%d%s[atom:@[<hov>%a@]]@ "
|
||||||
(sign a) (a.var.vid+1) (value a) E.Formula.print a.lit
|
(sign a) (a.var.vid+1) (value a) E.Formula.print a.lit
|
||||||
|
|
||||||
let pp_atoms_vec out vec =
|
let pp_atoms_vec out vec =
|
||||||
|
|
|
||||||
|
|
@ -189,9 +189,12 @@ let () =
|
||||||
exit 4
|
exit 4
|
||||||
| Type_sat.Typing_error (msg, t)
|
| Type_sat.Typing_error (msg, t)
|
||||||
| Type_smt.Typing_error (msg, t) ->
|
| Type_smt.Typing_error (msg, t) ->
|
||||||
|
let b = Printexc.get_backtrace () in
|
||||||
let loc = match t.Dolmen.Term.loc with
|
let loc = match t.Dolmen.Term.loc with
|
||||||
| Some l -> l | None -> Dolmen.ParseLocation.mk "<>" 0 0 0 0
|
| Some l -> l | None -> Dolmen.ParseLocation.mk "<>" 0 0 0 0
|
||||||
in
|
in
|
||||||
Format.fprintf Format.std_formatter "While typing:@\n%a@\n%a: typing error\n%s@."
|
Format.fprintf Format.std_formatter "While typing:@\n%a@\n%a: typing error\n%s@."
|
||||||
Dolmen.Term.print t Dolmen.ParseLocation.fmt loc msg
|
Dolmen.Term.print t Dolmen.ParseLocation.fmt loc msg;
|
||||||
|
if Printexc.backtrace_status () then
|
||||||
|
Format.fprintf Format.std_formatter "%s@." b
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,16 @@
|
||||||
|
|
||||||
module E = Eclosure.Make(Expr_smt.Term)
|
module E = Eclosure.Make(Expr_smt.Term)
|
||||||
module H = Backtrack.Hashtbl(Expr_smt.Term)
|
module H = Backtrack.Hashtbl(Expr_smt.Term)
|
||||||
|
module M = Hashtbl.Make(Expr_smt.Term)
|
||||||
|
|
||||||
(* Type definitions *)
|
(* Type definitions *)
|
||||||
|
|
||||||
type proof = unit
|
type proof = unit
|
||||||
type term = Expr_smt.Term.t
|
type term = Expr_smt.Term.t
|
||||||
type formula = Expr_smt.Atom.t
|
type formula = Expr_smt.Atom.t
|
||||||
|
|
||||||
type level = Backtrack.Stack.level
|
type level = Backtrack.Stack.level
|
||||||
|
|
||||||
|
exception Absurd of Expr_smt.Atom.t list
|
||||||
|
|
||||||
(* Backtracking *)
|
(* Backtracking *)
|
||||||
|
|
||||||
|
|
@ -32,23 +33,97 @@ let assign t =
|
||||||
| _, None -> t
|
| _, None -> t
|
||||||
| _, Some (_, v) -> v
|
| _, Some (_, v) -> v
|
||||||
|
|
||||||
(* Uninterpreted functions and predicates *)
|
(* Propositional constants *)
|
||||||
|
|
||||||
let map = H.create stack
|
|
||||||
|
|
||||||
let true_ = Expr_smt.(Term.of_id (Id.ty "true" Ty.prop))
|
let true_ = Expr_smt.(Term.of_id (Id.ty "true" Ty.prop))
|
||||||
let false_ = Expr_smt.(Term.of_id (Id.ty "false" Ty.prop))
|
let false_ = Expr_smt.(Term.of_id (Id.ty "false" Ty.prop))
|
||||||
|
|
||||||
|
(* Uninterpreted functions and predicates *)
|
||||||
|
|
||||||
|
let map = H.create stack
|
||||||
|
let watch = M.create 4096
|
||||||
|
let interpretation = H.create stack
|
||||||
|
|
||||||
|
let pop_watches t =
|
||||||
|
try
|
||||||
|
let l = M.find watch t in
|
||||||
|
M.remove watch t;
|
||||||
|
l
|
||||||
|
with Not_found ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
let add_job j x =
|
||||||
|
let l = try M.find watch x with Not_found -> [] in
|
||||||
|
M.add watch x (j :: l)
|
||||||
|
|
||||||
|
let update_job x ((t, watchees) as job) =
|
||||||
|
try
|
||||||
|
let y = List.find (fun y -> not (H.mem map y)) watchees in
|
||||||
|
add_job job y
|
||||||
|
with Not_found ->
|
||||||
|
add_job job x;
|
||||||
|
begin match t with
|
||||||
|
| { Expr_smt.term = Expr_smt.App (f, tys, l) } ->
|
||||||
|
let is_prop = Expr_smt.(Ty.equal t.t_type Ty.prop) in
|
||||||
|
let t_v, _ = H.find map t in
|
||||||
|
let l' = List.map (fun x -> fst (H.find map x)) l in
|
||||||
|
let u = Expr_smt.Term.apply f tys l' in
|
||||||
|
begin try
|
||||||
|
let t', u_v = H.find interpretation u in
|
||||||
|
if not (Expr_smt.Term.equal t_v u_v) then begin
|
||||||
|
match t' with
|
||||||
|
| { Expr_smt.term = Expr_smt.App (_, _, r) } when is_prop ->
|
||||||
|
let eqs = List.map2 (fun a b -> Expr_smt.Atom.neg (Expr_smt.Atom.eq a b)) l r in
|
||||||
|
if Expr_smt.(Term.equal u_v true_) then begin
|
||||||
|
let res = Expr_smt.Atom.pred t ::
|
||||||
|
Expr_smt.Atom.neg (Expr_smt.Atom.pred t') :: eqs in
|
||||||
|
raise (Absurd res)
|
||||||
|
end else begin
|
||||||
|
let res = Expr_smt.Atom.pred t' ::
|
||||||
|
Expr_smt.Atom.neg (Expr_smt.Atom.pred t) :: eqs in
|
||||||
|
raise (Absurd res)
|
||||||
|
end
|
||||||
|
| { Expr_smt.term = Expr_smt.App (_, _, r) } ->
|
||||||
|
let eqs = List.map2 (fun a b -> Expr_smt.Atom.neg (Expr_smt.Atom.eq a b)) l r in
|
||||||
|
let res = Expr_smt.Atom.eq t t' :: eqs in
|
||||||
|
raise (Absurd res)
|
||||||
|
| _ -> assert false
|
||||||
|
end
|
||||||
|
with Not_found ->
|
||||||
|
H.add interpretation u (t, t_v);
|
||||||
|
end
|
||||||
|
| _ -> assert false
|
||||||
|
end
|
||||||
|
|
||||||
|
let rec update_watches x = function
|
||||||
|
| [] -> ()
|
||||||
|
| job :: r ->
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
update_job x job;
|
||||||
|
with exn ->
|
||||||
|
List.iter (fun j -> add_job j x) r;
|
||||||
|
raise exn
|
||||||
|
end;
|
||||||
|
update_watches x r
|
||||||
|
|
||||||
|
let add_watch t l =
|
||||||
|
update_job t (t, l)
|
||||||
|
|
||||||
let add_assign t v lvl =
|
let add_assign t v lvl =
|
||||||
H.add map t (v, lvl)
|
H.add map t (v, lvl);
|
||||||
|
update_watches t (pop_watches t)
|
||||||
|
|
||||||
(* Assignemnts *)
|
(* Assignemnts *)
|
||||||
|
|
||||||
let rec iter_aux f = function
|
let rec iter_aux f = function
|
||||||
| { Expr_smt.term = Expr_smt.Var _ } as t ->
|
| { Expr_smt.term = Expr_smt.Var _ } as t ->
|
||||||
|
Log.debugf 10 "Adding %a as assignable" (fun k -> k Expr_smt.Term.print t);
|
||||||
f t
|
f t
|
||||||
| { Expr_smt.term = Expr_smt.App (_, _, l) } as t ->
|
| { Expr_smt.term = Expr_smt.App (_, _, l) } as t ->
|
||||||
|
if l <> [] then add_watch t (t :: l);
|
||||||
List.iter (iter_aux f) l;
|
List.iter (iter_aux f) l;
|
||||||
|
Log.debugf 10 "Adding %a as assignable" (fun k -> k Expr_smt.Term.print t);
|
||||||
f t
|
f t
|
||||||
|
|
||||||
let iter_assignable f = function
|
let iter_assignable f = function
|
||||||
|
|
@ -113,6 +188,8 @@ let assume s =
|
||||||
done;
|
done;
|
||||||
Plugin_intf.Sat
|
Plugin_intf.Sat
|
||||||
with
|
with
|
||||||
|
| Absurd l ->
|
||||||
|
Plugin_intf.Unsat (l, ())
|
||||||
| E.Unsat (a, b, l) ->
|
| E.Unsat (a, b, l) ->
|
||||||
let c = Expr_smt.Atom.eq a b :: List.map Expr_smt.Atom.neg (chain_eq l) in
|
let c = Expr_smt.Atom.eq a b :: List.map Expr_smt.Atom.neg (chain_eq l) in
|
||||||
Plugin_intf.Unsat (c, ())
|
Plugin_intf.Unsat (c, ())
|
||||||
|
|
|
||||||
2
tests/unsat/test-012.smt2
Normal file
2
tests/unsat/test-012.smt2
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
(assert (and (= a b) (not (= (f a) (f b)))))
|
||||||
|
(check-sat)
|
||||||
Loading…
Add table
Reference in a new issue