refactor(proof): use a suspension but keep uniform Proof_term.data type

this makes proof terms uniformly printable or (de)serializable.
This commit is contained in:
Simon Cruanes 2022-07-31 15:00:27 -04:00
parent dd50ab079e
commit 1edf054104
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
20 changed files with 182 additions and 192 deletions

View file

@ -2,12 +2,6 @@ open Types_
type view_as_cc = Term.t -> (Const.t, Term.t, Term.t Iter.t) View.t type view_as_cc = Term.t -> (Const.t, Term.t, Term.t Iter.t) View.t
open struct
(* proof rules *)
module Rules_ = Proof_core
module P = Proof_trace
end
type e_node = E_node.t type e_node = E_node.t
(** A node of the congruence closure *) (** A node of the congruence closure *)
@ -305,13 +299,13 @@ module Expl_state = struct
(* proof of [\/_i ¬lits[i]] *) (* proof of [\/_i ¬lits[i]] *)
let proof_of_th_lemmas (self : t) (proof : Proof_trace.t) : Proof_term.step_id let proof_of_th_lemmas (self : t) (proof : Proof_trace.t) : Proof_term.step_id
= =
let p_lits1 = Iter.of_list self.lits |> Iter.map Lit.neg in let p_lits1 = List.rev_map Lit.neg self.lits in
let p_lits2 = let p_lits2 =
Iter.of_list self.th_lemmas self.th_lemmas |> List.rev_map (fun (lit_t_u, _, _) -> Lit.neg lit_t_u)
|> Iter.map (fun (lit_t_u, _, _) -> Lit.neg lit_t_u)
in in
let p_cc = let p_cc =
P.add_step proof @@ Rules_.lemma_cc (Iter.append p_lits1 p_lits2) Proof_trace.add_step proof @@ fun () ->
Proof_core.lemma_cc (List.rev_append p_lits1 p_lits2)
in in
let resolve_with_th_proof pr (lit_t_u, sub_proofs, pr_th) = let resolve_with_th_proof pr (lit_t_u, sub_proofs, pr_th) =
(* pr_th: [sub_proofs |- t=u]. (* pr_th: [sub_proofs |- t=u].
@ -322,16 +316,16 @@ module Expl_state = struct
(fun pr_th (lit_i, hyps_i) -> (fun pr_th (lit_i, hyps_i) ->
(* [hyps_i |- lit_i] *) (* [hyps_i |- lit_i] *)
let lemma_i = let lemma_i =
P.add_step proof Proof_trace.add_step proof @@ fun () ->
@@ Rules_.lemma_cc Proof_core.lemma_cc (lit_i :: List.rev_map Lit.neg hyps_i)
Iter.(cons lit_i (of_list hyps_i |> map Lit.neg))
in in
(* resolve [lit_i] away. *) (* resolve [lit_i] away. *)
P.add_step proof Proof_trace.add_step proof @@ fun () ->
@@ Rules_.proof_res ~pivot:(Lit.term lit_i) lemma_i pr_th) Proof_core.proof_res ~pivot:(Lit.term lit_i) lemma_i pr_th)
pr_th sub_proofs pr_th sub_proofs
in in
P.add_step proof @@ Rules_.proof_res ~pivot:(Lit.term lit_t_u) pr_th pr Proof_trace.add_step proof @@ fun () ->
Proof_core.proof_res ~pivot:(Lit.term lit_t_u) pr_th pr
in in
(* resolve with theory proofs responsible for some merges, if any. *) (* resolve with theory proofs responsible for some merges, if any. *)
List.fold_left resolve_with_th_proof p_cc self.th_lemmas List.fold_left resolve_with_th_proof p_cc self.th_lemmas
@ -590,7 +584,7 @@ and task_merge_ self a b e_ab : unit =
E_node.pp ra E_node.pp a E_node.pp rb E_node.pp b Expl.pp e_ab); E_node.pp ra E_node.pp a E_node.pp rb E_node.pp b Expl.pp e_ab);
let th = ref false in let th = ref false in
(* TODO: (* TODO:
C1: P.true_neq_false C1: Proof_trace.true_neq_false
C2: lemma [lits |- true=false] (and resolve on theory proofs) C2: lemma [lits |- true=false] (and resolve on theory proofs)
C3: r1 C1 C2 C3: r1 C1 C2
*) *)

View file

@ -6,33 +6,24 @@
type lit = Lit.t type lit = Lit.t
let lemma_cc lits : Proof_term.t = Proof_term.make ~lits "core.lemma-cc" let lemma_cc lits : Proof_term.data = Proof_term.make_data ~lits "core.lemma-cc"
let define_term t1 t2 = let define_term t1 t2 =
Proof_term.make ~terms:(Iter.of_list [ t1; t2 ]) "core.define-term" Proof_term.make_data ~terms:[ t1; t2 ] "core.define-term"
let proof_r1 p1 p2 = let proof_r1 p1 p2 = Proof_term.make_data ~premises:[ p1; p2 ] "core.r1"
Proof_term.make ~premises:(Iter.of_list [ p1; p2 ]) "core.r1" let proof_p1 p1 p2 = Proof_term.make_data ~premises:[ p1; p2 ] "core.p1"
let proof_p1 p1 p2 =
Proof_term.make ~premises:(Iter.of_list [ p1; p2 ]) "core.p1"
let proof_res ~pivot p1 p2 = let proof_res ~pivot p1 p2 =
Proof_term.make ~terms:(Iter.return pivot) Proof_term.make_data ~terms:[ pivot ] ~premises:[ p1; p2 ] "core.res"
~premises:(Iter.of_list [ p1; p2 ])
"core.res"
let with_defs pr defs = let with_defs pr defs =
Proof_term.make ~premises:(Iter.append (Iter.return pr) defs) "core.with-defs" Proof_term.make_data ~premises:(pr :: defs) "core.with-defs"
let lemma_true t = Proof_term.make ~terms:(Iter.return t) "core.true" let lemma_true t = Proof_term.make_data ~terms:[ t ] "core.true"
let lemma_preprocess t1 t2 ~using = let lemma_preprocess t1 t2 ~using =
Proof_term.make Proof_term.make_data ~terms:[ t1; t2 ] ~premises:using "core.preprocess"
~terms:(Iter.of_list [ t1; t2 ])
~premises:using "core.preprocess"
let lemma_rw_clause pr ~res ~using = let lemma_rw_clause pr ~res ~using =
Proof_term.make Proof_term.make_data ~premises:(pr :: using) ~lits:res "core.rw-clause"
~premises:(Iter.append (Iter.return pr) using)
~lits:res "core.rw-clause"

