@@ -704,10 +704,11 @@ let rec evar_conv_x flags env evd pbty term1 term2 =
704704 let term1 = apprec_nohdbeta flags env evd term1 in
705705 let term2 = apprec_nohdbeta flags env evd term2 in
706706 let default () =
707+ let hd1 = (whd_nored_state env evd (term1,Stack. empty)) in
708+ let hd2 = (whd_nored_state env evd (term2,Stack. empty)) in
707709 match
708710 evar_eqappr_x flags env evd pbty (Cs_keys_cache. empty () ) None
709- (whd_nored_state env evd (term1,Stack. empty))
710- (whd_nored_state env evd (term2,Stack. empty))
711+ (hd1, hd2) hd1 hd2
711712 with
712713 | UnifFailure _ as x ->
713714 if Retyping. is_term_irrelevant env evd term1 ||
@@ -743,8 +744,8 @@ let rec evar_conv_x flags env evd pbty term1 term2 =
743744
744745and evar_eqappr_x ?(rhs_is_already_stuck = false ) flags env evd pbty
745746 keys (* canonical structure keys cache *)
746- lastUnfolded (* tells which side was last unfolded, if any *)
747- (term1 , sk1 as appr1 ) (term2 , sk2 as appr2 ) =
747+ lastUnfolded (* tells which side was last unfolded, if any, where `true` means RHS. *)
748+ hds (term1 , sk1 as appr1 ) (term2 , sk2 as appr2 ) =
748749 let quick_fail i = (* not costly, loses info *)
749750 UnifFailure (i, NotSameHead )
750751 in
@@ -781,8 +782,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
781782 flags.open_ts env' evd (c'1 , Stack. empty) in
782783 let out2 = whd_nored_state env' evd
783784 (lift 1 (Stack. zip evd (term', sk')), Stack. append_app [|EConstr. mkRel 1 |] Stack. empty) in
784- if onleft then evar_eqappr_x flags env' evd CONV keys None out1 out2
785- else evar_eqappr_x flags env' evd CONV (Cs_keys_cache. flip keys) None out2 out1
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
786787 in
787788 let rigids env evd sk term sk' term' =
788789 let nargs = Stack. args_size sk in
@@ -822,8 +823,13 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
822823 3. reduce the redex into M and recursively solve E[?n[inst]] =? E'[M] *)
823824 let switch f a b = if l2r then f a b else f b a in
824825 let delta i =
825- switch (evar_eqappr_x flags env i pbty keys None ) apprF
826- (whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vskM)
826+ let vskM = Option. get (eval_flexible_term flags.open_ts env evd (fst vskM) (snd vskM)) in
827+ let apprM' = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vskM in
828+ (* We cheat here. Unfolding here means that we should not go back to the heads
829+ when rediscovering the problem ?e=t, so we put the unfolded term in place of the
830+ head. *)
831+ let hds = (apprM', apprM') in
832+ switch (evar_eqappr_x flags env i pbty keys None hds) apprF apprM'
827833 in
828834 let default i = ise_try i [miller l2r ev apprF apprM;
829835 consume l2r apprF apprM;
@@ -844,8 +850,12 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
844850 let apprM' =
845851 whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd (termM',skM)
846852 in
853+ (* We cheat here. Unfolding here means that we should not go back to the heads
854+ when rediscovering the problem ?e=t, so we put the unfolded term in place of the
855+ head. *)
856+ let hds = if l2r then (fst hds, apprM') else (apprM', snd hds) in
847857 let delta' i =
848- switch (evar_eqappr_x flags env i pbty keys None ) apprF apprM'
858+ switch (evar_eqappr_x flags env i pbty keys None hds ) apprF apprM'
849859 in
850860 fun i -> ise_try i [miller l2r ev apprF apprM';
851861 consume l2r apprF apprM'; delta']
@@ -900,7 +910,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
900910 UnifFailure (evd,OccurCheck (fst ev,tR)))])
901911 ev lF tR evd
902912 in
903- let first_order env i t1 t2 sk1 sk2 =
913+ let first_order env i t1 t2 sk1 sk2 hds =
904914 (* Try first-order unification *)
905915 match ise_stack2 false env i (evar_conv_x flags) sk1 sk2 with
906916 | None , Success i' ->
@@ -912,7 +922,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
912922 (position_problem true pbty,destEvar i' ev1',term2)
913923 else
914924 (* HH: Why not to drop sk1 and sk2 since they unified *)
915- evar_eqappr_x flags env evd pbty keys None
925+ evar_eqappr_x flags env evd pbty keys None hds
916926 (ev1', sk1) (term2, sk2)
917927 | Some (r ,[] ), Success i' ->
918928 (* We have sk1'[] = sk2[] for some sk1' s.t. sk1[]=sk1'[r[]] *)
@@ -922,7 +932,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
922932 solve_simple_eqn (conv_fun evar_conv_x) flags env i'
923933 (position_problem false pbty,destEvar i' ev2',Stack. zip i' (term1,r))
924934 else
925- evar_eqappr_x flags env evd pbty keys None
935+ evar_eqappr_x flags env evd pbty keys None hds
926936 (ev2', sk1) (term2, sk2)
927937 | Some ([] ,r ), Success i' ->
928938 (* Symmetrically *)
@@ -934,7 +944,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
934944 (position_problem true pbty,destEvar i' ev1',Stack. zip i' (term2,r))
935945 else
936946 (* HH: Why not to drop sk1 and sk2 since they unified *)
937- evar_eqappr_x flags env evd pbty keys None
947+ evar_eqappr_x flags env evd pbty keys None hds
938948 (ev1', sk1) (term2, sk2)
939949 | None , (UnifFailure _ as x ) ->
940950 (* sk1 and sk2 have no common outer part *)
@@ -1007,6 +1017,13 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10071017 match (flex_kind_of_term flags env evd term1 sk1,
10081018 flex_kind_of_term flags env evd term2 sk2) with
10091019 | Flexible (sp1 ,al1 ), Flexible (sp2 ,al2 ) ->
1020+ let k1 = if lastUnfolded = Some true 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 then let (t, sk) = snd hds in flex_kind_of_term flags env evd t sk else Flexible (sp2, al2) in
1022+ 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+ | _ , Rigid | Rigid , _ -> anomaly (Pp. str " flexible terms cannot fold to rigid ones" )
1026+ | _ ->
10101027 (* Notations:
10111028 - "sk" is a stack (or, more abstractly, an evaluation context, written E)
10121029 - "ev" is an evar "?ev", more precisely an evar ?n with an instance inst
@@ -1018,7 +1035,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10181035 1b'. if E₁=E₁'[E₁''] and E₁'=E₂ unifiable, recursively solve E₁''[?n₁[inst₁]] = ?n₂[inst₂]
10191036 recursively solve E2[?n[inst]] = E'2[redex]
10201037 2. fails if neither E₁ nor E₂ is a prefix of the other *)
1021- let f1 i = first_order env i term1 term2 sk1 sk2
1038+ let f1 i = first_order env i term1 term2 sk1 sk2 hds
10221039 and f2 i =
10231040 if Evar. equal sp1 sp2 then
10241041 match ise_stack2 false env i (evar_conv_x flags) sk1 sk2 with
@@ -1046,12 +1063,13 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10461063 | UnifFailure _ -> quick_fail i
10471064 in
10481065 ise_try evd [f1; f2; f3; f4; f5]
1066+ end
10491067
10501068 | Flexible ev1 , MaybeFlexible v2 ->
1051- flex_maybeflex true ev1 appr1 appr2 v2
1069+ flex_maybeflex true ev1 appr1 appr2 (snd hds)
10521070
10531071 | MaybeFlexible vsk1 , Flexible ev2 ->
1054- flex_maybeflex false ev2 appr2 appr1 vsk1
1072+ flex_maybeflex false ev2 appr2 appr1 (fst hds)
10551073
10561074 | MaybeFlexible (v1' , sk1' as vsk1' ), MaybeFlexible (v2' , sk2' as vsk2' ) -> begin
10571075 match EConstr. kind evd term1, EConstr. kind evd term2 with
@@ -1071,7 +1089,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10711089 and f2 i =
10721090 let out1 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk1'
10731091 and out2 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk2'
1074- in evar_eqappr_x flags env i pbty keys None out1 out2
1092+ in evar_eqappr_x flags env i pbty keys None hds out1 out2
10751093 in
10761094 ise_try evd [f1; f2]
10771095
@@ -1083,7 +1101,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10831101 and f2 i =
10841102 let out1 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk1'
10851103 and out2 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk2'
1086- in evar_eqappr_x flags env i pbty keys None out1 out2
1104+ in evar_eqappr_x flags env i pbty keys None hds out1 out2
10871105 in
10881106 ise_try evd [f1; f2]
10891107
@@ -1095,7 +1113,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10951113 in
10961114 (match res with
10971115 | Some (f1 ,args1 ) ->
1098- evar_eqappr_x flags env evd pbty keys None (f1,Stack. append_app args1 sk1)
1116+ evar_eqappr_x flags env evd pbty keys None hds (f1,Stack. append_app args1 sk1)
10991117 appr2
11001118 | None -> UnifFailure (evd,NotSameHead ))
11011119
@@ -1106,7 +1124,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11061124 in
11071125 (match res with
11081126 | Some (f2 ,args2 ) ->
1109- evar_eqappr_x flags env evd pbty keys None appr1 (f2,Stack. append_app args2 sk2)
1127+ evar_eqappr_x flags env evd pbty keys None hds appr1 (f2,Stack. append_app args2 sk2)
11101128 | None -> UnifFailure (evd,NotSameHead ))
11111129
11121130 | _ , _ ->
@@ -1169,14 +1187,14 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11691187 ise_try i [
11701188 (fun i ->
11711189 if b || ! no_cs1 then
1172- evar_eqappr_x flags env i pbty keys (Some false )
1190+ evar_eqappr_x flags env i pbty keys (Some false ) hds
11731191 (whd_betaiota_deltazeta_for_iota_state
11741192 flags.open_ts env i vsk1')
11751193 appr2
11761194 else quick_fail i);
11771195 fun i ->
11781196 if b then quick_fail i else
1179- evar_eqappr_x flags env i pbty keys (Some true ) appr1
1197+ evar_eqappr_x flags env i pbty keys (Some true ) hds appr1
11801198 (whd_betaiota_deltazeta_for_iota_state
11811199 flags.open_ts env i vsk2')]
11821200 in
@@ -1195,8 +1213,20 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11951213 (* When in modulo_betaiota = false case, lambda's are not reduced *)
11961214 (fun i -> exact_ise_stack2 env i (evar_conv_x flags) sk1 sk2)]
11971215
1198- | Flexible ev1 , Rigid -> flex_rigid true ev1 appr1 appr2
1199- | Rigid , Flexible ev2 -> flex_rigid false ev2 appr2 appr1
1216+ | Flexible ev1 , Rigid ->
1217+ let (t2, sk2) as appr2 = snd hds in
1218+ begin match flex_kind_of_term flags env evd t2 sk2 with
1219+ | Flexible ev2 -> anomaly (Pp. str " rigid terms can not fold to flexible ones" )
1220+ | MaybeFlexible v2 -> flex_maybeflex true ev1 appr1 appr2 appr2
1221+ | Rigid -> flex_rigid true ev1 appr1 appr2
1222+ end
1223+ | Rigid , Flexible ev2 ->
1224+ let (t1, sk1) as appr1 = fst hds in
1225+ begin match flex_kind_of_term flags env evd t1 sk1 with
1226+ | Flexible ev1 -> anomaly (Pp. str " rigid terms can not fold to flexible ones" )
1227+ | MaybeFlexible v1 -> flex_maybeflex false ev2 appr2 appr1 appr1
1228+ | Rigid -> flex_rigid false ev2 appr2 appr1
1229+ end
12001230
12011231 | MaybeFlexible vsk1' , Rigid ->
12021232 let f3 i =
@@ -1206,7 +1236,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
12061236 | Inl x -> x
12071237 | Inr _ -> UnifFailure (i,NoCanonicalStructure )
12081238 and f4 i =
1209- evar_eqappr_x flags env i pbty keys (Some false )
1239+ evar_eqappr_x flags env i pbty keys (Some false ) hds
12101240 (whd_betaiota_deltazeta_for_iota_state
12111241 flags.open_ts env i vsk1')
12121242 appr2
@@ -1221,7 +1251,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
12211251 | Inl x -> x
12221252 | Inr _ -> UnifFailure (i,NoCanonicalStructure )
12231253 and f4 i =
1224- evar_eqappr_x flags env i pbty keys (Some true ) appr1
1254+ evar_eqappr_x flags env i pbty keys (Some true ) hds appr1
12251255 (whd_betaiota_deltazeta_for_iota_state
12261256 flags.open_ts env i vsk2')
12271257 in
0 commit comments