Skip to content

Commit 3c0a576

Browse files
committed
add typeclass resolution at the end of unification
1 parent 538e153 commit 3c0a576

File tree

1 file changed

+85
-7
lines changed

1 file changed

+85
-7
lines changed

pretyping/evarconv.ml

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,15 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
748748
let quick_fail i = (* not costly, loses info *)
749749
UnifFailure (i, NotSameHead)
750750
in
751+
let get_tc evd e =
752+
if not (Evd.is_typeclass_evar evd e) then raise Not_found else
753+
let tc_evars = Evd.get_typeclass_evars evd in
754+
let evd = Evd.set_typeclass_evars evd (Evar.Set.singleton e) in
755+
let evd = Typeclasses.resolve_typeclasses env evd in
756+
if not (Evd.is_defined evd e) then raise Not_found else
757+
let tc_evars = Evar.Set.union tc_evars (Evd.get_typeclass_evars evd) in
758+
let tc_evars = Evar.Set.filter (fun e -> not (Evd.is_defined evd e)) tc_evars in
759+
Evd.set_typeclass_evars evd tc_evars in
751760
let miller_pfenning l2r fallback ev lF tM evd =
752761
match is_unification_pattern_evar env evd ev lF tM with
753762
| None -> fallback ()
@@ -876,9 +885,16 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
876885
| Construct u -> eta_constructor flags env evd u skR apprF
877886
| _ -> UnifFailure (evd,NotSameHead)
878887
in
888+
let tc evd =
889+
let (e, _) = EConstr.destEvar evd termF in
890+
try let evd = get_tc evd e in
891+
let apprF = whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd apprF in
892+
let apprR = whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd apprR in
893+
evar_eqappr_x flags env evd pbty keys lastUnfolded apprF apprR
894+
with _ -> quick_fail evd in
879895
match Stack.list_of_app_stack skF with
880896
| None ->
881-
ise_try evd [consume_stack l2r apprF apprR; eta]
897+
ise_try evd [consume_stack l2r apprF apprR; eta; tc]
882898
| Some lF ->
883899
let tR = Stack.zip evd apprR in
884900
miller_pfenning l2r
@@ -1044,8 +1060,19 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10441060
match consume true appr1 appr2 i with
10451061
| Success _ as x -> x
10461062
| UnifFailure _ -> quick_fail i
1063+
and f6 i =
1064+
try let evd = get_tc evd sp2 in
1065+
evar_eqappr_x flags env evd pbty keys lastUnfolded
1066+
(whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd appr1)
1067+
(whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd appr2)
1068+
with _ -> try
1069+
let evd = get_tc evd sp1 in
1070+
evar_eqappr_x flags env evd pbty keys lastUnfolded
1071+
(whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd appr1)
1072+
(whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd appr2)
1073+
with _ -> quick_fail i
10471074
in
1048-
ise_try evd [f1; f2; f3; f4; f5]
1075+
ise_try evd [f1; f2; f3; f4; f5; f6]
10491076

10501077
| Flexible ev1, MaybeFlexible v2 ->
10511078
flex_maybeflex true ev1 appr1 appr2 v2
@@ -2018,7 +2045,7 @@ let solve_unconstrained_impossible_cases env evd =
20182045
(Evd.get_impossible_case_evars evd)
20192046
evd
20202047

2021-
let solve_unif_constraints_with_heuristics env
2048+
let do_solve_unif_constraints_with_heuristics env
20222049
?(flags=default_flags env) ?(with_ho=false) evd =
20232050
let evd = solve_unconstrained_evars_with_candidates flags env evd in
20242051
let rec aux evd pbs progress stuck =
@@ -2054,6 +2081,16 @@ let solve_unif_constraints_with_heuristics env
20542081
check_problems_are_solved env heuristic_solved_evd;
20552082
solve_unconstrained_impossible_cases env heuristic_solved_evd
20562083

2084+
(* A little bit of gymnastics to disable solve_unif_constraints_with_heuristics without changing the whole API. *)
2085+
let do_not_solve_unif_constraints_with_heuristics env
2086+
?(flags=default_flags env) ?(with_ho=false) evd = evd
2087+
2088+
let ref_solve_unif_constraints_with_heuristics =
2089+
ref do_solve_unif_constraints_with_heuristics
2090+
2091+
let solve_unif_constraints_with_heuristics env =
2092+
!ref_solve_unif_constraints_with_heuristics env
2093+
20572094
(* Main entry points *)
20582095