View file

@ -4,56 +4,56 @@ open Sidekick_core_logic
type lit = Lit.t type lit = Lit.t
val lemma_cc : lit Iter.t -> Proof_term.t val lemma_cc : lit list -> Proof_term.data
(** [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. *)
val define_term : Term.t -> Term.t -> Proof_term.t val define_term : Term.t -> Term.t -> Proof_term.data
(** [define_term cst u proof] defines the new constant [cst] as being equal (** [define_term cst u proof] defines the new constant [cst] as being equal
to [u]. to [u].
The result is a proof of the clause [cst = u] *) The result is a proof of the clause [cst = u] *)
val proof_p1 : Proof_term.step_id -> Proof_term.step_id -> Proof_term.t val proof_p1 : Proof_term.step_id -> Proof_term.step_id -> Proof_term.data
(** [proof_p1 p1 p2], where [p1] proves the unit clause [t=u] (t:bool) (** [proof_p1 p1 p2], where [p1] proves the unit clause [t=u] (t:bool)
and [p2] proves [C \/ t], is the Proof_term.t that produces [C \/ u], and [p2] proves [C \/ t], is the Proof_term.t that produces [C \/ u],
i.e unit paramodulation. *) i.e unit paramodulation. *)
val proof_r1 : Proof_term.step_id -> Proof_term.step_id -> Proof_term.t val proof_r1 : Proof_term.step_id -> Proof_term.step_id -> Proof_term.data
(** [proof_r1 p1 p2], where [p1] proves the unit clause [|- t] (t:bool) (** [proof_r1 p1 p2], where [p1] proves the unit clause [|- t] (t:bool)
and [p2] proves [C \/ ¬t], is the Proof_term.t that produces [C \/ u], and [p2] proves [C \/ ¬t], is the Proof_term.t that produces [C \/ u],
i.e unit resolution. *) i.e unit resolution. *)
val proof_res : val proof_res :
pivot:Term.t -> Proof_term.step_id -> Proof_term.step_id -> Proof_term.t pivot:Term.t -> Proof_term.step_id -> Proof_term.step_id -> Proof_term.data
(** [proof_res ~pivot p1 p2], where [p1] proves the clause [|- C \/ l] (** [proof_res ~pivot p1 p2], where [p1] proves the clause [|- C \/ l]
and [p2] proves [D \/ ¬l], where [l] is either [pivot] or [¬pivot], and [p2] proves [D \/ ¬l], where [l] is either [pivot] or [¬pivot],
is the Proof_term.t that produces [C \/ D], i.e boolean resolution. *) is the Proof_term.t that produces [C \/ D], i.e boolean resolution. *)
val with_defs : Proof_term.step_id -> Proof_term.step_id Iter.t -> Proof_term.t val with_defs : Proof_term.step_id -> Proof_term.step_id list -> Proof_term.data
(** [with_defs pr defs] specifies that [pr] is valid only in (** [with_defs pr defs] specifies that [pr] is valid only in
a context where the definitions [defs] are present. *) a context where the definitions [defs] are present. *)
val lemma_true : Term.t -> Proof_term.t val lemma_true : Term.t -> Proof_term.data
(** [lemma_true (true) p] asserts the clause [(true)] *) (** [lemma_true (true) p] asserts the clause [(true)] *)
val lemma_preprocess : val lemma_preprocess :
Term.t -> Term.t -> using:Proof_term.step_id Iter.t -> Proof_term.t Term.t -> Term.t -> using:Proof_term.step_id list -> Proof_term.data
(** [lemma_preprocess t u ~using p] asserts that [t = u] is a tautology (** [lemma_preprocess t u ~using p] asserts that [t = u] is a tautology
and that [t] has been preprocessed into [u]. and that [t] has been preprocessed into [u].
The theorem [/\_{eqn in using} eqn |- t=u] is proved using congruence The theorem [/\_{eqn in using} eqn |- t=u] is proved using congruence
closure, and then resolved against the clauses [using] to obtain closure, and then resolved against the clauses [using] to obtain
a unit equality. a unit equality.
From now on, [t] and [u] will be used interchangeably. From now on, [t] and [u] will be used interchangeably.
@return a Proof_term.t ID for the clause [(t=u)]. *) @return a Proof_term.t ID for the clause [(t=u)]. *)
val lemma_rw_clause : val lemma_rw_clause :
Proof_term.step_id -> Proof_term.step_id ->
res:lit Iter.t -> res:lit list ->
using:Proof_term.step_id Iter.t -> using:Proof_term.step_id list ->
Proof_term.t Proof_term.data
(** [lemma_rw_clause prc ~res ~using], where [prc] is the proof of [|- c], (** [lemma_rw_clause prc ~res ~using], where [prc] is the proof of [|- c],
uses the equations [|- p_i = q_i] from [using] uses the equations [|- p_i = q_i] from [using]
to rewrite some literals of [c] into [res]. This is used to preprocess to rewrite some literals of [c] into [res]. This is used to preprocess
literals of a clause (using {!lemma_preprocess} individually). *) literals of a clause (using {!lemma_preprocess} individually). *)

View file

@ -1,8 +1,10 @@
type lit = Lit.t type lit = Lit.t
let sat_input_clause lits : Proof_term.t = Proof_term.make "sat.input" ~lits let sat_input_clause lits : Proof_term.data =
Proof_term.make_data "sat.input" ~lits
let sat_redundant_clause lits ~hyps : Proof_term.t = let sat_redundant_clause lits ~hyps : Proof_term.data =
Proof_term.make "sat.rup" ~lits ~premises:hyps Proof_term.make_data "sat.rup" ~lits ~premises:(Iter.to_rev_list hyps)
let sat_unsat_core lits : Proof_term.t = Proof_term.make ~lits "sat.unsat-core" let sat_unsat_core lits : Proof_term.data =
Proof_term.make_data ~lits "sat.unsat-core"

View file

@ -4,12 +4,12 @@ open Proof_term
type lit = Lit.t type lit = Lit.t
val sat_input_clause : lit Iter.t -> Proof_term.t val sat_input_clause : lit list -> Proof_term.data
(** Emit an input clause. *) (** Emit an input clause. *)
val sat_redundant_clause : lit Iter.t -> hyps:step_id Iter.t -> Proof_term.t val sat_redundant_clause : lit list -> hyps:step_id Iter.t -> Proof_term.data
(** Emit a clause deduced by the SAT solver, redundant wrt previous clauses. (** Emit a clause deduced by the SAT solver, redundant wrt previous clauses.
The clause must be RUP wrt [hyps]. *) The clause must be RUP wrt [hyps]. *)
val sat_unsat_core : lit Iter.t -> Proof_term.t val sat_unsat_core : lit list -> Proof_term.data
(** TODO: is this relevant here? *) (** TODO: is this relevant here? *)

View file

@ -3,18 +3,20 @@ open Sidekick_core_logic
type step_id = Proof_step.id type step_id = Proof_step.id
type lit = Lit.t type lit = Lit.t
type t = { type data = {
rule_name: string; rule_name: string;
lit_args: lit Iter.t; lit_args: lit list;
term_args: Term.t Iter.t; term_args: Term.t list;
subst_args: Subst.t Iter.t; subst_args: Subst.t list;
premises: step_id Iter.t; premises: step_id list;
} }
type t = unit -> data
let pp out _ = Fmt.string out "<proof term>" (* TODO *) let pp out _ = Fmt.string out "<proof term>" (* TODO *)
let make ?(lits = Iter.empty) ?(terms = Iter.empty) ?(substs = Iter.empty) let make_data ?(lits = []) ?(terms = []) ?(substs = []) ?(premises = [])
?(premises = Iter.empty) rule_name : t = rule_name : data =
{ {
rule_name; rule_name;
lit_args = lits; lit_args = lits;

View file

@ -7,20 +7,22 @@ open Sidekick_core_logic
type step_id = Proof_step.id type step_id = Proof_step.id
type lit = Lit.t type lit = Lit.t
type t = { type data = {
rule_name: string; rule_name: string;
lit_args: lit Iter.t; lit_args: lit list;
term_args: Term.t Iter.t; term_args: Term.t list;
subst_args: Subst.t Iter.t; subst_args: Subst.t list;
premises: step_id Iter.t; premises: step_id list;
} }
type t = unit -> data
include Sidekick_sigs.PRINT with type t := t include Sidekick_sigs.PRINT with type t := t
val make : val make_data :
?lits:lit Iter.t -> ?lits:lit list ->
?terms:Term.t Iter.t -> ?terms:Term.t list ->
?substs:Subst.t Iter.t -> ?substs:Subst.t list ->
?premises:step_id Iter.t -> ?premises:step_id list ->
string -> string ->
t data

View file

@ -467,10 +467,10 @@ let rec proof_of_atom_lvl0_ (self : t) (a : atom) : Proof_step.id =
if !steps = [] then if !steps = [] then
proof_c2 proof_c2
else else
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Proof_sat.sat_redundant_clause Proof_sat.sat_redundant_clause
(Iter.return (Atom.lit self.store a)) [ Atom.lit self.store a ]
~hyps:Iter.(cons proof_c2 (of_list !steps)) ~hyps:Iter.(cons proof_c2 (of_list !steps))
in in
Atom.set_proof_lvl0 self.store a p; Atom.set_proof_lvl0 self.store a p;
@ -559,11 +559,12 @@ let preprocess_clause_ (self : t) (c : Clause.t) : Clause.t =
k "(@[sat.add-clause.resolved-lvl-0@ :into [@[%a@]]@])" k "(@[sat.add-clause.resolved-lvl-0@ :into [@[%a@]]@])"
(Atom.debug_a store) atoms); (Atom.debug_a store) atoms);
let proof = let proof =
let lits = Iter.of_array atoms |> Iter.map (Atom.lit store) in Proof_trace.add_step self.proof @@ fun () ->
Proof_trace.add_step self.proof let lits = Util.array_to_list_map (Atom.lit store) atoms in
@@ Proof_sat.sat_redundant_clause lits let hyps =
~hyps: Iter.(cons (Clause.proof_step self.store c) (of_list !res0_proofs))
Iter.(cons (Clause.proof_step self.store c) (of_list !res0_proofs)) in
Proof_sat.sat_redundant_clause lits ~hyps
in in
Clause.make_a store atoms proof ~removable:(Clause.removable store c) Clause.make_a store atoms proof ~removable:(Clause.removable store c)
) )
@ -1005,10 +1006,9 @@ let record_learnt_clause (self : t) ~pool (cr : conflict_res) : unit =
assert (cr.cr_backtrack_lvl = 0 && decision_level self = 0); assert (cr.cr_backtrack_lvl = 0 && decision_level self = 0);
let p = let p =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Proof_sat.sat_redundant_clause let lits = Util.array_to_list_map (Atom.lit self.store) cr.cr_learnt in
(Iter.of_array cr.cr_learnt |> Iter.map (Atom.lit self.store)) Proof_sat.sat_redundant_clause lits ~hyps:(Step_vec.to_iter cr.cr_steps)
~hyps:(Step_vec.to_iter cr.cr_steps)
in in
let uclause = Clause.make_a store ~removable:true cr.cr_learnt p in let uclause = Clause.make_a store ~removable:true cr.cr_learnt p in
Event.emit self.on_learnt uclause; Event.emit self.on_learnt uclause;
@ -1022,10 +1022,9 @@ let record_learnt_clause (self : t) ~pool (cr : conflict_res) : unit =
| _ -> | _ ->
let fuip = cr.cr_learnt.(0) in let fuip = cr.cr_learnt.(0) in
let p = let p =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Proof_sat.sat_redundant_clause let lits = Util.array_to_list_map (Atom.lit self.store) cr.cr_learnt in
(Iter.of_array cr.cr_learnt |> Iter.map (Atom.lit self.store)) Proof_sat.sat_redundant_clause lits ~hyps:(Step_vec.to_iter cr.cr_steps)
~hyps:(Step_vec.to_iter cr.cr_steps)
in in
let lclause = Clause.make_a store ~removable:true cr.cr_learnt p in let lclause = Clause.make_a store ~removable:true cr.cr_learnt p in
@ -1741,8 +1740,8 @@ let assume self cnf : unit =
(fun l -> (fun l ->
let atoms = Util.array_of_list_map (make_atom_ self) l in let atoms = Util.array_of_list_map (make_atom_ self) l in
let proof = let proof =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Proof_sat.sat_input_clause (Iter.of_list l) Proof_sat.sat_input_clause l
in in
let c = Clause.make_a self.store ~removable:false atoms proof in let c = Clause.make_a self.store ~removable:false atoms proof in
Log.debugf 10 (fun k -> Log.debugf 10 (fun k ->
@ -1825,10 +1824,10 @@ let resolve_with_lvl0 (self : t) (c : clause) : clause =
(* no resolution happened *) (* no resolution happened *)
else ( else (
let proof = let proof =
let lits = Iter.of_list !res |> Iter.map (Atom.lit self.store) in Proof_trace.add_step self.proof @@ fun () ->
let lits = List.rev_map (Atom.lit self.store) !res in
let hyps = Iter.of_list (Clause.proof_step self.store c :: !lvl0) in let hyps = Iter.of_list (Clause.proof_step self.store c :: !lvl0) in
Proof_trace.add_step self.proof Proof_sat.sat_redundant_clause lits ~hyps
@@ Proof_sat.sat_redundant_clause lits ~hyps
in in
Clause.make_l self.store ~removable:false !res proof Clause.make_l self.store ~removable:false !res proof
) )
@ -1861,8 +1860,9 @@ let mk_unsat (self : t) (us : unsat_cause) : _ unsat_state =
(* increasing trail order *) (* increasing trail order *)
assert (Atom.equal first @@ List.hd core); assert (Atom.equal first @@ List.hd core);
let proof = let proof =
let lits = Iter.of_list core |> Iter.map (Atom.lit self.store) in Proof_trace.add_step self.proof @@ fun () ->
Proof_trace.add_step self.proof @@ Proof_sat.sat_unsat_core lits let lits = List.rev_map (Atom.lit self.store) core in
Proof_sat.sat_unsat_core lits
in in
Clause.make_l self.store ~removable:false [] proof) Clause.make_l self.store ~removable:false [] proof)
in in
@ -1937,15 +1937,14 @@ let add_clause self (c : Lit.t list) (pr : Proof_step.id) : unit =
let add_input_clause self (c : Lit.t list) = let add_input_clause self (c : Lit.t list) =
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () -> Proof_sat.sat_input_clause c
@@ Proof_sat.sat_input_clause (Iter.of_list c)
in in
add_clause self c pr add_clause self c pr
let add_input_clause_a self c = let add_input_clause_a self c =
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Proof_sat.sat_input_clause (Iter.of_array c) Proof_sat.sat_input_clause (Array.to_list c)
in in
add_clause_a self c pr add_clause_a self c pr

View file

@ -1,10 +1,5 @@
open Sidekick_core open Sidekick_core
open struct
module P = Proof_trace
module Rule_ = Proof_core
end
type t = { type t = {
tst: Term.store; tst: Term.store;
proof: Proof_trace.t; proof: Proof_trace.t;
@ -68,8 +63,8 @@ let normalize (self : t) (t : Term.t) : (Term.t * Proof_step.id) option =
else ( else (
(* proof: [sub_proofs |- t=u] by CC + subproof *) (* proof: [sub_proofs |- t=u] by CC + subproof *)
let step = let step =
P.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Rule_.lemma_preprocess t u ~using:(Bag.to_iter pr_u) Proof_core.lemma_preprocess t u ~using:(Bag.to_list pr_u)
in in
Some (u, step) Some (u, step)
) )

View file

@ -113,7 +113,7 @@ let create arg ?(stat = Stat.global) ?size ~proof ~theories tst () : t =
let t_true = Term.true_ tst in let t_true = Term.true_ tst in
Sat_solver.add_clause self.solver Sat_solver.add_clause self.solver
[ Lit.atom t_true ] [ Lit.atom t_true ]
(P.add_step self.proof @@ Rule_.lemma_true t_true)); (P.add_step self.proof @@ fun () -> Rule_.lemma_true t_true));
self self
let[@inline] solver self = self.solver let[@inline] solver self = self.solver
@ -173,9 +173,7 @@ let add_clause_l self c p = add_clause self (CCArray.of_list c) p
let assert_terms self c = let assert_terms self c =
let c = CCList.map Lit.atom c in let c = CCList.map Lit.atom c in
let pr_c = let pr_c = P.add_step self.proof @@ fun () -> Proof_sat.sat_input_clause c in
P.add_step self.proof @@ Proof_sat.sat_input_clause (Iter.of_list c)
in
add_clause_l self c pr_c add_clause_l self c pr_c
let assert_term self t = assert_terms self [ t ] let assert_term self t = assert_terms self [ t ]

View file

@ -1,13 +1,6 @@
open Sigs open Sigs
module Proof_rules = Sidekick_core.Proof_sat
module P_core_rules = Sidekick_core.Proof_core
module Ty = Term module Ty = Term
open struct
module P = Proof_trace
module Rule_ = Proof_core
end
type th_states = type th_states =
| Ths_nil | Ths_nil
| Ths_cons : { | Ths_cons : {
@ -200,7 +193,7 @@ module type ARR = sig
type 'a t type 'a t
val map : ('a -> 'b) -> 'a t -> 'b t val map : ('a -> 'b) -> 'a t -> 'b t
val to_iter : 'a t -> 'a Iter.t val to_list : 'a t -> 'a list
end end
module Preprocess_clause (A : ARR) = struct module Preprocess_clause (A : ARR) = struct
@ -222,16 +215,21 @@ module Preprocess_clause (A : ARR) = struct
pr_c pr_c
else ( else (
Stat.incr self.count_preprocess_clause; Stat.incr self.count_preprocess_clause;
P.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Rule_.lemma_rw_clause pr_c ~res:(A.to_iter c') Proof_core.lemma_rw_clause pr_c ~res:(A.to_list c') ~using:!steps
~using:(Iter.of_list !steps)
) )
in in
c', pr_c' c', pr_c'
end end
[@@inline] [@@inline]
module PC_list = Preprocess_clause (CCList) module PC_list = Preprocess_clause (struct
type 'a t = 'a list
let map = CCList.map
let to_list l = l
end)
module PC_arr = Preprocess_clause (CCArray) module PC_arr = Preprocess_clause (CCArray)
let preprocess_clause = PC_list.top let preprocess_clause = PC_list.top
@ -518,7 +516,9 @@ let assert_lits_ ~final (self : t) (acts : theory_actions) (lits : Lit.t Iter.t)
in in
let c = List.rev_append c1 c2 in let c = List.rev_append c1 c2 in
let pr = P.add_step self.proof @@ Rule_.lemma_cc (Iter.of_list c) in let pr =
Proof_trace.add_step self.proof @@ fun () -> Proof_core.lemma_cc c
in
Log.debugf 20 (fun k -> Log.debugf 20 (fun k ->
k "(@[solver.th-comb.add-semantic-conflict-clause@ %a@])" k "(@[solver.th-comb.add-semantic-conflict-clause@ %a@])"

View file

@ -36,8 +36,9 @@ end = struct
let add_step_eq a b ~using ~c0 : unit = let add_step_eq a b ~using ~c0 : unit =
add_step_ @@ mk_step_ add_step_ @@ mk_step_
@@ Proof_core.lemma_rw_clause c0 ~using @@ fun () ->
~res:(Iter.return (Lit.atom (A.mk_bool tst (B_eq (a, b))))) Proof_core.lemma_rw_clause c0 ~using
~res:[ Lit.atom (A.mk_bool tst (B_eq (a, b))) ]
in in
let[@inline] ret u = Some (u, Iter.of_list !steps) in let[@inline] ret u = Some (u, Iter.of_list !steps) in
@ -81,11 +82,11 @@ end = struct
Option.iter add_step_ prf_a; Option.iter add_step_ prf_a;
(match A.view_as_bool a with (match A.view_as_bool a with
| B_bool true -> | B_bool true ->
add_step_eq t b ~using:(Iter.of_opt prf_a) add_step_eq t b ~using:(Option.to_list prf_a)
~c0:(mk_step_ @@ A.P.lemma_ite_true ~ite:t); ~c0:(mk_step_ @@ A.P.lemma_ite_true ~ite:t);
ret b ret b
| B_bool false -> | B_bool false ->
add_step_eq t c ~using:(Iter.of_opt prf_a) add_step_eq t c ~using:(Option.to_list prf_a)
~c0:(mk_step_ @@ A.P.lemma_ite_false ~ite:t); ~c0:(mk_step_ @@ A.P.lemma_ite_false ~ite:t);
ret c ret c
| _ -> None) | _ -> None)

View file

@ -9,7 +9,7 @@ let name = "th-cstor"
module type ARG = sig module type ARG = sig
val view_as_cstor : Term.t -> (Const.t, Term.t) cstor_view val view_as_cstor : Term.t -> (Const.t, Term.t) cstor_view
val lemma_cstor : Lit.t Iter.t -> Proof_term.t val lemma_cstor : Lit.t list -> Proof_term.data
end end
module Make (A : ARG) : sig module Make (A : ARG) : sig

View file

@ -7,7 +7,7 @@ type ('c, 't) cstor_view = T_cstor of 'c * 't array | T_other of 't
module type ARG = sig module type ARG = sig
val view_as_cstor : Term.t -> (Const.t, Term.t) cstor_view val view_as_cstor : Term.t -> (Const.t, Term.t) cstor_view
val lemma_cstor : Lit.t Iter.t -> Proof_term.t val lemma_cstor : Lit.t list -> Proof_term.data
end end
val make : (module ARG) -> SMT.theory val make : (module ARG) -> SMT.theory

View file

@ -186,7 +186,7 @@ end = struct
let t1 = E_node.term c1.c_n in let t1 = E_node.term c1.c_n in
let t2 = E_node.term c2.c_n in let t2 = E_node.term c2.c_n in
mk_expl t1 t2 @@ Proof_trace.add_step proof mk_expl t1 t2 @@ Proof_trace.add_step proof
@@ A.P.lemma_cstor_inj t1 t2 i @@ fun () -> A.P.lemma_cstor_inj t1 t2 i
in in
assert (CCArray.length c1.c_args = CCArray.length c2.c_args); assert (CCArray.length c1.c_args = CCArray.length c2.c_args);
@ -199,7 +199,7 @@ end = struct
let expl = let expl =
let t1 = E_node.term c1.c_n and t2 = E_node.term c2.c_n in let t1 = E_node.term c1.c_n and t2 = E_node.term c2.c_n in
mk_expl t1 t2 @@ Proof_trace.add_step proof mk_expl t1 t2 @@ Proof_trace.add_step proof
@@ A.P.lemma_cstor_distinct t1 t2 @@ fun () -> A.P.lemma_cstor_distinct t1 t2
in in
Error (CC.Handler_action.Conflict expl) Error (CC.Handler_action.Conflict expl)
@ -332,15 +332,14 @@ end = struct
with exhaustiveness: [|- is-c(t)] *) with exhaustiveness: [|- is-c(t)] *)
let proof = let proof =
let pr_isa = let pr_isa =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_isa_split t A.P.lemma_isa_split t [ Lit.atom (A.mk_is_a self.tst cstor t) ]
(Iter.return @@ Act.mk_lit (A.mk_is_a self.tst cstor t))
and pr_eq_sel = and pr_eq_sel =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_select_cstor ~cstor_t:u t A.P.lemma_select_cstor ~cstor_t:u t
in in
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ Proof_core.proof_r1 pr_isa pr_eq_sel Proof_core.proof_r1 pr_isa pr_eq_sel
in in
Term.Tbl.add self.single_cstor_preproc_done t (); Term.Tbl.add self.single_cstor_preproc_done t ();
@ -394,8 +393,8 @@ end = struct
%a@])" %a@])"
name Term.pp_debug t is_true E_node.pp n Monoid_cstor.pp cstor); name Term.pp_debug t is_true E_node.pp n Monoid_cstor.pp cstor);
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_isa_cstor ~cstor_t:(E_node.term cstor.c_n) t A.P.lemma_isa_cstor ~cstor_t:(E_node.term cstor.c_n) t
in in
let n_bool = CC.n_bool cc is_true in let n_bool = CC.n_bool cc is_true in
let expl = let expl =
@ -421,8 +420,8 @@ end = struct
assert (i < CCArray.length cstor.c_args); assert (i < CCArray.length cstor.c_args);
let u_i = CCArray.get cstor.c_args i in let u_i = CCArray.get cstor.c_args i in
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_select_cstor ~cstor_t:(E_node.term cstor.c_n) t A.P.lemma_select_cstor ~cstor_t:(E_node.term cstor.c_n) t
in in
let expl = let expl =
Expl.( Expl.(
@ -458,9 +457,9 @@ end = struct
name Monoid_parents.pp_is_a is_a2 is_true E_node.pp n1 E_node.pp n2 name Monoid_parents.pp_is_a is_a2 is_true E_node.pp n1 E_node.pp n2
Monoid_cstor.pp c1); Monoid_cstor.pp c1);
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_isa_cstor ~cstor_t:(E_node.term c1.c_n) A.P.lemma_isa_cstor ~cstor_t:(E_node.term c1.c_n)
(E_node.term is_a2.is_a_n) (E_node.term is_a2.is_a_n)
in in
let n_bool = CC.n_bool cc is_true in let n_bool = CC.n_bool cc is_true in
let expl = let expl =
@ -487,9 +486,9 @@ end = struct
E_node.pp n2 sel2.sel_idx Monoid_cstor.pp c1); E_node.pp n2 sel2.sel_idx Monoid_cstor.pp c1);
assert (sel2.sel_idx < CCArray.length c1.c_args); assert (sel2.sel_idx < CCArray.length c1.c_args);
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_select_cstor ~cstor_t:(E_node.term c1.c_n) A.P.lemma_select_cstor ~cstor_t:(E_node.term c1.c_n)
(E_node.term sel2.sel_n) (E_node.term sel2.sel_n)
in in
let u_i = CCArray.get c1.c_args sel2.sel_idx in let u_i = CCArray.get c1.c_args sel2.sel_idx in
let expl = let expl =
@ -598,10 +597,13 @@ end = struct
(* conflict: the [path] forms a cycle *) (* conflict: the [path] forms a cycle *)
let path = (n, node) :: path in let path = (n, node) :: path in
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_acyclicity let path =
(Iter.of_list path List.rev_map
|> Iter.map (fun (a, b) -> E_node.term a, E_node.term b.repr)) (fun (a, b) -> E_node.term a, E_node.term b.repr)
path
in
A.P.lemma_acyclicity path
in in
let expl = let expl =
let subs = let subs =
@ -654,7 +656,9 @@ end = struct
Log.debugf 50 (fun k -> Log.debugf 50 (fun k ->
k "(@[%s.assign-is-a@ :lhs %a@ :rhs %a@ :lit %a@])" name k "(@[%s.assign-is-a@ :lhs %a@ :rhs %a@ :lit %a@])" name
Term.pp_debug u Term.pp_debug rhs Lit.pp lit); Term.pp_debug u Term.pp_debug rhs Lit.pp lit);
let pr = Proof_trace.add_step self.proof @@ A.P.lemma_isa_sel t in let pr =
Proof_trace.add_step self.proof @@ fun () -> A.P.lemma_isa_sel t
in
(* merge [u] and [rhs] *) (* merge [u] and [rhs] *)
CC.merge_t (SI.cc solver) u rhs CC.merge_t (SI.cc solver) u rhs
(Expl.mk_theory u rhs (Expl.mk_theory u rhs
@ -680,12 +684,11 @@ end = struct
|> Iter.to_rev_list |> Iter.to_rev_list
in in
SI.add_clause_permanent solver acts c SI.add_clause_permanent solver acts c
(Proof_trace.add_step self.proof (Proof_trace.add_step self.proof @@ fun () -> A.P.lemma_isa_split t c);
@@ A.P.lemma_isa_split t (Iter.of_list c));
Iter.diagonal_l c (fun (l1, l2) -> Iter.diagonal_l c (fun (l1, l2) ->
let pr = let pr =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.P.lemma_isa_disj (Lit.neg l1) (Lit.neg l2) A.P.lemma_isa_disj (Lit.neg l1) (Lit.neg l2)
in in
SI.add_clause_permanent solver acts [ Lit.neg l1; Lit.neg l2 ] pr) SI.add_clause_permanent solver acts [ Lit.neg l1; Lit.neg l2 ] pr)
) )

