Skip to content

Commit 40e7379

Browse files
committed
patch evarconv
1 parent 5af3600 commit 40e7379

File tree

1 file changed

+82
-22
lines changed

1 file changed

+82
-22
lines changed

apps/cs/src/evarconv_hacked.ml

Lines changed: 82 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,10 @@ let rec ise_stack2 no_app env evd f sk1 sk2 =
488488
|_, _ -> fail (UnifFailure (i,(* Maybe improve: *) NotSameHead))
489489
in ise_rev_stack2 false evd (List.rev sk1) (List.rev sk2)
490490

491-
type hook = Environ.env -> Evd.evar_map -> EConstr.t -> EConstr.t -> Evd.evar_map option
491+
type hook = Environ.env -> Evd.evar_map -> (EConstr.t * Reductionops.Stack.t) -> (EConstr.t * Reductionops.Stack.t) -> (Evd.evar_map * (EConstr.t * EConstr.t) * EConstr.t * EConstr.t list *
492+
(EConstr.t list * EConstr.t list) * (EConstr.t list * EConstr.t list) *
493+
(Reductionops.Stack.t * Reductionops.Stack.t) * EConstr.constr *
494+
(int option * EConstr.constr)) option
492495

493496
let all_hooks = ref (CString.Map.empty : hook CString.Map.t)
494497

@@ -591,6 +594,38 @@ let infer_conv_noticing_evars ~pb ~ts env sigma t1 t2 =
591594
if !has_evar then None
592595
else Some (UnifFailure (sigma, UnifUnivInconsistency e))
593596

597+
let pr_econstr = ref (fun _ _ _ -> Pp.str "unable to print econstr")
598+
599+
(* TODO: move to a proper place *)
600+
let rec split_at n acc l =
601+
if n = 0 then (List.rev acc, l)
602+
else match l with
603+
| [] -> (List.rev acc, l)
604+
| h :: t -> split_at (n-1) (h :: acc) t
605+
let split_at n l = split_at n [] l
606+
607+
let try_simplify_proj_construct flags env evd v k sk =
608+
match k with (* try unfolding an applied projection on the rhs *)
609+
| Proj (p, _, c) -> begin
610+
let c = whd_all env evd c in (* reduce argument *)
611+
try let (hd, args) = destApp evd c in
612+
if isConstruct evd hd then Some (whd_nored_state env evd (args.(Projection.npars p + Projection.arg p), sk))
613+
else None
614+
with _ -> None
615+
end
616+
| Const (cn, _) when Structures.Structure.is_projection cn -> begin
617+
match split_at (Structures.Structure.projection_nparams cn) (Option.default [] (Stack.list_of_app_stack sk)) with
618+
| (_, []) -> None
619+
| (_, c :: _) -> begin
620+
let c = whd_all env evd c in
621+
try let (hd, _) = destApp evd c in
622+
if isConstruct evd hd then
623+
Some (whd_betaiota_deltazeta_for_iota_state flags.open_ts env evd (v,sk))
624+
else None
625+
with _ -> None
626+
end end
627+
| _ -> None
628+
594629
let rec evar_conv_x flags env evd pbty term1 term2 =
595630
let term1 = whd_head_evar evd term1 in
596631
let term2 = whd_head_evar evd term2 in
@@ -923,7 +958,10 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
923958
flex_maybeflex false ev2 appr2 appr1 v1
924959