20592096
exception UnableToUnify of evar_map * unification_error
@@ -2070,7 +2107,20 @@ let unify_delay ?flags env evd t1 t2 =
20702107
| Some flags -> flags
20712108
in
20722109
match evar_conv_x flags env evd CONV t1 t2 with
2073-
| Success evd' -> evd'
2110+
| Success evd' -> (try
2111+
let te1 = Evd.get_typeclass_evars evd in
2112+
let te2 = Evd.get_typeclass_evars evd' in
2113+
let ted = Evar.Set.diff te2 te1 in
2114+
let evd = Evd.set_typeclass_evars evd' ted in
2115+
let () = ref_solve_unif_constraints_with_heuristics := do_not_solve_unif_constraints_with_heuristics in
2116+
let evd = Typeclasses.resolve_typeclasses env evd in
2117+
let () = ref_solve_unif_constraints_with_heuristics := do_solve_unif_constraints_with_heuristics in
2118+
let tei = Evar.Set.inter te2 te1 in
2119+
let te2 = Evd.get_typeclass_evars evd in
2120+
let te1 = tei in
2121+
let evd = Evd.set_typeclass_evars evd (Evar.Set.union te1 te2) in
2122+
evd
2123+
with _ -> evd')
20742124
| UnifFailure (evd',e) -> raise (UnableToUnify (evd',e))
20752125

20762126
let unify_leq_delay ?flags env evd t1 t2 =
@@ -2080,7 +2130,21 @@ let unify_leq_delay ?flags env evd t1 t2 =
20802130
| Some flags -> flags
20812131
in
20822132
match evar_conv_x flags env evd CUMUL t1 t2 with
2083-
| Success evd' -> evd'
2133+
| Success evd' -> (try
2134+
let te1 = Evd.get_typeclass_evars evd in
2135+
let te1 = Evar.Set.map (fun e -> Option.default e (Evd.is_aliased_evar evd' e)) te1 in
2136+
let te2 = Evd.get_typeclass_evars evd' in
2137+
let ted = Evar.Set.diff te2 te1 in
2138+
let tei = Evar.Set.inter te2 te1 in
2139+
let evd = Evd.set_typeclass_evars evd' ted in
2140+
let () = ref_solve_unif_constraints_with_heuristics := do_not_solve_unif_constraints_with_heuristics in
2141+
let evd = Typeclasses.resolve_typeclasses env evd in
2142+
let () = ref_solve_unif_constraints_with_heuristics := do_solve_unif_constraints_with_heuristics in
2143+
let te2 = Evd.get_typeclass_evars evd in
2144+
let te1 = tei in
2145+
let evd = Evd.set_typeclass_evars evd (Evar.Set.union te1 te2) in
2146+
evd
2147+
with _ -> evd')
20842148
| UnifFailure (evd',e) -> raise (UnableToUnify (evd',e))
20852149

20862150
let unify ?flags ?(with_ho=true) env evd cv_pb ty1 ty2 =
@@ -2091,8 +2155,22 @@ let unify ?flags ?(with_ho=true) env evd cv_pb ty1 ty2 =
20912155
in
20922156
let res = evar_conv_x flags env evd cv_pb ty1 ty2 in
20932157
match res with
2094-
| Success evd ->
2095-
solve_unif_constraints_with_heuristics ~flags ~with_ho env evd
2158+
| Success evd' ->
2159+
let evd' = solve_unif_constraints_with_heuristics ~flags ~with_ho env evd' in
2160+
(try
2161+
let te1 = Evd.get_typeclass_evars evd in
2162+
let te2 = Evd.get_typeclass_evars evd' in
2163+
let ted = Evar.Set.diff te2 te1 in
2164+
let tei = Evar.Set.inter te2 te1 in
2165+
let evd = Evd.set_typeclass_evars evd' ted in
2166+
let () = ref_solve_unif_constraints_with_heuristics := do_not_solve_unif_constraints_with_heuristics in
2167+
let evd = Typeclasses.resolve_typeclasses env evd in
2168+
let () = ref_solve_unif_constraints_with_heuristics := do_solve_unif_constraints_with_heuristics in
2169+
let te2 = Evd.get_typeclass_evars evd in
2170+
let te1 = tei in
2171+
let evd = Evd.set_typeclass_evars evd (Evar.Set.union te1 te2) in
2172+
evd
2173+
with _ -> evd')
20962174
| UnifFailure (evd, reason) ->
20972175
raise (PretypeError (env, evd, CannotUnify (ty1, ty2, Some reason)))
20982176

0 commit comments

Comments
 (0)