View file

@ -22,35 +22,35 @@ type ('c, 'ty) data_ty_view =
| Ty_other | Ty_other
module type PROOF_RULES = sig module type PROOF_RULES = sig
val lemma_isa_cstor : cstor_t:Term.t -> Term.t -> Proof_term.t val lemma_isa_cstor : cstor_t:Term.t -> Term.t -> Proof_term.data
(** [lemma_isa_cstor (d …) (is-c t)] returns the clause (** [lemma_isa_cstor (d …) (is-c t)] returns the clause
[(c ) = t |- is-c t] or [(d ) = t |- ¬ (is-c t)] *) [(c ) = t |- is-c t] or [(d ) = t |- ¬ (is-c t)] *)
val lemma_select_cstor : cstor_t:Term.t -> Term.t -> Proof_term.t val lemma_select_cstor : cstor_t:Term.t -> Term.t -> Proof_term.data
(** [lemma_select_cstor (c t1…tn) (sel-c-i t)] (** [lemma_select_cstor (c t1…tn) (sel-c-i t)]
returns a proof of [t = c t1tn |- (sel-c-i t) = ti] *) returns a proof of [t = c t1tn |- (sel-c-i t) = ti] *)
val lemma_isa_split : Term.t -> Lit.t Iter.t -> Proof_term.t val lemma_isa_split : Term.t -> Lit.t list -> Proof_term.data
(** [lemma_isa_split t lits] is the proof of (** [lemma_isa_split t lits] is the proof of
[is-c1 t \/ is-c2 t \/ \/ is-c_n t] *) [is-c1 t \/ is-c2 t \/ \/ is-c_n t] *)
val lemma_isa_sel : Term.t -> Proof_term.t val lemma_isa_sel : Term.t -> Proof_term.data
(** [lemma_isa_sel (is-c t)] is the proof of (** [lemma_isa_sel (is-c t)] is the proof of
[is-c t |- t = c (sel-c-1 t)(sel-c-n t)] *) [is-c t |- t = c (sel-c-1 t)(sel-c-n t)] *)
val lemma_isa_disj : Lit.t -> Lit.t -> Proof_term.t val lemma_isa_disj : Lit.t -> Lit.t -> Proof_term.data
(** [lemma_isa_disj (is-c t) (is-d t)] is the proof (** [lemma_isa_disj (is-c t) (is-d t)] is the proof
of [¬ (is-c t) \/ ¬ (is-c t)] *) of [¬ (is-c t) \/ ¬ (is-c t)] *)
val lemma_cstor_inj : Term.t -> Term.t -> int -> Proof_term.t val lemma_cstor_inj : Term.t -> Term.t -> int -> Proof_term.data
(** [lemma_cstor_inj (c t1…tn) (c u1…un) i] is the proof of (** [lemma_cstor_inj (c t1…tn) (c u1…un) i] is the proof of
[c t1tn = c u1un |- ti = ui] *) [c t1tn = c u1un |- ti = ui] *)
val lemma_cstor_distinct : Term.t -> Term.t -> Proof_term.t val lemma_cstor_distinct : Term.t -> Term.t -> Proof_term.data
(** [lemma_isa_distinct (c …) (d …)] is the proof (** [lemma_isa_distinct (c …) (d …)] is the proof
of the unit clause [|- (c ) (d )] *) of the unit clause [|- (c ) (d )] *)
val lemma_acyclicity : (Term.t * Term.t) Iter.t -> Proof_term.t val lemma_acyclicity : (Term.t * Term.t) list -> Proof_term.data
(** [lemma_acyclicity pairs] is a proof of [t1=u1, …, tn=un |- false] (** [lemma_acyclicity pairs] is a proof of [t1=u1, …, tn=un |- false]
by acyclicity. *) by acyclicity. *)
end end