925960
| MaybeFlexible v1, MaybeFlexible v2 -> begin
926-
match EConstr.kind evd term1, EConstr.kind evd term2 with
961+
let k1 = EConstr.kind evd term1 in
962+
let k2 = EConstr.kind evd term2 in
963+
begin
964+
match k1, k2 with
927965
| LetIn (na1,b1,t1,c'1), LetIn (na2,b2,t2,c'2) ->
928966
let f1 i = (* FO *)
929967
ise_and i
@@ -996,16 +1034,22 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
9961034
| None ->
9971035
UnifFailure (i,NotSameHead)
9981036
and f2 i =
999-
(try
1037+
(match try_simplify_proj_construct flags env evd v1 k1 sk1, try_simplify_proj_construct flags env evd v2 k2 sk2 with
1038+
| Some x1, Some x2 -> UnifFailure (i,NoCanonicalStructure)
1039+
| Some x1, None -> UnifFailure (i,NoCanonicalStructure)
1040+
| None, Some x2 -> UnifFailure (i,NoCanonicalStructure)
1041+
| _, _ -> (try
10001042
if not flags.with_cs then raise Not_found
10011043
else conv_record flags env
10021044
(try check_conv_record env i appr1 appr2
1003-
with Not_found -> check_conv_record env i appr2 appr1)
1004-
with Not_found ->
1005-
let sigma = i in
1006-
match apply_hooks env sigma (Stack.zip sigma appr1) (Stack.zip sigma appr2) with
1007-
| Some sigma -> Success sigma
1008-
| None -> UnifFailure (i,NoCanonicalStructure))
1045+
with Not_found -> begin match (apply_hooks env i appr1 appr2) with
1046+
| Some r -> r
1047+
| None -> begin try check_conv_record env i appr2 appr1
1048+
with Not_found -> begin match (apply_hooks env i appr2 appr1) with
1049+
| Some r -> r
1050+
| None -> raise Not_found
1051+
end end end)
1052+
with Not_found -> UnifFailure (i,NoCanonicalStructure)))
10091053
and f3 i =
10101054
(* heuristic: unfold second argument first, exception made
10111055
if the first argument is a beta-redex (expand a constant
@@ -1044,7 +1088,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10441088
flags.open_ts env i (v2,sk2))
10451089
in
10461090
ise_try evd [f1; f2; f3]
1047-
end
1091+
end end
10481092

10491093
| Rigid, Rigid when EConstr.isLambda evd term1 && EConstr.isLambda evd term2 ->
10501094
let (na1,c1,c'1) = EConstr.destLambda evd term1 in
@@ -1062,14 +1106,21 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10621106
| Rigid, Flexible ev2 -> flex_rigid false ev2 appr2 appr1
10631107

10641108
| MaybeFlexible v1, Rigid ->
1109+
let k1 = EConstr.kind evd term1 in begin
1110+
let () = debug_unification (fun () -> Pp.(v 0 (str "v1 maybeflexible against rigid" ++ !pr_econstr env evd v1 ++ cut ()))) in
1111+
match try_simplify_proj_construct flags env evd v1 k1 sk1 with
1112+
| Some x1 -> evar_eqappr_x flags env evd pbty x1 appr2
1113+
| None ->
10651114
let f3 i =
10661115
(try
10671116
if not flags.with_cs then raise Not_found
1068-
else conv_record flags env (check_conv_record env i appr1 appr2)
1069-
with Not_found -> let sigma = i in
1070-
match apply_hooks env sigma (Stack.zip sigma appr1) (Stack.zip sigma appr2) with
1071-
| Some sigma -> Success sigma
1072-
| None -> UnifFailure (i,NoCanonicalStructure))
1117+
else conv_record flags env (
1118+
try check_conv_record env i appr1 appr2 with
1119+
| Not_found -> begin match apply_hooks env i appr1 appr2 with
1120+
| Some r -> r
1121+
| None -> raise Not_found
1122+
end)
1123+
with Not_found -> UnifFailure (i,NoCanonicalStructure))
10731124

10741125
and f4 i =
10751126
evar_eqappr_x flags env i pbty
@@ -1078,22 +1129,32 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) flags env evd pbty
10781129
appr2
10791130
in
10801131
ise_try evd [f3; f4]
1132+
end
10811133

10821134
| Rigid, MaybeFlexible v2 ->
1135+
let k2 = EConstr.kind evd term2 in begin
1136+
let () = debug_unification (fun () -> Pp.(v 0 (str "rigid against v2 maybeflexible" ++ !pr_econstr env evd v2 ++ cut ()))) in
1137+
match try_simplify_proj_construct flags env evd v2 k2 sk2 with
1138+
| Some x2 -> let () = debug_unification (fun () -> Pp.(v 0 (str "reduced to" ++ !pr_econstr env evd (let (x, _) = x2 in x)))) in evar_eqappr_x flags env evd pbty appr1 x2
1139+
| None ->
10831140
let f3 i =
10841141
(try
10851142
if not flags.with_cs then raise Not_found
1086-
else conv_record flags env (check_conv_record env i appr2 appr1)
1087-
with Not_found -> let sigma = i in
1088-
match apply_hooks env sigma (Stack.zip sigma appr1) (Stack.zip sigma appr2) with
1089-
| Some sigma -> Success sigma
1090-
| None -> UnifFailure (i,NoCanonicalStructure))
1143+
else conv_record flags env (
1144+
try check_conv_record env i appr2 appr1 with
1145+
| Not_found -> begin let () = debug_unification (fun () -> Pp.(v 0 (str "ask cs hook"))) in match apply_hooks env i appr2 appr1 with
1146+
| Some r -> r
1147+
| None -> raise Not_found
1148+
end
1149+
| e -> let () = Feedback.msg_info Pp.(str "cs hook crashed") in failwith "argh")
1150+
with Not_found -> UnifFailure (i,NoCanonicalStructure))
10911151
and f4 i =
10921152
evar_eqappr_x flags env i pbty appr1
10931153
(whd_betaiota_deltazeta_for_iota_state
10941154
flags.open_ts env i (v2,sk2))
10951155
in
10961156
ise_try evd [f3; f4]
1157+
end
10971158

10981159
(* Eta-expansion *)
10991160
| Rigid, _ when isLambda evd term1 && (* if ever ill-typed: *) List.is_empty sk1 ->
@@ -1277,8 +1338,7 @@ and conv_record flags env (evd,(h,h2),c,bs,(params,params1),(us,us2),(sk1,sk2),c
12771338
(fun i -> evar_conv_x flags env i CONV c1 app);
12781339
(fun i -> exact_ise_stack2 env i (evar_conv_x flags) sk1 sk2);
12791340
test;
1280-
(fun i -> evar_conv_x flags env i CONV h2
1281-
(fst (decompose_app i (substl ks h))))]
1341+
(fun i -> evar_conv_x flags env i CONV h2 (fst (decompose_app i (substl ks h))))]
12821342
else UnifFailure(evd,(*dummy*)NotSameHead)
12831343

12841344
and eta_constructor flags env evd ((ind, i), u) sk1 (term2,sk2) =

0 commit comments

Comments
 (0)