mirror of
https://github.com/c-cube/sidekick.git
synced 2026-01-28 20:34:53 -05:00
refactor: use 1st class for theory actions
This commit is contained in:
parent
edeb28c8ad
commit
47ddce5960
8 changed files with 153 additions and 115 deletions
|
|
@ -1345,23 +1345,33 @@ module Make (Th : Theory_intf.S) = struct
|
||||||
(Util.pp_list Atom.debug) l
|
(Util.pp_list Atom.debug) l
|
||||||
)
|
)
|
||||||
|
|
||||||
let current_slice st head = Theory_intf.Slice_acts {
|
let current_slice st head : formula Theory_intf.slice_actions =
|
||||||
slice_iter = slice_iter st head (Vec.size st.trail);
|
let module A = struct
|
||||||
}
|
type form = formula
|
||||||
|
let slice_iter = slice_iter st head (Vec.size st.trail)
|
||||||
|
end in
|
||||||
|
(module A)
|
||||||
|
|
||||||
(* full slice, for [if_sat] final check *)
|
(* full slice, for [if_sat] final check *)
|
||||||
let full_slice st = Theory_intf.Slice_acts {
|
let full_slice st : formula Theory_intf.slice_actions =
|
||||||
slice_iter = slice_iter st 0 (Vec.size st.trail);
|
let module A = struct
|
||||||
}
|
type form = formula
|
||||||
|
let slice_iter = slice_iter st 0 (Vec.size st.trail)
|
||||||
|
end in
|
||||||
|
(module A)
|
||||||
|
|
||||||
let act_at_level_0 st () = at_level_0 st
|
let act_at_level_0 st () = at_level_0 st
|
||||||
|
|
||||||
let actions st = Theory_intf.Actions {
|
let actions st: (formula,lemma) Theory_intf.actions =
|
||||||
push_persistent = act_push_persistent st;
|
let module A = struct
|
||||||
push_local = act_push_local st;
|
type nonrec formula = formula
|
||||||
on_backtrack = on_backtrack st;
|
type proof = lemma
|
||||||
propagate = act_propagate st;
|
let push_persistent = act_push_persistent st
|
||||||
}
|
let push_local = act_push_local st
|
||||||
|
let on_backtrack = on_backtrack st
|
||||||
|
let propagate = act_propagate st
|
||||||
|
end in
|
||||||
|
(module A)
|
||||||
|
|
||||||
let create ?(size=`Big) () : t =
|
let create ?(size=`Big) () : t =
|
||||||
let size_map, size_vars, size_trail, size_lvl = match size with
|
let size_map, size_vars, size_trail, size_lvl = match size with
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,8 @@ type 'clause export = 'clause Solver_intf.export = {
|
||||||
clauses : 'clause Vec.t;
|
clauses : 'clause Vec.t;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ('form, 'proof) actions = ('form,'proof) Theory_intf.actions = Actions of {
|
type ('form, 'proof) actions = ('form,'proof) Theory_intf.actions
|
||||||
push_persistent : 'form IArray.t -> 'proof -> unit;
|
type 'form slice_actions = 'form Theory_intf.slice_actions
|
||||||
push_local : 'form IArray.t -> 'proof -> unit;
|
|
||||||
on_backtrack: (unit -> unit) -> unit;
|
|
||||||
propagate : 'form -> 'form list -> 'proof -> unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ('form, 'proof) slice_actions = ('form, 'proof) Theory_intf.slice_actions = Slice_acts of {
|
|
||||||
slice_iter : ('form -> unit) -> unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
module Make = Solver.Make
|
module Make = Solver.Make
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,30 +39,40 @@ type ('formula, 'proof) res =
|
||||||
theory tautology (with its proof), for which every literal is false
|
theory tautology (with its proof), for which every literal is false
|
||||||
under the current assumptions. *)
|
under the current assumptions. *)
|
||||||
|
|
||||||
(** Actions given to the theory during initialization, to be used
|
module type ACTIONS = sig
|
||||||
at any time *)
|
type formula
|
||||||
type ('form, 'proof) actions = Actions of {
|
type proof
|
||||||
push_persistent : 'form IArray.t -> 'proof -> unit;
|
|
||||||
|
val push_persistent : formula IArray.t -> proof -> unit
|
||||||
(** Allows to add a persistent clause to the solver. *)
|
(** Allows to add a persistent clause to the solver. *)
|
||||||
|
|
||||||
push_local : 'form IArray.t -> 'proof -> unit;
|
val push_local : formula IArray.t -> proof -> unit
|
||||||
(** Allows to add a local clause to the solver. The clause
|
(** Allows to add a local clause to the solver. The clause
|
||||||
will be removed after backtracking. *)
|
will be removed after backtracking. *)
|
||||||
|
|
||||||
on_backtrack: (unit -> unit) -> unit;
|
val on_backtrack: (unit -> unit) -> unit
|
||||||
(** [on_backtrack f] calls [f] when the main solver backtracks *)
|
(** [on_backtrack f] calls [f] when the main solver backtracks *)
|
||||||
|
|
||||||
propagate : 'form -> 'form list -> 'proof -> unit;
|
val propagate : formula -> formula list -> proof -> unit
|
||||||
(** [propagate lit causes proof] informs the solver to propagate [lit], with the reason
|
(** [propagate lit causes proof] informs the solver to propagate [lit], with the reason
|
||||||
that the clause [causes => lit] is a theory tautology. It is faster than pushing
|
that the clause [causes => lit] is a theory tautology. It is faster than pushing
|
||||||
the associated clause but the clause will not be remembered by the sat solver,
|
the associated clause but the clause will not be remembered by the sat solver,
|
||||||
i.e it will not be used by the solver to do boolean propagation. *)
|
i.e it will not be used by the solver to do boolean propagation. *)
|
||||||
}
|
end
|
||||||
|
|
||||||
type ('form, 'proof) slice_actions = Slice_acts of {
|
(** Actions given to the theory during initialization, to be used
|
||||||
slice_iter : ('form -> unit) -> unit;
|
at any time *)
|
||||||
|
type ('form, 'proof) actions =
|
||||||
|
(module ACTIONS with type formula = 'form and type proof = 'proof)
|
||||||
|
|
||||||
|
module type SLICE_ACTIONS = sig
|
||||||
|
type form
|
||||||
|
|
||||||
|
val slice_iter : (form -> unit) -> unit
|
||||||
(** iterate on the slice of the trail *)
|
(** iterate on the slice of the trail *)
|
||||||
}
|
end
|
||||||
|
|
||||||
|
type 'form slice_actions = (module SLICE_ACTIONS with type form = 'form)
|
||||||
(** The type for a slice. Slices are some kind of view of the current
|
(** The type for a slice. Slices are some kind of view of the current
|
||||||
propagation queue. They allow to look at the propagated literals,
|
propagation queue. They allow to look at the propagated literals,
|
||||||
and to add new clauses to the solver. *)
|
and to add new clauses to the solver. *)
|
||||||
|
|
@ -110,11 +120,11 @@ module type S = sig
|
||||||
val create : (formula, proof) actions -> t
|
val create : (formula, proof) actions -> t
|
||||||
(** Create a new instance of the theory *)
|
(** Create a new instance of the theory *)
|
||||||
|
|
||||||
val assume : t -> (formula, proof) slice_actions -> (formula, proof) res
|
val assume : t -> formula slice_actions -> (formula, proof) res
|
||||||
(** Assume the formulas in the slice, possibly pushing new formulas to be propagated,
|
(** Assume the formulas in the slice, possibly pushing new formulas to be propagated,
|
||||||
and returns the result of the new assumptions. *)
|
and returns the result of the new assumptions. *)
|
||||||
|
|
||||||
val if_sat : t -> (formula, proof) slice_actions -> (formula, proof) res
|
val if_sat : t -> formula slice_actions -> (formula, proof) res
|
||||||
(** Called at the end of the search in case a model has been found. If no new clause is
|
(** Called at the end of the search in case a model has been found. If no new clause is
|
||||||
pushed, then 'sat' is returned, else search is resumed. *)
|
pushed, then 'sat' is returned, else search is resumed. *)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,21 @@ module Sig_tbl = CCHashtbl.Make(Signature)
|
||||||
type merge_op = node * node * explanation
|
type merge_op = node * node * explanation
|
||||||
(* a merge operation to perform *)
|
(* a merge operation to perform *)
|
||||||
|
|
||||||
type actions = {
|
module type ACTIONS = sig
|
||||||
on_backtrack:(unit -> unit) -> unit;
|
val on_backtrack: (unit -> unit) -> unit
|
||||||
(** Register a callback to be invoked upon backtracking below the current level *)
|
(** Register a callback to be invoked upon backtracking below the current level *)
|
||||||
|
|
||||||
on_merge:repr -> repr -> explanation -> unit;
|
val on_merge: repr -> repr -> explanation -> unit
|
||||||
(** Call this when two classes are merged *)
|
(** Call this when two classes are merged *)
|
||||||
|
|
||||||
raise_conflict: 'a. conflict -> 'a;
|
val raise_conflict: conflict -> 'a
|
||||||
(** Report a conflict *)
|
(** Report a conflict *)
|
||||||
|
|
||||||
propagate: Lit.t -> Lit.t list -> unit;
|
val propagate: Lit.t -> Lit.t list -> unit
|
||||||
(** Propagate a literal *)
|
(** Propagate a literal *)
|
||||||
}
|
end
|
||||||
|
|
||||||
|
type actions = (module ACTIONS)
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
tst: Term.state;
|
tst: Term.state;
|
||||||
|
|
@ -63,7 +65,9 @@ type t = {
|
||||||
several times.
|
several times.
|
||||||
See "fast congruence closure and extensions", Nieuwenhis&al, page 14 *)
|
See "fast congruence closure and extensions", Nieuwenhis&al, page 14 *)
|
||||||
|
|
||||||
let[@inline] on_backtrack cc f : unit = cc.acts.on_backtrack f
|
let[@inline] on_backtrack cc f : unit =
|
||||||
|
let (module A) = cc.acts in
|
||||||
|
A.on_backtrack f
|
||||||
|
|
||||||
let[@inline] is_root_ (n:node) : bool = n.n_root == n
|
let[@inline] is_root_ (n:node) : bool = n.n_root == n
|
||||||
|
|
||||||
|
|
@ -192,7 +196,8 @@ let rec reroot_expl (cc:t) (n:node): unit =
|
||||||
end
|
end
|
||||||
|
|
||||||
let[@inline] raise_conflict (cc:t) (e:conflict): _ =
|
let[@inline] raise_conflict (cc:t) (e:conflict): _ =
|
||||||
cc.acts.raise_conflict e
|
let (module A) = cc.acts in
|
||||||
|
A.raise_conflict e
|
||||||
|
|
||||||
let[@inline] all_classes cc : repr Sequence.t =
|
let[@inline] all_classes cc : repr Sequence.t =
|
||||||
Term.Tbl.values cc.tbl
|
Term.Tbl.values cc.tbl
|
||||||
|
|
@ -482,7 +487,8 @@ and update_combine cc =
|
||||||
Side effect: also pushes sub-tasks *)
|
Side effect: also pushes sub-tasks *)
|
||||||
and notify_merge cc (ra:repr) ~into:(rb:repr) (e:explanation): unit =
|
and notify_merge cc (ra:repr) ~into:(rb:repr) (e:explanation): unit =
|
||||||
assert (is_root_ rb);
|
assert (is_root_ rb);
|
||||||
cc.acts.on_merge ra rb e
|
let (module A) = cc.acts in
|
||||||
|
A.on_merge ra rb e
|
||||||
|
|
||||||
|
|
||||||
(* FIXME: callback?
|
(* FIXME: callback?
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,21 @@ type repr = Equiv_class.t
|
||||||
|
|
||||||
type conflict = Theory.conflict
|
type conflict = Theory.conflict
|
||||||
|
|
||||||
type actions = {
|
module type ACTIONS = sig
|
||||||
on_backtrack:(unit -> unit) -> unit;
|
val on_backtrack: (unit -> unit) -> unit
|
||||||
(** Register a callback to be invoked upon backtracking below the current level *)
|
(** Register a callback to be invoked upon backtracking below the current level *)
|
||||||
|
|
||||||
on_merge:repr -> repr -> explanation -> unit;
|
val on_merge: repr -> repr -> explanation -> unit
|
||||||
(** Call this when two classes are merged *)
|
(** Call this when two classes are merged *)
|
||||||
|
|
||||||
raise_conflict: 'a. conflict -> 'a;
|
val raise_conflict: conflict -> 'a
|
||||||
(** Report a conflict *)
|
(** Report a conflict *)
|
||||||
|
|
||||||
propagate: Lit.t -> Lit.t list -> unit;
|
val propagate: Lit.t -> Lit.t list -> unit
|
||||||
(** Propagate a literal *)
|
(** Propagate a literal *)
|
||||||
}
|
end
|
||||||
|
|
||||||
|
type actions = (module ACTIONS)
|
||||||
|
|
||||||
val create :
|
val create :
|
||||||
?size:int ->
|
?size:int ->
|
||||||
|
|
|
||||||
|
|
@ -14,58 +14,65 @@ end = struct
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Runtime state of a theory, with all the operations it provides.
|
module type STATE = sig
|
||||||
['a] is the internal state *)
|
type t
|
||||||
type state = State : {
|
|
||||||
mutable st: 'a;
|
val state : t
|
||||||
on_merge: 'a -> Equiv_class.t -> Equiv_class.t -> Explanation.t -> unit;
|
|
||||||
|
val on_merge: t -> Equiv_class.t -> Equiv_class.t -> Explanation.t -> unit
|
||||||
(** Called when two classes are merged *)
|
(** Called when two classes are merged *)
|
||||||
|
|
||||||
on_assert: 'a -> Lit.t -> unit;
|
val on_assert: t -> Lit.t -> unit
|
||||||
(** Called when a literal becomes true *)
|
(** Called when a literal becomes true *)
|
||||||
|
|
||||||
final_check: 'a -> Lit.t Sequence.t -> unit;
|
val final_check: t -> Lit.t Sequence.t -> unit
|
||||||
(** Final check, must be complete (i.e. must raise a conflict
|
(** Final check, must be complete (i.e. must raise a conflict
|
||||||
if the set of literals is not satisfiable) *)
|
if the set of literals is not satisfiable) *)
|
||||||
} -> state
|
end
|
||||||
|
|
||||||
|
|
||||||
|
(** Runtime state of a theory, with all the operations it provides. *)
|
||||||
|
type state = (module STATE)
|
||||||
|
|
||||||
(** Unsatisfiable conjunction.
|
(** Unsatisfiable conjunction.
|
||||||
Its negation will become a conflict clause *)
|
Its negation will become a conflict clause *)
|
||||||
type conflict = Lit.t list
|
type conflict = Lit.t list
|
||||||
|
|
||||||
(** Actions available to a theory during its lifetime *)
|
(** Actions available to a theory during its lifetime *)
|
||||||
type actions = {
|
module type ACTIONS = sig
|
||||||
on_backtrack: (unit -> unit) -> unit;
|
val on_backtrack: (unit -> unit) -> unit
|
||||||
(** Register an action to do when we backtrack *)
|
(** Register an action to do when we backtrack *)
|
||||||
|
|
||||||
raise_conflict: 'a. conflict -> 'a;
|
val raise_conflict: conflict -> 'a
|
||||||
(** Give a conflict clause to the solver *)
|
(** Give a conflict clause to the solver *)
|
||||||
|
|
||||||
propagate_eq: Term.t -> Term.t -> Lit.t list -> unit;
|
val propagate_eq: Term.t -> Term.t -> Lit.t list -> unit
|
||||||
(** Propagate an equality [t = u] because [e] *)
|
(** Propagate an equality [t = u] because [e] *)
|
||||||
|
|
||||||
propagate_distinct: Term.t list -> neq:Term.t -> Lit.t -> unit;
|
val propagate_distinct: Term.t list -> neq:Term.t -> Lit.t -> unit
|
||||||
(** Propagate a [distinct l] because [e] (where [e = neq] *)
|
(** Propagate a [distinct l] because [e] (where [e = neq] *)
|
||||||
|
|
||||||
propagate: Lit.t -> Lit.t list -> unit;
|
val propagate: Lit.t -> Lit.t list -> unit
|
||||||
(** Propagate a boolean using a unit clause.
|
(** Propagate a boolean using a unit clause.
|
||||||
[expl => lit] must be a theory lemma, that is, a T-tautology *)
|
[expl => lit] must be a theory lemma, that is, a T-tautology *)
|
||||||
|
|
||||||
add_local_axiom: Lit.t IArray.t -> unit;
|
val add_local_axiom: Lit.t IArray.t -> unit
|
||||||
(** Add local clause to the SAT solver. This clause will be
|
(** Add local clause to the SAT solver. This clause will be
|
||||||
removed when the solver backtracks. *)
|
removed when the solver backtracks. *)
|
||||||
|
|
||||||
add_persistent_axiom: Lit.t IArray.t -> unit;
|
val add_persistent_axiom: Lit.t IArray.t -> unit
|
||||||
(** Add toplevel clause to the SAT solver. This clause will
|
(** Add toplevel clause to the SAT solver. This clause will
|
||||||
not be backtracked. *)
|
not be backtracked. *)
|
||||||
|
|
||||||
find: Term.t -> Equiv_class.t;
|
val find: Term.t -> Equiv_class.t
|
||||||
(** Find representative of this term *)
|
(** Find representative of this term *)
|
||||||
|
|
||||||
all_classes: Equiv_class.t Sequence.t;
|
val all_classes: Equiv_class.t Sequence.t
|
||||||
(** All current equivalence classes
|
(** All current equivalence classes
|
||||||
(caution: linear in the number of terms existing in the solver) *)
|
(caution: linear in the number of terms existing in the solver) *)
|
||||||
}
|
end
|
||||||
|
|
||||||
|
type actions = (module ACTIONS)
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -75,9 +82,17 @@ type t = {
|
||||||
let make ~name ~make () : t = {name;make}
|
let make ~name ~make () : t = {name;make}
|
||||||
|
|
||||||
let make_st
|
let make_st
|
||||||
|
(type st)
|
||||||
?(on_merge=fun _ _ _ _ -> ())
|
?(on_merge=fun _ _ _ _ -> ())
|
||||||
?(on_assert=fun _ _ -> ())
|
?(on_assert=fun _ _ -> ())
|
||||||
~final_check
|
~final_check
|
||||||
~st
|
~st
|
||||||
() : state =
|
() : state =
|
||||||
State { st; on_merge; on_assert; final_check }
|
let module A = struct
|
||||||
|
type nonrec t = st
|
||||||
|
let state = st
|
||||||
|
let on_merge = on_merge
|
||||||
|
let on_assert = on_assert
|
||||||
|
let final_check = final_check
|
||||||
|
end in
|
||||||
|
(module A : STATE)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ let assume_lit (self:t) (lit:Lit.t) : unit =
|
||||||
| Lit_atom _ ->
|
| Lit_atom _ ->
|
||||||
(* transmit to theories. *)
|
(* transmit to theories. *)
|
||||||
Congruence_closure.assert_lit (cc self) lit;
|
Congruence_closure.assert_lit (cc self) lit;
|
||||||
theories self (fun (Theory.State th) -> th.on_assert th.st lit);
|
theories self (fun (module Th) -> Th.on_assert Th.state lit);
|
||||||
end
|
end
|
||||||
|
|
||||||
(* return result to the SAT solver *)
|
(* return result to the SAT solver *)
|
||||||
|
|
@ -84,13 +84,13 @@ let with_conflict_catch self f =
|
||||||
cdcl_return_res self
|
cdcl_return_res self
|
||||||
|
|
||||||
(* propagation from the bool solver *)
|
(* propagation from the bool solver *)
|
||||||
let assume_real (self:t) (slice:_ Sat_solver.slice_actions) =
|
let assume_real (self:t) (slice:Lit.t Sat_solver.slice_actions) =
|
||||||
(* TODO if Config.progress then print_progress(); *)
|
(* TODO if Config.progress then print_progress(); *)
|
||||||
let Sat_solver.Slice_acts slice = slice in
|
let (module SA) = slice in
|
||||||
Log.debugf 5 (fun k->k "(th_combine.assume :len %d)" (Sequence.length slice.slice_iter));
|
Log.debugf 5 (fun k->k "(th_combine.assume :len %d)" (Sequence.length @@ SA.slice_iter));
|
||||||
with_conflict_catch self
|
with_conflict_catch self
|
||||||
(fun () ->
|
(fun () ->
|
||||||
slice.slice_iter (assume_lit self);
|
SA.slice_iter (assume_lit self);
|
||||||
(* now check satisfiability *)
|
(* now check satisfiability *)
|
||||||
check self
|
check self
|
||||||
)
|
)
|
||||||
|
|
@ -104,28 +104,28 @@ let assume (self:t) (slice:_ Sat_solver.slice_actions) =
|
||||||
cdcl_return_res self
|
cdcl_return_res self
|
||||||
|
|
||||||
(* perform final check of the model *)
|
(* perform final check of the model *)
|
||||||
let if_sat (self:t) (slice:_) : _ Sat_solver.res =
|
let if_sat (self:t) (slice:Lit.t Sat_solver.slice_actions) : _ Sat_solver.res =
|
||||||
Congruence_closure.final_check (cc self);
|
Congruence_closure.final_check (cc self);
|
||||||
(* all formulas in the SAT solver's trail *)
|
(* all formulas in the SAT solver's trail *)
|
||||||
let forms =
|
let forms =
|
||||||
let Sat_solver.Slice_acts r = slice in
|
let (module SA) = slice in
|
||||||
r.slice_iter
|
SA.slice_iter
|
||||||
in
|
in
|
||||||
(* final check for each theory *)
|
(* final check for each theory *)
|
||||||
with_conflict_catch self
|
with_conflict_catch self
|
||||||
(fun () ->
|
(fun () ->
|
||||||
theories self
|
theories self
|
||||||
(fun (Theory.State th) -> th.final_check th.st forms))
|
(fun (module Th) -> Th.final_check Th.state forms))
|
||||||
|
|
||||||
(** {2 Various helpers} *)
|
(** {2 Various helpers} *)
|
||||||
|
|
||||||
(* forward propagations from CC or theories directly to the SMT core *)
|
(* forward propagations from CC or theories directly to the SMT core *)
|
||||||
let act_propagate (self:t) f guard : unit =
|
let act_propagate (self:t) f guard : unit =
|
||||||
let Sat_solver.Actions r = self.cdcl_acts in
|
let (module A) = self.cdcl_acts in
|
||||||
Sat_solver.Log.debugf 2
|
Sat_solver.Log.debugf 2
|
||||||
(fun k->k "(@[@{<green>propagate@}@ %a@ :guard %a@])"
|
(fun k->k "(@[@{<green>propagate@}@ %a@ :guard %a@])"
|
||||||
Lit.pp f (Util.pp_list Lit.pp) guard);
|
Lit.pp f (Util.pp_list Lit.pp) guard);
|
||||||
r.propagate f guard Proof.default
|
A.propagate f guard Proof.default
|
||||||
|
|
||||||
(** {2 Interface to Congruence Closure} *)
|
(** {2 Interface to Congruence Closure} *)
|
||||||
|
|
||||||
|
|
@ -134,16 +134,17 @@ let act_raise_conflict e = raise (Exn_conflict e)
|
||||||
(* when CC decided to merge [r1] and [r2], notify theories *)
|
(* when CC decided to merge [r1] and [r2], notify theories *)
|
||||||
let on_merge_from_cc (self:t) r1 r2 e : unit =
|
let on_merge_from_cc (self:t) r1 r2 e : unit =
|
||||||
theories self
|
theories self
|
||||||
(fun (Theory.State th) -> th.on_merge th.st r1 r2 e)
|
(fun (module Th) -> Th.on_merge Th.state r1 r2 e)
|
||||||
|
|
||||||
let mk_cc_actions (self:t) : Congruence_closure.actions =
|
let mk_cc_actions (self:t) : Congruence_closure.actions =
|
||||||
let Sat_solver.Actions r = self.cdcl_acts in
|
let (module A) = self.cdcl_acts in
|
||||||
{ Congruence_closure.
|
let module R = struct
|
||||||
on_backtrack = r.on_backtrack;
|
let on_backtrack = A.on_backtrack
|
||||||
on_merge = on_merge_from_cc self;
|
let on_merge = on_merge_from_cc self
|
||||||
raise_conflict = act_raise_conflict;
|
let raise_conflict = act_raise_conflict
|
||||||
propagate = act_propagate self;
|
let propagate = act_propagate self
|
||||||
}
|
end in
|
||||||
|
(module R)
|
||||||
|
|
||||||
(** {2 Main} *)
|
(** {2 Main} *)
|
||||||
|
|
||||||
|
|
@ -180,29 +181,30 @@ let act_find self t =
|
||||||
|
|
||||||
let act_add_local_axiom self c : unit =
|
let act_add_local_axiom self c : unit =
|
||||||
Sat_solver.Log.debugf 5 (fun k->k "(@[<2>th_combine.push_local_lemma@ %a@])" Theory.Clause.pp c);
|
Sat_solver.Log.debugf 5 (fun k->k "(@[<2>th_combine.push_local_lemma@ %a@])" Theory.Clause.pp c);
|
||||||
let Sat_solver.Actions r = self.cdcl_acts in
|
let (module A) = self.cdcl_acts in
|
||||||
r.push_local c Proof.default
|
A.push_local c Proof.default
|
||||||
|
|
||||||
(* push one clause into [M], in the current level (not a lemma but
|
(* push one clause into [M], in the current level (not a lemma but
|
||||||
an axiom) *)
|
an axiom) *)
|
||||||
let act_add_persistent_axiom self c : unit =
|
let act_add_persistent_axiom self c : unit =
|
||||||
Sat_solver.Log.debugf 5 (fun k->k "(@[<2>th_combine.push_persistent_lemma@ %a@])" Theory.Clause.pp c);
|
Sat_solver.Log.debugf 5 (fun k->k "(@[<2>th_combine.push_persistent_lemma@ %a@])" Theory.Clause.pp c);
|
||||||
let Sat_solver.Actions r = self.cdcl_acts in
|
let (module A) = self.cdcl_acts in
|
||||||
r.push_persistent c Proof.default
|
A.push_persistent c Proof.default
|
||||||
|
|
||||||
let mk_theory_actions (self:t) : Theory.actions =
|
let mk_theory_actions (self:t) : Theory.actions =
|
||||||
let Sat_solver.Actions r = self.cdcl_acts in
|
let (module A) = self.cdcl_acts in
|
||||||
{ Theory.
|
let module R = struct
|
||||||
on_backtrack = r.on_backtrack;
|
let on_backtrack = A.on_backtrack
|
||||||
raise_conflict = act_raise_conflict;
|
let raise_conflict = act_raise_conflict
|
||||||
propagate = act_propagate self;
|
let propagate = act_propagate self
|
||||||
all_classes = act_all_classes self;
|
let all_classes = act_all_classes self
|
||||||
propagate_eq = act_propagate_eq self;
|
let propagate_eq = act_propagate_eq self
|
||||||
propagate_distinct = act_propagate_distinct self;
|
let propagate_distinct = act_propagate_distinct self
|
||||||
add_local_axiom = act_add_local_axiom self;
|
let add_local_axiom = act_add_local_axiom self
|
||||||
add_persistent_axiom = act_add_persistent_axiom self;
|
let add_persistent_axiom = act_add_persistent_axiom self
|
||||||
find = act_find self;
|
let find = act_find self
|
||||||
}
|
end
|
||||||
|
in (module R)
|
||||||
|
|
||||||
let add_theory (self:t) (th:Theory.t) : unit =
|
let add_theory (self:t) (th:Theory.t) : unit =
|
||||||
Sat_solver.Log.debugf 2
|
Sat_solver.Log.debugf 2
|
||||||
|
|
|
||||||
|
|
@ -251,17 +251,18 @@ type t = {
|
||||||
|
|
||||||
let tseitin (self:t) (lit:Lit.t) (lit_t:term) (b:term builtin) : unit =
|
let tseitin (self:t) (lit:Lit.t) (lit_t:term) (b:term builtin) : unit =
|
||||||
Log.debugf 5 (fun k->k "(@[th_bool.tseitin@ %a@])" Lit.pp lit);
|
Log.debugf 5 (fun k->k "(@[th_bool.tseitin@ %a@])" Lit.pp lit);
|
||||||
|
let (module A) = self.acts in
|
||||||
match b with
|
match b with
|
||||||
| B_not _ -> assert false (* normalized *)
|
| B_not _ -> assert false (* normalized *)
|
||||||
| B_eq (t,u) ->
|
| B_eq (t,u) ->
|
||||||
if Lit.sign lit then (
|
if Lit.sign lit then (
|
||||||
self.acts.Theory.propagate_eq t u [lit]
|
A.propagate_eq t u [lit]
|
||||||
) else (
|
) else (
|
||||||
self.acts.Theory.propagate_distinct [t;u] ~neq:lit_t lit
|
A.propagate_distinct [t;u] ~neq:lit_t lit
|
||||||
)
|
)
|
||||||
| B_distinct l ->
|
| B_distinct l ->
|
||||||
if Lit.sign lit then (
|
if Lit.sign lit then (
|
||||||
self.acts.Theory.propagate_distinct l ~neq:lit_t lit
|
A.propagate_distinct l ~neq:lit_t lit
|
||||||
) else (
|
) else (
|
||||||
(* TODO: propagate pairwise equalities? *)
|
(* TODO: propagate pairwise equalities? *)
|
||||||
Error.errorf "cannot process negative distinct lit %a" Lit.pp lit;
|
Error.errorf "cannot process negative distinct lit %a" Lit.pp lit;
|
||||||
|
|
@ -272,39 +273,39 @@ let tseitin (self:t) (lit:Lit.t) (lit_t:term) (b:term builtin) : unit =
|
||||||
List.iter
|
List.iter
|
||||||
(fun sub ->
|
(fun sub ->
|
||||||
let sublit = Lit.atom sub in
|
let sublit = Lit.atom sub in
|
||||||
self.acts.Theory.propagate sublit [lit])
|
A.propagate sublit [lit])
|
||||||
subs
|
subs
|
||||||
) else (
|
) else (
|
||||||
(* propagate [¬lit => ∨_i ¬ subs_i] *)
|
(* propagate [¬lit => ∨_i ¬ subs_i] *)
|
||||||
let c = Lit.neg lit :: List.map (Lit.atom ~sign:false) subs in
|
let c = Lit.neg lit :: List.map (Lit.atom ~sign:false) subs in
|
||||||
self.acts.Theory.add_local_axiom (IArray.of_list c)
|
A.add_local_axiom (IArray.of_list c)
|
||||||
)
|
)
|
||||||
| B_or subs ->
|
| B_or subs ->
|
||||||
if Lit.sign lit then (
|
if Lit.sign lit then (
|
||||||
(* propagate [lit => ∨_i subs_i] *)
|
(* propagate [lit => ∨_i subs_i] *)
|
||||||
let c = Lit.neg lit :: List.map (Lit.atom ~sign:true) subs in
|
let c = Lit.neg lit :: List.map (Lit.atom ~sign:true) subs in
|
||||||
self.acts.Theory.add_local_axiom (IArray.of_list c)
|
A.add_local_axiom (IArray.of_list c)
|
||||||
) else (
|
) else (
|
||||||
(* propagate [¬lit => ¬subs_i] *)
|
(* propagate [¬lit => ¬subs_i] *)
|
||||||
List.iter
|
List.iter
|
||||||
(fun sub ->
|
(fun sub ->
|
||||||
let sublit = Lit.atom ~sign:false sub in
|
let sublit = Lit.atom ~sign:false sub in
|
||||||
self.acts.Theory.propagate sublit [lit])
|
A.propagate sublit [lit])
|
||||||
subs
|
subs
|
||||||
)
|
)
|
||||||
| B_imply (guard,concl) ->
|
| B_imply (guard,concl) ->
|
||||||
if Lit.sign lit then (
|
if Lit.sign lit then (
|
||||||
(* propagate [lit => ∨_i ¬guard_i ∨ concl] *)
|
(* propagate [lit => ∨_i ¬guard_i ∨ concl] *)
|
||||||
let c = Lit.atom concl :: Lit.neg lit :: List.map (Lit.atom ~sign:false) guard in
|
let c = Lit.atom concl :: Lit.neg lit :: List.map (Lit.atom ~sign:false) guard in
|
||||||
self.acts.Theory.add_local_axiom (IArray.of_list c)
|
A.add_local_axiom (IArray.of_list c)
|
||||||
) else (
|
) else (
|
||||||
(* propagate [¬lit => ¬concl] *)
|
(* propagate [¬lit => ¬concl] *)
|
||||||
self.acts.Theory.propagate (Lit.atom ~sign:false concl) [lit];
|
A.propagate (Lit.atom ~sign:false concl) [lit];
|
||||||
(* propagate [¬lit => ∧_i guard_i] *)
|
(* propagate [¬lit => ∧_i guard_i] *)
|
||||||
List.iter
|
List.iter
|
||||||
(fun sub ->
|
(fun sub ->
|
||||||
let sublit = Lit.atom ~sign:true sub in
|
let sublit = Lit.atom ~sign:true sub in
|
||||||
self.acts.Theory.propagate sublit [lit])
|
A.propagate sublit [lit])
|
||||||
guard
|
guard
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue