mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 03:05:31 -05:00
wip: decode more proof steps to quip
This commit is contained in:
parent
992b93abcf
commit
0abe4b7020
13 changed files with 159 additions and 43 deletions
|
|
@ -216,10 +216,12 @@ let lemma_cc lits (self:t) =
|
||||||
let lits = Iter.map (emit_lit_ self) lits |> Iter.to_array in
|
let lits = Iter.map (emit_lit_ self) lits |> Iter.to_array in
|
||||||
PS.(Step_view.Step_cc {Step_cc.eqns=lits})
|
PS.(Step_view.Step_cc {Step_cc.eqns=lits})
|
||||||
|
|
||||||
let lemma_rw_clause c ~using (self:t) =
|
let lemma_rw_clause c ~res ~using (self:t) =
|
||||||
emit_ self @@ fun() ->
|
emit_ self @@ fun() ->
|
||||||
|
let lits = Iter.map (emit_lit_ self) res |> Iter.to_array in
|
||||||
|
let res = Proof_ser.{Clause.lits} in
|
||||||
let using = Iter.to_array using in
|
let using = Iter.to_array using in
|
||||||
PS.(Step_view.Step_clause_rw {Step_clause_rw.c; using})
|
PS.(Step_view.Step_clause_rw {Step_clause_rw.c; res; using})
|
||||||
|
|
||||||
(* TODO *)
|
(* TODO *)
|
||||||
let with_defs _ _ (_pr:t) = dummy_step
|
let with_defs _ _ (_pr:t) = dummy_step
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ let emit_unsat_core _ (_pr:t) = ()
|
||||||
let lemma_preprocess _ _ ~using:_ (_pr:t) = ()
|
let lemma_preprocess _ _ ~using:_ (_pr:t) = ()
|
||||||
let lemma_true _ _ = ()
|
let lemma_true _ _ = ()
|
||||||
let lemma_cc _ _ = ()
|
let lemma_cc _ _ = ()
|
||||||
let lemma_rw_clause _ ~using:_ (_pr:t) = ()
|
let lemma_rw_clause _ ~res:_ ~using:_ (_pr:t) = ()
|
||||||
let with_defs _ _ (_pr:t) = ()
|
let with_defs _ _ (_pr:t) = ()
|
||||||
|
|
||||||
let lemma_lra _ _ = ()
|
let lemma_lra _ _ = ()
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,9 @@ end = struct
|
||||||
(* store reconstructed terms *)
|
(* store reconstructed terms *)
|
||||||
module L_terms = Make_lazy_tbl(struct type t = P.term end)()
|
module L_terms = Make_lazy_tbl(struct type t = P.term end)()
|
||||||
|
|
||||||
|
(* id -> function symbol *)
|
||||||
|
let funs: P.Fun.t Util.Int_tbl.t = Util.Int_tbl.create 32
|
||||||
|
|
||||||
(* list of toplevel steps, in the final proof order *)
|
(* list of toplevel steps, in the final proof order *)
|
||||||
let top_steps_ : P.composite_step lazy_t list ref = ref []
|
let top_steps_ : P.composite_step lazy_t list ref = ref []
|
||||||
let add_top_step s = top_steps_ := s :: !top_steps_
|
let add_top_step s = top_steps_ := s :: !top_steps_
|
||||||
|
|
@ -66,13 +69,23 @@ end = struct
|
||||||
P.Lit.mk sign t
|
P.Lit.mk sign t
|
||||||
)
|
)
|
||||||
|
|
||||||
let conv_clause (c:PS.Clause.t) : P.clause lazy_t =
|
let conv_lits (lits:PS.Lit.t array) : P.Lit.t list lazy_t =
|
||||||
let lits =
|
let lits =
|
||||||
c.lits
|
lits
|
||||||
|> Util.array_to_list_map conv_lit
|
|> Util.array_to_list_map conv_lit
|
||||||
in
|
in
|
||||||
lazy (List.map Lazy.force lits)
|
lazy (List.map Lazy.force lits)
|
||||||
|
|
||||||
|
let conv_clause (c:PS.Clause.t) : P.clause lazy_t = conv_lits c.lits
|
||||||
|
|
||||||
|
let name_clause (id: PS.ID.t) : string = Printf.sprintf "c%ld" id
|
||||||
|
|
||||||
|
(* TODO: see if we can allow `(stepc c5 (cl …) (… (@ c5) …))`.
|
||||||
|
Namely, the alias `c5 := (cl …)` could be available within its own proof
|
||||||
|
so we don't have to print it twice, which is useful for rules like `ccl`
|
||||||
|
where it's typically `(stepc c5 (cl …) (ccl (cl …)))` for twice the space.
|
||||||
|
*)
|
||||||
|
|
||||||
(* process a step of the trace *)
|
(* process a step of the trace *)
|
||||||
let process_step_ (step: PS.Step.t) : unit =
|
let process_step_ (step: PS.Step.t) : unit =
|
||||||
let lid = step.id in
|
let lid = step.id in
|
||||||
|
|
@ -85,7 +98,7 @@ end = struct
|
||||||
begin match step.view with
|
begin match step.view with
|
||||||
| PS.Step_view.Step_input i ->
|
| PS.Step_view.Step_input i ->
|
||||||
let c = conv_clause i.PS.Step_input.c in
|
let c = conv_clause i.PS.Step_input.c in
|
||||||
let name = Printf.sprintf "c%d" id in
|
let name = name_clause lid in
|
||||||
let step = lazy (
|
let step = lazy (
|
||||||
let lazy c = c in
|
let lazy c = c in
|
||||||
P.S_step_c {name; res=c; proof=P.assertion_c_l c}
|
P.S_step_c {name; res=c; proof=P.assertion_c_l c}
|
||||||
|
|
@ -94,23 +107,90 @@ end = struct
|
||||||
(* refer to the step by name now *)
|
(* refer to the step by name now *)
|
||||||
L_proofs.add lid (lazy (P.ref_by_name name));
|
L_proofs.add lid (lazy (P.ref_by_name name));
|
||||||
|
|
||||||
| PS.Step_view.Step_unsat us -> () (* TODO *)
|
| PS.Step_view.Step_unsat { c=uclause } ->
|
||||||
| PS.Step_view.Step_rup rup -> () (* TODO *)
|
let c = [] in
|
||||||
|
let name = "unsat" in
|
||||||
|
add_needed_step uclause;
|
||||||
|
let name_c = name_clause uclause in
|
||||||
|
add_top_step (lazy (P.S_step_c{name; res=c; proof=P.ref_by_name name_c}));
|
||||||
|
|
||||||
|
| PS.Step_view.Step_cc { eqns } ->
|
||||||
|
let c = conv_lits eqns in
|
||||||
|
let name = name_clause lid in
|
||||||
|
let step = lazy (
|
||||||
|
let lazy c = c in
|
||||||
|
P.S_step_c {name; res=c; proof=P.cc_lemma c}
|
||||||
|
) in
|
||||||
|
add_top_step step;
|
||||||
|
L_proofs.add lid (lazy (P.ref_by_name name))
|
||||||
|
|
||||||
|
| PS.Step_view.Fun_decl { f } ->
|
||||||
|
Util.Int_tbl.add funs id f;
|
||||||
|
|
||||||
|
| PS.Step_view.Expr_eq { lhs; rhs } ->
|
||||||
|
add_needed_step lhs;
|
||||||
|
add_needed_step rhs;
|
||||||
|
let t = lazy (
|
||||||
|
let lhs = L_terms.find lhs
|
||||||
|
and rhs = L_terms.find rhs in
|
||||||
|
P.T.eq lhs rhs
|
||||||
|
) in
|
||||||
|
L_terms.add lid t
|
||||||
|
|
||||||
|
| PS.Step_view.Expr_bool {b} ->
|
||||||
|
let t = Lazy.from_val (P.T.bool b) in
|
||||||
|
L_terms.add lid t
|
||||||
|
|
||||||
|
| PS.Step_view.Expr_app { f; args } ->
|
||||||
|
add_needed_step f;
|
||||||
|
Array.iter add_needed_step args;
|
||||||
|
let t = lazy (
|
||||||
|
let f =
|
||||||
|
try Util.Int_tbl.find funs (Int32.to_int f)
|
||||||
|
with Not_found -> Error.errorf "unknown function '%ld'" f
|
||||||
|
in
|
||||||
|
let args = Array.map L_terms.find args in
|
||||||
|
P.T.app_fun f args
|
||||||
|
) in
|
||||||
|
L_terms.add lid t
|
||||||
|
|
||||||
|
| PS.Step_view.Expr_def _ -> () (* TODO *)
|
||||||
|
| PS.Step_view.Expr_if _ -> () (* TODO *)
|
||||||
|
| PS.Step_view.Expr_not _ -> () (* TODO *)
|
||||||
|
|
||||||
|
| PS.Step_view.Step_rup { res; hyps } ->
|
||||||
|
let res = conv_clause res in
|
||||||
|
Array.iter add_needed_step hyps;
|
||||||
|
let name = name_clause lid in
|
||||||
|
let step = lazy (
|
||||||
|
let lazy res = res in
|
||||||
|
let hyps = Util.array_to_list_map L_proofs.find hyps in
|
||||||
|
P.S_step_c {name; res; proof=P.rup res hyps}
|
||||||
|
) in
|
||||||
|
add_top_step step;
|
||||||
|
L_proofs.add lid (lazy (P.ref_by_name name));
|
||||||
|
|
||||||
|
| PS.Step_view.Step_clause_rw { c; res; using } ->
|
||||||
|
let res = conv_clause res in
|
||||||
|
add_needed_step c;
|
||||||
|
Array.iter add_needed_step using;
|
||||||
|
let name = name_clause lid in
|
||||||
|
|
||||||
|
let step = lazy (
|
||||||
|
let lazy res = res in
|
||||||
|
let c = L_proofs.find c in
|
||||||
|
let using = Util.array_to_list_map L_proofs.find using in
|
||||||
|
P.S_step_c {name; res; proof=P.Clause_rw {res; c0=c; using}}
|
||||||
|
) in
|
||||||
|
add_top_step step;
|
||||||
|
L_proofs.add lid (lazy (P.ref_by_name name))
|
||||||
|
|
||||||
| PS.Step_view.Step_bridge_lit_expr _ -> assert false
|
| PS.Step_view.Step_bridge_lit_expr _ -> assert false
|
||||||
| PS.Step_view.Step_cc cc -> () (* TODO *)
|
|
||||||
| PS.Step_view.Step_preprocess _ -> () (* TODO *)
|
| PS.Step_view.Step_preprocess _ -> () (* TODO *)
|
||||||
| PS.Step_view.Step_clause_rw _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Step_bool_tauto _ -> () (* TODO *)
|
| PS.Step_view.Step_bool_tauto _ -> () (* TODO *)
|
||||||
| PS.Step_view.Step_bool_c _ -> () (* TODO *)
|
| PS.Step_view.Step_bool_c _ -> () (* TODO *)
|
||||||
| PS.Step_view.Step_proof_p1 _ -> () (* TODO *)
|
| PS.Step_view.Step_proof_p1 _ -> () (* TODO *)
|
||||||
| PS.Step_view.Step_true _ -> () (* TODO *)
|
| PS.Step_view.Step_true _ -> () (* TODO *)
|
||||||
| PS.Step_view.Fun_decl _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Expr_def _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Expr_bool _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Expr_if _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Expr_not _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Expr_eq _ -> () (* TODO *)
|
|
||||||
| PS.Step_view.Expr_app _ -> () (* TODO *)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -248,10 +248,10 @@ module type PROOF = sig
|
||||||
From now on, [t] and [u] will be used interchangeably.
|
From now on, [t] and [u] will be used interchangeably.
|
||||||
@return a proof_rule ID for the clause [(t=u)]. *)
|
@return a proof_rule ID for the clause [(t=u)]. *)
|
||||||
|
|
||||||
val lemma_rw_clause : proof_step -> using:proof_step Iter.t -> proof_rule
|
val lemma_rw_clause : proof_step -> res:lit Iter.t -> using:proof_step Iter.t -> proof_rule
|
||||||
(** [lemma_rw_clause prc ~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 [c']. 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). *)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
let pr = A.lemma_lra (Iter.of_list lits) PA.proof in
|
let pr = A.lemma_lra (Iter.of_list lits) PA.proof in
|
||||||
let pr = match using with
|
let pr = match using with
|
||||||
| None -> pr
|
| None -> pr
|
||||||
| Some using -> SI.P.lemma_rw_clause pr ~using PA.proof in
|
| Some using -> SI.P.lemma_rw_clause pr ~res:(Iter.of_list lits) ~using PA.proof in
|
||||||
PA.add_clause lits pr
|
PA.add_clause lits pr
|
||||||
|
|
||||||
(* preprocess linear expressions away *)
|
(* preprocess linear expressions away *)
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ type Step_preprocess {
|
||||||
|
|
||||||
type Step_clause_rw {
|
type Step_clause_rw {
|
||||||
c: ID
|
c: ID
|
||||||
|
res: Clause
|
||||||
using: []ID
|
using: []ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -483,21 +483,24 @@ end
|
||||||
module Step_clause_rw = struct
|
module Step_clause_rw = struct
|
||||||
type t = {
|
type t = {
|
||||||
c: ID.t;
|
c: ID.t;
|
||||||
|
res: Clause.t;
|
||||||
using: ID.t array;
|
using: ID.t array;
|
||||||
}
|
}
|
||||||
|
|
||||||
(** @raise Bare.Decode.Error in case of error. *)
|
(** @raise Bare.Decode.Error in case of error. *)
|
||||||
let decode (dec: Bare.Decode.t) : t =
|
let decode (dec: Bare.Decode.t) : t =
|
||||||
let c = ID.decode dec in
|
let c = ID.decode dec in
|
||||||
|
let res = Clause.decode dec in
|
||||||
let using =
|
let using =
|
||||||
(let len = Bare.Decode.uint dec in
|
(let len = Bare.Decode.uint dec in
|
||||||
if len>Int64.of_int Sys.max_array_length then raise (Bare.Decode.Error"array too big");
|
if len>Int64.of_int Sys.max_array_length then raise (Bare.Decode.Error"array too big");
|
||||||
Array.init (Int64.to_int len) (fun _ -> ID.decode dec)) in
|
Array.init (Int64.to_int len) (fun _ -> ID.decode dec)) in
|
||||||
{c; using; }
|
{c; res; using; }
|
||||||
|
|
||||||
let encode (enc: Bare.Encode.t) (self: t) : unit =
|
let encode (enc: Bare.Encode.t) (self: t) : unit =
|
||||||
begin
|
begin
|
||||||
ID.encode enc self.c;
|
ID.encode enc self.c;
|
||||||
|
Clause.encode enc self.res;
|
||||||
(let arr = self.using in
|
(let arr = self.using in
|
||||||
Bare.Encode.uint enc (Int64.of_int (Array.length arr));
|
Bare.Encode.uint enc (Int64.of_int (Array.length arr));
|
||||||
Array.iter (fun xi -> ID.encode enc xi) arr);
|
Array.iter (fun xi -> ID.encode enc xi) arr);
|
||||||
|
|
@ -508,6 +511,7 @@ module Step_clause_rw = struct
|
||||||
begin
|
begin
|
||||||
Format.fprintf out "{ @[";
|
Format.fprintf out "{ @[";
|
||||||
Format.fprintf out "c=%a;@ " ID.pp x.c;
|
Format.fprintf out "c=%a;@ " ID.pp x.c;
|
||||||
|
Format.fprintf out "res=%a;@ " Clause.pp x.res;
|
||||||
Format.fprintf out "using=%a;@ " (Bare.Pp.array ID.pp) x.using;
|
Format.fprintf out "using=%a;@ " (Bare.Pp.array ID.pp) x.using;
|
||||||
Format.fprintf out "@]}";
|
Format.fprintf out "@]}";
|
||||||
end) out self
|
end) out self
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ module T = struct
|
||||||
|
|
||||||
let true_ : t = Bool true
|
let true_ : t = Bool true
|
||||||
let false_ : t = Bool false
|
let false_ : t = Bool false
|
||||||
|
let bool b = Bool b
|
||||||
let not_ = function Not x -> x | x -> Not x
|
let not_ = function Not x -> x | x -> Not x
|
||||||
let eq a b : t = Eq (a,b)
|
let eq a b : t = Eq (a,b)
|
||||||
let ref id : t = Ref id
|
let ref id : t = Ref id
|
||||||
|
|
@ -115,6 +116,12 @@ type t =
|
||||||
| Hres of t * hres_step list
|
| Hres of t * hres_step list
|
||||||
| Res of term * t * t
|
| Res of term * t * t
|
||||||
| Res1 of t * t
|
| Res1 of t * t
|
||||||
|
| Rup of clause * t list
|
||||||
|
| Clause_rw of {
|
||||||
|
res: clause;
|
||||||
|
c0: t;
|
||||||
|
using: t list; (** the rewriting equations/atoms *)
|
||||||
|
}
|
||||||
| DT_isa_split of ty * term list
|
| DT_isa_split of ty * term list
|
||||||
| DT_isa_disj of ty * term * term
|
| DT_isa_disj of ty * term * term
|
||||||
| DT_cstor_inj of Cstor.t * int * term list * term list (* [c t…=c u… |- t_i=u_i] *)
|
| DT_cstor_inj of Cstor.t * int * term list * term list (* [c t…=c u… |- t_i=u_i] *)
|
||||||
|
|
@ -178,6 +185,8 @@ let cc_imply2 h1 h2 t u : t = CC_lemma_imply ([h1; h2], t, u)
|
||||||
let assertion t = Assertion t
|
let assertion t = Assertion t
|
||||||
let assertion_c c = Assertion_c (Iter.to_rev_list c)
|
let assertion_c c = Assertion_c (Iter.to_rev_list c)
|
||||||
let assertion_c_l c = Assertion_c c
|
let assertion_c_l c = Assertion_c c
|
||||||
|
let rup c hyps : t = Rup (c,hyps)
|
||||||
|
let clause_rw c0 ~res ~using : t = Clause_rw{res;c0;using}
|
||||||
let composite_a ?(assms=[]) steps : t =
|
let composite_a ?(assms=[]) steps : t =
|
||||||
Composite {assumptions=assms; steps}
|
Composite {assumptions=assms; steps}
|
||||||
let composite_l ?(assms=[]) steps : t =
|
let composite_l ?(assms=[]) steps : t =
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,10 @@ module Make_printer(Out : OUT) = struct
|
||||||
| Hres (c, steps) -> l[a"hres";pp_rec c;l(List.map pp_hres_step steps)]
|
| Hres (c, steps) -> l[a"hres";pp_rec c;l(List.map pp_hres_step steps)]
|
||||||
| Res (t,p1,p2) -> l[a"r";pp_t t;pp_rec p1;pp_rec p2]
|
| Res (t,p1,p2) -> l[a"r";pp_t t;pp_rec p1;pp_rec p2]
|
||||||
| Res1 (p1,p2) -> l[a"r1";pp_rec p1;pp_rec p2]
|
| Res1 (p1,p2) -> l[a"r1";pp_rec p1;pp_rec p2]
|
||||||
|
| Rup (c, hyps) ->
|
||||||
|
l[a"rup";pp_cl c;l(List.map pp_rec hyps)]
|
||||||
|
| Clause_rw{res; c0; using} ->
|
||||||
|
l[a"clause-rw";pp_cl res;pp_rec c0;l(List.map pp_rec using)]
|
||||||
| DT_isa_split (ty,cs) ->
|
| DT_isa_split (ty,cs) ->
|
||||||
l[a"dt.isa.split";pp_ty ty;l(a"cases"::List.map pp_t cs)]
|
l[a"dt.isa.split";pp_ty ty;l(a"cases"::List.map pp_t cs)]
|
||||||
| DT_isa_disj (ty,t,u) ->
|
| DT_isa_disj (ty,t,u) ->
|
||||||
|
|
|
||||||
|
|
@ -2168,12 +2168,13 @@ module Make(Plugin : PLUGIN)
|
||||||
in
|
in
|
||||||
let unsat_conflict = match us with
|
let unsat_conflict = match us with
|
||||||
| US_false c0 ->
|
| US_false c0 ->
|
||||||
Log.debugf 1 (fun k->k"unsat conflict clause %a" (Clause.debug store) c0);
|
Log.debugf 10 (fun k->k"unsat conflict clause %a" (Clause.debug store) c0);
|
||||||
let c = resolve_with_lvl0 self c0 in
|
let c = resolve_with_lvl0 self c0 in
|
||||||
Log.debugf 1 (fun k->k"proper conflict clause %a" (Clause.debug store) c);
|
Log.debugf 10 (fun k->k"proper conflict clause %a" (Clause.debug store) c);
|
||||||
(fun() -> c)
|
(fun() -> c)
|
||||||
| US_local {core=[]; _} -> assert false
|
| US_local {core=[]; _} -> assert false
|
||||||
| US_local {first; core} ->
|
| US_local {first; core} ->
|
||||||
|
(* TODO: do we need to filter out literals? *)
|
||||||
let c = lazy (
|
let c = lazy (
|
||||||
let core = List.rev core in (* increasing trail order *)
|
let core = List.rev core in (* increasing trail order *)
|
||||||
assert (Atom.equal first @@ List.hd core);
|
assert (Atom.equal first @@ List.hd core);
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,9 @@ module Make(A : ARG)
|
||||||
let steps = ref [] in
|
let steps = ref [] in
|
||||||
let c' = CCList.map (preprocess_lit ~steps) c in
|
let c' = CCList.map (preprocess_lit ~steps) c in
|
||||||
let pr_c' =
|
let pr_c' =
|
||||||
A.P.lemma_rw_clause pr_c ~using:(Iter.of_list !steps) proof
|
A.P.lemma_rw_clause pr_c
|
||||||
|
~res:(Iter.of_list c')
|
||||||
|
~using:(Iter.of_list !steps) proof
|
||||||
in
|
in
|
||||||
A0.add_clause c' pr_c'
|
A0.add_clause c' pr_c'
|
||||||
|
|
||||||
|
|
@ -455,7 +457,8 @@ module Make(A : ARG)
|
||||||
let pacts = preprocess_acts_of_acts self acts in
|
let pacts = preprocess_acts_of_acts self acts in
|
||||||
let c = CCList.map (preprocess_lit_ ~steps self pacts) c in
|
let c = CCList.map (preprocess_lit_ ~steps self pacts) c in
|
||||||
let pr =
|
let pr =
|
||||||
P.lemma_rw_clause proof ~using:(Iter.of_list !steps) self.proof
|
P.lemma_rw_clause proof
|
||||||
|
~res:(Iter.of_list c) ~using:(Iter.of_list !steps) self.proof
|
||||||
in
|
in
|
||||||
c, pr
|
c, pr
|
||||||
|
|
||||||
|
|
@ -783,7 +786,8 @@ module Make(A : ARG)
|
||||||
(* TODO: if c != c0 then P.emit_redundant_clause c
|
(* TODO: if c != c0 then P.emit_redundant_clause c
|
||||||
because we jsut preprocessed it away? *)
|
because we jsut preprocessed it away? *)
|
||||||
let pr = P.emit_input_clause (Iter.of_list c) self.proof in
|
let pr = P.emit_input_clause (Iter.of_list c) self.proof in
|
||||||
let pr = P.lemma_rw_clause pr ~using:(Iter.of_list !steps) self.proof in
|
let pr = P.lemma_rw_clause pr
|
||||||
|
~res:(Iter.of_list c) ~using:(Iter.of_list !steps) self.proof in
|
||||||
add_clause_l self c pr
|
add_clause_l self c pr
|
||||||
|
|
||||||
let assert_term self t = assert_terms self [t]
|
let assert_term self t = assert_terms self [t]
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,12 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
let steps = ref [] in
|
let steps = ref [] in
|
||||||
let add_step_ s = steps := s :: !steps in
|
let add_step_ s = steps := s :: !steps in
|
||||||
|
|
||||||
|
let add_step_eq a b ~using ~c0 :unit =
|
||||||
|
add_step_ @@ SI.P.lemma_rw_clause c0 (SI.Simplify.proof simp)
|
||||||
|
~using
|
||||||
|
~res:(Iter.return (Lit.atom tst (A.mk_bool tst (B_eq (a,b)))))
|
||||||
|
in
|
||||||
|
|
||||||
let[@inline] ret u =
|
let[@inline] ret u =
|
||||||
Some (u, Iter.of_list !steps)
|
Some (u, Iter.of_list !steps)
|
||||||
in
|
in
|
||||||
|
|
@ -170,13 +176,13 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
CCOpt.iter add_step_ prf_a;
|
CCOpt.iter add_step_ prf_a;
|
||||||
begin match A.view_as_bool a with
|
begin match A.view_as_bool a with
|
||||||
| B_bool true ->
|
| B_bool true ->
|
||||||
add_step_ @@ SI.P.lemma_rw_clause ~using:(Iter.of_opt prf_a)
|
add_step_eq t b ~using:(Iter.of_opt prf_a)
|
||||||
(A.lemma_ite_true ~ite:t proof) proof;
|
~c0:(A.lemma_ite_true ~ite:t proof);
|
||||||
ret b
|
ret b
|
||||||
|
|
||||||
| B_bool false ->
|
| B_bool false ->
|
||||||
add_step_ @@ SI.P.lemma_rw_clause ~using:(Iter.of_opt prf_a)
|
add_step_eq t c ~using:(Iter.of_opt prf_a)
|
||||||
(A.lemma_ite_false ~ite:t proof) proof;
|
~c0:(A.lemma_ite_false ~ite:t proof);
|
||||||
ret c
|
ret c
|
||||||
|
|
||||||
| _ ->
|
| _ ->
|
||||||
|
|
@ -208,11 +214,10 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
let proxy = fresh_term ~for_t ~pre self (Ty.bool self.ty_st) in
|
let proxy = fresh_term ~for_t ~pre self (Ty.bool self.ty_st) in
|
||||||
proxy, mk_lit proxy
|
proxy, mk_lit proxy
|
||||||
|
|
||||||
|
let pr_p1 p s1 s2 = SI.P.proof_p1 s1 s2 p
|
||||||
let pr_p1_opt p s1 s2 : SI.proof_step =
|
let pr_p1_opt p s1 s2 : SI.proof_step =
|
||||||
CCOpt.map_or ~default:s2 (fun s1 -> SI.P.proof_p1 s1 s2 p) s1
|
CCOpt.map_or ~default:s2 (fun s1 -> SI.P.proof_p1 s1 s2 p) s1
|
||||||
|
|
||||||
let pr_p1 p s1 s2 = SI.P.proof_p1 s1 s2 p
|
|
||||||
|
|
||||||
(* preprocess "ite" away *)
|
(* preprocess "ite" away *)
|
||||||
let preproc_ite self si (module PA:SI.PREPROCESS_ACTS)
|
let preproc_ite self si (module PA:SI.PREPROCESS_ACTS)
|
||||||
(t:T.t) : (T.t * SI.proof_step Iter.t) option =
|
(t:T.t) : (T.t * SI.proof_step Iter.t) option =
|
||||||
|
|
@ -221,6 +226,11 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
|
|
||||||
let ret t = Some (t, Iter.of_list !steps) in
|
let ret t = Some (t, Iter.of_list !steps) in
|
||||||
|
|
||||||
|
let add_clause_rw lits ~using ~c0 : unit =
|
||||||
|
PA.add_clause lits @@
|
||||||
|
SI.P.lemma_rw_clause c0 ~res:(Iter.of_list lits) ~using PA.proof
|
||||||
|
in
|
||||||
|
|
||||||
match A.view_as_bool t with
|
match A.view_as_bool t with
|
||||||
| B_ite (a,b,c) ->
|
| B_ite (a,b,c) ->
|
||||||
let a', pr_a = SI.simp_t si a in
|
let a', pr_a = SI.simp_t si a in
|
||||||
|
|
@ -228,26 +238,26 @@ module Make(A : ARG) : S with module A = A = struct
|
||||||
begin match A.view_as_bool a' with
|
begin match A.view_as_bool a' with
|
||||||
| B_bool true ->
|
| B_bool true ->
|
||||||
(* [a |- ite a b c=b], [a=true] implies [ite a b c=b] *)
|
(* [a |- ite a b c=b], [a=true] implies [ite a b c=b] *)
|
||||||
add_step_ @@ SI.P.lemma_rw_clause ~using:(Iter.of_opt pr_a)
|
add_step_
|
||||||
(A.lemma_ite_true ~ite:t PA.proof) PA.proof;
|
(pr_p1_opt PA.proof pr_a @@ A.lemma_ite_true ~ite:t PA.proof);
|
||||||
ret b
|
ret b
|
||||||
|
|
||||||
| B_bool false ->
|
| B_bool false ->
|
||||||
(* [¬a |- ite a b c=c], [a=false] implies [ite a b c=c] *)
|
(* [¬a |- ite a b c=c], [a=false] implies [ite a b c=c] *)
|
||||||
add_step_ @@ SI.P.lemma_rw_clause ~using:(Iter.of_opt pr_a)
|
add_step_
|
||||||
(A.lemma_ite_false ~ite:t PA.proof) PA.proof;
|
(pr_p1_opt PA.proof pr_a @@ A.lemma_ite_false ~ite:t PA.proof);
|
||||||
ret c
|
ret c
|
||||||
|
|
||||||
| _ ->
|
| _ ->
|
||||||
let t_ite = fresh_term self ~for_t:t ~pre:"ite" (T.ty b) in
|
let t_ite = fresh_term self ~for_t:t ~pre:"ite" (T.ty b) in
|
||||||
let pr_def = SI.P.define_term t_ite t PA.proof in
|
let pr_def = SI.P.define_term t_ite t PA.proof in
|
||||||
let lit_a = PA.mk_lit_nopreproc a' in
|
let lit_a = PA.mk_lit_nopreproc a' in
|
||||||
PA.add_clause [Lit.neg lit_a; PA.mk_lit_nopreproc (eq self.tst t_ite b)]
|
add_clause_rw [Lit.neg lit_a; PA.mk_lit_nopreproc (eq self.tst t_ite b)]
|
||||||
(SI.P.lemma_rw_clause ~using:Iter.(append (return pr_def) (of_opt pr_a))
|
~using:Iter.(append (return pr_def) (of_opt pr_a))
|
||||||
(A.lemma_ite_true ~ite:t PA.proof) PA.proof);
|
~c0:(A.lemma_ite_true ~ite:t PA.proof);
|
||||||
PA.add_clause [lit_a; PA.mk_lit_nopreproc (eq self.tst t_ite c)]
|
add_clause_rw [lit_a; PA.mk_lit_nopreproc (eq self.tst t_ite c)]
|
||||||
(SI.P.lemma_rw_clause ~using:Iter.(append (return pr_def) (of_opt pr_a))
|
~using:Iter.(append (return pr_def) (of_opt pr_a))
|
||||||
(A.lemma_ite_false ~ite:t PA.proof) PA.proof);
|
~c0:(A.lemma_ite_false ~ite:t PA.proof);
|
||||||
ret t_ite
|
ret t_ite
|
||||||
end
|
end
|
||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
|
||||||
|
|
@ -53,3 +53,4 @@ module Int_set = CCSet.Make(CCInt)
|
||||||
module Int_map = CCMap.Make(CCInt)
|
module Int_map = CCMap.Make(CCInt)
|
||||||
module Int_tbl = CCHashtbl.Make(CCInt)
|
module Int_tbl = CCHashtbl.Make(CCInt)
|
||||||
|
|
||||||
|
module Str_tbl = CCHashtbl.Make(CCString)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue