max_depth: int option;
depth : int;
defaults : bool;
+ cr : bool;
context : C.context;
case : int list
}
let get_type msg st t = H.get_type msg st.context (H.cic t)
let get_uri_of_head = function
- | C.AConst (_, u, _)
- | C.AAppl (_, C.AConst (_, u, _) :: _) -> Some (u, 0, 0)
- | C.AMutInd (_, u, i, _)
- | C.AAppl (_, C.AMutInd (_, u, i, _) :: _) -> Some (u, succ i, 0)
- | C.AMutConstruct (_, u, i, j, _)
- | C.AAppl (_, C.AMutConstruct (_, u, i, j, _) :: _) -> Some (u, succ i, j)
- | _ -> None
+ | C.AConst (_, u, _) ->
+ Some (u, 0, 0, 0)
+ | C.AAppl (_, C.AConst (_, u, _) :: vs) ->
+ Some (u, 0, 0, List.length vs)
+ | C.AMutInd (_, u, i, _) ->
+ Some (u, succ i, 0, 0)
+ | C.AAppl (_, C.AMutInd (_, u, i, _) :: vs) ->
+ Some (u, succ i, 0, List.length vs)
+ | C.AMutConstruct (_, u, i, j, _) ->
+ Some (u, succ i, j, 0)
+ | C.AAppl (_, C.AMutConstruct (_, u, i, j, _) :: vs) ->
+ Some (u, succ i, j, List.length vs)
+ | _ ->
+ None
let get_uri_of_apply = function
| T.Exact (t, _)
let is_reflexivity st step =
match get_uri_of_apply step with
- | None -> false
- | Some (uri, i, j) -> st.defaults && Obj.is_eq_URI uri && i = 1 && j = 1
+ | None -> false
+ | Some (uri, i, j, n) ->
+ st.defaults && Obj.is_eq_URI uri && i = 1 && j = 1 && n = 0
+
+let is_ho_reflexivity st step =
+ match get_uri_of_apply step with
+ | None -> false
+ | Some (uri, i, j, n) ->
+ st.defaults && Obj.is_eq_URI uri && i = 1 && j = 1 && n > 0
let are_convertible st pred sx dx =
let pred, sx, dx = H.cic pred, H.cic sx, H.cic dx in
let anonymous_premise = C.Name "UNNAMED"
-let mk_exp_args hd tl classes synth qs =
+let mk_lapply_args hd tl classes =
+ let map _ = Cn.meta "" in
+ let args = List.rev_map map tl in
+ if args = [] then hd else C.AAppl ("", hd :: args)
+
+let mk_apply_args hd tl classes synth qs =
let exp = ref 0 in
- let meta id = C.AImplicit (id, None) in
let map v (cl, b) =
if I.overlaps synth cl
- then if b then v, v else meta "", v
- else meta "", meta ""
+ then if b then v, v else Cn.meta "", v
+ else Cn.meta "", Cn.meta ""
in
let rec rev a = function
| [] -> a
| hd :: tl ->
- if snd hd <> meta "" then incr exp;
+ if snd hd <> Cn.meta "" then incr exp;
rev (snd hd :: a) tl
in
let rec aux = function
| [] -> []
| hd :: tl ->
- if fst hd = meta "" then aux tl else rev [] (hd :: tl)
+ if fst hd = Cn.meta "" then aux tl else rev [] (hd :: tl)
in
let args = T.list_rev_map2 map tl classes in
let args = aux args in
let mk_preamble st what script = match script with
| step :: script when is_reflexivity st step ->
+ T.Reflexivity (T.note_of_step step) :: script
+ | step :: script when is_ho_reflexivity st step ->
convert st what @ T.Reflexivity (T.note_of_step step) :: script
| T.Exact _ :: _ -> script
| _ -> convert st what @ script
let e = Cn.mk_pattern 1 ity pred in
let script = [T.Branch (qs, "")] in
if Cn.does_not_occur e then script else
- if are_convertible st pred sx dx then
+ if st.cr && are_convertible st pred sx dx then
let dtext = "convertible rewrite" ^ dtext in
let ity, ety, e = Cn.beta sx pred, Cn.beta dx pred, Cn.hole "" in
let city, cety = H.cic ity, H.cic ety in
mk_fwd_rewrite st dtext intro tl true v t ity ety
| C.AAppl (_, hd :: tl) when is_fwd_rewrite_left st hd tl ->
mk_fwd_rewrite st dtext intro tl false v t ity ety
+ | C.AAppl (_, hd :: tl) ->
+ let ty = match get_inner_types st hd with
+ | Some (ity, _) -> H.cic ity
+ | None -> get_type "TC3" st hd
+ in
+ let classes, _ = Cl.classify st.context ty in
+ let parsno, argsno = List.length classes, List.length tl in
+ let decurry = parsno - argsno in
+ if decurry <> 0 then begin
+(* FG: we fall back in the cut case *)
+ assert (Ut.is_sober st.context (H.cic ety));
+ let ety = H.acic_bc st.context ety in
+ let qs = [proc_proof (next st) v; [T.Id ""]] in
+ st, [T.Branch (qs, ""); T.Cut (intro, ety, dtext)]
+ end else
+ let names, synth = get_sub_names hd tl, I.S.empty in
+ let qs = proc_bkd_proofs (next st) synth names classes tl in
+ let hd = mk_lapply_args hd tl classes in
+ let qs = [T.Id ""] :: qs in
+ st, [T.Branch (qs, ""); T.LApply (intro, hd, dtext)]
| v ->
assert (Ut.is_sober st.context (H.cic ety));
let ety = H.acic_bc st.context ety in
in
if List.length qs <> List.length names then
let qs = proc_bkd_proofs (next st) synth [] classes tl in
- let b, hd, qs = mk_exp_args hd tl classes synth qs in
+ let b, hd, qs = mk_apply_args hd tl classes synth qs in
script @ [tactic b hd (dtext ^ text); T.Branch (qs, "")]
else if is_rewrite_right st hd then
script2 @ mk_rewrite st dtext where qs tl2 false what ity
| _ ->
let names = get_sub_names hd tl in
let qs = proc_bkd_proofs (next st) synth names classes tl in
- let b, hd, qs = mk_exp_args hd tl classes synth qs in
+ let b, hd, qs = mk_apply_args hd tl classes synth qs in
script @ [tactic b hd (dtext ^ text); T.Branch (qs, "")]
else
[T.Exact (what, dtext)]
max_depth = List.fold_left depth_map None params;
depth = 0;
defaults = not (List.mem G.IPNoDefaults params);
+ cr = List.mem G.IPCR params;
context = context;
case = []
}