Skip to content

Commit b6dcad4

Browse files
committed
optimize non-applicative stack nodes
When unifying terms that both have a Case, Fix or Proj node in their arguments stack, unify and remove the longest suffix of the stack containing applicative nodes or the last nodes if none exists.
1 parent 8e6284f commit b6dcad4

File tree

1 file changed

+64
-2
lines changed

1 file changed

+64
-2
lines changed

pretyping/evarconv.ml

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,56 @@ let rec exact_ise_stack2 env evd f sk1 sk2 =
609609
ise_rev_stack2 evd (List.rev sk1) (List.rev sk2)
610610
else UnifFailure (evd, (* Dummy *) NotSameHead)
611611

612+
(* Removes the last group of applicative stack nodes or one node if the last node is not applicative. *)
613+
let ise_stack2_once env evd f sk1 sk2 =
614+
let ise_rev_stack2 i revsk1 revsk2 =
615+
let stop app revsk1 revsk2 i = Some (app, List.rev revsk1, List.rev revsk2, i) in
616+
match revsk1, revsk2 with
617+
| [], [] -> (* We want to see a non-applicative node*) None
618+
| Stack.Case cse1 :: q1, Stack.Case cse2 :: q2 ->
619+
let () = debug_unification (fun () -> Pp.(v 0 (str "ise_stack2_once : case" ++ cut ()))) in
620+
let (ci1, u1, pms1, (t1,_), br1) = Stack.expand_case env evd cse1 in
621+
let (ci2, u2, pms2, (t2,_), br2) = Stack.expand_case env evd cse2 in
622+
let hd1 = mkIndU (ci1.ci_ind, u1) in
623+
let hd2 = mkIndU (ci2.ci_ind, u2) in
624+
let fctx i (ctx1, t1) (_ctx2, t2) = f (push_rel_context ctx1 env) i CONV t1 t2 in
625+
begin match (ise_and i [
626+
(fun i -> compare_heads CONV env i ~nargs:FullyApplied hd1 hd2);
627+
(fun i -> ise_array2 i (fun ii -> f env ii CONV) pms1 pms2);
628+
(fun i -> fctx i t1 t2);
629+
(fun i -> ise_array2 i fctx br1 br2);
630+
]) with
631+
| Success i -> stop false q1 q2 i
632+
| _ -> None
633+
end
634+
| Stack.Proj (p1,_)::q1, Stack.Proj (p2,_)::q2 ->
635+
let () = debug_unification (fun () -> Pp.(v 0 (str "ise_stack2_once : proj" ++ cut ()))) in
636+
if QProjection.Repr.equal env (Projection.repr p1) (Projection.repr p2)
637+
then stop false q1 q2 i
638+
else None
639+
| Stack.Fix (((li1, i1),(_,tys1,bds1 as recdef1)),a1)::q1,
640+
Stack.Fix (((li2, i2),(_,tys2,bds2)),a2)::q2 ->
641+
let () = debug_unification (fun () -> Pp.(v 0 (str "ise_stack2_once : fix" ++ cut ()))) in
642+
if Int.equal i1 i2 && Array.equal Int.equal li1 li2 then
643+
match ise_and i [
644+
(fun i -> ise_array2 i (fun ii -> f env ii CONV) tys1 tys2);
645+
(fun i -> ise_array2 i (fun ii -> f (push_rec_types recdef1 env) ii CONV) bds1 bds2);
646+
(fun i -> exact_ise_stack2 env i f a1 a2)] with
647+
| Success i ->
648+
let () = debug_unification (fun () -> Pp.(v 0 (str "ise_stack2_once : fix succeeds" ++ cut ()))) in
649+
stop false q1 q2 i
650+
| _ -> None
651+
else None
652+
| Stack.App a1 :: _, Stack.App a2 :: _ ->
653+
let () = debug_unification (fun () -> Pp.(v 0 (str "ise_stack2_once : app: " ++ cut () ++ Stack.pr_app_node (Termops.Internal.print_constr_env env i) a1 ++ cut () ++ Stack.pr_app_node (Termops.Internal.print_constr_env env i) a2 ++ cut ()))) in
654+
begin match ise_app_rev_stack2 env f i revsk1 revsk2 with
655+
|_,(UnifFailure _) -> None
656+
|(l1, l2), Success i' -> stop true l1 l2 i'
657+
end
658+
|_, _ -> None
659+
in ise_rev_stack2 evd (List.rev sk1) (List.rev sk2)
660+
661+
612662
let compare_heads pbty env evd ~nargs term term' =
613663
compare_heads pbty env evd ~nargs:(NumArgs nargs) term term'
614664

@@ -993,7 +1043,20 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
9931043
match x with | Some x -> Inl x | _ -> Inr false
9941044
with _ -> Inr false in
9951045
let () = debug_unification (fun () -> Pp.(v 0 (pr_state env evd appr1 ++ cut () ++ pr_state env evd appr2 ++ cut ()))) in
996-
match (flex_kind_of_term flags env evd term1 sk1,
1046+
if (List.exists (function (Stack.Fix _ | Stack.Case _ | Stack.Proj _) -> true | _ -> false) sk1) && (List.exists (function (Stack.Fix _ | Stack.Case _ | Stack.Proj _) -> true | _ -> false) sk2) then
1047+
let () = debug_unification (fun () -> Pp.(v 0 (str "both sides have non applicative stacks" ++ cut ()))) in
1048+
match ise_stack2_once env evd (evar_conv_x flags) sk1 sk2 with
1049+
| None -> quick_fail evd
1050+
| Some (app, sk1, sk2, evd) ->
1051+
if app then
1052+
evar_eqappr_x flags env evd pbty keys None
1053+
(whd_betaiota_deltazeta_for_iota_state
1054+
flags.open_ts env evd (term1, sk1))
1055+
(whd_betaiota_deltazeta_for_iota_state
1056+
flags.open_ts env evd (term2, sk2))
1057+
else
1058+
evar_eqappr_x flags env evd pbty keys None (term1, sk1) (term2, sk2)
1059+
else match (flex_kind_of_term flags env evd term1 sk1,
9971060
flex_kind_of_term flags env evd term2 sk2) with
9981061
| Flexible (sp1,al1), Flexible (sp2,al2) ->
9991062
(* Notations:
@@ -1154,7 +1217,6 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11541217
flags.open_ts env i (v2', applicative_stack)) in
11551218
let rhs_is_already_stuck =
11561219
rhs_is_already_stuck || rhs_is_stuck_and_unnamed () in
1157-
11581220
let b = EConstr.isLambda i term1 || rhs_is_already_stuck
11591221
&& (not (Stack.not_purely_applicative sk1')) in
11601222
ise_try i [

0 commit comments

Comments
 (0)