wip: refactor: replace literals by mere terms

This commit is contained in:
Simon Cruanes 2021-08-21 14:39:37 -04:00
parent 0668f28ac7
commit f5240a857b
No known key found for this signature in database
GPG key ID: 4AC01D0849AA62B6
5 changed files with 84 additions and 124 deletions

View file

@ -2,7 +2,7 @@
(name sidekick_base) (name sidekick_base)
(public_name sidekick-base) (public_name sidekick-base)
(synopsis "Base term definitions for the standalone SMT solver and library") (synopsis "Base term definitions for the standalone SMT solver and library")
(libraries containers sidekick.core sidekick.util sidekick.lit (libraries containers sidekick.core sidekick.util
sidekick.arith-lra sidekick.th-bool-static sidekick.arith-lra sidekick.th-bool-static
sidekick.zarith zarith) sidekick.zarith zarith)
(flags :standard -w -32 -open Sidekick_util)) (flags :standard -w -32 -open Sidekick_util))

View file

@ -106,7 +106,15 @@ module type TERM = sig
(** [as_bool t] is [Some true] if [t] is the term [true], and similarly (** [as_bool t] is [Some true] if [t] is the term [true], and similarly
for [false]. For other terms it is [None]. *) for [false]. For other terms it is [None]. *)
val abs : store -> t -> t * bool val sign : t -> bool
(** For boolean terms, return the sign ([true] for most terms, [false]
for [not u]). For non boolean terms just return [true]. *)
val neg : store -> t -> t
(** For boolean terms, return negation of the term.
Should fail on non-boolean terms. *)
val norm_sign : store -> t -> t * bool
(** [abs t] returns an "absolute value" for the term, along with the (** [abs t] returns an "absolute value" for the term, along with the
sign of [t]. sign of [t].
@ -196,7 +204,8 @@ module type PROOF = sig
of the problem's assertions, and the theories) *) of the problem's assertions, and the theories) *)
type term type term
type lit
type lit = private term
include CC_PROOF include CC_PROOF
with type t := t with type t := t
@ -219,7 +228,7 @@ module type PROOF = sig
(** [define_term p cst u] defines the new constant [cst] as being equal (** [define_term p cst u] defines the new constant [cst] as being equal
to [u]. *) to [u]. *)
val lemma_true : t -> term -> unit val lemma_true : t -> lit -> unit
(** [lemma_true p (true)] asserts the clause [(true)] *) (** [lemma_true p (true)] asserts the clause [(true)] *)
val lemma_preprocess : t -> term -> term -> unit val lemma_preprocess : t -> term -> term -> unit
@ -233,47 +242,31 @@ end
(** Literals (** Literals
Literals are a pair of a boolean-sorted term, and a sign. Literals are boolean terms that have been preprocessed.
Positive literals are the same as their term, and negative literals
are the negation of their term.
The SAT solver deals only in literals and clauses (sets of literals). The SAT solver deals only in literals and clauses (sets of literals).
Everything else belongs in the SMT solver. *) Everything else belongs in the SMT solver. *)
module type LIT = sig module type LIT = sig
module T : TERM type term
(** Literals depend on terms *) module T : TERM with type Term.t = term
type t = private term
type t
(** A literal *)
val term : t -> T.Term.t
(** Get the (positive) term *)
val sign : t -> bool
(** Get the sign. A negated literal has sign [false]. *)
val neg : t -> t
(** Take negation of literal. [sign (neg lit) = not (sign lit)]. *)
val abs : t -> t
(** [abs lit] is like [lit] but always positive, i.e. [sign (abs lit) = true] *)
val signed_term : t -> T.Term.t * bool
(** Return the atom and the sign *)
val atom : T.Term.store -> ?sign:bool -> T.Term.t -> t
(** [atom store t] makes a literal out of a term, possibly normalizing
its sign in the process.
@param sign if provided, and [sign=false], negate the resulting lit. *)
val norm_sign : t -> t * bool
(** [norm_sign (+t)] is [+t, true],
and [norm_sign (-t)] is [+t, false].
In both cases the term is positive, and the boolean reflects the initial sign. *)
val equal : t -> t -> bool val equal : t -> t -> bool
val hash : t -> int val hash : t -> int
val pp : t Fmt.printer val pp : t Fmt.printer
val term : t -> term
(** Term-only view *)
val sign : t -> bool
(** Get the sign. A negated literal has sign [false]. *)
val neg : T.Term.store -> t -> t
(** Take negation of literal. [sign (neg lit) = not (sign lit)]. *)
val norm_sign : T.Term.store -> t -> t * bool
(** [norm_sign store (+t)] is [+t, true],
and [norm_sign (-t)] is [+t, false].
In both cases the term is positive, and the boolean reflects the initial sign. *)
end end
(** Actions provided to the congruence closure. (** Actions provided to the congruence closure.
@ -283,25 +276,28 @@ end
be able to create conflicts when the set of (dis)equalities be able to create conflicts when the set of (dis)equalities
is inconsistent *) is inconsistent *)
module type CC_ACTIONS = sig module type CC_ACTIONS = sig
module T : TERM type term
module Lit : LIT with module T = T module T : TERM with type Term.t = term
type lit = private term
type proof type proof
type dproof = proof -> unit type dproof = proof -> unit
module P : CC_PROOF with type lit = Lit.t and type t = proof module P : CC_PROOF
with type lit = lit
and type t = proof
type t type t
(** An action handle. It is used by the congruence closure (** An action handle. It is used by the congruence closure
to perform the actions below. How it performs the actions to perform the actions below. How it performs the actions
is not specified and is solver-specific. *) is not specified and is solver-specific. *)
val raise_conflict : t -> Lit.t list -> dproof -> 'a val raise_conflict : t -> term list -> dproof -> 'a
(** [raise_conflict acts c pr] declares that [c] is a tautology of (** [raise_conflict acts c pr] declares that [c] is a tautology of
the theory of congruence. This does not return (it should raise an the theory of congruence. This does not return (it should raise an
exception). exception).
@param pr the proof of [c] being a tautology *) @param pr the proof of [c] being a tautology *)
val propagate : t -> Lit.t -> reason:(unit -> Lit.t list * dproof) -> unit val propagate : t -> term -> reason:(unit -> term list * dproof) -> unit
(** [propagate acts lit ~reason pr] declares that [reason() => lit] (** [propagate acts lit ~reason pr] declares that [reason() => lit]
is a tautology. is a tautology.
@ -314,16 +310,19 @@ end
(** Arguments to a congruence closure's implementation *) (** Arguments to a congruence closure's implementation *)
module type CC_ARG = sig module type CC_ARG = sig
module T : TERM type term
module Lit : LIT with module T = T module T : TERM with type Term.t = term
type lit = private term
type proof type proof
module P : CC_PROOF with type lit = Lit.t and type t = proof module P : CC_PROOF with type lit = lit and type t = proof
module Actions : CC_ACTIONS module Actions : CC_ACTIONS
with module T=T with type term=term
and module Lit = Lit and module T=T
and type lit = lit
and type proof = proof and type proof = proof
val cc_view : T.Term.t -> (T.Fun.t, T.Term.t, T.Term.t Iter.t) CC_view.t val cc_view : term -> (T.Fun.t, term, term Iter.t) CC_view.t
(** View the term through the lens of the congruence closure *) (** View the term through the lens of the congruence closure *)
end end
@ -346,19 +345,19 @@ module type CC_S = sig
(** first, some aliases. *) (** first, some aliases. *)
module T : TERM type term
module Lit : LIT with module T = T module T : TERM with type Term.t = term
type lit = private term
type proof type proof
type dproof = proof -> unit type dproof = proof -> unit
module P : CC_PROOF with type lit = Lit.t and type t = proof module P : CC_PROOF with type lit=lit and type t = proof
module Actions : CC_ACTIONS module Actions : CC_ACTIONS
with module T = T with type term=term
and module Lit = Lit and module T = T
and type proof = proof and type proof = proof
type term_store = T.Term.store type term_store = T.Term.store
type term = T.Term.t
type fun_ = T.Fun.t type fun_ = T.Fun.t
type lit = Lit.t
type actions = Actions.t type actions = Actions.t
type t type t
@ -441,7 +440,7 @@ module type CC_S = sig
val mk_merge : N.t -> N.t -> t val mk_merge : N.t -> N.t -> t
val mk_merge_t : term -> term -> t val mk_merge_t : term -> term -> t
val mk_lit : lit -> t val mk_lit : lit -> t (* true because this literal was asserted *)
val mk_list : t list -> t val mk_list : t list -> t
val mk_theory : t -> t (* TODO: indicate what theory, or even provide a lemma *) val mk_theory : t -> t (* TODO: indicate what theory, or even provide a lemma *)
end end
@ -640,11 +639,12 @@ end
Theories should interact with the solver via this module, to assert Theories should interact with the solver via this module, to assert
new lemmas, propagate literals, access the congruence closure, etc. *) new lemmas, propagate literals, access the congruence closure, etc. *)
module type SOLVER_INTERNAL = sig module type SOLVER_INTERNAL = sig
module T : TERM type term
module Lit : LIT with module T = T module T : TERM with type Term.t=term
type lit = private term
module Lit : LIT with type term = term and type t = lit and module T = T
type ty = T.Ty.t type ty = T.Ty.t
type term = T.Term.t
type term_store = T.Term.store type term_store = T.Term.store
type ty_store = T.Ty.store type ty_store = T.Ty.store
type proof type proof
@ -652,7 +652,10 @@ module type SOLVER_INTERNAL = sig
(** Delayed proof. This is used to build a proof step on demand. *) (** Delayed proof. This is used to build a proof step on demand. *)
(** {3 Proofs} *) (** {3 Proofs} *)
module P : PROOF with type lit = Lit.t and type term = term and type t = proof module P : PROOF
with type term = term
and type t = proof
and type lit = lit
(** {3 Main type for a solver} *) (** {3 Main type for a solver} *)
type t type t
@ -662,13 +665,15 @@ module type SOLVER_INTERNAL = sig
val ty_st : t -> ty_store val ty_st : t -> ty_store
val stats : t -> Stat.t val stats : t -> Stat.t
(** {3 Literals}
One can create literals from boolean terms. *)
(** {3 Actions for the theories} *) (** {3 Actions for the theories} *)
type actions type actions
(** Handle that the theories can use to perform actions. *) (** Handle that the theories can use to perform actions. *)
type lit = Lit.t
(** {3 Proof helpers} *) (** {3 Proof helpers} *)
val define_const : t -> const:term -> rhs:term -> unit val define_const : t -> const:term -> rhs:term -> unit
@ -680,8 +685,9 @@ module type SOLVER_INTERNAL = sig
(** Congruence closure instance *) (** Congruence closure instance *)
module CC : CC_S module CC : CC_S
with module T = T with type term = term
and module Lit = Lit and module T = T
and type lit = lit
and type proof = proof and type proof = proof
and type P.t = proof and type P.t = proof
and type P.lit = lit and type P.lit = lit
@ -767,7 +773,7 @@ module type SOLVER_INTERNAL = sig
(** Create a literal. This automatically preprocesses the term. *) (** Create a literal. This automatically preprocesses the term. *)
val preprocess_term : val preprocess_term :
t -> add_clause:(Lit.t list -> dproof -> unit) -> term -> term * dproof t -> add_clause:(lit list -> dproof -> unit) -> term -> term * dproof
(** Preprocess a term. *) (** Preprocess a term. *)
val add_lit : t -> actions -> lit -> unit val add_lit : t -> actions -> lit -> unit
@ -892,15 +898,18 @@ end
Theory implementors will mostly interact with {!SOLVER_INTERNAL}. *) Theory implementors will mostly interact with {!SOLVER_INTERNAL}. *)
module type SOLVER = sig module type SOLVER = sig
module T : TERM type term
module Lit : LIT with module T = T module T : TERM with type Term.t = term
type lit = private term
module Lit : LIT with type term = term and type t = lit and module T = T
type proof type proof
module P : PROOF with type lit = Lit.t and type t = proof and type term = T.Term.t module P : PROOF with type term = term and type t = proof and type lit = lit
module Solver_internal module Solver_internal
: SOLVER_INTERNAL : SOLVER_INTERNAL
with module T = T with type term = term
and module Lit = Lit and module T = T
and type lit = lit
and type proof = proof and type proof = proof
and module P = P and module P = P
(** Internal solver, available to theories. *) (** Internal solver, available to theories. *)
@ -909,9 +918,7 @@ module type SOLVER = sig
(** The solver's state. *) (** The solver's state. *)
type solver = t type solver = t
type term = T.Term.t
type ty = T.Ty.t type ty = T.Ty.t
type lit = Lit.t
type dproof = proof -> unit type dproof = proof -> unit
(** Delayed proof. This is used to build a proof step on demand. *) (** Delayed proof. This is used to build a proof step on demand. *)

