summaryrefslogtreecommitdiff
path: root/pretyping/coercion.ml
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping/coercion.ml')
-rw-r--r--pretyping/coercion.ml46
1 files changed, 32 insertions, 14 deletions
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index d0f20615..553c9127 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -1,11 +1,18 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2011 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* $Id: coercion.ml 14641 2011-11-06 11:59:10Z herbelin $ *)
+
+(* Created by Hugo Herbelin for Coq V7 by isolating the coercion
+ mechanism out of the type inference algorithm in file trad.ml from
+ Coq V6.3, Nov 1999; The coercion mechanism was implemented in
+ trad.ml by Amokrane Saïbi, May 1996 *)
+(* Addition of products and sorts in canonical structures by Pierre
+ Corbineau, Feb 2008 *)
+(* Turned into an abstract compilation unit by Matthieu Sozeau, March 2006 *)
open Util
open Names
@@ -66,7 +73,7 @@ module type S = sig
pattern [pat] typed in [ind1] into a pattern typed in [ind2];
raises [Not_found] if no coercion found *)
val inh_pattern_coerce_to :
- loc -> Rawterm.cases_pattern -> inductive -> inductive -> Rawterm.cases_pattern
+ loc -> Glob_term.cases_pattern -> inductive -> inductive -> Glob_term.cases_pattern
end
module Default = struct
@@ -92,8 +99,8 @@ module Default = struct
let apply_pattern_coercion loc pat p =
List.fold_left
(fun pat (co,n) ->
- let f i = if i<n then Rawterm.PatVar (loc, Anonymous) else pat in
- Rawterm.PatCstr (loc, co, list_tabulate f (n+1), Anonymous))
+ let f i = if i<n then Glob_term.PatVar (loc, Anonymous) else pat in
+ Glob_term.PatCstr (loc, co, list_tabulate f (n+1), Anonymous))
pat p
(* raise Not_found if no coercion found *)
@@ -130,8 +137,8 @@ module Default = struct
(evd',{ uj_val = j.uj_val; uj_type = t })
| _ ->
let t,p =
- lookup_path_to_fun_from env ( evd) j.uj_type in
- (evd,apply_coercion env ( evd) p j t)
+ lookup_path_to_fun_from env evd j.uj_type in
+ (evd,apply_coercion env evd p j t)
let inh_app_fun env evd j =
try inh_app_fun env evd j
@@ -141,15 +148,15 @@ module Default = struct
let inh_tosort_force loc env evd j =
try
- let t,p = lookup_path_to_sort_from env ( evd) j.uj_type in
- let j1 = apply_coercion env ( evd) p j t in
- let j2 = on_judgment_type (whd_evar ( evd)) j1 in
+ let t,p = lookup_path_to_sort_from env evd j.uj_type in
+ let j1 = apply_coercion env evd p j t in
+ let j2 = on_judgment_type (whd_evar evd) j1 in
(evd,type_judgment env j2)
with Not_found ->
- error_not_a_type_loc loc env ( evd) j
+ error_not_a_type_loc loc env evd j
let inh_coerce_to_sort loc env evd j =
- let typ = whd_betadeltaiota env ( evd) j.uj_type in
+ let typ = whd_betadeltaiota env evd j.uj_type in
match kind_of_term typ with
| Sort s -> (evd,{ utj_val = j.uj_val; utj_type = s })
| Evar ev when not (is_defined_evar evd ev) ->
@@ -195,6 +202,8 @@ module Default = struct
(* We eta-expand (hence possibly modifying the original term!) *)
(* and look for a coercion c:u1->t1 s.t. fun x:u1 => v' (c x)) *)
(* has type forall (x:u1), u2 (with v' recursively obtained) *)
+ (* Note: we retype the term because sort-polymorphism may have *)
+ (* weaken its type *)
let name = match name with
| Anonymous -> Name (id_of_string "x")
| _ -> name in
@@ -204,7 +213,9 @@ module Default = struct
(Some (mkRel 1)) (lift 1 u1) (lift 1 t1) in
let v1 = Option.get v1 in
let v2 = Option.map (fun v -> beta_applist (lift 1 v,[v1])) v in
- let t2 = subst_term v1 t2 in
+ let t2 = match v2 with
+ | None -> subst_term v1 t2
+ | Some v2 -> Retyping.get_type_of env1 evd' v2 in
let (evd'',v2') = inh_conv_coerce_to_fail loc env1 evd' rigidonly v2 t2 u2 in
(evd'', Option.map (fun v2' -> mkLambda (name, u1, v2')) v2')
| _ -> raise NoCoercion
@@ -231,7 +242,14 @@ module Default = struct
let inh_conv_coerce_rigid_to = inh_conv_coerce_to_gen true
- let inh_conv_coerces_to loc env (evd : evar_map) t (abs, t') = evd
+ let inh_conv_coerces_to loc env (evd : evar_map) t (abs, t') =
+ if abs = None then
+ try
+ fst (inh_conv_coerce_to_fail loc env evd true None t t')
+ with NoCoercion ->
+ evd (* Maybe not enough information to unify *)
+ else
+ evd
(* Still problematic, as it changes unification
let nabsinit, nabs =
match abs with