mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-10 05:03:59 -05:00
176 lines
5 KiB
OCaml
176 lines
5 KiB
OCaml
(** The external interface implemented by SAT solvers. *)
|
|
|
|
(*
|
|
MSAT is free software, using the Apache license, see file LICENSE
|
|
Copyright 2016 Guillaume Bury
|
|
Copyright 2016 Simon Cruanes
|
|
*)
|
|
|
|
open Sidekick_core
|
|
open Sigs
|
|
|
|
type clause
|
|
type plugin = Sigs.plugin
|
|
|
|
type solver
|
|
(** The main solver type. *)
|
|
|
|
type store
|
|
(** Stores atoms, clauses, etc. *)
|
|
|
|
module Clause : sig
|
|
type t = clause
|
|
|
|
val equal : t -> t -> bool
|
|
|
|
module Tbl : Hashtbl.S with type key = t
|
|
|
|
val pp : store -> t Fmt.printer
|
|
(** Print the clause *)
|
|
|
|
val short_name : store -> t -> string
|
|
(** Short name for a clause. Unspecified *)
|
|
|
|
val n_atoms : store -> t -> int
|
|
|
|
val lits_iter : store -> t -> Lit.t Iter.t
|
|
(** Literals of a clause *)
|
|
|
|
val lits_a : store -> t -> Lit.t array
|
|
(** Atoms of a clause *)
|
|
|
|
val lits_l : store -> t -> Lit.t list
|
|
(** List of atoms of a clause *)
|
|
end
|
|
|
|
(** {2 Main Solver Type} *)
|
|
|
|
type t = solver
|
|
(** Main solver type, containing all state for solving. *)
|
|
|
|
val store : t -> store
|
|
(** Store for the solver *)
|
|
|
|
val stat : t -> Stat.t
|
|
(** Statistics *)
|
|
|
|
val proof : t -> Proof_trace.t
|
|
(** Access the inner proof *)
|
|
|
|
val on_conflict : t -> (Clause.t, unit) Event.t
|
|
val on_decision : t -> (Lit.t, unit) Event.t
|
|
val on_learnt : t -> (Clause.t, unit) Event.t
|
|
val on_gc : t -> (Lit.t array, unit) Event.t
|
|
|
|
(** {2 Types} *)
|
|
|
|
(** Result type for the solver *)
|
|
type res =
|
|
| Sat of sat_state (** Returned when the solver reaches SAT, with a model *)
|
|
| Unsat of clause unsat_state
|
|
(** Returned when the solver reaches UNSAT, with a proof *)
|
|
|
|
exception UndecidedLit
|
|
(** Exception raised by the evaluating functions when a literal
|
|
has not yet been assigned a value. *)
|
|
|
|
(** {2 Base operations} *)
|
|
|
|
val assume : t -> Lit.t list list -> unit
|
|
(** Add the list of clauses to the current set of assumptions.
|
|
Modifies the sat solver state in place. *)
|
|
|
|
val add_clause : t -> Lit.t list -> Proof_step.id -> unit
|
|
(** Lower level addition of clauses *)
|
|
|
|
val add_clause_a : t -> Lit.t array -> Proof_step.id -> unit
|
|
(** Lower level addition of clauses *)
|
|
|
|
val add_input_clause : t -> Lit.t list -> unit
|
|
(** Like {!add_clause} but with the justification of being an input clause *)
|
|
|
|
val add_input_clause_a : t -> Lit.t array -> unit
|
|
(** Like {!add_clause_a} but with justification of being an input clause *)
|
|
|
|
(** {2 Solving} *)
|
|
|
|
val solve : ?on_progress:(unit -> unit) -> ?assumptions:Lit.t list -> t -> res
|
|
(** Try and solves the current set of clauses.
|
|
@param assumptions additional atomic assumptions to be temporarily added.
|
|
The assumptions are just used for this call to [solve], they are
|
|
not saved in the solver's state.
|
|
@param on_progress regularly called during solving.
|
|
Can raise {!Resource_exhausted}
|
|
to stop solving.
|
|
|
|
@raise Resource_exhausted if the on_progress handler raised it to stop
|
|
*)
|
|
|
|
(** {2 Evaluating and adding literals} *)
|
|
|
|
val add_lit : t -> ?default_pol:bool -> Lit.t -> unit
|
|
(** Ensure the SAT solver handles this particular literal, ie add
|
|
a boolean variable for it if it's not already there. *)
|
|
|
|
val set_default_pol : t -> Lit.t -> bool -> unit
|
|
(** Set default polarity for the given boolean variable.
|
|
Sign of the literal is ignored. *)
|
|
|
|
val true_at_level0 : t -> Lit.t -> bool
|
|
(** [true_at_level0 a] returns [true] if [a] was proved at level0, i.e.
|
|
it must hold in all models *)
|
|
|
|
val eval_lit : t -> Lit.t -> lbool
|
|
(** Evaluate atom in current state *)
|
|
|
|
(** {2 Assumption stack} *)
|
|
|
|
val push_assumption : t -> Lit.t -> unit
|
|
(** Pushes an assumption onto the assumption stack. It will remain
|
|
there until it's pop'd by {!pop_assumptions}. *)
|
|
|
|
val pop_assumptions : t -> int -> unit
|
|
(** [pop_assumptions solver n] removes [n] assumptions from the stack.
|
|
It removes the assumptions that were the most
|
|
recently added via {!push_assumptions}. *)
|
|
|
|
(** Result returned by {!check_sat_propagations_only} *)
|
|
type propagation_result =
|
|
| PR_sat
|
|
| PR_conflict of { backtracked: int }
|
|
| PR_unsat of clause unsat_state
|
|
|
|
val check_sat_propagations_only :
|
|
?assumptions:Lit.t list -> t -> propagation_result
|
|
(** [check_sat_propagations_only solver] uses the added clauses
|
|
and local assumptions (using {!push_assumptions} and [assumptions])
|
|
to quickly assess whether the context is satisfiable.
|
|
It is not complete; calling {!solve} is required to get an accurate
|
|
result.
|
|
@returns either [Ok()] if propagation yielded no conflict, or [Error c]
|
|
if a conflict clause [c] was found. *)
|
|
|
|
(** {2 Initialization} *)
|
|
|
|
val plugin_cdcl_t : (module THEORY_CDCL_T) -> (module PLUGIN)
|
|
|
|
val create :
|
|
?stat:Stat.t ->
|
|
?size:[ `Tiny | `Small | `Big ] ->
|
|
proof:Proof_trace.t ->
|
|
plugin ->
|
|
t
|
|
(** Create new solver
|
|
@param theory the theory
|
|
@param the proof
|
|
@param size the initial size of internal data structures. The bigger,
|
|
the faster, but also the more RAM it uses. *)
|
|
|
|
val plugin_pure_sat : plugin
|
|
|
|
val create_pure_sat :
|
|
?stat:Stat.t ->
|
|
?size:[ `Tiny | `Small | `Big ] ->
|
|
proof:Proof_trace.t ->
|
|
unit ->
|
|
t
|