Skip to content

Commit 94a02b1

Browse files
committed
(hds -> orig) + changelog
1 parent 77f55d5 commit 94a02b1

File tree

3 files changed

+38
-30
lines changed

3 files changed

+38
-30
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- **Changed:**
2+
The unification algorithm (evarconv) may need to unfold its two input terms to succeed. Now, when one of the terms is an evar, it instantiates it with the folded version of the other term. In other words, tactics now unfold less than before, which may change the behavior of subsequent tactics.
3+
(`#19987 <https://github.com/rocq-prover/rocq/pull/19987>`_,
4+
by Quentin Vermande).

pretyping/evarconv.ml

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,8 @@ struct
685685
if l2r then clear_left c else clear_left (flip c)
686686
end
687687

688+
type orig = { left : state; right : state }
689+
688690
let rec evar_conv_x flags env evd pbty term1 term2 =
689691
let term1 = whd_head_evar evd term1 in
690692
let term2 = whd_head_evar evd term2 in
@@ -708,7 +710,7 @@ let rec evar_conv_x flags env evd pbty term1 term2 =
708710
let hd2 = (whd_nored_state env evd (term2,Stack.empty)) in
709711
match
710712
evar_eqappr_x flags env evd pbty (Cs_keys_cache.empty ()) None
711-
(hd1, hd2) hd1 hd2
713+
{ left = hd1; right = hd2 } hd1 hd2
712714
with
713715
| UnifFailure _ as x ->
714716
if Retyping.is_term_irrelevant env evd term1 ||
@@ -745,7 +747,7 @@ let rec evar_conv_x flags env evd pbty term1 term2 =
745747
and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
746748
keys (* canonical structure keys cache *)
747749
lastUnfolded (* tells which side was last unfolded, if any, where `true` means RHS. *)
748-
hds (term1, sk1 as appr1) (term2, sk2 as appr2) =
750+
orig (term1, sk1 as appr1) (term2, sk2 as appr2) =
749751
let quick_fail i = (* not costly, loses info *)
750752
UnifFailure (i, NotSameHead)
751753
in
@@ -782,8 +784,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
782784
flags.open_ts env' evd (c'1, Stack.empty) in
783785
let out2 = whd_nored_state env' evd
784786
(lift 1 (Stack.zip evd (term', sk')), Stack.append_app [|EConstr.mkRel 1|] Stack.empty) in
785-
if onleft then evar_eqappr_x flags env' evd CONV keys None (out1, out2) out1 out2
786-
else evar_eqappr_x flags env' evd CONV (Cs_keys_cache.flip keys) None (out2, out1) out2 out1
787+
if onleft then evar_eqappr_x flags env' evd CONV keys None { left = out1; right = out2 } out1 out2
788+
else evar_eqappr_x flags env' evd CONV (Cs_keys_cache.flip keys) None { left = out2; right = out1 } out2 out1
787789
in
788790
let rigids env evd sk term sk' term' =
789791
let nargs = Stack.args_size sk in
@@ -828,8 +830,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
828830
(* We cheat here. Unfolding here means that we should not go back to the heads
829831
when rediscovering the problem ?e=t, so we put the unfolded term in place of the
830832
head. *)
831-
let hds = (apprM', apprM') in
832-
switch (evar_eqappr_x flags env i pbty keys None hds) apprF apprM'
833+
let orig = { left = apprM'; right = apprM' } in
834+
switch (evar_eqappr_x flags env i pbty keys None orig) apprF apprM'
833835
in
834836
let default i = ise_try i [miller l2r ev apprF apprM;
835837
consume l2r apprF apprM;
@@ -853,9 +855,9 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
853855
(* We cheat here. Unfolding here means that we should not go back to the heads
854856
when rediscovering the problem ?e=t, so we put the unfolded term in place of the
855857
head. *)
856-
let hds = if l2r then (fst hds, apprM') else (apprM', snd hds) in
858+
let orig = if l2r then { left = orig.right; right = apprM' } else { left = apprM'; right = orig.left } in
857859
let delta' i =
858-
switch (evar_eqappr_x flags env i pbty keys None hds) apprF apprM'
860+
switch (evar_eqappr_x flags env i pbty keys None orig) apprF apprM'
859861
in
860862
fun i -> ise_try i [miller l2r ev apprF apprM';
861863
consume l2r apprF apprM'; delta']
@@ -910,7 +912,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
910912
UnifFailure (evd,OccurCheck (fst ev,tR)))])
911913
ev lF tR evd
912914
in
913-
let first_order env i t1 t2 sk1 sk2 hds =
915+
let first_order env i t1 t2 sk1 sk2 orig =
914916
(* Try first-order unification *)
915917
match ise_stack2 false env i (evar_conv_x flags) sk1 sk2 with
916918
| None, Success i' ->
@@ -922,7 +924,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
922924
(position_problem true pbty,destEvar i' ev1',term2)
923925
else
924926
(* HH: Why not to drop sk1 and sk2 since they unified *)
925-
evar_eqappr_x flags env evd pbty keys None hds
927+
evar_eqappr_x flags env evd pbty keys None orig
926928
(ev1', sk1) (term2, sk2)
927929
| Some (r,[]), Success i' ->
928930
(* We have sk1'[] = sk2[] for some sk1' s.t. sk1[]=sk1'[r[]] *)
@@ -932,7 +934,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
932934
solve_simple_eqn (conv_fun evar_conv_x) flags env i'
933935
(position_problem false pbty,destEvar i' ev2',Stack.zip i' (term1,r))
934936
else
935-
evar_eqappr_x flags env evd pbty keys None hds
937+
evar_eqappr_x flags env evd pbty keys None orig
936938
(ev2', sk1) (term2, sk2)
937939
| Some ([],r), Success i' ->
938940
(* Symmetrically *)
@@ -944,7 +946,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
944946
(position_problem true pbty,destEvar i' ev1',Stack.zip i' (term2,r))
945947
else
946948
(* HH: Why not to drop sk1 and sk2 since they unified *)
947-
evar_eqappr_x flags env evd pbty keys None hds
949+
evar_eqappr_x flags env evd pbty keys None orig
948950
(ev1', sk1) (term2, sk2)
949951
| None, (UnifFailure _ as x) ->
950952
(* sk1 and sk2 have no common outer part *)
@@ -1017,11 +1019,11 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10171019
match (flex_kind_of_term flags env evd term1 sk1,
10181020
flex_kind_of_term flags env evd term2 sk2) with
10191021
| Flexible (sp1,al1), Flexible (sp2,al2) ->
1020-
let k1 = if lastUnfolded = Some true && not (Stack.not_purely_applicative sk1) then let (t, sk) = fst hds in flex_kind_of_term flags env evd t sk else Flexible (sp1, al1) in
1021-
let k2 = if lastUnfolded = Some false && not (Stack.not_purely_applicative sk2) then let (t, sk) = snd hds in flex_kind_of_term flags env evd t sk else Flexible (sp2, al2) in
1022+
let k1 = if lastUnfolded = Some true && not (Stack.not_purely_applicative sk1) then let (t, sk) = orig.left in flex_kind_of_term flags env evd t sk else Flexible (sp1, al1) in
1023+
let k2 = if lastUnfolded = Some false && not (Stack.not_purely_applicative sk2) then let (t, sk) = orig.right in flex_kind_of_term flags env evd t sk else Flexible (sp2, al2) in
10221024
begin match (k1, k2) with
1023-
| Flexible ev1, MaybeFlexible v2 -> flex_maybeflex true ev1 appr1 (snd hds) (snd hds)
1024-
| MaybeFlexible v1, Flexible ev2 -> flex_maybeflex false ev2 appr2 (fst hds) (fst hds)
1025+
| Flexible ev1, MaybeFlexible v2 -> flex_maybeflex true ev1 appr1 orig.right orig.right
1026+
| MaybeFlexible v1, Flexible ev2 -> flex_maybeflex false ev2 appr2 orig.left orig.left
10251027
| _, Rigid | Rigid, _ -> anomaly (Pp.str "flexible terms cannot fold to rigid ones")
10261028
| _ ->
10271029
(* Notations:
@@ -1035,7 +1037,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10351037
1b'. if E₁=E₁'[E₁''] and E₁'=E₂ unifiable, recursively solve E₁''[?n₁[inst₁]] = ?n₂[inst₂]
10361038
recursively solve E2[?n[inst]] = E'2[redex]
10371039
2. fails if neither E₁ nor E₂ is a prefix of the other *)
1038-
let f1 i = first_order env i term1 term2 sk1 sk2 hds
1040+
let f1 i = first_order env i term1 term2 sk1 sk2 orig
10391041
and f2 i =
10401042
if Evar.equal sp1 sp2 then
10411043
match ise_stack2 false env i (evar_conv_x flags) sk1 sk2 with
@@ -1066,10 +1068,10 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10661068
end
10671069

10681070
| Flexible ev1, MaybeFlexible v2 ->
1069-
flex_maybeflex true ev1 appr1 appr2 (if Stack.not_purely_applicative sk1 then appr2 else snd hds)
1071+
flex_maybeflex true ev1 appr1 appr2 (if Stack.not_purely_applicative sk1 then appr2 else orig.right)
10701072

10711073
| MaybeFlexible vsk1, Flexible ev2 ->
1072-
flex_maybeflex false ev2 appr2 appr1 (if Stack.not_purely_applicative sk2 then appr1 else fst hds)
1074+
flex_maybeflex false ev2 appr2 appr1 (if Stack.not_purely_applicative sk2 then appr1 else orig.left)
10731075

10741076
| MaybeFlexible (v1', sk1' as vsk1'), MaybeFlexible (v2', sk2' as vsk2') -> begin
10751077
match EConstr.kind evd term1, EConstr.kind evd term2 with
@@ -1089,7 +1091,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10891091
and f2 i =
10901092
let out1 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk1'
10911093
and out2 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk2'
1092-
in evar_eqappr_x flags env i pbty keys None hds out1 out2
1094+
in evar_eqappr_x flags env i pbty keys None orig out1 out2
10931095
in
10941096
ise_try evd [f1; f2]
10951097

@@ -1101,7 +1103,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11011103
and f2 i =
11021104
let out1 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk1'
11031105
and out2 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk2'
1104-
in evar_eqappr_x flags env i pbty keys None hds out1 out2
1106+
in evar_eqappr_x flags env i pbty keys None orig out1 out2
11051107
in
11061108
ise_try evd [f1; f2]
11071109

@@ -1113,7 +1115,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11131115
in
11141116
(match res with
11151117
| Some (f1,args1) ->
1116-
evar_eqappr_x flags env evd pbty keys None hds (f1,Stack.append_app args1 sk1)
1118+
evar_eqappr_x flags env evd pbty keys None orig (f1,Stack.append_app args1 sk1)
11171119
appr2
11181120
| None -> UnifFailure (evd,NotSameHead))
11191121

@@ -1124,7 +1126,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11241126
in
11251127
(match res with
11261128
| Some (f2,args2) ->
1127-
evar_eqappr_x flags env evd pbty keys None hds appr1 (f2,Stack.append_app args2 sk2)
1129+
evar_eqappr_x flags env evd pbty keys None orig appr1 (f2,Stack.append_app args2 sk2)
11281130
| None -> UnifFailure (evd,NotSameHead))
11291131

11301132
| _, _ ->
@@ -1187,14 +1189,14 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11871189
ise_try i [
11881190
(fun i ->
11891191
if b || !no_cs1 then
1190-
evar_eqappr_x flags env i pbty keys (Some false) hds
1192+
evar_eqappr_x flags env i pbty keys (Some false) orig
11911193
(whd_betaiota_deltazeta_for_iota_state
11921194
flags.open_ts env i vsk1')
11931195
appr2
11941196
else quick_fail i);
11951197
fun i ->
11961198
if b then quick_fail i else
1197-
evar_eqappr_x flags env i pbty keys (Some true) hds appr1
1199+
evar_eqappr_x flags env i pbty keys (Some true) orig appr1
11981200
(whd_betaiota_deltazeta_for_iota_state
11991201
flags.open_ts env i vsk2')]
12001202
in
@@ -1215,15 +1217,15 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
12151217

12161218
| Flexible ev1, Rigid ->
12171219
if Stack.not_purely_applicative sk1 then flex_rigid true ev1 appr1 appr2 else
1218-
let (t2, sk2) as appr2 = snd hds in
1220+
let (t2, sk2) as appr2 = orig.right in
12191221
begin match flex_kind_of_term flags env evd t2 sk2 with
12201222
| Flexible ev2 -> anomaly (Pp.str "rigid terms can not fold to flexible ones")
12211223
| MaybeFlexible v2 -> flex_maybeflex true ev1 appr1 appr2 appr2
12221224
| Rigid -> flex_rigid true ev1 appr1 appr2
12231225
end
12241226
| Rigid, Flexible ev2 ->
12251227
if Stack.not_purely_applicative sk2 then flex_rigid false ev2 appr2 appr1 else
1226-
let (t1, sk1) as appr1 = fst hds in
1228+
let (t1, sk1) as appr1 = orig.left in
12271229
begin match flex_kind_of_term flags env evd t1 sk1 with
12281230
| Flexible ev1 -> anomaly (Pp.str "rigid terms can not fold to flexible ones")
12291231
| MaybeFlexible v1 -> flex_maybeflex false ev2 appr2 appr1 appr1
@@ -1238,7 +1240,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
12381240
| Inl x -> x
12391241
| Inr _ -> UnifFailure (i,NoCanonicalStructure)
12401242
and f4 i =
1241-
evar_eqappr_x flags env i pbty keys (Some false) hds
1243+
evar_eqappr_x flags env i pbty keys (Some false) orig
12421244
(whd_betaiota_deltazeta_for_iota_state
12431245
flags.open_ts env i vsk1')
12441246
appr2
@@ -1253,7 +1255,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
12531255
| Inl x -> x
12541256
| Inr _ -> UnifFailure (i,NoCanonicalStructure)
12551257
and f4 i =
1256-
evar_eqappr_x flags env i pbty keys (Some true) hds appr1
1258+
evar_eqappr_x flags env i pbty keys (Some true) orig appr1
12571259
(whd_betaiota_deltazeta_for_iota_state
12581260
flags.open_ts env i vsk2')
12591261
in

pretyping/evarconv.mli

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ val evar_unify : Evarsolve.unifier
156156
(* For debugging *)
157157
module Cs_keys_cache : sig type t end
158158

159+
type orig = { left: state; right: state }
160+
159161
val evar_eqappr_x : ?rhs_is_already_stuck:bool -> unify_flags ->
160162
env -> evar_map -> conv_pb ->
161163
Cs_keys_cache.t ->
162-
bool option -> (state * state) -> state -> state ->
164+
bool option -> orig -> state -> state ->
163165
Evarsolve.unification_result
164166

165167
val occur_rigidly : Evarsolve.unify_flags ->

0 commit comments

Comments
 (0)