diff options
| author | msozeau | 2009-10-27 19:43:51 +0000 |
|---|---|---|
| committer | msozeau | 2009-10-27 19:43:51 +0000 |
| commit | 36c448f43c7fa16163b543b941be4a917a712a37 (patch) | |
| tree | 73affd4fede1fea0dd56a2600bc420de769432e2 /interp/implicit_quantifiers.ml | |
| parent | 3178c7a29ff8b57a4598c4c5ded2eb29b8067dcf (diff) | |
Add a new vernacular command for controling implicit generalization of
variables with syntax:
[Local?|Global] Generalizable Variable(s)? [all|none|id1 idn].
By default no variable is generalizable, so this patch breaks backward
compatibility with files that used implicit generalization (through
Instance declarations for example). To get back the old behavior, one
just needs to use [Global Generalizable Variables all].
Make coq_makefile more robust using [mkdir -p].
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12428 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'interp/implicit_quantifiers.ml')
| -rw-r--r-- | interp/implicit_quantifiers.ml | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml index a55daff364..93f4eedff2 100644 --- a/interp/implicit_quantifiers.ml +++ b/interp/implicit_quantifiers.ml @@ -24,8 +24,49 @@ open Libnames open Typeclasses open Typeclasses_errors open Pp +open Libobject +open Nameops (*i*) +let generalizable_table = ref Idpred.empty + +let _ = + Summary.declare_summary "generalizable-ident" + { Summary.freeze_function = (fun () -> !generalizable_table); + Summary.unfreeze_function = (fun r -> generalizable_table := r); + Summary.init_function = (fun () -> generalizable_table := Idpred.empty) } + +let declare_generalizable_ident table (loc,id) = + if id <> root_of_id id then + user_err_loc(loc,"declare_generalizable_ident", + (pr_id id ++ str + " is not declarable as generalizable identifier: it must have no trailing digits, quote, or _")); + if Idpred.mem id table then + user_err_loc(loc,"declare_generalizable_ident", + (pr_id id++str" is already declared as a generalizable identifier")) + else Idpred.add id table + +let add_generalizable gen table = + match gen with + | None -> Idpred.empty + | Some [] -> Idpred.full + | Some l -> List.fold_left (fun table lid -> declare_generalizable_ident table lid) + table l + +let cache_generalizable_type (_,(local,cmd)) = + generalizable_table := add_generalizable cmd !generalizable_table + +let (in_generalizable, _) = + declare_object {(default_object "GENERALIZED-IDENT") with + cache_function = cache_generalizable_type; + classify_function = (fun (local, _ as obj) -> if local then Dispose else Keep obj) + } + +let declare_generalizable local gen = + Lib.add_anonymous_leaf (in_generalizable (local, gen)) + +let find_generalizable_ident id = Idpred.mem (root_of_id id) !generalizable_table + let ids_of_list l = List.fold_right Idset.add l Idset.empty @@ -51,13 +92,16 @@ let is_freevar ids env x = (* Auxilliary functions for the inference of implicitly quantified variables. *) let free_vars_of_constr_expr c ?(bound=Idset.empty) l = - let found id bdvars l = + let found loc id bdvars l = if List.mem id l then l - else if not (is_freevar bdvars (Global.env ()) id) - then l else id :: l + else if is_freevar bdvars (Global.env ()) id + then + if find_generalizable_ident id then id :: l + else user_err_loc (loc, "Generalization", str "Unbound and ungeneralizable variable " ++ pr_id id) + else l in let rec aux bdvars l c = match c with - | CRef (Ident (_,id)) -> found id bdvars l + | CRef (Ident (loc,id)) -> found loc id bdvars l | CNotation (_, "{ _ : _ | _ }", (CRef (Ident (_, id)) :: _, [])) when not (Idset.mem id bdvars) -> fold_constr_expr_with_binders (fun a l -> Idset.add a l) aux (Idset.add id bdvars) l c | c -> fold_constr_expr_with_binders (fun a l -> Idset.add a l) aux bdvars l c @@ -204,14 +248,14 @@ let combine_params_freevar = let destClassApp cl = match cl with - | CApp (loc, (None,CRef ref), l) -> loc, ref, List.map fst l + | CApp (loc, (None, CRef ref), l) -> loc, ref, List.map fst l | CAppExpl (loc, (None, ref), l) -> loc, ref, l | CRef ref -> loc_of_reference ref, ref, [] | _ -> raise Not_found let destClassAppExpl cl = match cl with - | CApp (loc, (None,CRef ref), l) -> loc, ref, l + | CApp (loc, (None, CRef ref), l) -> loc, ref, l | CRef ref -> loc_of_reference ref, ref, [] | _ -> raise Not_found |
