@@ -979,69 +979,52 @@ let collapse_appl sigma c = match EConstr.kind sigma c with
979
979
980
980
(* First utilities for avoiding telescope computation for subst_term *)
981
981
982
- let prefix_application sigma eq_fun ( k , c ) t =
982
+ let prefix_application sigma eq_fun k l1 t =
983
983
let open EConstr in
984
- let c' = collapse_appl sigma c and t' = collapse_appl sigma t in
985
- match EConstr. kind sigma c', EConstr. kind sigma t' with
986
- | App (f1 ,cl1 ), App (f2 ,cl2 ) ->
987
- let l1 = Array. length cl1
988
- and l2 = Array. length cl2 in
984
+ let t' = collapse_appl sigma t in
985
+ if 0 < l1 then match EConstr. kind sigma t' with
986
+ | App (f2 ,cl2 ) ->
987
+ let l2 = Array. length cl2 in
989
988
if l1 < = l2
990
- && eq_fun sigma c' (mkApp (f2, Array. sub cl2 0 l1)) then
991
- Some (mkApp (mkRel k, Array. sub cl2 l1 (l2 - l1) ))
989
+ && eq_fun sigma k (mkApp (f2, Array. sub cl2 0 l1)) then
990
+ Some (Array. sub cl2 l1 (l2 - l1))
992
991
else
993
992
None
994
993
| _ -> None
994
+ else None
995
995
996
- let my_prefix_application sigma eq_fun (k ,c ) by_c t =
997
- let open EConstr in
998
- let c' = collapse_appl sigma c and t' = collapse_appl sigma t in
999
- match EConstr. kind sigma c', EConstr. kind sigma t' with
1000
- | App (f1 ,cl1 ), App (f2 ,cl2 ) ->
1001
- let l1 = Array. length cl1
1002
- and l2 = Array. length cl2 in
1003
- if l1 < = l2
1004
- && eq_fun sigma c' (mkApp (f2, Array. sub cl2 0 l1)) then
1005
- Some (mkApp ((Vars. lift k by_c), Array. sub cl2 l1 (l2 - l1)))
1006
- else
1007
- None
1008
- | _ -> None
1009
-
1010
- (* Recognizing occurrences of a given subterm in a term: [subst_term c t]
1011
- substitutes [(Rel 1)] for all occurrences of term [c] in a term [t];
1012
- works if [c] has rels *)
1013
-
1014
- let subst_term_gen sigma eq_fun c t =
1015
- let open EConstr in
1016
- let open Vars in
1017
- let rec substrec (k ,c as kc ) t =
1018
- match prefix_application sigma eq_fun kc t with
1019
- | Some x -> x
1020
- | None ->
1021
- if eq_fun sigma c t then mkRel k
1022
- else
1023
- EConstr. map_with_binders sigma (fun (k ,c ) -> (k+ 1 ,lift 1 c)) substrec kc t
996
+ let eq_upto_lift cache c sigma k t =
997
+ let c =
998
+ try Int.Map. find k ! cache
999
+ with Not_found ->
1000
+ let c = EConstr.Vars. lift k c in
1001
+ let () = cache := Int.Map. add k c ! cache in
1002
+ c
1024
1003
in
1025
- substrec (1 ,c) t
1026
-
1027
- let subst_term sigma c t = subst_term_gen sigma EConstr. eq_constr c t
1004
+ EConstr. eq_constr sigma c t
1028
1005
1029
1006
(* Recognizing occurrences of a given subterm in a term :
1030
1007
[replace_term c1 c2 t] substitutes [c2] for all occurrences of
1031
1008
term [c1] in a term [t]; works if [c1] and [c2] have rels *)
1032
1009
1033
- let replace_term_gen sigma eq_fun c by_c in_t =
1034
- let rec substrec ( k , c as kc ) t =
1035
- match my_prefix_application sigma eq_fun kc by_c t with
1036
- | Some x -> x
1010
+ let replace_term_gen sigma eq_fun ar by_c in_t =
1011
+ let rec substrec k t =
1012
+ match prefix_application sigma eq_fun k ar t with
1013
+ | Some args -> EConstr. mkApp ( EConstr.Vars. lift k by_c, args)
1037
1014
| None ->
1038
- (if eq_fun sigma c t then (EConstr.Vars. lift k by_c) else
1039
- EConstr. map_with_binders sigma (fun (k ,c ) -> (k+ 1 ,EConstr.Vars. lift 1 c))
1040
- substrec kc t)
1015
+ (if eq_fun sigma k t then (EConstr.Vars. lift k by_c) else
1016
+ EConstr. map_with_binders sigma succ substrec k t)
1041
1017
in
1042
- substrec (0 ,c) in_t
1018
+ substrec 0 in_t
1019
+
1020
+ let replace_term sigma c byc t =
1021
+ let cache = ref Int.Map. empty in
1022
+ let c = collapse_appl sigma c in
1023
+ let ar = Array. length (snd (decompose_app_vect sigma c)) in
1024
+ let eq sigma k t = eq_upto_lift cache c sigma k t in
1025
+ replace_term_gen sigma eq ar byc t
1043
1026
1044
- let replace_term sigma c byc t = replace_term_gen sigma EConstr. eq_constr c byc t
1027
+ let subst_term sigma c t = replace_term sigma c ( EConstr. mkRel 1 ) t
1045
1028
1046
1029
let vars_of_env env =
1047
1030
let s = Environ. ids_of_named_context_val (Environ. named_context_val env) in
0 commit comments