View file

@ -44,7 +44,7 @@ module type ARG = sig
val has_ty_real : Term.t -> bool val has_ty_real : Term.t -> bool
(** Does this term have the type [Real] *) (** Does this term have the type [Real] *)
val lemma_lra : Lit.t Iter.t -> Proof_term.t val lemma_lra : Lit.t list -> Proof_term.data
module Gensym : sig module Gensym : sig
type t type t

View file

@ -248,13 +248,13 @@ module Make (A : ARG) = (* : S with module A = A *) struct
proxy) proxy)
let add_clause_lra_ ?using (module PA : SI.PREPROCESS_ACTS) lits = let add_clause_lra_ ?using (module PA : SI.PREPROCESS_ACTS) lits =
let pr = Proof_trace.add_step PA.proof @@ A.lemma_lra (Iter.of_list lits) in let pr = Proof_trace.add_step PA.proof @@ fun () -> A.lemma_lra lits in
let pr = let pr =
match using with match using with
| None -> pr | None -> pr
| Some using -> | Some using ->
Proof_trace.add_step PA.proof Proof_trace.add_step PA.proof @@ fun () ->
@@ Proof_core.lemma_rw_clause pr ~res:(Iter.of_list lits) ~using Proof_core.lemma_rw_clause pr ~res:lits ~using
in in
PA.add_clause lits pr PA.add_clause lits pr
@ -396,12 +396,12 @@ module Make (A : ARG) = (* : S with module A = A *) struct
let simplify (self : state) (_recurse : _) (t : Term.t) : let simplify (self : state) (_recurse : _) (t : Term.t) :
(Term.t * Proof_step.id Iter.t) option = (Term.t * Proof_step.id Iter.t) option =
let proof_eq t u = let proof_eq t u =
Proof_trace.add_step self.proof Proof_trace.add_step self.proof @@ fun () ->
@@ A.lemma_lra (Iter.return (Lit.atom (Term.eq self.tst t u))) A.lemma_lra [ Lit.atom (Term.eq self.tst t u) ]
in in
let proof_bool t ~sign:b = let proof_bool t ~sign:b =
let lit = Lit.atom ~sign:b t in let lit = Lit.atom ~sign:b t in
Proof_trace.add_step self.proof @@ A.lemma_lra (Iter.return lit) Proof_trace.add_step self.proof @@ fun () -> A.lemma_lra [ lit ]
in in
match A.view_as_lra t with match A.view_as_lra t with
@ -467,7 +467,7 @@ module Make (A : ARG) = (* : S with module A = A *) struct
|> List.rev_map Lit.neg |> List.rev_map Lit.neg
in in
let pr = let pr =
Proof_trace.add_step (SI.proof si) @@ A.lemma_lra (Iter.of_list confl) Proof_trace.add_step (SI.proof si) @@ fun () -> A.lemma_lra confl
in in
SI.raise_conflict si acts confl pr SI.raise_conflict si acts confl pr
@ -478,8 +478,8 @@ module Make (A : ARG) = (* : S with module A = A *) struct
SI.propagate si acts lit ~reason:(fun () -> SI.propagate si acts lit ~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 pr = let pr =
Proof_trace.add_step (SI.proof si) Proof_trace.add_step (SI.proof si) @@ fun () ->
@@ A.lemma_lra Iter.(cons lit (of_list lits)) A.lemma_lra (lit :: lits)
in in
CCList.flat_map (Tag.to_lits si) reason, pr) CCList.flat_map (Tag.to_lits si) reason, pr)
| _ -> () | _ -> ()
@ -525,7 +525,7 @@ module Make (A : ARG) = (* : S with module A = A *) struct
(* [c=0] when [c] is not 0 *) (* [c=0] when [c] is not 0 *)
let lit = Lit.atom ~sign:false @@ Term.eq self.tst t1 t2 in let lit = Lit.atom ~sign:false @@ Term.eq self.tst t1 t2 in
let pr = let pr =
Proof_trace.add_step self.proof @@ A.lemma_lra (Iter.return lit) Proof_trace.add_step self.proof @@ fun () -> A.lemma_lra [ lit ]
in in
SI.add_clause_permanent si acts [ lit ] pr SI.add_clause_permanent si acts [ lit ] pr
) )

View file

@ -44,6 +44,8 @@ let rec fold f acc = function
| L x -> f acc x | L x -> f acc x
| N (a, b) -> fold f (fold f acc a) b | N (a, b) -> fold f (fold f acc a) b
let to_list self = fold (fun acc x -> x :: acc) [] self
let[@unroll 2] rec to_iter t yield = let[@unroll 2] rec to_iter t yield =
match t with match t with
| E -> () | E -> ()

View file

@ -15,6 +15,7 @@ val snoc : 'a t -> 'a -> 'a t
val append : 'a t -> 'a t -> 'a t val append : 'a t -> 'a t -> 'a t
val of_iter : 'a Iter.t -> 'a t val of_iter : 'a Iter.t -> 'a t
val to_iter : 'a t -> 'a Iter.t val to_iter : 'a t -> 'a Iter.t
val to_list : 'a t -> 'a list
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
val iter : ('a -> unit) -> 'a t -> unit val iter : ('a -> unit) -> 'a t -> unit