mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-07 03:35:38 -05:00
feat(core): change the way proofs work
Now a proof returns a `step_id` which identifies its resulting clause. This might be a dummy value when proofs are disabled. We attach a step_id to each new clause to make sure it's properly tracked, but step_ids might outlive their clause (and the actual proof data might be on disk, only keeping in ram a small unique identifier).
This commit is contained in:
parent
313e9db026
commit
4621cc948f
1 changed files with 89 additions and 57 deletions
|
|
@ -147,86 +147,101 @@ end
|
||||||
|
|
||||||
(** Proofs for the congruence closure *)
|
(** Proofs for the congruence closure *)
|
||||||
module type CC_PROOF = sig
|
module type CC_PROOF = sig
|
||||||
|
type step_id
|
||||||
type t
|
type t
|
||||||
type lit
|
type lit
|
||||||
|
|
||||||
val lemma_cc : lit Iter.t -> t -> unit
|
val lemma_cc : lit Iter.t -> t -> step_id
|
||||||
(** [lemma_cc proof lits] asserts that [lits] form a tautology for the theory
|
(** [lemma_cc proof lits] asserts that [lits] form a tautology for the theory
|
||||||
of uninterpreted functions. *)
|
of uninterpreted functions. *)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Signature for SAT-solver proof emission, using DRUP.
|
(** Signature for SAT-solver proof emission. *)
|
||||||
|
|
||||||
We do not store the resolution steps, just the stream of clauses deduced.
|
|
||||||
See {!Sidekick_drup} for checking these proofs. *)
|
|
||||||
module type SAT_PROOF = sig
|
module type SAT_PROOF = sig
|
||||||
type t
|
type t
|
||||||
(** The stored proof (possibly nil, possibly on disk, possibly in memory) *)
|
(** The stored proof (possibly nil, possibly on disk, possibly in memory) *)
|
||||||
|
|
||||||
|
type step_id
|
||||||
|
(** identifier for a proof step *)
|
||||||
|
|
||||||
|
module Step_vec : Vec_sig.S with type elt = step_id
|
||||||
|
(** A vector of steps *)
|
||||||
|
|
||||||
type lit
|
type lit
|
||||||
(** A boolean literal for the proof trace *)
|
(** A boolean literal for the proof trace *)
|
||||||
|
|
||||||
type dproof = t -> unit
|
type pstep = t -> step_id
|
||||||
(** A delayed proof, used to produce proofs on demand from theories. *)
|
(** A proof step constructor, used to obtain proofs from theories *)
|
||||||
|
|
||||||
val with_proof : t -> (t -> unit) -> unit
|
val enabled : t -> bool
|
||||||
|
(** Returns true if proof production is enabled *)
|
||||||
|
|
||||||
|
val with_proof : t -> (t -> 'a) -> 'a
|
||||||
(** If proof is enabled, call [f] on it to emit steps.
|
(** If proof is enabled, call [f] on it to emit steps.
|
||||||
if proof is disabled, the callback won't even be called. *)
|
if proof is disabled, the callback won't even be called, and
|
||||||
|
a dummy step is returned. *)
|
||||||
|
|
||||||
val emit_input_clause : lit Iter.t -> t -> unit
|
val emit_input_clause : lit Iter.t -> pstep
|
||||||
(** Emit an input clause. *)
|
(** Emit an input clause. *)
|
||||||
|
|
||||||
val emit_redundant_clause : lit Iter.t -> t -> unit
|
val emit_redundant_clause : lit Iter.t -> hyps:step_id Iter.t -> pstep
|
||||||
(** Emit a clause deduced by the SAT solver, redundant wrt axioms.
|
(** Emit a clause deduced by the SAT solver, redundant wrt previous clauses.
|
||||||
The clause must be RUP wrt previous clauses. *)
|
The clause must be RUP wrt [hyps]. *)
|
||||||
|
|
||||||
val del_clause : lit Iter.t -> t -> unit
|
val emit_unsat_core : lit Iter.t -> pstep
|
||||||
|
(** Produce a proof of the empty clause given this subset of the assumptions.
|
||||||
|
FIXME: probably needs the list of step_id that disprove the lits? *)
|
||||||
|
|
||||||
|
val emit_unsat : step_id -> t -> unit
|
||||||
|
(** Signal "unsat" result at the given step *)
|
||||||
|
|
||||||
|
val del_clause : step_id -> t -> unit
|
||||||
(** Forget a clause. Only useful for performance considerations. *)
|
(** Forget a clause. Only useful for performance considerations. *)
|
||||||
(* TODO: replace with something index-based? *)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Proofs of unsatisfiability.
|
(** Proofs of unsatisfiability. *)
|
||||||
|
|
||||||
We use DRUP(T)-style traces where we simply emit clauses as we go,
|
|
||||||
annotating enough for the checker to reconstruct them.
|
|
||||||
This allows for low overhead proof production. *)
|
|
||||||
module type PROOF = sig
|
module type PROOF = sig
|
||||||
type t
|
type t
|
||||||
(** The abstract representation of a proof. A proof always proves
|
(** The abstract representation of a proof. A proof always proves
|
||||||
a clause to be {b valid} (true in every possible interpretation
|
a clause to be {b valid} (true in every possible interpretation
|
||||||
of the problem's assertions, and the theories) *)
|
of the problem's assertions, and the theories) *)
|
||||||
|
|
||||||
|
type step_id
|
||||||
|
(** Identifier for a proof step (like a unique ID for a clause previously
|
||||||
|
added/proved) *)
|
||||||
|
|
||||||
type term
|
type term
|
||||||
type lit
|
type lit
|
||||||
|
type step = t -> step_id
|
||||||
|
|
||||||
include CC_PROOF
|
include CC_PROOF
|
||||||
with type t := t
|
with type t := t
|
||||||
and type lit := lit
|
and type lit := lit
|
||||||
|
and type step_id := step_id
|
||||||
|
|
||||||
include SAT_PROOF
|
include SAT_PROOF
|
||||||
with type t := t
|
with type t := t
|
||||||
and type lit := lit
|
and type lit := lit
|
||||||
|
and type step_id := step_id
|
||||||
|
|
||||||
val begin_subproof : t -> unit
|
val define_term : term -> term -> step
|
||||||
(** Begins a subproof. The result of this will only be the
|
(** [define_term cst u proof] defines the new constant [cst] as being equal
|
||||||
clause with which {!end_subproof} is called; all other intermediate
|
to [u].
|
||||||
steps will be discarded. *)
|
The result is a proof of the clause [cst = u] *)
|
||||||
|
|
||||||
val end_subproof : t -> unit
|
val lemma_true : term -> step
|
||||||
(** [end_subproof p] ends the current active subproof, the last result
|
(** [lemma_true (true) p] asserts the clause [(true)] *)
|
||||||
of which is kept. *)
|
|
||||||
|
|
||||||
val define_term : term -> term -> t -> unit
|
val lemma_preprocess : term -> term -> using:step_id Iter.t -> step
|
||||||
(** [define_term p cst u] defines the new constant [cst] as being equal
|
(** [lemma_preprocess t u ~using p] asserts that [t = u] is a tautology
|
||||||
to [u]. *)
|
|
||||||
|
|
||||||
val lemma_true : term -> t -> unit
|
|
||||||
(** [lemma_true p (true)] asserts the clause [(true)] *)
|
|
||||||
|
|
||||||
val lemma_preprocess : term -> term -> t -> unit
|
|
||||||
(** [lemma_preprocess p t u] asserts that [t = u] is a tautology
|
|
||||||
and that [t] has been preprocessed into [u].
|
and that [t] has been preprocessed into [u].
|
||||||
From now on, [t] and [u] will be used interchangeably. *)
|
|
||||||
|
The theorem [/\_{eqn in using} eqn |- t=u] is proved using congruence
|
||||||
|
closure, and then resolved against the clauses [using] to obtain
|
||||||
|
a unit equality.
|
||||||
|
|
||||||
|
From now on, [t] and [u] will be used interchangeably.
|
||||||
|
@return a step ID for the clause [(t=u)]. *)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Literals
|
(** Literals
|
||||||
|
|
@ -285,7 +300,8 @@ module type CC_ACTIONS = sig
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
|
|
||||||
type proof
|
type proof
|
||||||
type dproof = proof -> unit
|
type step_id
|
||||||
|
type pstep = proof -> step_id
|
||||||
module P : CC_PROOF with type lit = Lit.t and type t = proof
|
module P : CC_PROOF with type lit = Lit.t and type t = proof
|
||||||
|
|
||||||
type t
|
type t
|
||||||
|
|
@ -293,13 +309,13 @@ module type CC_ACTIONS = sig
|
||||||
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 -> Lit.t list -> pstep -> '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 -> Lit.t -> reason:(unit -> Lit.t list * pstep) -> 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.
|
||||||
|
|
||||||
|
|
@ -315,11 +331,16 @@ module type CC_ARG = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
type proof
|
type proof
|
||||||
module P : CC_PROOF with type lit = Lit.t and type t = proof
|
type step_id
|
||||||
|
module P : CC_PROOF
|
||||||
|
with type lit = Lit.t
|
||||||
|
and type t = proof
|
||||||
|
and type step_id = step_id
|
||||||
module Actions : CC_ACTIONS
|
module Actions : CC_ACTIONS
|
||||||
with module T=T
|
with module T=T
|
||||||
and module Lit = Lit
|
and module Lit = Lit
|
||||||
and type proof = proof
|
and type proof = proof
|
||||||
|
and type step_id = step_id
|
||||||
|
|
||||||
val cc_view : T.Term.t -> (T.Fun.t, T.Term.t, T.Term.t Iter.t) CC_view.t
|
val cc_view : T.Term.t -> (T.Fun.t, T.Term.t, T.Term.t 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 *)
|
||||||
|
|
@ -347,12 +368,17 @@ module type CC_S = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with module T = T
|
||||||
type proof
|
type proof
|
||||||
type dproof = proof -> unit
|
type step_id
|
||||||
module P : CC_PROOF with type lit = Lit.t and type t = proof
|
type pstep = proof -> step_id
|
||||||
|
module P : CC_PROOF
|
||||||
|
with type lit = Lit.t
|
||||||
|
and type t = proof
|
||||||
|
and type step_id = step_id
|
||||||
module Actions : CC_ACTIONS
|
module Actions : CC_ACTIONS
|
||||||
with module T = T
|
with module T = T
|
||||||
and module Lit = Lit
|
and module Lit = Lit
|
||||||
and type proof = proof
|
and type proof = proof
|
||||||
|
and type step_id = step_id
|
||||||
type term_store = T.Term.store
|
type term_store = T.Term.store
|
||||||
type term = T.Term.t
|
type term = T.Term.t
|
||||||
type fun_ = T.Fun.t
|
type fun_ = T.Fun.t
|
||||||
|
|
@ -493,7 +519,7 @@ module type CC_S = sig
|
||||||
participating in the conflict are purely syntactic theories
|
participating in the conflict are purely syntactic theories
|
||||||
like injectivity of constructors. *)
|
like injectivity of constructors. *)
|
||||||
|
|
||||||
type ev_on_propagate = t -> lit -> (unit -> lit list * dproof) -> unit
|
type ev_on_propagate = t -> lit -> (unit -> lit list * pstep) -> unit
|
||||||
(** [ev_on_propagate cc lit reason] is called whenever [reason() => lit]
|
(** [ev_on_propagate cc lit reason] is called whenever [reason() => lit]
|
||||||
is a propagated lemma. See {!CC_ACTIONS.propagate}. *)
|
is a propagated lemma. See {!CC_ACTIONS.propagate}. *)
|
||||||
|
|
||||||
|
|
@ -647,7 +673,8 @@ module type SOLVER_INTERNAL = sig
|
||||||
type ty_store = T.Ty.store
|
type ty_store = T.Ty.store
|
||||||
type clause_pool
|
type clause_pool
|
||||||
type proof
|
type proof
|
||||||
type dproof = proof -> unit
|
type step_id
|
||||||
|
type pstep = proof -> step_id
|
||||||
(** 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} *)
|
||||||
|
|
@ -749,7 +776,7 @@ module type SOLVER_INTERNAL = sig
|
||||||
val mk_lit : ?sign:bool -> term -> lit
|
val mk_lit : ?sign:bool -> term -> lit
|
||||||
(** creates a new literal for a boolean term. *)
|
(** creates a new literal for a boolean term. *)
|
||||||
|
|
||||||
val add_clause : lit list -> dproof -> unit
|
val add_clause : lit list -> pstep -> unit
|
||||||
(** pushes a new clause into the SAT solver. *)
|
(** pushes a new clause into the SAT solver. *)
|
||||||
|
|
||||||
val add_lit : ?default_pol:bool -> lit -> unit
|
val add_lit : ?default_pol:bool -> lit -> unit
|
||||||
|
|
@ -782,7 +809,7 @@ module type SOLVER_INTERNAL = sig
|
||||||
|
|
||||||
(** {3 hooks for the theory} *)
|
(** {3 hooks for the theory} *)
|
||||||
|
|
||||||
val raise_conflict : t -> theory_actions -> lit list -> dproof -> 'a
|
val raise_conflict : t -> theory_actions -> lit list -> pstep -> 'a
|
||||||
(** Give a conflict clause to the solver *)
|
(** Give a conflict clause to the solver *)
|
||||||
|
|
||||||
val push_decision : t -> theory_actions -> lit -> unit
|
val push_decision : t -> theory_actions -> lit -> unit
|
||||||
|
|
@ -791,19 +818,19 @@ 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 -> theory_actions -> lit -> reason:(unit -> lit list * dproof) -> unit
|
val propagate: t -> theory_actions -> lit -> reason:(unit -> lit list * pstep) -> 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 *)
|
||||||
|
|
||||||
val propagate_l: t -> theory_actions -> lit -> lit list -> dproof -> unit
|
val propagate_l: t -> theory_actions -> lit -> lit list -> pstep -> 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 *)
|
||||||
|
|
||||||
val add_clause_temp : t -> theory_actions -> lit list -> dproof -> unit
|
val add_clause_temp : t -> theory_actions -> lit list -> pstep -> unit
|
||||||
(** Add local clause to the SAT solver. This clause will be
|
(** Add local clause to the SAT solver. This clause will be
|
||||||
removed when the solver backtracks. *)
|
removed when the solver backtracks. *)
|
||||||
|
|
||||||
val add_clause_permanent : t -> theory_actions -> lit list -> dproof -> unit
|
val add_clause_permanent : t -> theory_actions -> lit list -> pstep -> unit
|
||||||
(** Add toplevel clause to the SAT solver. This clause will
|
(** Add toplevel clause to the SAT solver. This clause will
|
||||||
not be backtracked. *)
|
not be backtracked. *)
|
||||||
|
|
||||||
|
|
@ -867,7 +894,7 @@ module type SOLVER_INTERNAL = sig
|
||||||
val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit
|
val on_cc_conflict : t -> (CC.t -> th:bool -> lit list -> unit) -> unit
|
||||||
(** Callback called on every CC conflict *)
|
(** Callback called on every CC conflict *)
|
||||||
|
|
||||||
val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list * dproof) -> unit) -> unit
|
val on_cc_propagate : t -> (CC.t -> lit -> (unit -> lit list * pstep) -> unit) -> unit
|
||||||
(** Callback called on every CC propagation *)
|
(** Callback called on every CC propagation *)
|
||||||
|
|
||||||
val on_partial_check : t -> (t -> theory_actions -> lit Iter.t -> unit) -> unit
|
val on_partial_check : t -> (t -> theory_actions -> lit Iter.t -> unit) -> unit
|
||||||
|
|
@ -914,7 +941,12 @@ module type SOLVER = sig
|
||||||
module T : TERM
|
module T : TERM
|
||||||
module Lit : LIT with module T = T
|
module Lit : LIT with 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
|
type step_id
|
||||||
|
module P : PROOF
|
||||||
|
with type lit = Lit.t
|
||||||
|
and type t = proof
|
||||||
|
and type step_id = step_id
|
||||||
|
and type term = T.Term.t
|
||||||
|
|
||||||
module Solver_internal
|
module Solver_internal
|
||||||
: SOLVER_INTERNAL
|
: SOLVER_INTERNAL
|
||||||
|
|
@ -931,8 +963,8 @@ module type SOLVER = sig
|
||||||
type term = T.Term.t
|
type term = T.Term.t
|
||||||
type ty = T.Ty.t
|
type ty = T.Ty.t
|
||||||
type lit = Lit.t
|
type lit = Lit.t
|
||||||
type dproof = proof -> unit
|
type pstep = proof -> step_id
|
||||||
(** Delayed proof. This is used to build a proof step on demand. *)
|
(** Proof step. *)
|
||||||
|
|
||||||
(** {3 A theory}
|
(** {3 A theory}
|
||||||
|
|
||||||
|
|
@ -1067,11 +1099,11 @@ module type SOLVER = sig
|
||||||
|
|
||||||
The proof of [|- lit = lit'] is directly added to the solver's proof. *)
|
The proof of [|- lit = lit'] is directly added to the solver's proof. *)
|
||||||
|
|
||||||
val add_clause : t -> lit IArray.t -> dproof -> unit
|
val add_clause : t -> lit IArray.t -> pstep -> unit
|
||||||
(** [add_clause solver cs] adds a boolean clause to the solver.
|
(** [add_clause solver cs] adds a boolean clause to the solver.
|
||||||
Subsequent calls to {!solve} will need to satisfy this clause. *)
|
Subsequent calls to {!solve} will need to satisfy this clause. *)
|
||||||
|
|
||||||
val add_clause_l : t -> lit list -> dproof -> unit
|
val add_clause_l : t -> lit list -> pstep -> unit
|
||||||
(** Add a clause to the solver, given as a list. *)
|
(** Add a clause to the solver, given as a list. *)
|
||||||
|
|
||||||
val assert_terms : t -> term list -> unit
|
val assert_terms : t -> term list -> unit
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue