@@ -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
493496let 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+
594629let 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
12841344and eta_constructor flags env evd ((ind , i ), u ) sk1 (term2 ,sk2 ) =
0 commit comments