@@ -692,10 +692,11 @@ let rec evar_conv_x flags env evd pbty term1 term2 =
692692 let term1 = apprec_nohdbeta flags env evd term1 in
693693 let term2 = apprec_nohdbeta flags env evd term2 in
694694 let default () =
695+ let hd1 = (whd_nored_state env evd (term1,Stack. empty)) in
696+ let hd2 = (whd_nored_state env evd (term2,Stack. empty)) in
695697 match
696698 evar_eqappr_x flags env evd pbty (Cs_keys_cache. empty () ) None
697- (whd_nored_state env evd (term1,Stack. empty))
698- (whd_nored_state env evd (term2,Stack. empty))
699+ (hd1, hd2) hd1 hd2
699700 with
700701 | UnifFailure _ as x ->
701702 if Retyping. is_term_irrelevant env evd term1 ||
@@ -731,8 +732,8 @@ let rec evar_conv_x flags env evd pbty term1 term2 =
731732
732733and evar_eqappr_x ?(rhs_is_already_stuck = false ) flags env evd pbty
733734 keys (* canonical structure keys cache *)
734- lastUnfolded (* tells which side was last unfolded, if any *)
735- (term1 , sk1 as appr1 ) (term2 , sk2 as appr2 ) =
735+ lastUnfolded (* tells which side was last unfolded, if any, where `true` means RHS. *)
736+ hds (term1 , sk1 as appr1 ) (term2 , sk2 as appr2 ) =
736737 let quick_fail i = (* not costly, loses info *)
737738 UnifFailure (i, NotSameHead )
738739 in
@@ -769,8 +770,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
769770 flags.open_ts env' evd (c'1 , Stack. empty) in
770771 let out2 = whd_nored_state env' evd
771772 (lift 1 (Stack. zip evd (term', sk')), Stack. append_app [|EConstr. mkRel 1 |] Stack. empty) in
772- if onleft then evar_eqappr_x flags env' evd CONV keys None out1 out2
773- else evar_eqappr_x flags env' evd CONV (Cs_keys_cache. flip keys) None out2 out1
773+ if onleft then evar_eqappr_x flags env' evd CONV keys None (out1, out2) out1 out2
774+ else evar_eqappr_x flags env' evd CONV (Cs_keys_cache. flip keys) None (out2, out1) out2 out1
774775 in
775776 let rigids env evd sk term sk' term' =
776777 let nargs = Stack. args_size sk in
@@ -809,9 +810,14 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
809810 recursively solve E2[?n[inst]] = E'2[redex]
810811 3. reduce the redex into M and recursively solve E[?n[inst]] =? E'[M] *)
811812 let switch f a b = if l2r then f a b else f b a in
812- let delta i =
813- switch (evar_eqappr_x flags env i pbty keys None ) apprF
814- (whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vskM)
813+ let delta i =
814+ let vskM = Option. get (eval_flexible_term flags.open_ts env evd (fst vskM) (snd vskM)) in
815+ let apprM' = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vskM in
816+ (* We cheat here. Unfolding here means that we should not go back to the heads
817+ when rediscovering the problem ?e=t, so we put the unfolded term in place of the
818+ head. *)
819+ let hds = (apprM', apprM') in
820+ switch (evar_eqappr_x flags env i pbty keys None hds) apprF apprM'
815821 in
816822 let default i = ise_try i [miller l2r ev apprF apprM;
817823 consume l2r apprF apprM;
@@ -832,8 +838,12 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
832838 let apprM' =
833839 whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd (termM',skM)
834840 in
841+ (* We cheat here. Unfolding here means that we should not go back to the heads
842+ when rediscovering the problem ?e=t, so we put the unfolded term in place of the
843+ head. *)
844+ let hds = if l2r then (fst hds, apprM') else (apprM', snd hds) in
835845 let delta' i =
836- switch (evar_eqappr_x flags env i pbty keys None ) apprF apprM'
846+ switch (evar_eqappr_x flags env i pbty keys None hds ) apprF apprM'
837847 in
838848 fun i -> ise_try i [miller l2r ev apprF apprM';
839849 consume l2r apprF apprM'; delta']
@@ -888,7 +898,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
888898 UnifFailure (evd,OccurCheck (fst ev,tR)))])
889899 ev lF tR evd
890900 in
891- let first_order env i t1 t2 sk1 sk2 =
901+ let first_order env i t1 t2 sk1 sk2 hds =
892902 (* Try first-order unification *)
893903 match ise_stack2 false env i (evar_conv_x flags) sk1 sk2 with
894904 | None , Success i' ->
@@ -900,7 +910,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
900910 (position_problem true pbty,destEvar i' ev1',term2)
901911 else
902912 (* HH: Why not to drop sk1 and sk2 since they unified *)
903- evar_eqappr_x flags env evd pbty keys None
913+ evar_eqappr_x flags env evd pbty keys None hds
904914 (ev1', sk1) (term2, sk2)
905915 | Some (r ,[] ), Success i' ->
906916 (* We have sk1'[] = sk2[] for some sk1' s.t. sk1[]=sk1'[r[]] *)
@@ -910,7 +920,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
910920 solve_simple_eqn (conv_fun evar_conv_x) flags env i'
911921 (position_problem false pbty,destEvar i' ev2',Stack. zip i' (term1,r))
912922 else
913- evar_eqappr_x flags env evd pbty keys None
923+ evar_eqappr_x flags env evd pbty keys None hds
914924 (ev2', sk1) (term2, sk2)
915925 | Some ([] ,r ), Success i' ->
916926 (* Symmetrically *)
@@ -922,7 +932,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
922932 (position_problem true pbty,destEvar i' ev1',Stack. zip i' (term2,r))
923933 else
924934 (* HH: Why not to drop sk1 and sk2 since they unified *)
925- evar_eqappr_x flags env evd pbty keys None
935+ evar_eqappr_x flags env evd pbty keys None hds
926936 (ev1', sk1) (term2, sk2)
927937 | None , (UnifFailure _ as x ) ->
928938 (* sk1 and sk2 have no common outer part *)
@@ -996,6 +1006,12 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
9961006 match (flex_kind_of_term flags env evd term1 sk1,
9971007 flex_kind_of_term flags env evd term2 sk2) with
9981008 | Flexible (sp1 ,al1 ), Flexible (sp2 ,al2 ) ->
1009+ begin match ((if lastUnfolded = Some true then let (t, sk) = fst hds in flex_kind_of_term flags env evd t sk else Flexible (sp1, al1)),
1010+ if lastUnfolded = Some false then let (t, sk) = snd hds in flex_kind_of_term flags env evd t sk else Flexible (sp2, al2)) with
1011+ | Flexible ev1 , MaybeFlexible v2 -> flex_maybeflex true ev1 appr1 (snd hds) (snd hds)
1012+ | MaybeFlexible v1 , Flexible ev2 -> flex_maybeflex false ev2 appr2 (fst hds) (fst hds)
1013+ | _ , Rigid | Rigid , _ -> anomaly (Pp. str " flexible terms cannot fold to rigid ones" )
1014+ | _ ->
9991015 (* Notations:
10001016 - "sk" is a stack (or, more abstractly, an evaluation context, written E)
10011017 - "ev" is an evar "?ev", more precisely an evar ?n with an instance inst
@@ -1007,7 +1023,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10071023 1b'. if E₁=E₁'[E₁''] and E₁'=E₂ unifiable, recursively solve E₁''[?n₁[inst₁]] = ?n₂[inst₂]
10081024 recursively solve E2[?n[inst]] = E'2[redex]
10091025 2. fails if neither E₁ nor E₂ is a prefix of the other *)
1010- let f1 i = first_order env i term1 term2 sk1 sk2
1026+ let f1 i = first_order env i term1 term2 sk1 sk2 hds
10111027 and f2 i =
10121028 if Evar. equal sp1 sp2 then
10131029 match ise_stack2 false env i (evar_conv_x flags) sk1 sk2 with
@@ -1035,12 +1051,13 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10351051 | UnifFailure _ -> quick_fail i
10361052 in
10371053 ise_try evd [f1; f2; f3; f4; f5]
1054+ end
10381055
10391056 | Flexible ev1 , MaybeFlexible v2 ->
1040- flex_maybeflex true ev1 appr1 appr2 v2
1057+ flex_maybeflex true ev1 appr1 appr2 (snd hds)
10411058
10421059 | MaybeFlexible vsk1 , Flexible ev2 ->
1043- flex_maybeflex false ev2 appr2 appr1 vsk1
1060+ flex_maybeflex false ev2 appr2 appr1 (fst hds)
10441061
10451062 | MaybeFlexible (v1' , sk1' as vsk1' ), MaybeFlexible (v2' , sk2' as vsk2' ) -> begin
10461063 match EConstr. kind evd term1, EConstr. kind evd term2 with
@@ -1060,7 +1077,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10601077 and f2 i =
10611078 let out1 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk1'
10621079 and out2 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk2'
1063- in evar_eqappr_x flags env i pbty keys None out1 out2
1080+ in evar_eqappr_x flags env i pbty keys None hds out1 out2
10641081 in
10651082 ise_try evd [f1; f2]
10661083
@@ -1072,7 +1089,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10721089 and f2 i =
10731090 let out1 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk1'
10741091 and out2 = whd_betaiota_deltazeta_for_iota_state flags.open_ts env i vsk2'
1075- 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
10761093 in
10771094 ise_try evd [f1; f2]
10781095
@@ -1084,7 +1101,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10841101 in
10851102 (match res with
10861103 | Some (f1 ,args1 ) ->
1087- evar_eqappr_x flags env evd pbty keys None (f1,Stack. append_app args1 sk1)
1104+ evar_eqappr_x flags env evd pbty keys None hds (f1,Stack. append_app args1 sk1)
10881105 appr2
10891106 | None -> UnifFailure (evd,NotSameHead ))
10901107
@@ -1095,7 +1112,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10951112 in
10961113 (match res with
10971114 | Some (f2 ,args2 ) ->
1098- evar_eqappr_x flags env evd pbty keys None appr1 (f2,Stack. append_app args2 sk2)
1115+ evar_eqappr_x flags env evd pbty keys None hds appr1 (f2,Stack. append_app args2 sk2)
10991116 | None -> UnifFailure (evd,NotSameHead ))
11001117
11011118 | _ , _ ->
@@ -1160,14 +1177,14 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11601177 ise_try i [
11611178 (fun i ->
11621179 if b || ! no_cs1 then
1163- evar_eqappr_x flags env i pbty keys (Some false )
1180+ evar_eqappr_x flags env i pbty keys (Some false ) hds
11641181 (whd_betaiota_deltazeta_for_iota_state
11651182 flags.open_ts env i vsk1')
11661183 appr2
11671184 else quick_fail i);
11681185 fun i ->
11691186 if b then quick_fail i else
1170- evar_eqappr_x flags env i pbty keys (Some true ) appr1
1187+ evar_eqappr_x flags env i pbty keys (Some true ) hds appr1
11711188 (whd_betaiota_deltazeta_for_iota_state
11721189 flags.open_ts env i vsk2')]
11731190 in
@@ -1186,8 +1203,20 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11861203 (* When in modulo_betaiota = false case, lambda's are not reduced *)
11871204 (fun i -> exact_ise_stack2 env i (evar_conv_x flags) sk1 sk2)]
11881205
1189- | Flexible ev1 , Rigid -> flex_rigid true ev1 appr1 appr2
1190- | Rigid , Flexible ev2 -> flex_rigid false ev2 appr2 appr1
1206+ | Flexible ev1 , Rigid ->
1207+ let (t2, sk2) as appr2 = snd hds in
1208+ begin match flex_kind_of_term flags env evd t2 sk2 with
1209+ | Flexible ev2 -> anomaly (Pp. str " rigid terms can not fold to flexible ones" )
1210+ | MaybeFlexible v2 -> flex_maybeflex true ev1 appr1 appr2 appr2
1211+ | Rigid -> flex_rigid true ev1 appr1 appr2
1212+ end
1213+ | Rigid , Flexible ev2 ->
1214+ let (t1, sk1) as appr1 = fst hds in
1215+ begin match flex_kind_of_term flags env evd t1 sk1 with
1216+ | Flexible ev1 -> anomaly (Pp. str " rigid terms can not fold to flexible ones" )
1217+ | MaybeFlexible v1 -> flex_maybeflex true ev2 appr2 appr1 appr1
1218+ | Rigid -> flex_rigid true ev2 appr2 appr1
1219+ end
11911220
11921221 | MaybeFlexible vsk1' , Rigid ->
11931222 let f3 i =
@@ -1199,7 +1228,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
11991228 | Inr _ -> raise Not_found )
12001229 with Not_found -> UnifFailure (i,NoCanonicalStructure ))
12011230 and f4 i =
1202- evar_eqappr_x flags env i pbty keys (Some false )
1231+ evar_eqappr_x flags env i pbty keys (Some false ) hds
12031232 (whd_betaiota_deltazeta_for_iota_state
12041233 flags.open_ts env i vsk1')
12051234 appr2
@@ -1216,7 +1245,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
12161245 | Inr _ -> raise Not_found )
12171246 with Not_found -> UnifFailure (i,NoCanonicalStructure ))
12181247 and f4 i =
1219- evar_eqappr_x flags env i pbty keys (Some true ) appr1
1248+ evar_eqappr_x flags env i pbty keys (Some true ) hds appr1
12201249 (whd_betaiota_deltazeta_for_iota_state
12211250 flags.open_ts env i vsk2')
12221251 in
0 commit comments