diff options
Diffstat (limited to 'pretyping')
-rw-r--r-- | pretyping/coercion.ml | 2 | ||||
-rw-r--r-- | pretyping/evarutil.ml | 7 | ||||
-rw-r--r-- | pretyping/evarutil.mli | 3 | ||||
-rw-r--r-- | pretyping/typeclasses.ml | 87 | ||||
-rw-r--r-- | pretyping/typeclasses.mli | 17 | ||||
-rw-r--r-- | pretyping/unification.ml | 47 |
6 files changed, 112 insertions, 51 deletions
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml index 586ad716d..2f5099c1a 100644 --- a/pretyping/coercion.ml +++ b/pretyping/coercion.ml @@ -79,7 +79,7 @@ module Default = struct | [] -> { uj_val = applist (j_val funj,argl); uj_type = typ } | h::restl -> - (* On devrait pouvoir s'arranger pour qu'on n'ait pas à faire hnf_constr *) + (* On devrait pouvoir s'arranger pour qu'on n'ait pas à faire hnf_constr *) match kind_of_term (whd_betadeltaiota env Evd.empty typ) with | Prod (_,c1,c2) -> (* Typage garanti par l'appel à app_coercion*) diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml index 8d19feea4..0fe691358 100644 --- a/pretyping/evarutil.ml +++ b/pretyping/evarutil.ml @@ -1231,8 +1231,11 @@ let check_evars env initial_sigma evd c = assert (Evd.mem sigma evk); if not (Evd.mem initial_sigma evk) then let (loc,k) = evar_source evk evd in - let evi = nf_evar_info sigma (Evd.find sigma evk) in - error_unsolvable_implicit loc env sigma evi k None + (match k with + | ImplicitArg (gr, (i, id), false) -> () + | _ -> + let evi = nf_evar_info sigma (Evd.find sigma evk) in + error_unsolvable_implicit loc env sigma evi k None) | _ -> iter_constr proc_rec c in proc_rec c diff --git a/pretyping/evarutil.mli b/pretyping/evarutil.mli index dc212c9ca..883a64b9a 100644 --- a/pretyping/evarutil.mli +++ b/pretyping/evarutil.mli @@ -191,3 +191,6 @@ exception ClearDependencyError of identifier * clear_dependency_error val clear_hyps_in_evi : evar_defs ref -> named_context_val -> types -> identifier list -> named_context_val * types + +val push_rel_context_to_named_context : Environ.env -> types -> + named_context_val * types * constr list diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml index ceaf25be0..38fca2f19 100644 --- a/pretyping/typeclasses.ml +++ b/pretyping/typeclasses.ml @@ -24,6 +24,17 @@ open Typeclasses_errors open Libobject (*i*) + +let add_instance_hint_ref = ref (fun id pri -> assert false) +let register_add_instance_hint = + (:=) add_instance_hint_ref +let add_instance_hint id = !add_instance_hint_ref id + +let set_typeclass_transparency_ref = ref (fun id pri -> assert false) +let register_set_typeclass_transparency = + (:=) set_typeclass_transparency_ref +let set_typeclass_transparency gr c = !set_typeclass_transparency_ref gr c + let mismatched_params env n m = mismatched_ctx_inst env Parameters n m (* let mismatched_defs env n m = mismatched_ctx_inst env Definitions n m *) let mismatched_props env n m = mismatched_ctx_inst env Properties n m @@ -54,10 +65,10 @@ type instance = { -1 for discard, 0 for none, mutable to avoid redeclarations when multiple rebuild_object happen. *) is_global: int; - is_impl: constant; + is_impl: global_reference; } -type instances = (global_reference, instance Cmap.t) Gmap.t +type instances = (global_reference, (global_reference, instance) Gmap.t) Gmap.t let instance_impl is = is.is_impl @@ -95,11 +106,6 @@ let _ = Summary.unfreeze_function = unfreeze; Summary.init_function = init } -let add_instance_hint_ref = ref (fun id pri -> assert false) -let register_add_instance_hint = - (:=) add_instance_hint_ref -let add_instance_hint id = !add_instance_hint_ref id - (* * classes persistent object *) @@ -177,11 +183,11 @@ let add_class cl = * instances persistent object *) -let load_instance (_,inst) = - let insts = - try Gmap.find inst.is_class !instances - with Not_found -> Cmap.empty in - let insts = Cmap.add inst.is_impl inst insts in +let load_instance (_,inst) = + let insts = + try Gmap.find inst.is_class !instances + with Not_found -> Gmap.empty in + let insts = Gmap.add inst.is_impl inst insts in instances := Gmap.add inst.is_class insts !instances let cache_instance = load_instance @@ -189,7 +195,7 @@ let cache_instance = load_instance let subst_instance (subst,inst) = { inst with is_class = fst (subst_global subst inst.is_class); - is_impl = fst (Mod_subst.subst_con subst inst.is_impl) } + is_impl = fst (subst_global subst inst.is_impl) } let discharge_instance (_,inst) = if inst.is_global <= 0 then None @@ -197,7 +203,7 @@ let discharge_instance (_,inst) = { inst with is_global = pred inst.is_global; is_class = Lib.discharge_global inst.is_class; - is_impl = Lib.discharge_con inst.is_impl } + is_impl = Lib.discharge_global inst.is_impl } let rebuild_instance inst = add_instance_hint inst.is_impl inst.is_pri; @@ -222,6 +228,36 @@ let add_instance i = Lib.add_anonymous_leaf (instance_input i); add_instance_hint i.is_impl i.is_pri +open Declarations + +let add_constant_class cst = + let ty = Typeops.type_of_constant (Global.env ()) cst in + let ctx, arity = decompose_prod_assum ty in + let tc = + { cl_impl = ConstRef cst; + cl_context = ([], ctx); + cl_props = [(Anonymous, None, arity)]; + cl_projs = [] + } + in add_class tc; + set_typeclass_transparency (EvalConstRef cst) false + +let add_inductive_class ind = + let mind, oneind = Global.lookup_inductive ind in + let k = + let ty = Inductive.type_of_inductive_knowing_parameters + (push_rel_context oneind.mind_arity_ctxt (Global.env ())) + oneind (Termops.rel_vect 1 (List.length oneind.mind_arity_ctxt)) + in + { cl_impl = IndRef ind; + cl_context = [], oneind.mind_arity_ctxt; + cl_props = [Anonymous, None, ty]; + cl_projs = [] } + in add_class k; + Array.iteri (fun i _ -> + add_instance (new_instance k None true (ConstructRef (ind, succ i)))) + oneind.mind_consnames + (* * interface functions *) @@ -243,25 +279,24 @@ let typeclasses () = Gmap.fold (fun _ l c -> l :: c) !classes [] let cmapl_add x y m = try let l = Gmap.find x m in - Gmap.add x (Cmap.add y.is_impl y l) m + Gmap.add x (Gmap.add y.is_impl y l) m with Not_found -> - Gmap.add x (Cmap.add y.is_impl y Cmap.empty) m + Gmap.add x (Gmap.add y.is_impl y Gmap.empty) m -let cmap_elements c = Cmap.fold (fun k v acc -> v :: acc) c [] +let cmap_elements c = Gmap.fold (fun k v acc -> v :: acc) c [] let instances_of c = try cmap_elements (Gmap.find c.cl_impl !instances) with Not_found -> [] -let all_instances () = - Gmap.fold (fun k v acc -> - Cmap.fold (fun k v acc -> v :: acc) v acc) +let all_instances () = + Gmap.fold (fun k v acc -> + Gmap.fold (fun k v acc -> v :: acc) v acc) !instances [] -let instances r = - let cl = class_info r in instances_of cl - - -let is_class gr = +let instances r = + let cl = class_info r in instances_of cl + +let is_class gr = Gmap.fold (fun k v acc -> acc || v.cl_impl = gr) !classes false let is_instance = function @@ -273,6 +308,8 @@ let is_instance = function (match Decls.variable_kind v with | IsDefinition Instance -> true | _ -> false) + | ConstructRef (ind,_) -> + is_class (IndRef ind) | _ -> false let is_implicit_arg k = diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli index c9ee9adf0..19ec47cf4 100644 --- a/pretyping/typeclasses.mli +++ b/pretyping/typeclasses.mli @@ -49,7 +49,11 @@ val all_instances : unit -> instance list val add_class : typeclass -> unit -val new_instance : typeclass -> int option -> bool -> constant -> instance +val add_constant_class : constant -> unit + +val add_inductive_class : inductive -> unit + +val new_instance : typeclass -> int option -> bool -> global_reference -> instance val add_instance : instance -> unit val class_info : global_reference -> typeclass (* raises a UserError if not a class *) @@ -60,8 +64,8 @@ val dest_class_app : env -> constr -> typeclass * constr list (* Just return None if not a class *) val class_of_constr : constr -> typeclass option - -val instance_impl : instance -> constant + +val instance_impl : instance -> global_reference val is_class : global_reference -> bool val is_instance : global_reference -> bool @@ -86,8 +90,11 @@ val resolve_typeclasses : ?onlyargs:bool -> ?split:bool -> ?fail:bool -> env -> evar_defs -> evar_defs val resolve_one_typeclass : env -> evar_map -> types -> open_constr -val register_add_instance_hint : (constant -> int option -> unit) -> unit -val add_instance_hint : constant -> int option -> unit +val register_set_typeclass_transparency : (evaluable_global_reference -> bool -> unit) -> unit +val set_typeclass_transparency : evaluable_global_reference -> bool -> unit + +val register_add_instance_hint : (global_reference -> int option -> unit) -> unit +val add_instance_hint : global_reference -> int option -> unit val solve_instanciations_problem : (env -> evar_defs -> bool -> bool -> bool -> evar_defs) ref val solve_instanciation_problem : (env -> evar_map -> types -> open_constr) ref diff --git a/pretyping/unification.ml b/pretyping/unification.ml index e8d95a798..a3e63541f 100644 --- a/pretyping/unification.ml +++ b/pretyping/unification.ml @@ -27,6 +27,18 @@ open Retyping open Coercion.Default open Recordops +let occur_meta_or_undefined_evar evd c = + let rec occrec c = match kind_of_term c with + | Meta _ -> raise Occur + | Evar (ev,args) -> + (match evar_body (Evd.find evd ev) with + | Evar_defined c -> + occrec c; Array.iter occrec args + | Evar_empty -> raise Occur) + | Sort s when is_sort_variable evd s -> raise Occur + | _ -> iter_constr occrec c + in try occrec c; false with Occur | Not_found -> true + (* if lname_typ is [xn,An;..;x1,A1] and l is a list of terms, gives [x1:A1]..[xn:An]c' such that c converts to ([x1:A1]..[xn:An]c' l) *) @@ -192,15 +204,16 @@ let oracle_order env cf1 cf2 = let unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb flags m n = let trivial_unify curenv pb (sigma,metasubst,_) m n = let subst = if flags.use_metas_eagerly then metasubst else ms in - match subst_defined_metas subst m with - | Some m1 -> - if (match flags.modulo_conv_on_closed_terms with - Some flags -> + match subst_defined_metas subst m, subst_defined_metas subst n with + | Some m1, Some n1 -> + let evd = (create_evar_defs sigma) in + if (occur_meta_or_undefined_evar evd m1 || occur_meta_or_undefined_evar evd n1) + then false + else if (match flags.modulo_conv_on_closed_terms with + | Some flags -> is_trans_fconv (conv_pb_of pb) flags env sigma m1 n - | None -> false) then true else - if (not (is_ground_term (create_evar_defs sigma) m1)) - || occur_meta_or_existential n then false else - error_cannot_unify curenv sigma (m, n) + | None -> false) then true + else error_cannot_unify curenv sigma (m, n) | _ -> false in let rec unirec_rec (curenv,nb as curenvnb) pb b ((sigma,metasubst,evarsubst) as substn) curm curn = let cM = Evarutil.whd_castappevar sigma curm @@ -370,22 +383,20 @@ let unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb flag unirec_rec curenvnb pb b substn c1 (applist (c,(List.rev ks))) in - if (if occur_meta m then false else - if (match flags.modulo_conv_on_closed_terms with - Some flags -> - is_trans_fconv (conv_pb_of cv_pb) flags env sigma m n - | None -> constr_cmp (conv_pb_of cv_pb) m n) then true else - if (not (is_ground_term (create_evar_defs sigma) m)) - || occur_meta_or_existential n then false else - if (match flags.modulo_conv_on_closed_terms, flags.modulo_delta with + let evd = create_evar_defs sigma in + if (if occur_meta_or_undefined_evar evd m || occur_meta_or_undefined_evar evd n then false + else if (match flags.modulo_conv_on_closed_terms with + | Some flags -> + is_trans_fconv (conv_pb_of cv_pb) flags env sigma m n + | None -> constr_cmp (conv_pb_of cv_pb) m n) then true + else if (match flags.modulo_conv_on_closed_terms, flags.modulo_delta with | Some (cv_id, cv_k), (dl_id, dl_k) -> Idpred.subset dl_id cv_id && Cpred.subset dl_k cv_k | None,(dl_id, dl_k) -> Idpred.is_empty dl_id && Cpred.is_empty dl_k) then error_cannot_unify env sigma (m, n) else false) then subst - else - unirec_rec (env,0) cv_pb conv_at_top subst m n + else unirec_rec (env,0) cv_pb conv_at_top subst m n let unify_0 env sigma = unify_0_with_initial_metas (sigma,[],[]) true env |