View file

@ -1,40 +0,0 @@
(** Implementation of literals from terms *)
module Make(T : Sidekick_core.TERM)
: Sidekick_core.LIT with module T = T
= struct
module T = T
type term = T.Term.t
type t = {
lit_term: term;
lit_sign : bool
}
let[@inline] neg l = {l with lit_sign=not l.lit_sign}
let[@inline] sign t = t.lit_sign
let[@inline] abs t = {t with lit_sign=true}
let[@inline] term (t:t): term = t.lit_term
let[@inline] signed_term t = term t, sign t
let make ~sign t = {lit_sign=sign; lit_term=t}
let atom tst ?(sign=true) (t:term) : t =
let t, sign' = T.Term.abs tst t in
let sign = if not sign' then not sign else sign in
make ~sign t
let equal a b =
a.lit_sign = b.lit_sign &&
T.Term.equal a.lit_term b.lit_term
let hash a =
let sign = a.lit_sign in
CCHash.combine3 2 (CCHash.bool sign) (T.Term.hash a.lit_term)
let pp out l =
if l.lit_sign then T.Term.pp out l.lit_term
else Format.fprintf out "(@[@<1>¬@ %a@])" T.Term.pp l.lit_term
let norm_sign l = if l.lit_sign then l, true else neg l, false
end

