Solver.Solver_internalInternal solver, available to theories.
module T = Tmodule Lit = Littype ty = T.Ty.ttype term = T.Term.ttype value = T.Term.ttype term_store = T.Term.storetype ty_store = T.Ty.storetype proof = prooftype proof_step = proof_stepmodule P = Ptype solver = tval tst : t -> term_storeval stats : t -> Sidekick_util.Stat.tmodule Registry : Sidekick_core.REGISTRYval registry : t -> Registry.tA solver contains a registry so that theories can share data
type lit = Lit.tmodule CC :
Sidekick_core.CC_S
with module T = T
and module Lit = Lit
and type proof = proof
and type proof_step = proof_step
and type P.t = proof
and type P.lit = lit
and type Actions.t = theory_actionsCongruence closure instance
module Simplify : sig ... endSimplify terms
type simplify_hook = Simplify.hookval add_simplifier : t -> Simplify.hook -> unitAdd a simplifier hook for preprocessing.
val simplify_t : t -> term -> (term * proof_step) optionSimplify input term, returns Some u if some simplification occurred.
val simp_t : t -> term -> term * proof_step optionsimp_t si t returns u even if no simplification occurred (in which case t == u syntactically). It emits |- t=u. (see simplifier)
These preprocessors turn mixed, raw literals (possibly simplified) into literals suitable for reasoning. Typically some clauses are also added to the solver.
module type PREPROCESS_ACTS = sig ... endtype preprocess_actions = (module PREPROCESS_ACTS)Actions available to the preprocessor
type preprocess_hook = t -> preprocess_actions -> term -> unitGiven a term, preprocess it.
The idea is to add literals and clauses to help define the meaning of the term, if needed. For example for boolean formulas, clauses for their Tseitin encoding can be added, with the formula acting as its own proxy symbol.
val on_preprocess : t -> preprocess_hook -> unitAdd a hook that will be called when terms are preprocessed
val raise_conflict : t -> theory_actions -> lit list -> proof_step -> 'aGive a conflict clause to the solver
val push_decision : t -> theory_actions -> lit -> unitAsk the SAT solver to decide the given literal in an extension of the current trail. This is useful for theory combination. If the SAT solver backtracks, this (potential) decision is removed and forgotten.
val propagate :
t ->
theory_actions ->
lit ->
reason:( unit -> lit list * proof_step ) ->
unitPropagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology
val propagate_l : t -> theory_actions -> lit -> lit list -> proof_step -> unitPropagate a boolean using a unit clause. expl => lit must be a theory lemma, that is, a T-tautology
val add_clause_temp : t -> theory_actions -> lit list -> proof_step -> unitAdd local clause to the SAT solver. This clause will be removed when the solver backtracks.
val add_clause_permanent :
t ->
theory_actions ->
lit list ->
proof_step ->
unitAdd toplevel clause to the SAT solver. This clause will not be backtracked.
val mk_lit : t -> theory_actions -> ?sign:bool -> term -> litCreate a literal. This automatically preprocesses the term.
val add_lit : t -> theory_actions -> ?default_pol:bool -> lit -> unitAdd the given literal to the SAT solver, so it gets assigned a boolean value.
val add_lit_t : t -> theory_actions -> ?sign:bool -> term -> unitAdd the given (signed) bool term to the SAT solver, so it gets assigned a boolean value
val cc_raise_conflict_expl : t -> theory_actions -> CC.Expl.t -> 'aRaise a conflict with the given congruence closure explanation. it must be a theory tautology that expl ==> absurd. To be used in theories.
val cc_merge : t -> theory_actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unitMerge these two nodes in the congruence closure, given this explanation. It must be a theory tautology that expl ==> n1 = n2. To be used in theories.
val cc_merge_t : t -> theory_actions -> term -> term -> CC.Expl.t -> unitMerge these two terms in the congruence closure, given this explanation. See cc_merge
Add/retrieve congruence closure node for this term. To be used in theories
Return true if the term is explicitly in the congruence closure. To be used in theories
val on_cc_pre_merge :
t ->
( CC.t -> theory_actions -> CC.N.t -> CC.N.t -> CC.Expl.t -> unit ) ->
unitCallback for when two classes containing data for this key are merged (called before)
val on_cc_post_merge :
t ->
( CC.t -> theory_actions -> CC.N.t -> CC.N.t -> unit ) ->
unitCallback for when two classes containing data for this key are merged (called after)
Callback to add data on terms when they are added to the congruence closure
Callback for when a term is a subterm of another term in the congruence closure
Callback called on every CC conflict
val on_cc_propagate :
t ->
( CC.t -> lit -> ( unit -> lit list * proof_step ) -> unit ) ->
unitCallback called on every CC propagation
val on_partial_check :
t ->
( t -> theory_actions -> lit Iter.t -> unit ) ->
unitRegister callbacked to be called with the slice of literals newly added on the trail.
This is called very often and should be efficient. It doesn't have to be complete, only correct. It's given only the slice of the trail consisting in new literals.
val on_final_check : t -> ( t -> theory_actions -> lit Iter.t -> unit ) -> unitRegister callback to be called during the final check.
Must be complete (i.e. must raise a conflict if the set of literals is not satisfiable) and can be expensive. The function is given the whole trail.
val on_th_combination :
t ->
( t -> theory_actions -> (term * value) Iter.t ) ->
unitAdd a hook called during theory combination. The hook must return an iterator of pairs (t, v) which mean that term t has value v in the model.
Terms with the same value (according to Term.equal) will be merged in the CC; if two terms with different values are merged, we get a semantic conflict and must pick another model.
val declare_pb_is_incomplete : t -> unitDeclare that, in some theory, the problem is outside the logic fragment that is decidable (e.g. if we meet proper NIA formulas). The solver will not reply "SAT" from now on.
A model-production hook to query values from a theory.
It takes the solver, a class, and returns a term for this class. For example, an arithmetic theory might detect that a class contains a numeric constant, and return this constant as a model value.
If no hook assigns a value to a class, a fake value is created for it.
A model production hook, for the theory to add values. The hook is given a add function to add bindings to the model.
val on_model :
?ask:model_ask_hook ->
?complete:model_completion_hook ->
t ->
unitAdd model production/completion hooks.