Sidekick_smt_solver.SolverMain solver type, user facing.
This is the solver a user of sidekick can see, after instantiating everything. The user can add some theories, clauses, etc. and asks the solver to check satisfiability.
Theory implementors will mostly interact with SOLVER_INTERNAL.
val registry : t -> Registry.tA solver contains a registry so that theories can share data
type theory = Theory.tval mk_theory :
name:string ->
create_and_setup:( id:Theory_id.t -> Solver_internal.t -> 'th ) ->
?push_level:( 'th -> unit ) ->
?pop_levels:( 'th -> int -> unit ) ->
unit ->
Theory.tHelper to create a theory.
module Unknown : sig ... endval stats : t -> Sidekick_util.Stat.tval tst : t -> Sigs.Term.storeval proof : t -> Sigs.proof_traceval create :
(module Sigs.ARG) ->
?stat:Sidekick_util.Stat.t ->
?size:[ `Big | `Tiny | `Small ] ->
proof:Sigs.proof_trace ->
theories:Theory.t list ->
Sigs.Term.store ->
unit ->
tCreate a new solver.
It needs a term state and a type state to manipulate terms and types. All terms and types interacting with this solver will need to come from these exact states.
val create_default :
?stat:Sidekick_util.Stat.t ->
?size:[ `Big | `Tiny | `Small ] ->
proof:Sigs.proof_trace ->
theories:Theory.t list ->
Sigs.Term.store ->
unit ->
tCreate a new solver with the default CC view, and where all boolean subterms are mapped to boolean atoms.
Add a theory to the solver. This should be called before any call to solve or to add_clause and the likes (otherwise the theory will have a partial view of the problem).
mk_lit_t _ ~sign t returns lit', where lit' is preprocess(lit) and lit is an internal representation of ± t.
The proof of |- lit = lit' is directly added to the solver's proof.
val add_clause : t -> Sigs.lit array -> Sigs.step_id -> unitadd_clause solver cs adds a boolean clause to the solver. Subsequent calls to solve will need to satisfy this clause.
val add_clause_l : t -> Sigs.lit list -> Sigs.step_id -> unitAdd a clause to the solver, given as a list.
Helper that turns each term into an atom, before adding the result to the solver as an assertion
Helper that turns the term into an atom, before adding the result to the solver as a unit clause assertion
type res = | Sat of Model.t | (* Satisfiable *) | ||||
| Unsat of {
} | (* Unsatisfiable *) | ||||
| Unknown of Unknown.t | (* Unknown, obtained after a timeout, memory limit, etc. *) |
Result of solving for the current set of clauses
val solve :
?on_exit:( unit -> unit ) list ->
?check:bool ->
?on_progress:( t -> unit ) ->
?should_stop:( t -> int -> bool ) ->
assumptions:Sigs.lit list ->
t ->
ressolve s checks the satisfiability of the clauses added so far to s.
Last result, if any. Some operations will erase this (e.g. assert_term).
Pushes an assumption onto the assumption stack. It will remain there until it's pop'd by pop_assumptions.
val pop_assumptions : t -> int -> unitpop_assumptions solver n removes n assumptions from the stack. It removes the assumptions that were the most recently added via push_assumptions. Note that check_sat_propagations_only can call this if it meets a conflict.
type propagation_result = | PR_sat | |
| PR_conflict of {
} | |
| PR_unsat of {
} |
val check_sat_propagations_only :
assumptions:Sigs.lit list ->
t ->
propagation_resultcheck_sat_propagations_only solver uses assumptions (including the assumptions parameter, and atoms previously added via push_assumptions) and boolean+theory propagation to quickly assess satisfiability. It is not complete; calling solve is required to get an accurate result.
val pp_stats : t CCFormat.printerPrint some statistics. What it prints exactly is unspecified.