View file

@ -1,7 +0,0 @@
(library
(name sidekick_lit)
(public_name sidekick.lit)
(synopsis "Implementation of literals for Sidekick")
(libraries containers sidekick.core sidekick.util)
(flags :standard -warn-error -a+8 -open Sidekick_util))

View file

@ -60,7 +60,7 @@ module type ARG = sig
val has_ty_real : term -> bool val has_ty_real : term -> bool
(** Does this term have the type [Real] *) (** Does this term have the type [Real] *)
val lemma_lra : S.proof -> S.Lit.t Iter.t -> unit val lemma_lra : S.proof -> S.lit Iter.t -> unit
module Gensym : sig module Gensym : sig
type t type t
@ -100,7 +100,7 @@ module Make(A : ARG) : S with module A = A = struct
module Tag = struct module Tag = struct
type t = type t =
| By_def | By_def
| Lit of Lit.t | Lit of lit
| CC_eq of N.t * N.t | CC_eq of N.t * N.t
let pp out = function let pp out = function
@ -174,7 +174,7 @@ module Make(A : ARG) : S with module A = A = struct
() ()
let fresh_term self ~pre ty = A.Gensym.fresh_term self.gensym ~pre ty let fresh_term self ~pre ty = A.Gensym.fresh_term self.gensym ~pre ty
let fresh_lit (self:state) ~mk_lit ~pre : Lit.t = let fresh_lit (self:state) ~mk_lit ~pre : lit =
let t = fresh_term ~pre self (Ty.bool self.ty_st) in let t = fresh_term ~pre self (Ty.bool self.ty_st) in
mk_lit t mk_lit t