module Pp = CicPp
module PEH = ProofEngineHelpers
module HEL = HExtlib
+module DTI = DoubleTypeInference
module Cl = ProceduralClassify
module T = ProceduralTypes
max_depth: int option;
depth: int;
context: C.context;
- intros: string list;
+ intros: string option list;
+ clears: string list;
+ clears_note: string;
case: int list
}
(* proof construction *******************************************************)
-let unused_premise = "UNUSED"
-
let mk_exp_args hd tl classes synth =
let meta id = C.AImplicit (id, None) in
let map v (cl, b) =
if Ut.alpha_equivalence csty w then []
else
[T.Note (Pp.ppterm csty); T.Note (Pp.ppterm w);
- T.Change (sty, ety, Some (id, id), e, "")]
+ T.Change (sty, ety, Some (id, Some id), e, "")]
end
let get_intro = function
- | C.Anonymous -> unused_premise
- | C.Name s -> s
+ | C.Anonymous -> None
+ | C.Name s -> Some s
let mk_intros st script =
- if st.intros = [] then script else
- let count = List.length st.intros in
- T.Intros (Some count, List.rev st.intros, "") :: script
+ let intros st script =
+ if st.intros = [] then script else
+ let count = List.length st.intros in
+ T.Intros (Some count, List.rev st.intros, "") :: script
+ in
+ let clears st script =
+ if st.clears = [] then script else T.Clear (st.clears, st.clears_note) :: script
+ in
+ intros st (clears st script)
let mk_arg st = function
| C.ARel (_, _, i, name) as what -> convert st ~name:(name, i) what
| C.ARel (_, _, _, premise) ->
let script = mk_arg st what in
let where = Some (premise, name) in
- T.Rewrite (direction, what, where, e, dtext) :: script
+ let st = {st with context = Cn.clear st.context premise} in
+ st, T.Rewrite (direction, what, where, e, dtext) :: script
| _ -> assert false
let mk_rewrite st dtext what qs tl direction =
[T.Rewrite (direction, what, None, e, dtext); T.Branch (qs, "")]
let rec proc_lambda st name v t =
+ let dno = DTI.does_not_occur 1 (cic t) in
+ let dno = dno && match get_inner_types st v with
+ | None -> true
+ | Some (it, et) ->
+ DTI.does_not_occur 1 (cic it) && DTI.does_not_occur 1 (cic et)
+ in
+ let name = if dno then C.Anonymous else name in
let entry = Some (name, C.Decl (cic v)) in
let intro = get_intro name in
proc_proof (add st entry intro) t
let intro = get_intro name in
let proceed, dtext = test_depth st in
let script = if proceed then
- let hyp, rqv = match get_inner_types st v with
+ let st, hyp, rqv = match get_inner_types st v with
| Some (ity, _) ->
- let rqv = match v with
+ let st, rqv = match v with
| C.AAppl (_, hd :: tl) when is_fwd_rewrite_right hd tl ->
mk_fwd_rewrite st dtext intro tl true
| C.AAppl (_, hd :: tl) when is_fwd_rewrite_left hd tl ->
mk_fwd_rewrite st dtext intro tl false
| v ->
let qs = [proc_proof (next st) v; [T.Id ""]] in
- [T.Branch (qs, ""); T.Cut (intro, ity, dtext)]
+ st, [T.Branch (qs, ""); T.Cut (intro, ity, dtext)]
in
- C.Decl (cic ity), rqv
+ st, C.Decl (cic ity), rqv
| None ->
- C.Def (cic v, None), [T.LetIn (intro, v, dtext)]
+ st, C.Def (cic v, None), [T.LetIn (intro, v, dtext)]
in
let entry = Some (name, hyp) in
let qt = proc_proof (next (add st entry intro)) t in
let script = [T.Note text] in
mk_intros st script
-and proc_proof st = function
- | C.ALambda (_, name, w, t) -> proc_lambda st name w t
- | C.ALetIn (_, name, v, t) as what -> proc_letin st what name v t
- | C.ARel _ as what -> proc_rel st what
- | C.AMutConstruct _ as what -> proc_mutconstruct st what
- | C.AAppl (_, hd :: tl) as what -> proc_appl st what hd tl
- | what -> proc_other st what
+and proc_proof st t =
+ let f st =
+ let xet = match get_inner_types st t with
+ | Some (_, et) -> Some (cic et)
+ | None -> None
+ in
+ let context, clears = Cn.get_clears st.context (cic t) xet in
+ let note = Pp.ppcontext st.context in
+ {st with context = context; clears = clears; clears_note = note}
+ in
+ match t with
+ | C.ALambda (_, name, w, t) -> proc_lambda st name w t
+ | C.ALetIn (_, name, v, t) as what -> proc_letin (f st) what name v t
+ | C.ARel _ as what -> proc_rel (f st) what
+ | C.AMutConstruct _ as what -> proc_mutconstruct (f st) what
+ | C.AAppl (_, hd :: tl) as what -> proc_appl (f st) what hd tl
+ | what -> proc_other (f st) what
and proc_bkd_proofs st synth names classes ts =
try
let ast = proc_proof st v in
let count = T.count_steps 0 ast in
let text = Printf.sprintf "tactics: %u" count in
- T.Theorem (s, t, "") :: ast @ [T.Qed text]
+ T.Theorem (Some s, t, "") :: ast @ [T.Qed text]
| _ ->
failwith "not a theorem"
let acic2procedural ~ids_to_inner_sorts ~ids_to_inner_types ?depth prefix aobj =
let st = {
- sorts = ids_to_inner_sorts;
- types = ids_to_inner_types;
- prefix = prefix;
- max_depth = depth;
- depth = 0;
- context = [];
- intros = [];
- case = []
+ sorts = ids_to_inner_sorts;
+ types = ids_to_inner_types;
+ prefix = prefix;
+ max_depth = depth;
+ depth = 0;
+ context = [];
+ intros = [];
+ clears = [];
+ clears_note = "";
+ case = []
} in
HLog.debug "Procedural: level 2 transformation";
let steps = proc_obj st aobj in