diff --git a/src/backend/Backend_intf.ml b/src/backend/Backend_intf.ml
index 29900a0c..b83b5acb 100644
--- a/src/backend/Backend_intf.ml
+++ b/src/backend/Backend_intf.ml
@@ -17,10 +17,12 @@ module type S = sig
according to the conventions of a given format.
*)
+ type store
+
type t
(** The type of proofs. *)
- val pp : Format.formatter -> t -> unit
+ val pp : store -> Format.formatter -> t -> unit
(** A function for printing proofs in the desired format. *)
end
diff --git a/src/backend/Dot.ml b/src/backend/Dot.ml
index 7085fc86..e8f2f8e1 100644
--- a/src/backend/Dot.ml
+++ b/src/backend/Dot.ml
@@ -13,17 +13,18 @@ module type Arg = sig
type atom
(* Type of atoms *)
+ type store
type hyp
type lemma
type assumption
(** Types for hypotheses, lemmas, and assumptions. *)
- val print_atom : Format.formatter -> atom -> unit
+ val print_atom : store -> Format.formatter -> atom -> unit
(** Printing function for atoms *)
- val hyp_info : hyp -> string * string option * (Format.formatter -> unit -> unit) list
- val lemma_info : lemma -> string * string option * (Format.formatter -> unit -> unit) list
- val assumption_info : assumption -> string * string option * (Format.formatter -> unit -> unit) list
+ val hyp_info : store -> hyp -> string * string option * (Format.formatter -> unit -> unit) list
+ val lemma_info : store -> lemma -> string * string option * (Format.formatter -> unit -> unit) list
+ val assumption_info : store -> assumption -> string * string option * (Format.formatter -> unit -> unit) list
(** Functions to return information about hypotheses and lemmas *)
end
@@ -32,19 +33,20 @@ module Default(S : Sidekick_sat.S) = struct
module Atom = S.Atom
module Clause = S.Clause
- let print_atom = Atom.pp
+ type store = S.solver
+ let print_atom = S.Atom.pp
- let hyp_info c =
+ let hyp_info store c =
"hypothesis", Some "LIGHTBLUE",
- [ fun fmt () -> Format.fprintf fmt "%s" @@ Clause.short_name c]
+ [ fun fmt () -> Format.fprintf fmt "%s" @@ S.Clause.short_name store c]
- let lemma_info c =
+ let lemma_info store c =
"lemma", Some "BLUE",
- [ fun fmt () -> Format.fprintf fmt "%s" @@ Clause.short_name c]
+ [ fun fmt () -> Format.fprintf fmt "%s" @@ S.Clause.short_name store c]
- let assumption_info c =
+ let assumption_info store c =
"assumption", Some "PURPLE",
- [ fun fmt () -> Format.fprintf fmt "%s" @@ Clause.short_name c]
+ [ fun fmt () -> Format.fprintf fmt "%s" @@ S.Clause.short_name store c]
end
@@ -52,24 +54,25 @@ end
module Make(S : Sidekick_sat.S)(A : Arg with type atom := S.atom
and type hyp := S.clause
and type lemma := S.clause
+ and type store := S.store
and type assumption := S.clause) = struct
module Atom = S.Atom
module Clause = S.Clause
module P = S.Proof
- let node_id n = Clause.short_name n.P.conclusion
- let proof_id p = node_id (P.expand p)
- let res_nn_id n1 n2 = node_id n1 ^ "_" ^ node_id n2 ^ "_res"
- let res_np_id n1 n2 = node_id n1 ^ "_" ^ proof_id n2 ^ "_res"
+ let node_id store n = S.Clause.short_name store n.P.conclusion
+ let proof_id store p = node_id store (P.expand store p)
+ let res_nn_id store n1 n2 = node_id store n1 ^ "_" ^ node_id store n2 ^ "_res"
+ let res_np_id store n1 n2 = node_id store n1 ^ "_" ^ proof_id store n2 ^ "_res"
- let print_clause fmt c =
- let v = Clause.atoms c in
+ let print_clause store fmt c =
+ let v = S.Clause.atoms_a store c in
if Array.length v = 0 then
Format.fprintf fmt "⊥"
else
let n = Array.length v in
for i = 0 to n - 1 do
- Format.fprintf fmt "%a" A.print_atom v.(i);
+ Format.fprintf fmt "%a" (A.print_atom store) v.(i);
if i < n - 1 then
Format.fprintf fmt ", "
done
@@ -77,21 +80,21 @@ module Make(S : Sidekick_sat.S)(A : Arg with type atom := S.atom
let print_edge fmt i j =
Format.fprintf fmt "%s -> %s;@\n" j i
- let print_edges fmt n =
+ let print_edges store fmt n =
match P.(n.step) with
| P.Hyper_res {P.hr_steps=[];_} -> assert false (* NOTE: should never happen *)
| P.Hyper_res {P.hr_init; hr_steps=((_,p0)::_) as l} ->
- print_edge fmt (res_np_id n p0) (proof_id hr_init);
+ print_edge fmt (res_np_id store n p0) (proof_id store hr_init);
List.iter
- (fun (_,p2) -> print_edge fmt (res_np_id n p2) (proof_id p2))
+ (fun (_,p2) -> print_edge fmt (res_np_id store n p2) (proof_id store p2))
l;
| _ -> ()
let table_options fmt color =
Format.fprintf fmt "BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" BGCOLOR=\"%s\"" color
- let table fmt (c, rule, color, l) =
- Format.fprintf fmt "
| %a |
" print_clause c;
+ let table store fmt (c, rule, color, l) =
+ Format.fprintf fmt "| %a |
" (print_clause store) c;
match l with
| [] ->
Format.fprintf fmt "| %s |
" color rule
@@ -100,92 +103,54 @@ module Make(S : Sidekick_sat.S)(A : Arg with type atom := S.atom
color (List.length l) rule f ();
List.iter (fun f -> Format.fprintf fmt "| %a |
" f ()) r
- let print_dot_node fmt id color c rule rule_color l =
+ let print_dot_node store fmt id color c rule rule_color l =
Format.fprintf fmt "%s [shape=plaintext, label=<>];@\n"
- id table_options color table (c, rule, rule_color, l)
+ id table_options color (table store) (c, rule, rule_color, l)
- let print_dot_res_node fmt id a =
- Format.fprintf fmt "%s [label=<%a>];@\n" id A.print_atom a
+ let print_dot_res_node store fmt id a =
+ Format.fprintf fmt "%s [label=<%a>];@\n" id (A.print_atom store) a
let ttify f c = fun fmt () -> f fmt c
- let print_contents fmt n =
+ let print_contents store fmt n =
match P.(n.step) with
(* Leafs of the proof tree *)
| P.Hypothesis _ ->
- let rule, color, l = A.hyp_info P.(n.conclusion) in
+ let rule, color, l = A.hyp_info store P.(n.conclusion) in
let color = match color with None -> "LIGHTBLUE" | Some c -> c in
- print_dot_node fmt (node_id n) "LIGHTBLUE" P.(n.conclusion) rule color l
+ print_dot_node store fmt (node_id store n) "LIGHTBLUE" P.(n.conclusion) rule color l
| P.Assumption ->
- let rule, color, l = A.assumption_info P.(n.conclusion) in
+ let rule, color, l = A.assumption_info store P.(n.conclusion) in
let color = match color with None -> "LIGHTBLUE" | Some c -> c in
- print_dot_node fmt (node_id n) "LIGHTBLUE" P.(n.conclusion) rule color l
+ print_dot_node store fmt (node_id store n) "LIGHTBLUE" P.(n.conclusion) rule color l
| P.Lemma _ ->
- let rule, color, l = A.lemma_info P.(n.conclusion) in
+ let rule, color, l = A.lemma_info store P.(n.conclusion) in
let color = match color with None -> "YELLOW" | Some c -> c in
- print_dot_node fmt (node_id n) "LIGHTBLUE" P.(n.conclusion) rule color l
+ print_dot_node store fmt (node_id store n) "LIGHTBLUE" P.(n.conclusion) rule color l
(* Tree nodes *)
| P.Duplicate (p, l) ->
- print_dot_node fmt (node_id n) "GREY" P.(n.conclusion) "Duplicate" "GREY"
- ((fun fmt () -> (Format.fprintf fmt "%s" (node_id n))) ::
- List.map (ttify A.print_atom) l);
- print_edge fmt (node_id n) (node_id (P.expand p))
+ print_dot_node store fmt (node_id store n) "GREY" P.(n.conclusion) "Duplicate" "GREY"
+ ((fun fmt () -> (Format.fprintf fmt "%s" (node_id store n))) ::
+ List.map (ttify @@ A.print_atom store) l);
+ print_edge fmt (node_id store n) (node_id store (P.expand store p))
| P.Hyper_res {P.hr_steps=l; _} ->
- print_dot_node fmt (node_id n) "GREY" P.(n.conclusion) "Resolution" "GREY"
- [(fun fmt () -> (Format.fprintf fmt "%s" (node_id n)))];
+ print_dot_node store fmt (node_id store n) "GREY" P.(n.conclusion) "Resolution" "GREY"
+ [(fun fmt () -> (Format.fprintf fmt "%s" (node_id store n)))];
List.iter
(fun (a,p2) ->
- print_dot_res_node fmt (res_np_id n p2) a;
- print_edge fmt (node_id n) (res_np_id n p2))
+ print_dot_res_node store fmt (res_np_id store n p2) a;
+ print_edge fmt (node_id store n) (res_np_id store n p2))
l
- let print_node fmt n =
- print_contents fmt n;
- print_edges fmt n
+ let print_node store fmt n =
+ print_contents store fmt n;
+ print_edges store fmt n
- let pp fmt p =
+ let pp store fmt p =
Format.fprintf fmt "digraph proof {@\n";
- P.fold (fun () -> print_node fmt) () p;
+ P.fold store (fun () -> print_node store fmt) () p;
Format.fprintf fmt "}@."
end
-module Simple(S : Sidekick_sat.S)
- (A : Arg with type atom := S.formula
- and type hyp = S.formula list
- and type lemma := S.lemma
- and type assumption = S.formula) =
- Make(S)(struct
- module Atom = S.Atom
- module Clause = S.Clause
- module P = S.Proof
-
- (* Some helpers *)
- let lit = Atom.formula
-
- let get_assumption c =
- match S.Clause.atoms_l c with
- | [ x ] -> x
- | _ -> assert false
-
- let get_lemma c =
- match P.expand (P.prove c) with
- | {P.step=P.Lemma p;_} -> p
- | _ -> assert false
-
- (* Actual functions *)
- let print_atom fmt a =
- A.print_atom fmt (lit a)
-
- let hyp_info c =
- A.hyp_info (List.map lit (S.Clause.atoms_l c))
-
- let lemma_info c =
- A.lemma_info (get_lemma c)
-
- let assumption_info c =
- A.assumption_info (lit (get_assumption c))
-
- end)
-
diff --git a/src/backend/Dot.mli b/src/backend/Dot.mli
index eecdebaf..11bd9a7d 100644
--- a/src/backend/Dot.mli
+++ b/src/backend/Dot.mli
@@ -28,14 +28,16 @@ module type Arg = sig
type assumption
(** The type of theory-specifi proofs (also called lemmas). *)
- val print_atom : Format.formatter -> atom -> unit
+ type store
+
+ val print_atom : store -> Format.formatter -> atom -> unit
(** Print the contents of the given atomic formulas.
WARNING: this function should take care to escape and/or not output special
reserved characters for the dot format (such as quotes and so on). *)
- val hyp_info : hyp -> string * string option * (Format.formatter -> unit -> unit) list
- val lemma_info : lemma -> string * string option * (Format.formatter -> unit -> unit) list
- val assumption_info : assumption -> string * string option * (Format.formatter -> unit -> unit) list
+ val hyp_info : store -> hyp -> string * string option * (Format.formatter -> unit -> unit) list
+ val lemma_info : store -> lemma -> string * string option * (Format.formatter -> unit -> unit) list
+ val assumption_info : store -> assumption -> string * string option * (Format.formatter -> unit -> unit) list
(** Generate some information about the leafs of the proof tree. Currently this backend
print each lemma/assumption/hypothesis as a single leaf of the proof tree.
These function should return a triplet [(rule, color, l)], such that:
@@ -50,21 +52,16 @@ end
module Default(S : Sidekick_sat.S) : Arg with type atom := S.atom
and type hyp := S.clause
and type lemma := S.clause
+ and type store := S.store
and type assumption := S.clause
(** Provides a reasonnable default to instantiate the [Make] functor, assuming
the original printing functions are compatible with DOT html labels. *)
-module Make(S : Sidekick_sat.S)(A : Arg with type atom := S.atom
- and type hyp := S.clause
- and type lemma := S.clause
- and type assumption := S.clause) : S with type t := S.Proof.t
+module Make(S : Sidekick_sat.S)
+ (A : Arg with type atom := S.atom
+ and type hyp := S.clause
+ and type lemma := S.clause
+ and type store := S.store
+ and type assumption := S.clause)
+ : S with type t := S.Proof.t and type store := S.store
(** Functor for making a module to export proofs to the DOT format. *)
-
-module Simple(S : Sidekick_sat.S)(A : Arg with type atom := S.formula
- and type hyp = S.formula list
- and type lemma := S.lemma
- and type assumption = S.formula) : S with type t := S.Proof.t
-(** Functor for making a module to export proofs to the DOT format.
- The substitution of the hyp type is non-destructive due to a restriction
- of destructive substitutions on earlier versions of ocaml. *)
-
diff --git a/src/backend/dune b/src/backend/dune
index 316c6d7a..93b0e234 100644
--- a/src/backend/dune
+++ b/src/backend/dune
@@ -2,5 +2,6 @@
(name sidekick_backend)
(public_name sidekick.backend)
(synopsis "Proof backends for sidekick")
+ (flags :standard -warn-error -a+8)
(libraries sidekick.sat))
diff --git a/src/core/Sidekick_core.ml b/src/core/Sidekick_core.ml
index e4642fb4..3316679d 100644
--- a/src/core/Sidekick_core.ml
+++ b/src/core/Sidekick_core.ml
@@ -948,6 +948,7 @@ module type SOLVER = sig
theory
(** Helper to create a theory. *)
+ (* TODO: remove? hide? *)
(** {3 Boolean Atoms}
Atoms are the SAT solver's version of our boolean literals
diff --git a/src/msat-solver/Sidekick_msat_solver.ml b/src/msat-solver/Sidekick_msat_solver.ml
index 03963f12..b7f51080 100644
--- a/src/msat-solver/Sidekick_msat_solver.ml
+++ b/src/msat-solver/Sidekick_msat_solver.ml
@@ -516,13 +516,12 @@ module Make(A : ARG)
(** the parametrized SAT Solver *)
module Sat_solver = Sidekick_sat.Make_cdcl_t(Solver_internal)
- module Atom = Sat_solver.Atom
-
module Pre_proof = struct
module SP = Sat_solver.Proof
module SC = Sat_solver.Clause
type t = {
+ solver: Sat_solver.t;
msat: Sat_solver.Proof.t;
tdefs: (term*term) list; (* term definitions *)
p: P.t lazy_t;
@@ -533,7 +532,7 @@ module Make(A : ARG)
let pp_dot =
let module Dot =
Sidekick_backend.Dot.Make(Sat_solver)(Sidekick_backend.Dot.Default(Sat_solver)) in
- let pp out self = Dot.pp out self.msat in
+ let pp out self = Dot.pp (Sat_solver.store self.solver) out self.msat in
Some pp
(* export to proof {!P.t}, translating Msat-level proof ising:
@@ -545,7 +544,7 @@ module Make(A : ARG)
clause [c] under given assumptions (each assm is a lit),
and return [-a1 \/ … \/ -an \/ c], discharging assumptions
*)
- let conv_proof (msat:Sat_solver.Proof.t) (t_defs:_ list) : P.t =
+ let conv_proof (store:Sat_solver.store) (msat:Sat_solver.Proof.t) (t_defs:_ list) : P.t =
let assms = ref [] in
let steps = ref [] in
@@ -558,7 +557,7 @@ module Make(A : ARG)
with Not_found ->
Error.errorf
"msat-solver.pre-proof.to_proof: cannot find proof step with conclusion %a"
- SC.pp (SP.conclusion p)
+ (SC.pp store) (SP.conclusion p)
in
let add_step s = steps := s :: !steps in
@@ -577,10 +576,10 @@ module Make(A : ARG)
(* build conclusion of proof step *)
let tr_atom a : P.lit =
let sign = Sat_solver.Atom.sign a in
- let t = Lit.term (Sat_solver.Atom.formula a) in
+ let t = Lit.term (Sat_solver.Atom.formula store a) in
P.lit_mk sign t
in
- let concl = List.rev_map tr_atom @@ Sat_solver.Clause.atoms_l c in
+ let concl = List.rev_map tr_atom @@ Sat_solver.Clause.atoms_l store c in
(* proof for the node *)
let pr_step : P.t =
@@ -592,7 +591,7 @@ module Make(A : ARG)
let name = Printf.sprintf "a%d" !n_step in
let lit = match concl with
| [l] -> l
- | _ -> Error.errorf "assumption with non-unit clause %a" SC.pp c
+ | _ -> Error.errorf "assumption with non-unit clause %a" (SC.pp store) c
in
incr n_step;
assms := (name, lit) :: !assms;
@@ -611,12 +610,12 @@ module Make(A : ARG)
let proof_init = P.ref_by_name @@ find_proof_name init in
let tr_step (pivot,p') : P.hres_step =
(* unit resolution? *)
- let is_r1_step = Array.length (SC.atoms (SP.conclusion p')) = 1 in
+ let is_r1_step = Iter.length (SC.atoms store (SP.conclusion p')) = 1 in
let proof_p' = P.ref_by_name @@ find_proof_name p' in
if is_r1_step then (
P.r1 proof_p'
) else (
- let pivot = Lit.term (Sat_solver.Atom.formula pivot) in
+ let pivot = Lit.term (Sat_solver.Atom.formula store pivot) in
P.r proof_p' ~pivot
)
in
@@ -630,17 +629,17 @@ module Make(A : ARG)
in
(* this should traverse from the leaves, so that order of [steps] is correct *)
- Sat_solver.Proof.fold tr_node_to_step () msat;
+ Sat_solver.Proof.fold store tr_node_to_step () msat;
let assms = !assms in
(* gather all term definitions *)
let t_defs = CCList.map (fun (c,rhs) -> P.deft c rhs) t_defs in
P.composite_l ~assms (CCList.append t_defs (List.rev !steps))
- let make (msat: Sat_solver.Proof.t) (tdefs: _ list) : t =
- { msat; tdefs; p=lazy (conv_proof msat tdefs) }
+ let make solver (msat: Sat_solver.Proof.t) (tdefs: _ list) : t =
+ { solver; msat; tdefs; p=lazy (conv_proof (Sat_solver.store solver) msat tdefs) }
- let check self = SP.check self.msat
+ let check self = SP.check (Sat_solver.store self.solver) self.msat
let pp_debug out self = P.pp_debug ~sharing:false out (to_proof self)
let output oc (self:t) = P.Quip.output oc (to_proof self)
end
@@ -656,6 +655,12 @@ module Make(A : ARG)
}
type solver = t
+ module Atom = struct
+ include Sat_solver.Atom
+ let pp self out a = pp (Sat_solver.store self.solver) out a
+ let formula self a = formula (Sat_solver.store self.solver) a
+ end
+
module type THEORY = sig
type t
val name : string
@@ -741,7 +746,8 @@ module Make(A : ARG)
let atom = mk_atom_t_ self sub in
(* also map [sub] to this atom in the congruence closure, for propagation *)
let cc = cc self in
- CC.set_as_lit cc (CC.add_term cc sub ) (Sat_solver.Atom.formula atom);
+ let store = Sat_solver.store self.solver in
+ CC.set_as_lit cc (CC.add_term cc sub ) (Sat_solver.Atom.formula store atom);
())
let rec mk_atom_lit self lit : Atom.t * P.t =
@@ -833,8 +839,10 @@ module Make(A : ARG)
let add_clause (self:t) (c:Atom.t IArray.t) (proof:P.t) : unit =
Stat.incr self.count_clause;
- Log.debugf 50 (fun k->k "(@[solver.add-clause@ %a@ :proof %a@])"
- (Util.pp_iarray Atom.pp) c (P.pp_debug ~sharing:false) proof);
+ Log.debugf 50 (fun k->
+ let store = Sat_solver.store self.solver in
+ k "(@[solver.add-clause@ %a@ :proof %a@])"
+ (Util.pp_iarray (Sat_solver.Atom.pp store)) c (P.pp_debug ~sharing:false) proof);
let pb = Profile.begin_ "add-clause" in
Sat_solver.add_clause_a self.solver (c:> Atom.t array) proof;
Profile.exit pb
@@ -927,8 +935,9 @@ module Make(A : ARG)
let proof = lazy (
try
let pr = UNSAT.get_proof () in
- if check then Sat_solver.Proof.check pr;
- Some (Pre_proof.make pr (List.rev self.si.t_defs))
+ let store = Sat_solver.store self.solver in
+ if check then Sat_solver.Proof.check store pr;
+ Some (Pre_proof.make self.solver pr (List.rev self.si.t_defs))
with Sidekick_sat.Solver_intf.No_proof -> None
) in
let unsat_core = lazy (UNSAT.unsat_assumptions ()) in
diff --git a/src/sat/Solver.ml b/src/sat/Solver.ml
index 6d8c22a3..6741fce0 100644
--- a/src/sat/Solver.ml
+++ b/src/sat/Solver.ml
@@ -42,11 +42,11 @@ module Make(Plugin : PLUGIN)
(* ### types ### *)
(* a boolean variable (positive int) *)
- module Var : INT_ID = Mk_int_id()
- type var = Var.t
+ module Var0 : INT_ID = Mk_int_id()
+ type var = Var0.t
(* a signed atom. +v is (v << 1), -v is (v<<1 | 1) *)
- module Atom : sig
+ module Atom0 : sig
include INT_ID
val neg : t -> t
val sign : t -> bool
@@ -65,11 +65,11 @@ module Make(Plugin : PLUGIN)
let[@inline] pa v = (v:var:>int) lsl 1
let of_var = pa
let[@inline] abs a = a land (lnot 1)
- let[@inline] var a = Var.of_int_unsafe (a lsr 1)
+ let[@inline] var a = Var0.of_int_unsafe (a lsr 1)
let[@inline] na v = (((v:var:>int) lsl 1) lor 1)
module Set = Util.Int_set
end
- type atom = Atom.t
+ type atom = Atom0.t
(* TODO: special clause allocator *)
type clause = {
@@ -151,9 +151,10 @@ module Make(Plugin : PLUGIN)
(** iterate on variables *)
let iter_vars self f =
- Vec.iteri (fun i _ -> f (Var.of_int_unsafe i)) self.v_level
+ Vec.iteri (fun i _ -> f (Var0.of_int_unsafe i)) self.v_level
- module Vars = struct
+ module Var = struct
+ include Var0
let[@inline] level self v = Vec.get self.v_level (v:var:>int)
let[@inline] set_level self v l = Vec.set self.v_level (v:var:>int) l
let[@inline] reason self v = Vec.get self.v_reason (v:var:>int)
@@ -169,8 +170,10 @@ module Make(Plugin : PLUGIN)
let[@inline] set_heap_idx self v i = Vec.set self.v_heap_idx (v:var:>int) i
end
- module Atoms = struct
+ module Atom = struct
+ include Atom0
let[@inline] lit self a = Vec.get self.a_form (a:atom:>int)
+ let formula = lit
let[@inline] mark self a = Bitvec.set self.a_seen (a:atom:>int) true
let[@inline] unmark self a = Bitvec.set self.a_seen (a:atom:>int) false
let[@inline] seen self a = Bitvec.get self.a_seen (a:atom:>int)
@@ -178,12 +181,12 @@ module Make(Plugin : PLUGIN)
let[@inline] is_true self a = Bitvec.get self.a_is_true (a:atom:>int)
let[@inline] set_is_true self a b = Bitvec.set self.a_is_true (a:atom:>int) b
- let[@inline] is_false self a = is_true self (Atom.neg a)
+ let[@inline] is_false self a = is_true self (neg a)
let[@inline] has_value self a = is_true self a || is_false self a
- let[@inline] reason self a = Vars.reason self (Atom.var a)
- let[@inline] level self a = Vars.level self (Atom.var a)
- let[@inline] seen_both self a = seen self a && seen self (Atom.neg a)
+ let[@inline] reason self a = Var.reason self (var a)
+ let[@inline] level self a = Var.level self (var a)
+ let[@inline] seen_both self a = seen self a && seen self (neg a)
(*
let[@inline] var a = a.var
@@ -194,7 +197,7 @@ module Make(Plugin : PLUGIN)
let[@inline] sign a = a == abs a
let[@inline] hash a = Hashtbl.hash a.aid
let[@inline] compare a b = compare a.aid b.aid
- let[@inline] reason a = Var.reason a.var
+ let[@inline] reason a = V.reason a.var
let[@inline] id a = a.aid
*)
@@ -214,7 +217,7 @@ module Make(Plugin : PLUGIN)
(* Complete debug printing *)
- let[@inline] pp_sign a = if Atom.sign a then "+" else "-"
+ let[@inline] pp_sign a = if sign a then "+" else "-"
(* print level+reason of assignment *)
let debug_reason out = function
@@ -226,8 +229,8 @@ module Make(Plugin : PLUGIN)
| n, Some (Bcp_lazy _) -> Format.fprintf out "->%d/" n
let pp_level self out a =
- let v = Atom.var a in
- debug_reason out (Vars.level self v, Vars.reason self v)
+ let v = var a in
+ debug_reason out (Var.level self v, Var.reason self v)
let debug_value self out (a:atom) =
if is_true self a then Format.fprintf out "T%a" (pp_level self) a
@@ -236,7 +239,7 @@ module Make(Plugin : PLUGIN)
let debug self out a =
Format.fprintf out "%s%d[%a][atom:@[%a@]]"
- (pp_sign a) (Atom.var a:var:>int) (debug_value self) a
+ (pp_sign a) (var a:var:>int) (debug_value self) a
Formula.pp (lit self a)
let debug_a self out vec =
@@ -285,9 +288,9 @@ module Make(Plugin : PLUGIN)
v, negated
let clear_var (self:t) (v:var) : unit =
- Vars.unmark self v;
- Atoms.unmark self (Atom.pa v);
- Atoms.unmark self (Atom.na v);
+ Var.unmark self v;
+ Atom.unmark self (Atom.pa v);
+ Atom.unmark self (Atom.na v);
()
let alloc_atom (self:t) ?default_pol lit : atom =
@@ -302,7 +305,7 @@ module Make(Plugin : PLUGIN)
let has_value a = is_true a || is_false a
let[@inline] make ?default_pol st lit =
- let var, negated = Var.make ?default_pol st lit in
+ let var, negated = V.make ?default_pol st lit in
match negated with
| Solver_intf.Negated -> var.na
| Solver_intf.Same_sign -> var.pa
@@ -323,7 +326,9 @@ module Make(Plugin : PLUGIN)
*)
end
type store = Store.t
- open Store
+
+ module Atom = Store.Atom
+ module Var = Store.Var
(* FIXME
@@ -361,9 +366,9 @@ module Make(Plugin : PLUGIN)
let empty = make [] (History [])
let[@inline] equal c1 c2 = c1.cid = c2.cid
let[@inline] hash c = Hashtbl.hash c.cid
- let[@inline] atoms c = c.atoms
- let[@inline] atoms_seq c = Iter.of_array c.atoms
- let[@inline] atoms_l c = Array.to_list c.atoms
+ let[@inline] atoms _ c = Iter.of_array c.atoms
+ let[@inline] atoms_a _ c = c.atoms
+ let[@inline] atoms_l _ c = Array.to_list c.atoms
let flag_attached = 0b1
let flag_visited = 0b10
@@ -401,10 +406,10 @@ module Make(Plugin : PLUGIN)
let equal = equal
end)
- let short_name c = Printf.sprintf "%s%d" (kind_of_clause c) c.cid
+ let short_name _store c = Printf.sprintf "%s%d" (kind_of_clause c) c.cid
let pp self fmt c =
Format.fprintf fmt "(cl[%s%d] : %a" (kind_of_clause c) c.cid
- (Store.Atoms.pp_a self) c.atoms
+ (Store.Atom.pp_a self) c.atoms
let debug_premise out = function
| Hyp _ -> Format.fprintf out "hyp"
@@ -419,7 +424,7 @@ module Make(Plugin : PLUGIN)
let debug self out ({atoms=arr; cpremise=cp;_}as c) =
Format.fprintf out
"(@[cl[%s%d]@ {@[%a@]}@ :premise %a@])"
- (kind_of_clause c) c.cid (Store.Atoms.debug_a self) arr debug_premise cp
+ (kind_of_clause c) c.cid (Store.Atom.debug_a self) arr debug_premise cp
end
module Proof = struct
@@ -429,23 +434,24 @@ module Make(Plugin : PLUGIN)
type clause = Clause.t
type formula = Formula.t
type lemma = Plugin.proof
+ type nonrec store = store
let error_res_f msg = Format.kasprintf (fun s -> raise (Resolution_error s)) msg
- let[@inline] clear_var_of_ store (a:atom) = clear_var store (Atom.var a)
+ let[@inline] clear_var_of_ store (a:atom) = Store.clear_var store (Atom.var a)
(* Compute resolution of 2 clauses.
returns [pivots, resulting_atoms] *)
let resolve self (c1:clause) (c2:clause) : atom list * atom list =
(* invariants: only atoms in [c2] are marked, and the pivot is
cleared when traversing [c1] *)
- Array.iter (Atoms.mark self) c2.atoms;
+ Array.iter (Atom.mark self) c2.atoms;
let pivots = ref [] in
let l =
Array.fold_left
(fun l a ->
- if Atoms.seen self a then l
- else if Atoms.seen self (Atom.neg a) then (
+ if Atom.seen self a then l
+ else if Atom.seen self (Atom.neg a) then (
pivots := (Atom.abs a) :: !pivots;
clear_var_of_ self a;
l
@@ -453,7 +459,7 @@ module Make(Plugin : PLUGIN)
[] c1.atoms
in
let l =
- Array.fold_left (fun l a -> if Atoms.seen self a then a::l else l) l c2.atoms
+ Array.fold_left (fun l a -> if Atom.seen self a then a::l else l) l c2.atoms
in
Array.iter (clear_var_of_ self) c2.atoms;
!pivots, l
@@ -463,10 +469,10 @@ module Make(Plugin : PLUGIN)
let res =
Array.fold_left
(fun (dups,l) a ->
- if Atoms.seen self a then (
+ if Atom.seen self a then (
a::dups, l
) else (
- Atoms.mark self a;
+ Atom.mark self a;
dups, a::l
))
([], []) c.atoms
@@ -477,14 +483,14 @@ module Make(Plugin : PLUGIN)
(* do [c1] and [c2] have the same lits, modulo reordering and duplicates? *)
let same_lits self (c1:atom Iter.t) (c2:atom Iter.t): bool =
let subset a b =
- Iter.iter (Atoms.mark self) b;
- let res = Iter.for_all (Atoms.seen self) a in
+ Iter.iter (Atom.mark self) b;
+ let res = Iter.for_all (Atom.seen self) a in
Iter.iter (clear_var_of_ self) b;
res
in
subset c1 c2 && subset c2 c1
- let prove conclusion =
+ let prove _sol conclusion =
match conclusion.cpremise with
| History [] -> assert false
| Empty_premise -> raise Solver_intf.No_proof
@@ -495,27 +501,27 @@ module Make(Plugin : PLUGIN)
if Atom.equal (Atom.neg a) b then acc
else set_atom_proof self b :: acc
in
- assert (Vars.level self (Atom.var a) >= 0);
- match Vars.reason self (Atom.var a) with
+ assert (Var.level self (Atom.var a) >= 0);
+ match Var.reason self (Atom.var a) with
| Some (Bcp c | Bcp_lazy (lazy c)) ->
Log.debugf 5 (fun k->k "(@[proof.analyze.clause@ :atom %a@ :c %a@])"
- (Atoms.debug self) a (Clause.debug self) c);
+ (Atom.debug self) a (Clause.debug self) c);
if Array.length c.atoms = 1 then (
Log.debugf 5 (fun k -> k "(@[proof.analyze.old-reason@ %a@])"
- (Atoms.debug self) a);
+ (Atom.debug self) a);
c
) else (
- assert (Atoms.is_false self a);
+ assert (Atom.is_false self a);
let r = History (c :: (Array.fold_left aux [] c.atoms)) in
let c' = Clause.make_permanent [Atom.neg a] r in
- Vars.set_reason self (Atom.var a) (Some (Bcp c'));
+ Var.set_reason self (Atom.var a) (Some (Bcp c'));
Log.debugf 5
(fun k -> k "(@[proof.analyze.new-reason@ :atom %a@ :c %a@])"
- (Atoms.debug self) a (Clause.debug self) c');
+ (Atom.debug self) a (Clause.debug self) c');
c'
)
| _ ->
- error_res_f "cannot prove atom %a" (Atoms.debug self) a
+ error_res_f "cannot prove atom %a" (Atom.debug self) a
let prove_unsat self conflict =
if Array.length conflict.atoms = 0 then (
@@ -529,8 +535,8 @@ module Make(Plugin : PLUGIN)
)
let prove_atom self a =
- if Atoms.is_true self a &&
- Vars.level self (Atom.var a) = 0 then
+ if Atom.is_true self a &&
+ Var.level self (Atom.var a) = 0 then
Some (set_atom_proof self a)
else
None
@@ -560,14 +566,14 @@ module Make(Plugin : PLUGIN)
Log.debugf 15
(fun k->k "(@[proof.find-pivots@ :init %a@ :l %a@])"
(Clause.debug self) init (Format.pp_print_list (Clause.debug self)) l);
- Array.iter (Atoms.mark self) init.atoms;
+ Array.iter (Atom.mark self) init.atoms;
let steps =
List.map
(fun c ->
let pivot =
match
Iter.of_array c.atoms
- |> Iter.filter (fun a -> Atoms.seen self (Atom.neg a))
+ |> Iter.filter (fun a -> Atom.seen self (Atom.neg a))
|> Iter.to_list
with
| [a] -> a
@@ -575,9 +581,9 @@ module Make(Plugin : PLUGIN)
error_res_f "(@[proof.expand.pivot_missing@ %a@])" (Clause.debug self) c
| pivots ->
error_res_f "(@[proof.expand.multiple_pivots@ %a@ :pivots %a@])"
- (Clause.debug self) c (Atoms.debug_l self) pivots
+ (Clause.debug self) c (Atom.debug_l self) pivots
in
- Array.iter (Atoms.mark self) c.atoms; (* add atoms to result *)
+ Array.iter (Atom.mark self) c.atoms; (* add atoms to result *)
clear_var_of_ self pivot;
Atom.abs pivot, c)
l
@@ -585,7 +591,7 @@ module Make(Plugin : PLUGIN)
(* cleanup *)
let res = ref [] in
let cleanup_a_ a =
- if Atoms.seen self a then (
+ if Atom.seen self a then (
res := a :: !res;
clear_var_of_ self a
)
@@ -594,8 +600,8 @@ module Make(Plugin : PLUGIN)
List.iter (fun c -> Array.iter cleanup_a_ c.atoms) l;
!res, steps
- let expand self conclusion =
- Log.debugf 5 (fun k -> k "(@[sat.proof.expand@ @[%a@]@])" (Clause.debug self) conclusion);
+ let expand store conclusion =
+ Log.debugf 5 (fun k -> k "(@[sat.proof.expand@ @[%a@]@])" (Clause.debug store) conclusion);
match conclusion.cpremise with
| Lemma l ->
{ conclusion; step = Lemma l; }
@@ -604,14 +610,14 @@ module Make(Plugin : PLUGIN)
| Hyp l ->
{ conclusion; step = Hypothesis l; }
| History [] ->
- error_res_f "@[empty history for clause@ %a@]" (Clause.debug self) conclusion
+ error_res_f "@[empty history for clause@ %a@]" (Clause.debug store) conclusion
| History [c] ->
- let duplicates, res = find_dups self c in
- assert (same_lits self (Iter.of_list res) (Clause.atoms_seq conclusion));
+ let duplicates, res = find_dups store c in
+ assert (same_lits store (Iter.of_list res) (Clause.atoms store conclusion));
{ conclusion; step = Duplicate (c, duplicates) }
| History (c :: r) ->
- let res, steps = find_pivots self c r in
- assert (same_lits self (Iter.of_list res) (Clause.atoms_seq conclusion));
+ let res, steps = find_pivots store c r in
+ assert (same_lits store (Iter.of_list res) (Clause.atoms store conclusion));
{ conclusion; step = Hyper_res {hr_init=c; hr_steps=steps}; }
| Empty_premise -> raise Solver_intf.No_proof
@@ -721,9 +727,9 @@ module Make(Plugin : PLUGIN)
type t = var
open Store
let[@inline] cmp store i j =
- Vars.weight store j < Vars.weight store i (* comparison by weight *)
- let heap_idx = Vars.heap_idx
- let set_heap_idx = Vars.set_heap_idx
+ Var.weight store j < Var.weight store i (* comparison by weight *)
+ let heap_idx = Var.heap_idx
+ let set_heap_idx = Var.set_heap_idx
end)
(* cause of "unsat", possibly conditional to local assumptions *)
@@ -892,11 +898,11 @@ module Make(Plugin : PLUGIN)
(* create a new atom, pushing it into the decision queue if needed *)
let make_atom (self:t) ?default_pol (p:formula) : atom =
let a = Store.alloc_atom self.store ?default_pol p in
- if Atoms.level self.store a < 0 then (
+ if Atom.level self.store a < 0 then (
insert_var_order self (Atom.var a);
(match self.on_new_atom with Some f -> f a | None -> ());
) else (
- assert (Atoms.is_true self.store a || Atoms.is_false self.store a);
+ assert (Atom.is_true self.store a || Atom.is_false self.store a);
);
a
@@ -912,11 +918,11 @@ module Make(Plugin : PLUGIN)
(* increase activity of [v] *)
let var_bump_activity self v =
let store = self.store in
- Vars.set_weight store v (Vars.weight store v +. self.var_incr);
- if Vars.weight store v > 1e100 then (
+ Var.set_weight store v (Var.weight store v +. self.var_incr);
+ if Var.weight store v > 1e100 then (
Store.iter_vars store
(fun v ->
- Vars.set_weight store v (Vars.weight store v *. 1e-100));
+ Var.set_weight store v (Var.weight store v *. 1e-100));
self.var_incr <- self.var_incr *. 1e-100;
);
if H.in_heap self.order v then (
@@ -955,15 +961,15 @@ module Make(Plugin : PLUGIN)
let duplicates = ref [] in
let res = ref [] in
Array.iter (fun a ->
- if Atoms.seen store a then duplicates := a :: !duplicates
+ if Atom.seen store a then duplicates := a :: !duplicates
else (
- Atoms.mark store a;
+ Atom.mark store a;
res := a :: !res
))
clause.atoms;
List.iter
(fun a ->
- if Atoms.seen_both store a then trivial := true;
+ if Atom.seen_both store a then trivial := true;
Store.clear_var store (Atom.var a))
!res;
if !trivial then (
@@ -987,20 +993,20 @@ module Make(Plugin : PLUGIN)
trues @ unassigned @ falses, history
) else (
let a = atoms.(i) in
- if Atoms.is_true store a then (
- let l = Atoms.level store a in
+ if Atom.is_true store a then (
+ let l = Atom.level store a in
if l = 0 then
- raise_notrace Trivial (* A var true at level 0 gives a trivially true clause *)
+ raise_notrace Trivial (* Atom var true at level 0 gives a trivially true clause *)
else
(a :: trues) @ unassigned @ falses @
(arr_to_list atoms (i + 1)), history
- ) else if Atoms.is_false store a then (
- let l = Atoms.level store a in
+ ) else if Atom.is_false store a then (
+ let l = Atom.level store a in
if l = 0 then (
- match Atoms.reason store a with
+ match Atom.reason store a with
| Some (Bcp cl | Bcp_lazy (lazy cl)) ->
partition_aux trues unassigned falses (cl :: history) (i + 1)
- (* A var false at level 0 can be eliminated from the clause,
+ (* Atom var false at level 0 can be eliminated from the clause,
but we need to kepp in mind that we used another clause to simplify it. *)
(* TODO: get a proof of the propagation. *)
| None | Some Decision -> assert false
@@ -1033,7 +1039,7 @@ module Make(Plugin : PLUGIN)
(* Attach/Detach a clause.
- A clause is attached (to its watching lits) when it is first added,
+ Atom clause is attached (to its watching lits) when it is first added,
either because it is assumed or learnt.
*)
@@ -1041,8 +1047,8 @@ module Make(Plugin : PLUGIN)
let store = self.store in
assert (not @@ Clause.attached c);
Log.debugf 20 (fun k -> k "(@[sat.attach-clause@ %a@])" (Clause.debug store) c);
- Vec.push (Atoms.watched store (Atom.neg c.atoms.(0))) c;
- Vec.push (Atoms.watched store (Atom.neg c.atoms.(1))) c;
+ Vec.push (Atom.watched store (Atom.neg c.atoms.(0))) c;
+ Vec.push (Atom.watched store (Atom.neg c.atoms.(1))) c;
Clause.set_attached c true;
()
@@ -1066,11 +1072,11 @@ module Make(Plugin : PLUGIN)
(i.e to the right of elt_head in the queue. *)
for c = self.elt_head to Vec.size self.trail - 1 do
let a = Vec.get self.trail c in
- (* A literal is unassigned, we nedd to add it back to
+ (* Atom literal is unassigned, we nedd to add it back to
the heap of potentially assignable literals, unless it has
a level lower than [lvl], in which case we just move it back. *)
- (* A variable is not true/false anymore, one of two things can happen: *)
- if Atoms.level store a <= lvl then (
+ (* Atom variable is not true/false anymore, one of two things can happen: *)
+ if Atom.level store a <= lvl then (
(* It is a late propagation, which has a level
lower than where we backtrack, so we just move it to the head
of the queue, to be propagated again. *)
@@ -1080,10 +1086,10 @@ module Make(Plugin : PLUGIN)
(* it is a result of bolean propagation, or a semantic propagation
with a level higher than the level to which we backtrack,
in that case, we simply unset its value and reinsert it into the heap. *)
- Atoms.set_is_true store a false;
- Atoms.set_is_true store (Atom.neg a) false;
- Vars.set_level store (Atom.var a) (-1);
- Vars.set_reason store (Atom.var a) None;
+ Atom.set_is_true store a false;
+ Atom.set_is_true store (Atom.neg a) false;
+ Var.set_level store (Atom.var a) (-1);
+ Var.set_reason store (Atom.var a) None;
insert_var_order self (Atom.var a)
)
done;
@@ -1101,7 +1107,7 @@ module Make(Plugin : PLUGIN)
let pp_unsat_cause self out = function
| US_local {first=_; core} ->
Format.fprintf out "(@[unsat-cause@ :false-assumptions %a@])"
- (Format.pp_print_list (Atoms.pp self.store)) core
+ (Format.pp_print_list (Atom.pp self.store)) core
| US_false c ->
Format.fprintf out "(@[unsat-cause@ :false %a@])" (Clause.debug self.store) c
@@ -1149,7 +1155,7 @@ module Make(Plugin : PLUGIN)
Log.debugf 0
(fun k ->
k "(@[sat.simplify-reason.failed@ :at %a@ %a@]"
- (Vec.pp ~sep:"" (Atoms.debug self.store)) (Vec.of_list l)
+ (Vec.pp ~sep:"" (Atom.debug self.store)) (Vec.of_list l)
(Clause.debug self.store) cl);
assert false
end
@@ -1159,25 +1165,25 @@ module Make(Plugin : PLUGIN)
Wrapper function for adding a new propagated formula. *)
let enqueue_bool (self:t) a ~level:lvl reason : unit =
let store = self.store in
- if Atoms.is_false store a then (
+ if Atom.is_false store a then (
Log.debugf 0
- (fun k->k "(@[sat.error.trying to enqueue a false literal %a@])" (Atoms.debug store) a);
+ (fun k->k "(@[sat.error.trying to enqueue a false literal %a@])" (Atom.debug store) a);
assert false
);
- assert (not (Atoms.is_true store a) &&
- Atoms.level store a < 0 &&
- Atoms.reason store a == None && lvl >= 0);
+ assert (not (Atom.is_true store a) &&
+ Atom.level store a < 0 &&
+ Atom.reason store a == None && lvl >= 0);
let reason =
if lvl > 0 then reason
else simpl_reason self reason
in
- Atoms.set_is_true store a true;
- Vars.set_level store (Atom.var a) lvl;
- Vars.set_reason store (Atom.var a) (Some reason);
+ Atom.set_is_true store a true;
+ Var.set_level store (Atom.var a) lvl;
+ Var.set_reason store (Atom.var a) (Some reason);
Vec.push self.trail a;
Log.debugf 20
(fun k->k "(@[sat.enqueue[%d]@ %a@])"
- (Vec.size self.trail) (Atoms.debug store) a);
+ (Vec.size self.trail) (Atom.debug store) a);
()
(* swap elements of array *)
@@ -1192,7 +1198,7 @@ module Make(Plugin : PLUGIN)
let put_high_level_atoms_first (store:store) (arr:atom array) : unit =
Array.iteri
(fun i a ->
- if i>0 && Atoms.level store a > Atoms.level store arr.(0) then (
+ if i>0 && Atom.level store a > Atom.level store arr.(0) then (
(* move first to second, [i]-th to first, second to [i] *)
if i=1 then (
swap_arr arr 0 1;
@@ -1202,7 +1208,7 @@ module Make(Plugin : PLUGIN)
arr.(0) <- arr.(i);
arr.(i) <- tmp;
);
- ) else if i>1 && Atoms.level store a > Atoms.level store arr.(1) then (
+ ) else if i>1 && Atom.level store a > Atom.level store arr.(1) then (
swap_arr arr 1 i;
))
arr
@@ -1218,14 +1224,14 @@ module Make(Plugin : PLUGIN)
) else (
let a = arr.(0) in
let b = arr.(1) in
- assert (Atoms.level store a > 0);
- if Atoms.level store a > Atoms.level store b then (
+ assert (Atom.level store a > 0);
+ if Atom.level store a > Atom.level store b then (
(* backtrack below [a], so we can propagate [not a] *)
- Atoms.level store b, true
+ Atom.level store b, true
) else (
- assert (Atoms.level store a = Atoms.level store b);
- assert (Atoms.level store a >= 0);
- max (Atoms.level store a - 1) 0, false
+ assert (Atom.level store a = Atom.level store b);
+ assert (Atom.level store a >= 0);
+ max (Atom.level store a - 1) 0, false
)
)
@@ -1260,7 +1266,7 @@ module Make(Plugin : PLUGIN)
Vec.clear to_unmark;
let conflict_level =
if Plugin.has_theory
- then Array.fold_left (fun acc p -> max acc (Atoms.level store p)) 0 c_clause.atoms
+ then Array.fold_left (fun acc p -> max acc (Atom.level store p)) 0 c_clause.atoms
else decision_level self
in
Log.debugf 30
@@ -1281,25 +1287,25 @@ module Make(Plugin : PLUGIN)
(* visit the current predecessors *)
for j = 0 to Array.length clause.atoms - 1 do
let q = clause.atoms.(j) in
- assert (Atoms.is_true store q ||
- Atoms.is_false store q &&
- Atoms.level store q >= 0); (* unsure? *)
- if Atoms.level store q <= 0 then (
- assert (Atoms.is_false store q);
- match Atoms.reason store q with
+ assert (Atom.is_true store q ||
+ Atom.is_false store q &&
+ Atom.level store q >= 0); (* unsure? *)
+ if Atom.level store q <= 0 then (
+ assert (Atom.is_false store q);
+ match Atom.reason store q with
| Some (Bcp cl | Bcp_lazy (lazy cl)) -> history := cl :: !history
| Some Decision | None -> assert false
);
- if not (Vars.marked store (Atom.var q)) then (
- Vars.mark store (Atom.var q);
+ if not (Var.marked store (Atom.var q)) then (
+ Var.mark store (Atom.var q);
Vec.push to_unmark (Atom.var q);
- if Atoms.level store q > 0 then (
+ if Atom.level store q > 0 then (
var_bump_activity self (Atom.var q);
- if Atoms.level store q >= conflict_level then (
+ if Atom.level store q >= conflict_level then (
incr pathC;
) else (
learnt := q :: !learnt;
- blevel := max !blevel (Atoms.level store q)
+ blevel := max !blevel (Atom.level store q)
)
)
)
@@ -1310,22 +1316,22 @@ module Make(Plugin : PLUGIN)
while
let a = Vec.get self.trail !tr_ind in
Log.debugf 30
- (fun k -> k "(@[sat.analyze-conflict.at-trail-elt@ %a@])" (Atoms.debug store) a);
- (not (Vars.marked store (Atom.var a))) ||
- (Atoms.level store a < conflict_level)
+ (fun k -> k "(@[sat.analyze-conflict.at-trail-elt@ %a@])" (Atom.debug store) a);
+ (not (Var.marked store (Atom.var a))) ||
+ (Atom.level store a < conflict_level)
do
decr tr_ind;
done;
let p = Vec.get self.trail !tr_ind in
decr pathC;
decr tr_ind;
- match !pathC, Atoms.reason store p with
+ match !pathC, Atom.reason store p with
| 0, _ ->
cond := false;
learnt := Atom.neg p :: List.rev !learnt
| n, Some (Bcp cl | Bcp_lazy (lazy cl)) ->
assert (n > 0);
- assert (Atoms.level store p >= conflict_level);
+ assert (Atom.level store p >= conflict_level);
c := Some cl
| _, (None | Some Decision) -> assert false
done;
@@ -1337,7 +1343,7 @@ module Make(Plugin : PLUGIN)
let a = Array.of_list !learnt in
(* TODO: use a preallocate vec for learnt *)
(* TODO: a sort that doesn't allocate as much, on the vec *)
- Array.fast_sort (fun p q -> compare (Atoms.level store q) (Atoms.level store p)) a;
+ Array.fast_sort (fun p q -> compare (Atom.level store q) (Atom.level store p)) a;
(* put_high_level_atoms_first a; *)
let level, is_uip = backtrack_lvl self a in
{ cr_backtrack_lvl = level;
@@ -1354,7 +1360,7 @@ module Make(Plugin : PLUGIN)
| [| |] -> assert false
| [|fuip|] ->
assert (cr.cr_backtrack_lvl = 0 && decision_level self = 0);
- if Atoms.is_false store fuip then (
+ if Atom.is_false store fuip then (
(* incompatible at level 0 *)
report_unsat self (US_false confl)
) else (
@@ -1387,7 +1393,7 @@ module Make(Plugin : PLUGIN)
self.next_decisions <- [];
assert (decision_level self >= 0);
if decision_level self = 0 ||
- Array.for_all (fun a -> Atoms.level store a <= 0) confl.atoms then (
+ Array.for_all (fun a -> Atom.level store a <= 0) confl.atoms then (
(* Top-level conflict *)
report_unsat self (US_false confl);
);
@@ -1433,31 +1439,31 @@ module Make(Plugin : PLUGIN)
report_unsat self @@ US_false clause
| [a] ->
cancel_until self 0;
- if Atoms.is_false store a then (
+ if Atom.is_false store a then (
(* cannot recover from this *)
report_unsat self @@ US_false clause
- ) else if Atoms.is_true store a then (
+ ) else if Atom.is_true store a then (
() (* atom is already true, nothing to do *)
) else (
Log.debugf 40
- (fun k->k "(@[sat.add-clause.unit-clause@ :propagating %a@])" (Atoms.debug store) a);
+ (fun k->k "(@[sat.add-clause.unit-clause@ :propagating %a@])" (Atom.debug store) a);
add_clause_to_vec self clause;
enqueue_bool self a ~level:0 (Bcp clause)
)
| a::b::_ ->
add_clause_to_vec self clause;
- if Atoms.is_false store a then (
- (* Atoms need to be sorted in decreasing order of decision level,
+ if Atom.is_false store a then (
+ (* Atom need to be sorted in decreasing order of decision level,
or we might watch the wrong literals. *)
put_high_level_atoms_first store clause.atoms;
attach_clause self clause;
add_boolean_conflict self clause
) else (
attach_clause self clause;
- if Atoms.is_false store b &&
- not (Atoms.is_true store a) &&
- not (Atoms.is_false store a) then (
- let lvl = List.fold_left (fun m a -> max m (Atoms.level store a)) 0 atoms in
+ if Atom.is_false store b &&
+ not (Atom.is_true store a) &&
+ not (Atom.is_false store a) then (
+ let lvl = List.fold_left (fun m a -> max m (Atom.level store a)) 0 atoms in
cancel_until self lvl;
enqueue_bool self a ~level:lvl (Bcp clause)
)
@@ -1496,25 +1502,25 @@ module Make(Plugin : PLUGIN)
assert (Atom.neg a = atoms.(1))
);
let first = atoms.(0) in
- if Atoms.is_true store first then (
+ if Atom.is_true store first then (
Watch_kept (* true clause, keep it in watched *)
) else (
try (* look for another watch lit *)
for k = 2 to Array.length atoms - 1 do
let ak = atoms.(k) in
- if not (Atoms.is_false store ak) then (
+ if not (Atom.is_false store ak) then (
(* watch lit found: update and exit *)
atoms.(1) <- ak;
atoms.(k) <- Atom.neg a;
(* remove [c] from [a.watched], add it to [ak.neg.watched] *)
- Vec.push (Atoms.watched store (Atom.neg ak)) c;
- assert (Vec.get (Atoms.watched store a) i == c);
- Vec.fast_remove (Atoms.watched store a) i;
+ Vec.push (Atom.watched store (Atom.neg ak)) c;
+ assert (Vec.get (Atom.watched store a) i == c);
+ Vec.fast_remove (Atom.watched store a) i;
raise_notrace Exit
)
done;
(* no watch lit found *)
- if Atoms.is_false store first then (
+ if Atom.is_false store first then (
(* clause is false *)
self.elt_head <- Vec.size self.trail;
raise_notrace (Conflict c)
@@ -1532,7 +1538,7 @@ module Make(Plugin : PLUGIN)
@param res the optional conflict clause that the propagation might trigger *)
let propagate_atom (self:t) a : unit =
let store = self.store in
- let watched = Atoms.watched store a in
+ let watched = Atom.watched store a in
let rec aux i =
if i >= Vec.size watched then ()
else (
@@ -1568,8 +1574,8 @@ module Make(Plugin : PLUGIN)
let store = self.store in
let a = make_atom self f in
let a = if sign then a else Atom.neg a in
- if not (Atoms.has_value store a) then (
- Log.debugf 10 (fun k->k "(@[sat.th.add-decision-lit@ %a@])" (Atoms.debug store) a);
+ if not (Atom.has_value store a) then (
+ Log.debugf 10 (fun k->k "(@[sat.th.add-decision-lit@ %a@])" (Atom.debug store) a);
self.next_decisions <- a :: self.next_decisions
)
@@ -1583,11 +1589,11 @@ module Make(Plugin : PLUGIN)
let check_consequence_lits_false_ self l : unit =
let store = self.store in
- match List.find (Atoms.is_true store) l with
+ match List.find (Atom.is_true store) l with
| a ->
invalid_argf
"slice.acts_propagate:@ Consequence should contain only true literals, but %a isn't"
- (Atoms.debug store) (Atom.neg a)
+ (Atom.debug store) (Atom.neg a)
| exception Not_found -> ()
let acts_propagate (self:t) f expl =
@@ -1595,8 +1601,8 @@ module Make(Plugin : PLUGIN)
match expl with
| Solver_intf.Consequence mk_expl ->
let p = make_atom self f in
- if Atoms.is_true store p then ()
- else if Atoms.is_false store p then (
+ if Atom.is_true store p then ()
+ else if Atom.is_false store p then (
let lits, proof = mk_expl() in
let l = List.rev_map (fun f -> Atom.neg @@ make_atom self f) lits in
check_consequence_lits_false_ self l;
@@ -1623,12 +1629,12 @@ module Make(Plugin : PLUGIN)
let[@specialise] acts_iter self ~full head f : unit =
for i = (if full then 0 else head) to Vec.size self.trail-1 do
let a = Vec.get self.trail i in
- f (Atoms.lit self.store a);
+ f (Atom.lit self.store a);
done
let eval_atom_ self a =
- if Atoms.is_true self.store a then Solver_intf.L_true
- else if Atoms.is_false self.store a then Solver_intf.L_false
+ if Atom.is_true self.store a then Solver_intf.L_true
+ else if Atom.is_false self.store a then Solver_intf.L_false
else Solver_intf.L_undefined
let[@inline] acts_eval_lit self (f:formula) : Solver_intf.lbool =
@@ -1669,7 +1675,7 @@ module Make(Plugin : PLUGIN)
(* Assert that the conflict is indeeed a conflict *)
let check_is_conflict_ self (c:Clause.t) : unit =
- if not @@ Array.for_all (Atoms.is_false self.store) c.atoms then (
+ if not @@ Array.for_all (Atom.is_false self.store) c.atoms then (
invalid_argf "conflict should be false: %a" (Clause.debug self.store) c
)
@@ -1718,33 +1724,33 @@ module Make(Plugin : PLUGIN)
(* compute unsat core from assumption [a] *)
let analyze_final (self:t) (a:atom) : atom list =
let store = self.store in
- Log.debugf 5 (fun k->k "(@[sat.analyze-final@ :lit %a@])" (Atoms.debug store) a);
- assert (Atoms.is_false store a);
+ Log.debugf 5 (fun k->k "(@[sat.analyze-final@ :lit %a@])" (Atom.debug store) a);
+ assert (Atom.is_false store a);
let core = ref [a] in
let idx = ref (Vec.size self.trail - 1) in
- Vars.mark store (Atom.var a);
+ Var.mark store (Atom.var a);
let seen = ref [Atom.var a] in
while !idx >= 0 do
let a' = Vec.get self.trail !idx in
- if Vars.marked store (Atom.var a') then (
- match Atoms.reason store a' with
+ if Var.marked store (Atom.var a') then (
+ match Atom.reason store a' with
| Some Decision -> core := a' :: !core
| Some (Bcp c | Bcp_lazy (lazy c)) ->
Array.iter
(fun a ->
let v = Atom.var a in
- if not (Vars.marked store v) then (
+ if not (Var.marked store v) then (
seen := v :: !seen;
- Vars.mark store v;
+ Var.mark store v;
))
c.atoms
| None -> ()
);
decr idx
done;
- List.iter (Vars.unmark store) !seen;
+ List.iter (Var.unmark store) !seen;
Log.debugf 5 (fun k->k "(@[sat.analyze-final.done@ :core %a@])"
- (Format.pp_print_list (Atoms.debug store)) !core);
+ (Format.pp_print_list (Atom.debug store)) !core);
!core
(* remove some learnt clauses. *)
@@ -1768,9 +1774,9 @@ module Make(Plugin : PLUGIN)
(* Decide on a new literal, and enqueue it into the trail *)
let rec pick_branch_aux self atom : unit =
let v = Atom.var atom in
- if Vars.level self.store v >= 0 then (
- assert (Atoms.is_true self.store (Atom.pa v) ||
- Atoms.is_true self.store (Atom.na v));
+ if Var.level self.store v >= 0 then (
+ assert (Atom.is_true self.store (Atom.pa v) ||
+ Atom.is_true self.store (Atom.na v));
pick_branch_lit self
) else (
new_decision_level self;
@@ -1787,10 +1793,10 @@ module Make(Plugin : PLUGIN)
| [] when decision_level self < Vec.size self.assumptions ->
(* use an assumption *)
let a = Vec.get self.assumptions (decision_level self) in
- if Atoms.is_true self.store a then (
+ if Atom.is_true self.store a then (
new_decision_level self; (* pseudo decision level, [a] is already true *)
pick_branch_lit self
- ) else if Atoms.is_false self.store a then (
+ ) else if Atom.is_false self.store a then (
(* root conflict, find unsat core *)
let core = analyze_final self a in
raise (E_unsat (US_local {first=a; core}))
@@ -1801,7 +1807,7 @@ module Make(Plugin : PLUGIN)
begin match H.remove_min self.order with
| v ->
pick_branch_aux self
- (if Vars.default_pol self.store v then Atom.pa v else Atom.na v)
+ (if Var.default_pol self.store v then Atom.pa v else Atom.na v)
| exception Not_found -> raise_notrace E_sat
end
@@ -1845,11 +1851,11 @@ module Make(Plugin : PLUGIN)
done
let eval_level (self:t) (a:atom) =
- let lvl = Atoms.level self.store a in
- if Atoms.is_true self.store a then (
+ let lvl = Atom.level self.store a in
+ if Atom.is_true self.store a then (
assert (lvl >= 0);
true, lvl
- ) else if Atoms.is_false self.store a then (
+ ) else if Atom.is_false self.store a then (
false, lvl
) else (
raise UndecidedLit
@@ -1914,7 +1920,7 @@ module Make(Plugin : PLUGIN)
(* Check satisfiability *)
let check_clause self c =
- let res = Array.exists (Atoms.is_true self.store) c.atoms in
+ let res = Array.exists (Atom.is_true self.store) c.atoms in
if not res then (
Log.debugf 30
(fun k -> k "(@[sat.check-clause@ :not-satisfied @[%a@]@])"
@@ -1930,6 +1936,7 @@ module Make(Plugin : PLUGIN)
check_vec self self.clauses_learnt
let[@inline] theory st = st.th
+ let[@inline] store st = st.store
(* Unsafe access to internal data *)
@@ -1950,7 +1957,7 @@ module Make(Plugin : PLUGIN)
"(@[sat.full-state :res %s - Full summary:@,@[Trail:@\n%a@]@,\
@[Hyps:@\n%a@]@,@[Lemmas:@\n%a@]@,@]@."
status
- (Vec.pp ~sep:"" @@ Atoms.debug self.store) (trail self)
+ (Vec.pp ~sep:"" @@ Atom.debug self.store) (trail self)
(Vec.pp ~sep:"" @@ Clause.debug self.store) (hyps self)
(Vec.pp ~sep:"" @@ Clause.debug self.store) (history self)
)
@@ -1960,7 +1967,7 @@ module Make(Plugin : PLUGIN)
let t = trail self in
let module M = struct
type formula = Formula.t
- let iter_trail f = Vec.iter (fun a -> f (Atoms.lit self.store a)) t
+ let iter_trail f = Vec.iter (fun a -> f (Atom.lit self.store a)) t
let[@inline] eval f = eval self (make_atom self f)
let[@inline] eval_level f = eval_level self (make_atom self f)
end in
@@ -1979,7 +1986,7 @@ module Make(Plugin : PLUGIN)
let c = lazy (
let core = List.rev core in (* increasing trail order *)
assert (Atom.equal first @@ List.hd core);
- let proof_of (a:atom) = match Atoms.reason self.store a with
+ let proof_of (a:atom) = match Atom.reason self.store a with
| Some Decision -> Clause.make_removable [a] Local
| Some (Bcp c | Bcp_lazy (lazy c)) -> c
| None -> assert false
@@ -1993,9 +2000,9 @@ module Make(Plugin : PLUGIN)
) in
fun () -> Lazy.force c
in
- let get_proof () =
+ let get_proof () : Proof.t =
let c = unsat_conflict () in
- Proof.prove c
+ Proof.prove self.store c
in
let module M = struct
type nonrec atom = atom
@@ -2040,13 +2047,6 @@ module Make(Plugin : PLUGIN)
with UndecidedLit -> false
let[@inline] eval_atom self a : Solver_intf.lbool = eval_atom_ self a
-
-
- module Atom = struct
- include Atom
- let pp self out a = Atoms.pp self.store out a
- let formula self a = Atoms.lit self.store a
- end
end
[@@inline][@@specialise]
diff --git a/src/sat/Solver_intf.ml b/src/sat/Solver_intf.ml
index 0277b952..ca2f140c 100644
--- a/src/sat/Solver_intf.ml
+++ b/src/sat/Solver_intf.ml
@@ -63,6 +63,7 @@ type negated =
(** This type is used during the normalisation of formulas.
See {!val:Expr_intf.S.norm} for more details. *)
+(** The type of reasons for propagations of a formula [f]. *)
type ('formula, 'proof) reason =
| Consequence of (unit -> 'formula list * 'proof) [@@unboxed]
(** [Consequence (l, p)] means that the formulas in [l] imply the propagated
@@ -83,7 +84,6 @@ type ('formula, 'proof) reason =
propagating, and then use [Consequence (fun () -> expl, proof)] with
the already produced [(expl,proof)] tuple.
*)
-(** The type of reasons for propagations of a formula [f]. *)
type lbool = L_true | L_false | L_undefined
(** Valuation of an atom *)
@@ -206,6 +206,8 @@ module type PROOF = sig
type clause
(** Abstract types for atoms, clauses and theory-specific lemmas *)
+ type store
+
type t
(** Lazy type for proof trees. Proofs are persistent objects, and can be
extended to proof nodes using functions defined later. *)
@@ -236,18 +238,18 @@ module type PROOF = sig
(** {3 Proof building functions} *)
- val prove : clause -> t
+ val prove : store -> clause -> t
(** Given a clause, return a proof of that clause.
@raise Resolution_error if it does not succeed. *)
- val prove_unsat : clause -> t
+ val prove_unsat : store -> clause -> t
(** Given a conflict clause [c], returns a proof of the empty clause.
@raise Resolution_error if it does not succeed. *)
- val prove_atom : atom -> t option
+ val prove_atom : store -> atom -> t option
(** Given an atom [a], returns a proof of the clause [[a]] if [a] is true at level 0 *)
- val res_of_hyper_res : hyper_res_step -> t * t * atom
+ val res_of_hyper_res : store -> hyper_res_step -> t * t * atom
(** Turn an hyper resolution step into a resolution step.
The conclusion can be deduced by performing a resolution between the conclusions
of the two given proofs.
@@ -271,13 +273,13 @@ module type PROOF = sig
(** {3 Proof Manipulation} *)
- val expand : t -> proof_node
+ val expand : store -> t -> proof_node
(** Return the proof step at the root of a given proof. *)
val conclusion : t -> clause
(** What is proved at the root of the clause *)
- val fold : ('a -> proof_node -> 'a) -> 'a -> t -> 'a
+ val fold : store -> ('a -> proof_node -> 'a) -> 'a -> t -> 'a
(** [fold f acc p], fold [f] over the proof [p] and all its node. It is guaranteed that
[f] is executed exactly once on each proof node in the tree, and that the execution of
[f] on a proof node happens after the execution on the parents of the nodes. *)
@@ -290,11 +292,11 @@ module type PROOF = sig
(** {3 Misc} *)
- val check_empty_conclusion : t -> unit
+ val check_empty_conclusion : store -> t -> unit
(** Check that the proof's conclusion is the empty clause,
@raise Resolution_error otherwise *)
- val check : t -> unit
+ val check : store -> t -> unit
(** Check the contents of a proof. Mainly for internal use. *)
module Tbl : Hashtbl.S with type key = t
@@ -325,6 +327,8 @@ module type S = sig
type solver
+ type store
+
(* TODO: keep this internal *)
module Atom : sig
type t = atom
@@ -336,21 +340,32 @@ module type S = sig
val sign : t -> bool
val abs : t -> t
- val formula : solver -> t -> formula
- val pp : solver -> t printer
+ val pp : store -> t printer
+ (** Print the atom *)
+
+ val formula : store -> t -> formula
+ (** Get back the formula for this atom *)
end
module Clause : sig
type t = clause
val equal : t -> t -> bool
- val atoms : solver -> t -> atom array
- val atoms_l : solver -> t -> atom list
-
- val pp : solver -> t printer
- val short_name : t -> string
-
module Tbl : Hashtbl.S with type key = t
+
+ val pp : store -> t printer
+ (** Print the clause *)
+
+ val short_name : store -> t -> string
+ (** Short name for a clause. Unspecified *)
+
+ val atoms : store -> t -> atom Iter.t
+ (** Atoms of a clause *)
+
+ val atoms_a : store -> t -> atom array
+
+ val atoms_l : store -> t -> atom list
+ (** List of atoms of a clause *)
end
module Proof : PROOF
@@ -358,6 +373,7 @@ module type S = sig
and type atom = atom
and type formula = formula
and type lemma = lemma
+ and type store = store
(** A module to manipulate proofs. *)
type t = solver
@@ -381,6 +397,9 @@ module type S = sig
val theory : t -> theory
(** Access the theory state *)
+ val store : t -> store
+ (** Store for the solver *)
+
(** {2 Types} *)
(** Result type for the solver *)
@@ -412,10 +431,12 @@ module type S = sig
The assumptions are just used for this call to [solve], they are
not saved in the solver's state. *)
- val make_atom : t -> formula -> atom
+ val make_atom : t -> ?default_pol:bool -> formula -> atom
(** Add a new atom (i.e propositional formula) to the solver.
This formula will be decided on at some point during solving,
- wether it appears in clauses or not. *)
+ wether it appears in clauses or not.
+ @param default_pol default polarity of the boolean variable.
+ Default is [true]. *)
val true_at_level0 : t -> atom -> bool
(** [true_at_level0 a] returns [true] if [a] was proved at level0, i.e.
diff --git a/src/sat/dune b/src/sat/dune
index 25a4c2cf..8b762d67 100644
--- a/src/sat/dune
+++ b/src/sat/dune
@@ -4,7 +4,7 @@
(public_name sidekick.sat)
(libraries iter sidekick.util)
(synopsis "Pure OCaml SAT solver implementation for sidekick")
- (flags :standard -open Sidekick_util)
+ (flags :standard -warn-error -a+8 -open Sidekick_util)
(ocamlopt_flags :standard -O3 -bin-annot
-unbox-closures -unbox-closures-factor 20)
)
diff --git a/src/util/Bitvec.ml b/src/util/Bitvec.ml
index ab861ea7..0c043858 100644
--- a/src/util/Bitvec.ml
+++ b/src/util/Bitvec.ml
@@ -1,7 +1,4 @@
-module I32Vec = Vec
-type i32vec = int Vec.t
-
type t = {
mutable chunks: bytes; (* TODO: use a in32vec with bigarray *)
}
@@ -10,7 +7,6 @@ let create () : t = {
chunks = Bytes.make 32 '\x00';
}
-let n_bits_ = 8
let i2c = Char.chr
let c2i = Char.code
diff --git a/src/util/dune b/src/util/dune
index 584dcca7..800a53c7 100644
--- a/src/util/dune
+++ b/src/util/dune
@@ -1,4 +1,5 @@
(library
(name sidekick_util)
(public_name sidekick.util)
+ (flags :standard -warn-error -a+8)
(libraries containers iter sidekick.sigs))