aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dev/doc/changes.txt7
-rw-r--r--dev/printers.mllib1
-rw-r--r--pretyping/find_subterm.ml166
-rw-r--r--pretyping/find_subterm.mli66
-rw-r--r--pretyping/pretype_errors.ml6
-rw-r--r--pretyping/pretype_errors.mli6
-rw-r--r--pretyping/pretyping.mllib1
-rw-r--r--pretyping/tacred.ml19
-rw-r--r--pretyping/tacred.mli8
-rw-r--r--pretyping/termops.ml136
-rw-r--r--pretyping/termops.mli50
-rw-r--r--pretyping/unification.ml27
-rw-r--r--tactics/extratactics.ml44
-rw-r--r--tactics/tactics.ml3
-rw-r--r--toplevel/himsg.ml7
15 files changed, 277 insertions, 230 deletions
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index d4e42142b..a919b86c2 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -78,6 +78,13 @@
- Tactics API: new_induct -> induction; new_destruct -> destruct;
letin_pat_tac do not accept a type anymore
+- New file find_subterm.ml for gathering former functions
+ subst_closed_term_occ_modulo, subst_closed_term_occ_decl (which now
+ take and outputs also an evar_map), and
+ subst_closed_term_occ_modulo, subst_closed_term_occ_decl_modulo (now
+ renamed into replace_term_occ_modulo and
+ replace_term_occ_decl_modulo).
+
=========================================
= CHANGES BETWEEN COQ V8.3 AND COQ V8.4 =
=========================================
diff --git a/dev/printers.mllib b/dev/printers.mllib
index f826984b4..8477df76c 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -129,6 +129,7 @@ Arguments_renaming
Typing
Patternops
ConstrMatching
+Find_subterm
Tacred
Classops
Typeclasses_errors
diff --git a/pretyping/find_subterm.ml b/pretyping/find_subterm.ml
new file mode 100644
index 000000000..61bb2ce03
--- /dev/null
+++ b/pretyping/find_subterm.ml
@@ -0,0 +1,166 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open Util
+open Errors
+open Names
+open Locus
+open Context
+open Term
+open Nameops
+open Termops
+open Pretype_errors
+
+(** Processing occurrences *)
+
+type occurrence_error =
+ | InvalidOccurrence of int list
+ | IncorrectInValueOccurrence of Id.t
+
+let explain_invalid_occurrence l =
+ let l = List.sort_uniquize Int.compare l in
+ str ("Invalid occurrence " ^ String.plural (List.length l) "number" ^": ")
+ ++ prlist_with_sep spc int l ++ str "."
+
+let explain_incorrect_in_value_occurrence id =
+ pr_id id ++ str " has no value."
+
+let explain_occurrence_error = function
+ | InvalidOccurrence l -> explain_invalid_occurrence l
+ | IncorrectInValueOccurrence id -> explain_incorrect_in_value_occurrence id
+
+let error_occurrences_error e =
+ errorlabstrm "" (explain_occurrence_error e)
+
+let error_invalid_occurrence occ =
+ error_occurrences_error (InvalidOccurrence occ)
+
+let check_used_occurrences nbocc (nowhere_except_in,locs) =
+ let rest = List.filter (fun o -> o >= nbocc) locs in
+ match rest with
+ | [] -> ()
+ | _ -> error_occurrences_error (InvalidOccurrence rest)
+
+let proceed_with_occurrences f occs x =
+ match occs with
+ | NoOccurrences -> x
+ | _ ->
+ (* TODO FINISH ADAPTING WITH HUGO *)
+ let plocs = Locusops.convert_occs occs in
+ assert (List.for_all (fun x -> x >= 0) (snd plocs));
+ let (nbocc,x) = f 1 x in
+ check_used_occurrences nbocc plocs;
+ x
+
+(** Applying a function over a named_declaration with an hypothesis
+ location request *)
+
+let map_named_declaration_with_hyploc f hyploc acc (id,bodyopt,typ) =
+ let f = f (Some (id,hyploc)) in
+ match bodyopt,hyploc with
+ | None, InHypValueOnly ->
+ error_occurrences_error (IncorrectInValueOccurrence id)
+ | None, _ | Some _, InHypTypeOnly ->
+ let acc,typ = f acc typ in acc,(id,bodyopt,typ)
+ | Some body, InHypValueOnly ->
+ let acc,body = f acc body in acc,(id,Some body,typ)
+ | Some body, InHyp ->
+ let acc,body = f acc body in
+ let acc,typ = f acc typ in
+ acc,(id,Some body,typ)
+
+(** Finding a subterm up to some testing function *)
+
+exception SubtermUnificationError of subterm_unification_error
+
+exception NotUnifiable of (constr * constr * unification_error) option
+
+type 'a testing_function = {
+ match_fun : 'a -> constr -> 'a;
+ merge_fun : 'a -> 'a -> 'a;
+ mutable testing_state : 'a;
+ mutable last_found : ((Id.t * hyp_location_flag) option * int * constr) option
+}
+
+(* Find subterms using a testing function, but only at a list of
+ locations or excluding a list of locations; in the occurrences list
+ (b,l), b=true means no occurrence except the ones in l and b=false,
+ means all occurrences except the ones in l *)
+
+let replace_term_occ_gen_modulo occs test bywhat cl occ t =
+ let (nowhere_except_in,locs) = Locusops.convert_occs occs in
+ let maxocc = List.fold_right max locs 0 in
+ let pos = ref occ in
+ let nested = ref false in
+ let add_subst t subst =
+ try
+ test.testing_state <- test.merge_fun subst test.testing_state;
+ test.last_found <- Some (cl,!pos,t)
+ with NotUnifiable e ->
+ let lastpos = Option.get test.last_found in
+ raise (SubtermUnificationError (!nested,(cl,!pos,t),lastpos,e)) in
+ let rec substrec k t =
+ if nowhere_except_in && !pos > maxocc then t else
+ try
+ let subst = test.match_fun test.testing_state t in
+ if Locusops.is_selected !pos occs then
+ (add_subst t subst; incr pos;
+ (* Check nested matching subterms *)
+ nested := true; ignore (subst_below k t); nested := false;
+ (* Do the effective substitution *)
+ Vars.lift k (bywhat ()))
+ else
+ (incr pos; subst_below k t)
+ with NotUnifiable _ ->
+ subst_below k t
+ and subst_below k t =
+ map_constr_with_binders_left_to_right (fun d k -> k+1) substrec k t
+ in
+ let t' = substrec 0 t in
+ (!pos, t')
+
+let replace_term_occ_modulo occs test bywhat t =
+ proceed_with_occurrences
+ (replace_term_occ_gen_modulo occs test bywhat None) occs t
+
+let replace_term_occ_decl_modulo (plocs,hyploc) test bywhat d =
+ proceed_with_occurrences
+ (map_named_declaration_with_hyploc
+ (replace_term_occ_gen_modulo plocs test bywhat)
+ hyploc)
+ plocs d
+
+(** Finding an exact subterm *)
+
+let make_eq_univs_test evd c =
+ { match_fun = (fun evd c' ->
+ let b, cst = Universes.eq_constr_universes c c' in
+ if b then
+ try Evd.add_universe_constraints evd cst
+ with Evd.UniversesDiffer -> raise (NotUnifiable None)
+ else raise (NotUnifiable None));
+ merge_fun = (fun evd _ -> evd);
+ testing_state = evd;
+ last_found = None
+}
+
+let subst_closed_term_occ evd occs c t =
+ let test = make_eq_univs_test evd c in
+ let bywhat () = mkRel 1 in
+ let t' = replace_term_occ_modulo occs test bywhat t in
+ t', test.testing_state
+
+let subst_closed_term_occ_decl evd (plocs,hyploc) c d =
+ let test = make_eq_univs_test evd c in
+ let bywhat () = mkRel 1 in
+ proceed_with_occurrences
+ (map_named_declaration_with_hyploc
+ (fun _ -> replace_term_occ_gen_modulo plocs test bywhat None)
+ hyploc) plocs d,
+ test.testing_state
diff --git a/pretyping/find_subterm.mli b/pretyping/find_subterm.mli
new file mode 100644
index 000000000..44e435e69
--- /dev/null
+++ b/pretyping/find_subterm.mli
@@ -0,0 +1,66 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Locus
+open Context
+open Term
+open Evd
+open Pretype_errors
+
+(** Finding subterms, possibly up to some unification function,
+ possibly at some given occurrences *)
+
+exception NotUnifiable of (constr * constr * unification_error) option
+
+exception SubtermUnificationError of subterm_unification_error
+
+(** A testing function is typically a unification function returning a
+ substitution or failing with a NotUnifiable error, together with a
+ function to merge substitutions and an initial substitution;
+ last_found is used for error messages and it has to be initialized
+ with None. *)
+type 'a testing_function = {
+ match_fun : 'a -> constr -> 'a;
+ merge_fun : 'a -> 'a -> 'a;
+ mutable testing_state : 'a;
+ mutable last_found : ((Id.t * hyp_location_flag) option * int * constr) option
+}
+
+(** This is the basic testing function, looking for exact matches of a
+ closed term *)
+val make_eq_univs_test : evar_map -> constr -> evar_map testing_function
+
+(** [replace_term_occ_modulo occl test mk c] looks in [c] for subterm
+ modulo a testing function [test] and replaces successfully
+ matching subterms at the indicated occurrences [occl] with [mk
+ ()]; it turns a NotUnifiable exception raised by the testing
+ function into a SubtermUnificationError. *)
+val replace_term_occ_modulo :
+ occurrences -> 'a testing_function -> (unit -> constr) -> constr -> constr
+
+(** [replace_term_occ_decl_modulo] is similar to
+ [replace_term_occ_modulo] but for a named_declaration. *)
+val replace_term_occ_decl_modulo :
+ occurrences * hyp_location_flag -> 'a testing_function -> (unit -> constr) ->
+ named_declaration -> named_declaration
+
+(** [subst_closed_term_occ occl c d] replaces occurrences of
+ closed [c] at positions [occl] by [Rel 1] in [d] (see also Note OCC),
+ unifying universes which results in a set of constraints. *)
+val subst_closed_term_occ : evar_map -> occurrences -> constr ->
+ constr -> constr * evar_map
+
+(** [subst_closed_term_occ_decl evd occl c decl] replaces occurrences of
+ closed [c] at positions [occl] by [Rel 1] in [decl]. *)
+val subst_closed_term_occ_decl : evar_map ->
+ occurrences * hyp_location_flag ->
+ constr -> named_declaration -> named_declaration * evar_map
+
+(** Miscellaneous *)
+val error_invalid_occurrence : int list -> 'a
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index d8f51054d..934e7bdbb 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -23,6 +23,10 @@ type unification_error =
| InstanceNotSameType of existential_key * env * types * types
| UnifUnivInconsistency of Univ.univ_inconsistency
+type position =(Id.t * Locus.hyp_location_flag) option
+
+type subterm_unification_error = bool * (position * int * constr) * (position * int * constr) * (constr * constr * unification_error) option
+
type pretype_error =
(* Old Case *)
| CantFindCaseType of constr
@@ -46,7 +50,7 @@ type pretype_error =
| UnexpectedType of constr * constr
| NotProduct of constr
| TypingError of type_error
- | CannotUnifyOccurrences of Termops.subterm_unification_error
+ | CannotUnifyOccurrences of subterm_unification_error
exception PretypeError of env * Evd.evar_map * pretype_error
diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli
index f8e39f316..e816463e7 100644
--- a/pretyping/pretype_errors.mli
+++ b/pretyping/pretype_errors.mli
@@ -24,6 +24,10 @@ type unification_error =
| InstanceNotSameType of existential_key * env * types * types
| UnifUnivInconsistency of Univ.univ_inconsistency
+type position =(Id.t * Locus.hyp_location_flag) option
+
+type subterm_unification_error = bool * (position * int * constr) * (position * int * constr) * (constr * constr * unification_error) option
+
type pretype_error =
(** Old Case *)
| CantFindCaseType of constr
@@ -47,7 +51,7 @@ type pretype_error =
| UnexpectedType of constr * constr
| NotProduct of constr
| TypingError of type_error
- | CannotUnifyOccurrences of Termops.subterm_unification_error
+ | CannotUnifyOccurrences of subterm_unification_error
exception PretypeError of env * Evd.evar_map * pretype_error
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index f1a9d6915..ceb01fd95 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -9,6 +9,7 @@ Nativenorm
Retyping
Cbv
Pretype_errors
+Find_subterm
Evarutil
Evarsolve
Recordops
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 75f6f66fe..6e522933f 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -15,6 +15,7 @@ open Vars
open Libnames
open Globnames
open Termops
+open Find_subterm
open Namegen
open Environ
open Closure
@@ -1075,22 +1076,6 @@ let compute = cbv_betadeltaiota
(* Pattern *)
-let make_eq_univs_test evd c =
- { match_fun = (fun evd c' ->
- let b, cst = Universes.eq_constr_universes c c' in
- if b then
- try Evd.add_universe_constraints evd cst
- with Evd.UniversesDiffer -> raise NotUnifiable
- else raise NotUnifiable);
- merge_fun = (fun evd _ -> evd);
- testing_state = evd;
- last_found = None
-}
-let subst_closed_term_univs_occ evd occs c t =
- let test = make_eq_univs_test evd c in
- let t' = subst_closed_term_occ_modulo occs test None t in
- t', test.testing_state
-
(* gives [na:ta]c' such that c converts to ([na:ta]c' a), abstracting only
* the specified occurrences. *)
@@ -1101,7 +1086,7 @@ let abstract_scheme env sigma (locc,a) c =
if occur_meta a then
mkLambda (na,ta,c)
else
- let c', sigma' = subst_closed_term_univs_occ sigma locc a c in
+ let c', sigma' = subst_closed_term_occ sigma locc a c in
mkLambda (na,ta,c')
let pattern_occs loccs_trm env sigma c =
diff --git a/pretyping/tacred.mli b/pretyping/tacred.mli
index 5e4bc5c46..91364c4ae 100644
--- a/pretyping/tacred.mli
+++ b/pretyping/tacred.mli
@@ -60,14 +60,6 @@ val unfoldn :
(** Fold *)
val fold_commands : constr list -> reduction_function
-val make_eq_univs_test : evar_map -> constr -> evar_map Termops.testing_function
-
-(** [subst_closed_term_occ occl c d] replaces occurrences of closed [c] at
- positions [occl] by [Rel 1] in [d] (see also Note OCC), unifying universes
- which results in a set of constraints. *)
-val subst_closed_term_univs_occ : evar_map -> occurrences -> constr -> constr ->
- constr * evar_map
-
(** Pattern *)
val pattern_occs : (occurrences * constr) list -> env -> evar_map -> constr ->
constr
diff --git a/pretyping/termops.ml b/pretyping/termops.ml
index c68f2c4d9..67ffcf8aa 100644
--- a/pretyping/termops.ml
+++ b/pretyping/termops.ml
@@ -679,142 +679,6 @@ let replace_term_gen eq_fun c by_c in_t =
let replace_term = replace_term_gen eq_constr
-(* Substitute only at a list of locations or excluding a list of
- locations; in the occurrences list (b,l), b=true means no
- occurrence except the ones in l and b=false, means all occurrences
- except the ones in l *)
-
-type occurrence_error =
- | InvalidOccurrence of int list
- | IncorrectInValueOccurrence of Id.t
-
-let explain_invalid_occurrence l =
- let l = List.sort_uniquize Int.compare l in
- str ("Invalid occurrence " ^ String.plural (List.length l) "number" ^": ")
- ++ prlist_with_sep spc int l ++ str "."
-
-let explain_incorrect_in_value_occurrence id =
- pr_id id ++ str " has no value."
-
-let explain_occurrence_error = function
- | InvalidOccurrence l -> explain_invalid_occurrence l
- | IncorrectInValueOccurrence id -> explain_incorrect_in_value_occurrence id
-
-let error_occurrences_error e =
- errorlabstrm "" (explain_occurrence_error e)
-
-let error_invalid_occurrence occ =
- error_occurrences_error (InvalidOccurrence occ)
-
-type position =(Id.t * Locus.hyp_location_flag) option
-
-type subterm_unification_error = bool * (position * int * constr) * (position * int * constr)
-
-exception SubtermUnificationError of subterm_unification_error
-
-exception NotUnifiable
-
-type 'a testing_function = {
- match_fun : 'a -> constr -> 'a;
- merge_fun : 'a -> 'a -> 'a;
- mutable testing_state : 'a;
- mutable last_found : ((Id.t * hyp_location_flag) option * int * constr) option
-}
-
-let subst_closed_term_occ_gen_modulo occs test cl occ t =
- let (nowhere_except_in,locs) = Locusops.convert_occs occs in
- let maxocc = List.fold_right max locs 0 in
- let pos = ref occ in
- let nested = ref false in
- let add_subst t subst =
- try
- test.testing_state <- test.merge_fun subst test.testing_state;
- test.last_found <- Some (cl,!pos,t)
- with NotUnifiable ->
- let lastpos = Option.get test.last_found in
- raise (SubtermUnificationError (!nested,(cl,!pos,t),lastpos)) in
- let rec substrec k t =
- if nowhere_except_in && !pos > maxocc then t else
- try
- let subst = test.match_fun test.testing_state t in
- if Locusops.is_selected !pos occs then
- (add_subst t subst; incr pos;
- (* Check nested matching subterms *)
- nested := true; ignore (subst_below k t); nested := false;
- (* Do the effective substitution *)
- mkRel k)
- else
- (incr pos; subst_below k t)
- with NotUnifiable ->
- subst_below k t
- and subst_below k t =
- map_constr_with_binders_left_to_right (fun d k -> k+1) substrec k t
- in
- let t' = substrec 1 t in
- (!pos, t')
-
-let check_used_occurrences nbocc (nowhere_except_in,locs) =
- let rest = List.filter (fun o -> o >= nbocc) locs in
- match rest with
- | [] -> ()
- | _ -> error_occurrences_error (InvalidOccurrence rest)
-
-let proceed_with_occurrences f occs x =
- match occs with
- | NoOccurrences -> x
- | _ ->
- (* TODO FINISH ADAPTING WITH HUGO *)
- let plocs = Locusops.convert_occs occs in
- assert (List.for_all (fun x -> x >= 0) (snd plocs));
- let (nbocc,x) = f 1 x in
- check_used_occurrences nbocc plocs;
- x
-
-let make_eq_test c = {
- match_fun = (fun () c' -> if eq_constr c c' then () else raise NotUnifiable);
- merge_fun = (fun () () -> ());
- testing_state = ();
- last_found = None
-}
-
-let subst_closed_term_occ_gen occs pos c t =
- subst_closed_term_occ_gen_modulo occs (make_eq_test c) None pos t
-
-let subst_closed_term_occ occs c t =
- proceed_with_occurrences
- (fun occ -> subst_closed_term_occ_gen occs occ c)
- occs t
-
-let subst_closed_term_occ_modulo occs test cl t =
- proceed_with_occurrences
- (subst_closed_term_occ_gen_modulo occs test cl) occs t
-
-let map_named_declaration_with_hyploc f hyploc acc (id,bodyopt,typ) =
- let f = f (Some (id,hyploc)) in
- match bodyopt,hyploc with
- | None, InHypValueOnly ->
- error_occurrences_error (IncorrectInValueOccurrence id)
- | None, _ | Some _, InHypTypeOnly ->
- let acc,typ = f acc typ in acc,(id,bodyopt,typ)
- | Some body, InHypValueOnly ->
- let acc,body = f acc body in acc,(id,Some body,typ)
- | Some body, InHyp ->
- let acc,body = f acc body in
- let acc,typ = f acc typ in
- acc,(id,Some body,typ)
-
-let subst_closed_term_occ_decl (plocs,hyploc) c d =
- proceed_with_occurrences
- (map_named_declaration_with_hyploc
- (fun _ occ -> subst_closed_term_occ_gen plocs occ c) hyploc) plocs d
-
-let subst_closed_term_occ_decl_modulo (plocs,hyploc) test d =
- proceed_with_occurrences
- (map_named_declaration_with_hyploc
- (subst_closed_term_occ_gen_modulo plocs test)
- hyploc)
- plocs d
-
let vars_of_env env =
let s =
Context.fold_named_context (fun (id,_,_) s -> Id.Set.add id s)
diff --git a/pretyping/termops.mli b/pretyping/termops.mli
index ebcf4285c..e01b3f455 100644
--- a/pretyping/termops.mli
+++ b/pretyping/termops.mli
@@ -147,56 +147,6 @@ val subst_term : constr -> constr -> constr
(** [replace_term d e c] replaces [d] by [e] in [c] *)
val replace_term : constr -> constr -> constr -> constr
-(** [subst_closed_term_occ_gen occl n c d] replaces occurrences of closed [c] at
- positions [occl], counting from [n], by [Rel 1] in [d] *)
-val subst_closed_term_occ_gen :
- occurrences -> int -> constr -> types -> int * types
-
-(** [subst_closed_term_occ_modulo] looks for subterm modulo a
- testing function returning a substitution of type ['a] (or failing
- with NotUnifiable); a function for merging substitution (possibly
- failing with NotUnifiable) and an initial substitution are
- required too; [subst_closed_term_occ_modulo] itself turns a
- NotUnifiable exception into a SubtermUnificationError *)
-
-exception NotUnifiable
-
-type position =(Id.t * Locus.hyp_location_flag) option
-
-type subterm_unification_error = bool * (position * int * constr) * (position * int * constr)
-
-exception SubtermUnificationError of subterm_unification_error
-
-type 'a testing_function = {
- match_fun : 'a -> constr -> 'a;
- merge_fun : 'a -> 'a -> 'a;
- mutable testing_state : 'a;
- mutable last_found : ((Id.t * hyp_location_flag) option * int * constr) option
-}
-
-val make_eq_test : constr -> unit testing_function
-
-val subst_closed_term_occ_modulo :
- occurrences -> 'a testing_function -> (Id.t * hyp_location_flag) option
- -> constr -> types
-
-(** [subst_closed_term_occ occl c d] replaces occurrences of closed [c] at
- positions [occl] by [Rel 1] in [d] (see also Note OCC) *)
-val subst_closed_term_occ : occurrences -> constr -> constr -> constr
-
-(** [subst_closed_term_occ_decl occl c decl] replaces occurrences of closed [c]
- at positions [occl] by [Rel 1] in [decl] *)
-
-val subst_closed_term_occ_decl :
- occurrences * hyp_location_flag -> constr -> named_declaration ->
- named_declaration
-
-val subst_closed_term_occ_decl_modulo :
- occurrences * hyp_location_flag -> 'a testing_function ->
- named_declaration -> named_declaration
-
-val error_invalid_occurrence : int list -> 'a
-
(** Alternative term equalities *)
val base_sort_cmp : Reduction.conv_pb -> sorts -> sorts -> bool
val compare_constr_univ : (Reduction.conv_pb -> constr -> constr -> bool) ->
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 9baabae77..dd0f68390 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -26,6 +26,7 @@ open Coercion
open Recordops
open Locus
open Locusops
+open Find_subterm
let occur_meta_or_undefined_evar evd c =
let rec occrec c = match kind_of_term c with
@@ -62,7 +63,7 @@ let abstract_scheme env evd c l lname_typ =
else *)
if occur_meta a then mkLambda_name env (na,ta,t), evd
else
- let t', evd' = Tacred.subst_closed_term_univs_occ evd locc a t in
+ let t', evd' = Find_subterm.subst_closed_term_occ evd locc a t in
mkLambda_name env (na,ta,t'), evd')
(c,evd)
(List.rev l)
@@ -1222,17 +1223,21 @@ let make_pattern_test inf_flags env sigma0 (sigma,c) =
let matching_fun _ t =
try let sigma = w_typed_unify env sigma Reduction.CONV flags c t in
Some(sigma, t)
- with e when Errors.noncritical e -> raise NotUnifiable in
+ with
+ | PretypeError (_,_,CannotUnify (c1,c2,Some e)) ->
+ raise (NotUnifiable (Some (c1,c2,e)))
+ | e when Errors.noncritical e -> raise (NotUnifiable None) in
let merge_fun c1 c2 =
match c1, c2 with
| Some (evd,c1), Some (_,c2) ->
(try let evd = w_typed_unify env evd Reduction.CONV flags c1 c2 in
Some (evd, c1)
- with e when Errors.noncritical e -> raise NotUnifiable)
+ with
+ | PretypeError (_,_,CannotUnify (c1,c2,Some e)) -> raise (NotUnifiable (Some (c1,c2,e)))
+ | e when Errors.noncritical e -> raise (NotUnifiable None))
| Some _, None -> c1
| None, Some _ -> c2
- | None, None -> None
- in
+ | None, None -> None in
{ match_fun = matching_fun; merge_fun = merge_fun;
testing_state = None; last_found = None },
(fun test -> match test.testing_state with
@@ -1247,7 +1252,7 @@ let make_eq_test evd c =
let out cstr =
Evd.evar_universe_context cstr.testing_state, c
in
- (Tacred.make_eq_univs_test evd c, out)
+ (make_eq_univs_test evd c, out)
let make_abstraction_core name (test,out) (sigmac,c) ty occs check_occs env concl =
let id =
@@ -1260,6 +1265,7 @@ let make_abstraction_core name (test,out) (sigmac,c) ty occs check_occs env conc
else
x
in
+ let mkvarid () = mkVar id in
let compute_dependency _ (hyp,_,_ as d) depdecls =
match occurrences_of_hyp hyp occs with
| None ->
@@ -1272,7 +1278,7 @@ let make_abstraction_core name (test,out) (sigmac,c) ty occs check_occs env conc
else
depdecls
| Some ((AllOccurrences, InHyp) as occ) ->
- let newdecl = subst_closed_term_occ_decl_modulo occ test d in
+ let newdecl = replace_term_occ_decl_modulo occ test mkvarid d in
if Context.eq_named_declaration d newdecl
&& not (indirectly_dependent c d depdecls)
then
@@ -1280,16 +1286,15 @@ let make_abstraction_core name (test,out) (sigmac,c) ty occs check_occs env conc
then raise (PretypeError (env,sigmac,NoOccurrenceFound (c,Some hyp)))
else depdecls
else
- (subst1_named_decl (mkVar id) newdecl)::depdecls
+ newdecl :: depdecls
| Some occ ->
- let newdecl = subst_closed_term_occ_decl_modulo occ test d in
- (subst1_named_decl (mkVar id) newdecl)::depdecls in
+ replace_term_occ_decl_modulo occ test mkvarid d :: depdecls in
try
let depdecls = fold_named_context compute_dependency env ~init:[] in
let ccl = match occurrences_of_goal occs with
| None -> concl
| Some occ ->
- subst1 (mkVar id) (subst_closed_term_occ_modulo occ test None concl)
+ replace_term_occ_modulo occ test mkvarid concl
in
let lastlhyp =
if List.is_empty depdecls then None else Some (pi1(List.last depdecls)) in
diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4
index 6adec45bc..fa2ac3712 100644
--- a/tactics/extratactics.ml4
+++ b/tactics/extratactics.ml4
@@ -582,7 +582,7 @@ END
(**********************************************************************)
let subst_var_with_hole occ tid t =
- let occref = if occ > 0 then ref occ else Termops.error_invalid_occurrence [occ] in
+ let occref = if occ > 0 then ref occ else Find_subterm.error_invalid_occurrence [occ] in
let locref = ref 0 in
let rec substrec = function
| GVar (_,id) as x ->
@@ -598,7 +598,7 @@ let subst_var_with_hole occ tid t =
| c -> map_glob_constr_left_to_right substrec c in
let t' = substrec t
in
- if !occref > 0 then Termops.error_invalid_occurrence [occ] else t'
+ if !occref > 0 then Find_subterm.error_invalid_occurrence [occ] else t'
let subst_hole_with_term occ tc t =
let locref = ref 0 in
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 30568edab..d046a0642 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -15,6 +15,7 @@ open Term
open Vars
open Context
open Termops
+open Find_subterm
open Namegen
open Declarations
open Inductiveops
@@ -1865,7 +1866,7 @@ let generalize_goal_gen ids i ((occs,c,b),na) t (cl,evd) =
let decls,cl = decompose_prod_n_assum i cl in
let dummy_prod = it_mkProd_or_LetIn mkProp decls in
let newdecls,_ = decompose_prod_n_assum i (subst_term_gen eq_constr_nounivs c dummy_prod) in
- let cl',evd' = subst_closed_term_univs_occ evd occs c (it_mkProd_or_LetIn cl newdecls) in
+ let cl',evd' = subst_closed_term_occ evd occs c (it_mkProd_or_LetIn cl newdecls) in
let na = generalized_name c t ids cl' na in
mkProd_or_LetIn (na,b,t) cl', evd'
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index d251b571c..16d324029 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -645,15 +645,16 @@ let pr_position (cl,pos) =
| Some (id,Locus.InHypValueOnly) -> str " of the body of hypothesis " ++ pr_id id in
int pos ++ clpos
-let explain_cannot_unify_occurrences env nested (cl2,pos2,t2) (cl1,pos1,t1) =
+let explain_cannot_unify_occurrences env sigma nested (cl2,pos2,t2) (cl1,pos1,t1) e =
let s = if nested then "Found nested occurrences of the pattern"
else "Found incompatible occurrences of the pattern" in
+ let ppreason = match e with None -> mt() | Some (c1,c2,e) -> explain_unification_error env sigma c1 c2 (Some e) in
str s ++ str ":" ++
spc () ++ str "Matched term " ++ pr_lconstr_env env t2 ++
strbrk " at position " ++ pr_position (cl2,pos2) ++
strbrk " is not compatible with matched term " ++
pr_lconstr_env env t1 ++ strbrk " at position " ++
- pr_position (cl1,pos1) ++ str "."
+ pr_position (cl1,pos1) ++ ppreason ++ str "."
let explain_pretype_error env sigma err =
let env = Evarutil.env_nf_betaiotaevar sigma env in
@@ -687,7 +688,7 @@ let explain_pretype_error env sigma err =
| AbstractionOverMeta (m,n) -> explain_abstraction_over_meta env m n
| NonLinearUnification (m,c) -> explain_non_linear_unification env m c
| TypingError t -> explain_type_error env sigma t
- | CannotUnifyOccurrences (b,c1,c2) -> explain_cannot_unify_occurrences env b c1 c2
+ | CannotUnifyOccurrences (b,c1,c2,e) -> explain_cannot_unify_occurrences env sigma b c1 c2 e
(* Module errors *)