summaryrefslogtreecommitdiff
path: root/pretyping/classops.ml
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping/classops.ml')
-rw-r--r--pretyping/classops.ml103
1 files changed, 69 insertions, 34 deletions
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index b5a5709e..398da529 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* $Id: classops.ml 11309 2008-08-06 10:30:35Z herbelin $ *)
+(* $Id: classops.ml 11343 2008-09-01 20:55:13Z herbelin $ *)
open Util
open Pp
@@ -128,6 +128,10 @@ let class_exists cl = Bijint.mem cl !class_tab
let class_info_from_index i = Bijint.map i !class_tab
+let cl_fun_index = fst(class_info CL_FUN)
+
+let cl_sort_index = fst(class_info CL_SORT)
+
(* coercion_info : coe_typ -> coe_info_typ *)
let coercion_info coe = Gmap.find coe !coercion_tab
@@ -136,32 +140,10 @@ let coercion_exists coe = Gmap.mem coe !coercion_tab
let coercion_params coe_info = coe_info.coe_param
-let lookup_path_between (s,t) =
- Gmap.find (s,t) !inheritance_graph
-
-let lookup_path_to_fun_from s =
- lookup_path_between (s,fst(class_info CL_FUN))
+(* find_class_type : env -> evar_map -> constr -> cl_typ * int *)
-let lookup_path_to_sort_from s =
- lookup_path_between (s,fst(class_info CL_SORT))
-
-let lookup_pattern_path_between (s,t) =
- let l = Gmap.find (s,t) !inheritance_graph in
- List.map
- (fun coe ->
- let c, _ =
- Reductionops.whd_betadeltaiota_stack (Global.env()) Evd.empty
- coe.coe_value
- in
- match kind_of_term c with
- | Construct cstr ->
- (cstr, Inductiveops.constructor_nrealargs (Global.env()) cstr -1)
- | _ -> raise Not_found) l
-
-(* find_class_type : constr -> cl_typ * int *)
-
-let find_class_type t =
- let t', args = decompose_app (Reductionops.whd_betaiotazeta t) in
+let find_class_type env sigma t =
+ let t', args = Reductionops.whd_betaiotazetaevar_stack env sigma t in
match kind_of_term t' with
| Var id -> CL_SECVAR id, args
| Const sp -> CL_CONST sp, args
@@ -178,7 +160,7 @@ let subst_cl_typ subst ct = match ct with
| CL_CONST kn ->
let kn',t = subst_con subst kn in
if kn' == kn then ct else
- fst (find_class_type t)
+ fst (find_class_type (Global.env()) Evd.empty t)
| CL_IND (kn,i) ->
let kn' = subst_kn subst kn in
if kn' == kn then ct else
@@ -188,19 +170,17 @@ let subst_cl_typ subst ct = match ct with
to declare any term as a coercion *)
let subst_coe_typ subst t = fst (subst_global subst t)
-(* classe d'un terme *)
-
(* class_of : Term.constr -> int *)
let class_of env sigma t =
let (t, n1, i, args) =
try
- let (cl,args) = find_class_type t in
+ let (cl,args) = find_class_type env sigma t in
let (i, { cl_param = n1 } ) = class_info cl in
(t, n1, i, args)
with Not_found ->
let t = Tacred.hnf_constr env sigma t in
- let (cl, args) = find_class_type t in
+ let (cl, args) = find_class_type env sigma t in
let (i, { cl_param = n1 } ) = class_info cl in
(t, n1, i, args)
in
@@ -208,7 +188,7 @@ let class_of env sigma t =
let inductive_class_of ind = fst (class_info (CL_IND ind))
-let class_args_of c = snd (find_class_type c)
+let class_args_of env sigma c = snd (find_class_type env sigma c)
let string_of_class = function
| CL_FUN -> "Funclass"
@@ -222,6 +202,61 @@ let string_of_class = function
let pr_class x = str (string_of_class x)
+(* lookup paths *)
+
+let lookup_path_between_class (s,t) =
+ Gmap.find (s,t) !inheritance_graph
+
+let lookup_path_to_fun_from_class s =
+ lookup_path_between_class (s,cl_fun_index)
+
+let lookup_path_to_sort_from_class s =
+ lookup_path_between_class (s,cl_sort_index)
+
+(* advanced path lookup *)
+
+let apply_on_class_of env sigma t cont =
+ try
+ let (cl,args) = find_class_type env sigma t in
+ let (i, { cl_param = n1 } ) = class_info cl in
+ if List.length args <> n1 then raise Not_found;
+ t, cont i
+ with Not_found ->
+ (* Is it worth to be more incremental on the delta steps? *)
+ let t = Tacred.hnf_constr env sigma t in
+ let (cl, args) = find_class_type env sigma t in
+ let (i, { cl_param = n1 } ) = class_info cl in
+ if List.length args <> n1 then raise Not_found;
+ t, cont i
+
+let lookup_path_between env sigma (s,t) =
+ let (s,(t,p)) =
+ apply_on_class_of env sigma s (fun i ->
+ apply_on_class_of env sigma t (fun j ->
+ lookup_path_between_class (i,j))) in
+ (s,t,p)
+
+let lookup_path_to_fun_from env sigma s =
+ apply_on_class_of env sigma s lookup_path_to_fun_from_class
+
+let lookup_path_to_sort_from env sigma s =
+ apply_on_class_of env sigma s lookup_path_to_sort_from_class
+
+let get_coercion_constructor coe =
+ let c, _ =
+ Reductionops.whd_betadeltaiota_stack (Global.env()) Evd.empty coe.coe_value
+ in
+ match kind_of_term c with
+ | Construct cstr ->
+ (cstr, Inductiveops.constructor_nrealargs (Global.env()) cstr -1)
+ | _ ->
+ raise Not_found
+
+let lookup_pattern_path_between (s,t) =
+ let i = inductive_class_of s in
+ let j = inductive_class_of t in
+ List.map get_coercion_constructor (Gmap.find (i,j) !inheritance_graph)
+
(* coercion_value : coe_index -> unsafe_judgment * bool *)
let coercion_value { coe_value = c; coe_type = t; coe_is_identity = b } =
@@ -255,11 +290,11 @@ let add_coercion_in_graph (ic,source,target) =
try
if i=j then begin
if different_class_params i j then begin
- let _ = lookup_path_between ij in
+ let _ = lookup_path_between_class ij in
ambig_paths := (ij,p)::!ambig_paths
end
end else begin
- let _ = lookup_path_between (i,j) in
+ let _ = lookup_path_between_class (i,j) in
ambig_paths := (ij,p)::!ambig_paths
end;
false