mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 11:15:43 -05:00
more cleanup, add doc
This commit is contained in:
parent
79bc3def3f
commit
590f1ef887
10 changed files with 37 additions and 36 deletions
15
README.md
15
README.md
|
|
@ -42,15 +42,16 @@ Sidekick comes in several components (as in, opam packages):
|
||||||
|
|
||||||
- `sidekick` is the core library, with core type definitions (see `src/core/`),
|
- `sidekick` is the core library, with core type definitions (see `src/core/`),
|
||||||
an implementation of CDCL(T) based on [mSat](https://github.com/Gbury/mSAT/),
|
an implementation of CDCL(T) based on [mSat](https://github.com/Gbury/mSAT/),
|
||||||
a congruence closure, and the theories of boolean formulas and datatypes.
|
a congruence closure, and the theories of boolean formulas, LRA (linear rational
|
||||||
- `sidekick-arith` is a library with an additional dependency
|
arithmetic, using a simplex algorithm), and datatypes.
|
||||||
on [zarith](https://github.com/ocaml/Zarith)
|
- `sidekick-base` is a library with concrete implementations for terms,
|
||||||
(a GMP wrapper for arbitrary precision numbers).
|
arithmetic functions, and proofs.
|
||||||
It currently implements LRA (linear rational arithmetic)
|
It comes with an additional dependency on
|
||||||
using a Simplex algorithm.
|
[zarith](https://github.com/ocaml/Zarith) to represent numbers (zarith is a
|
||||||
|
GMP wrapper for arbitrary precision numbers).
|
||||||
- `sidekick-bin` is an executable that is able to parse problems in
|
- `sidekick-bin` is an executable that is able to parse problems in
|
||||||
the SMT-LIB-2.6 format, in the `QF_UFLRA` fragment, and solves them using
|
the SMT-LIB-2.6 format, in the `QF_UFLRA` fragment, and solves them using
|
||||||
the libraries previously listed.
|
`sidekick` instantiated with `sidekick-base`.
|
||||||
It is mostly useful as a test tool for the libraries and as a starting point
|
It is mostly useful as a test tool for the libraries and as a starting point
|
||||||
for writing custom solvers.
|
for writing custom solvers.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -816,7 +816,7 @@ module Term : sig
|
||||||
|
|
||||||
val pp : t Fmt.printer
|
val pp : t Fmt.printer
|
||||||
|
|
||||||
(** {6 Views} *)
|
(** {3 Views} *)
|
||||||
|
|
||||||
val is_true : t -> bool
|
val is_true : t -> bool
|
||||||
val is_false : t -> bool
|
val is_false : t -> bool
|
||||||
|
|
@ -828,7 +828,7 @@ module Term : sig
|
||||||
val as_fun_undef : t -> (fun_ * Ty.Fun.t) option
|
val as_fun_undef : t -> (fun_ * Ty.Fun.t) option
|
||||||
val as_bool : t -> bool option
|
val as_bool : t -> bool option
|
||||||
|
|
||||||
(** {6 Containers} *)
|
(** {3 Containers} *)
|
||||||
|
|
||||||
module Tbl : CCHashtbl.S with type key = t
|
module Tbl : CCHashtbl.S with type key = t
|
||||||
module Map : CCMap.S with type key = t
|
module Map : CCMap.S with type key = t
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,21 @@
|
||||||
|
(** {1 Sidekick base}
|
||||||
|
|
||||||
|
This library is a starting point for writing concrete implementations
|
||||||
|
of SMT solvers with Sidekick.
|
||||||
|
|
||||||
|
It provides a representation of terms, boolean formulas,
|
||||||
|
linear arithmetic expressions, datatypes for the functors in Sidekick.
|
||||||
|
|
||||||
|
In addition, it has a notion of {!Statement}. Statements are instructions
|
||||||
|
for the SMT solver to do something, such as: define a new constant,
|
||||||
|
declare a new constant, assert a formula as being true,
|
||||||
|
set an option, check satisfiability of the set of statements added so far,
|
||||||
|
etc. Logic formats such as SMT-LIB 2.6 are in fact based on a similar
|
||||||
|
notion of statements, and a [.smt2] files contains a list of statements.
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
||||||
module Base_types = Base_types
|
module Base_types = Base_types
|
||||||
module ID = ID
|
module ID = ID
|
||||||
module Fun = Base_types.Fun
|
module Fun = Base_types.Fun
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,9 @@ module type PROOF = sig
|
||||||
val default : t [@@alert cstor "do not use default constructor"]
|
val default : t [@@alert cstor "do not use default constructor"]
|
||||||
|
|
||||||
val pp_debug : sharing:bool -> t Fmt.printer
|
val pp_debug : sharing:bool -> t Fmt.printer
|
||||||
|
(** Pretty print a proof.
|
||||||
|
@param sharing if true, try to compact the proof by introducing
|
||||||
|
definitions for common terms, clauses, and steps as needed. Safe to ignore. *)
|
||||||
|
|
||||||
module Quip : sig
|
module Quip : sig
|
||||||
val output : out_channel -> t -> unit
|
val output : out_channel -> t -> unit
|
||||||
|
|
@ -662,11 +665,6 @@ module type SOLVER_INTERNAL = sig
|
||||||
|
|
||||||
(** {3 hooks for the theory} *)
|
(** {3 hooks for the theory} *)
|
||||||
|
|
||||||
val propagate : t -> actions -> lit -> reason:(unit -> lit list * proof) -> unit
|
|
||||||
(** Propagate a literal for a reason. This is similar to asserting
|
|
||||||
the clause [reason => lit], but more lightweight, and in a way
|
|
||||||
that is backtrackable. *)
|
|
||||||
|
|
||||||
val raise_conflict : t -> actions -> lit list -> proof -> 'a
|
val raise_conflict : t -> actions -> lit list -> proof -> 'a
|
||||||
(** Give a conflict clause to the solver *)
|
(** Give a conflict clause to the solver *)
|
||||||
|
|
||||||
|
|
@ -676,7 +674,7 @@ module type SOLVER_INTERNAL = sig
|
||||||
If the SAT solver backtracks, this (potential) decision is removed
|
If the SAT solver backtracks, this (potential) decision is removed
|
||||||
and forgotten. *)
|
and forgotten. *)
|
||||||
|
|
||||||
val propagate: t -> actions -> lit -> (unit -> lit list * proof) -> unit
|
val propagate: t -> actions -> lit -> reason:(unit -> lit list * proof) -> 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 *)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -433,7 +433,7 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
in
|
in
|
||||||
(* TODO: more detailed proof certificate *)
|
(* TODO: more detailed proof certificate *)
|
||||||
let pr =
|
let pr =
|
||||||
A.(S.P.(proof_lra (Iter.of_list confl |> Iter.map plit_of_lit))) in
|
A.(proof_lra (Iter.of_list confl |> Iter.map plit_of_lit)) in
|
||||||
SI.raise_conflict si acts confl pr
|
SI.raise_conflict si acts confl pr
|
||||||
|
|
||||||
let on_propagate_ si acts lit ~reason =
|
let on_propagate_ si acts lit ~reason =
|
||||||
|
|
@ -441,7 +441,7 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
| Tag.Lit lit ->
|
| Tag.Lit lit ->
|
||||||
(* TODO: more detailed proof certificate *)
|
(* TODO: more detailed proof certificate *)
|
||||||
SI.propagate si acts lit
|
SI.propagate si acts lit
|
||||||
(fun() ->
|
~reason:(fun() ->
|
||||||
let lits = CCList.flat_map (Tag.to_lits si) reason in
|
let lits = CCList.flat_map (Tag.to_lits si) reason in
|
||||||
let proof = A.proof_lra Iter.(cons lit (of_list lits) |> map plit_of_lit) in
|
let proof = A.proof_lra Iter.(cons lit (of_list lits) |> map plit_of_lit) in
|
||||||
CCList.flat_map (Tag.to_lits si) reason, proof)
|
CCList.flat_map (Tag.to_lits si) reason, proof)
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ module Make(Q : RATIONAL)(Var: VAR)
|
||||||
module V_map = CCMap.Make(Var)
|
module V_map = CCMap.Make(Var)
|
||||||
module Q = Q
|
module Q = Q
|
||||||
|
|
||||||
type num = Q.t (** Numbers *)
|
type num = Q.t
|
||||||
let pp_q_dbg = Q.pp_approx 1
|
let pp_q_dbg = Q.pp_approx 1
|
||||||
|
|
||||||
module Constraint = struct
|
module Constraint = struct
|
||||||
|
|
|
||||||
|
|
@ -70,9 +70,7 @@ module Make(A : ARG)
|
||||||
if l.lit_sign then Term.pp out l.lit_term
|
if l.lit_sign then Term.pp out l.lit_term
|
||||||
else Format.fprintf out "(@[@<1>¬@ %a@])" Term.pp l.lit_term
|
else Format.fprintf out "(@[@<1>¬@ %a@])" Term.pp l.lit_term
|
||||||
|
|
||||||
let apply_sign t s = if s then t else neg t
|
|
||||||
let norm_sign l = if l.lit_sign then l, true else neg l, false
|
let norm_sign l = if l.lit_sign then l, true else neg l, false
|
||||||
let norm l = let l, sign = norm_sign l in l, if sign then Msat.Same_sign else Msat.Negated
|
|
||||||
end
|
end
|
||||||
|
|
||||||
type lit = Lit_.t
|
type lit = Lit_.t
|
||||||
|
|
@ -252,12 +250,12 @@ module Make(A : ARG)
|
||||||
Stat.incr self.count_conflict;
|
Stat.incr self.count_conflict;
|
||||||
acts.Msat.acts_raise_conflict c proof
|
acts.Msat.acts_raise_conflict c proof
|
||||||
|
|
||||||
let[@inline] propagate self acts p reason : unit =
|
let[@inline] propagate self acts p ~reason : unit =
|
||||||
Stat.incr self.count_propagate;
|
Stat.incr self.count_propagate;
|
||||||
acts.Msat.acts_propagate p (Msat.Consequence reason)
|
acts.Msat.acts_propagate p (Msat.Consequence reason)
|
||||||
|
|
||||||
let[@inline] propagate_l self acts p cs proof : unit =
|
let[@inline] propagate_l self acts p cs proof : unit =
|
||||||
propagate self acts p (fun()->cs,proof)
|
propagate self acts p ~reason:(fun()->cs,proof)
|
||||||
|
|
||||||
let add_sat_clause_ self acts ~keep lits (proof:P.t) : unit =
|
let add_sat_clause_ self acts ~keep lits (proof:P.t) : unit =
|
||||||
Stat.incr self.count_axiom;
|
Stat.incr self.count_axiom;
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@ module Parse = struct
|
||||||
let parse_file_exn file : Parse_ast.statement list =
|
let parse_file_exn file : Parse_ast.statement list =
|
||||||
CCIO.with_in file (parse_chan_exn ~filename:file)
|
CCIO.with_in file (parse_chan_exn ~filename:file)
|
||||||
|
|
||||||
let parse_file file =
|
|
||||||
try Result.Ok (parse_file_exn file)
|
|
||||||
with e -> Result.Error (Printexc.to_string e)
|
|
||||||
|
|
||||||
let parse_file_exn ctx file : Stmt.t list =
|
let parse_file_exn ctx file : Stmt.t list =
|
||||||
(* delegate parsing to [Tip_parser] *)
|
(* delegate parsing to [Tip_parser] *)
|
||||||
parse_file_exn file
|
parse_file_exn file
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ module Ctx = struct
|
||||||
|
|
||||||
and ty_kind =
|
and ty_kind =
|
||||||
| K_atomic of Ty.def
|
| K_atomic of Ty.def
|
||||||
| K_bool
|
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
tst: T.state;
|
tst: T.state;
|
||||||
|
|
@ -63,13 +62,8 @@ module Ctx = struct
|
||||||
match StrTbl.get self.names s with
|
match StrTbl.get self.names s with
|
||||||
| Some (_, K_ty (K_atomic def)) -> def
|
| Some (_, K_ty (K_atomic def)) -> def
|
||||||
| _ -> Error.errorf "expected %s to be an atomic type" s
|
| _ -> Error.errorf "expected %s to be an atomic type" s
|
||||||
|
|
||||||
let pp_kind out = function
|
|
||||||
| K_ty _ -> Format.fprintf out "type"
|
|
||||||
| K_fun f -> Fun.pp out f
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let error_loc ctx : string = Fmt.sprintf "at %a: " pp_loc_opt (Ctx.loc ctx)
|
|
||||||
let errorf_ctx ctx msg =
|
let errorf_ctx ctx msg =
|
||||||
Error.errorf ("at %a:@ " ^^ msg) pp_loc_opt (Ctx.loc ctx)
|
Error.errorf ("at %a:@ " ^^ msg) pp_loc_opt (Ctx.loc ctx)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,10 +109,6 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
}
|
}
|
||||||
|
|
||||||
let[@inline] not_ tst t = A.mk_bool tst (B_not t)
|
let[@inline] not_ tst t = A.mk_bool tst (B_not t)
|
||||||
let[@inline] and_a tst a = A.mk_bool tst (B_and a)
|
|
||||||
let[@inline] or_a tst a = A.mk_bool tst (B_or a)
|
|
||||||
let[@inline] ite tst a b c = A.mk_bool tst (B_ite (a,b,c))
|
|
||||||
let[@inline] equiv tst a b = A.mk_bool tst (B_equiv (a,b))
|
|
||||||
let[@inline] eq tst a b = A.mk_bool tst (B_eq (a,b))
|
let[@inline] eq tst a b = A.mk_bool tst (B_eq (a,b))
|
||||||
|
|
||||||
let is_true t = match T.as_bool t with Some true -> true | _ -> false
|
let is_true t = match T.as_bool t with Some true -> true | _ -> false
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue