diff options
author | Pierre-Marie Pédrot <pierre-marie.pedrot@inria.fr> | 2013-12-22 02:32:49 +0100 |
---|---|---|
committer | Pierre-Marie Pédrot <pierre-marie.pedrot@inria.fr> | 2013-12-22 04:42:35 +0100 |
commit | 455d5ee36dc36cbf094ddccf43059cddceedcd1f (patch) | |
tree | 4d4e1e139e667fd18c8502f736fed2ae09f380ba | |
parent | ca67a3fb4184c81449101d9a0cec511ccde09d43 (diff) |
Notations now accept the $(...)$ tactic-in-term syntax. They are resolved at
internalization time.
-rw-r--r-- | dev/printers.mllib | 2 | ||||
-rw-r--r-- | interp/constrintern.ml | 62 | ||||
-rw-r--r-- | interp/interp.mllib | 4 | ||||
-rw-r--r-- | interp/notation_ops.ml | 24 | ||||
-rw-r--r-- | intf/notation_term.mli | 2 | ||||
-rw-r--r-- | tactics/tacinterp.ml | 3 |
6 files changed, 62 insertions, 35 deletions
diff --git a/dev/printers.mllib b/dev/printers.mllib index 2c4f84397..1d560e699 100644 --- a/dev/printers.mllib +++ b/dev/printers.mllib @@ -139,6 +139,7 @@ Pputils Stdarg Constrarg Constrexpr_ops +Genintern Notation_ops Topconstr Notation @@ -148,7 +149,6 @@ Impargs Syntax_def Implicit_quantifiers Smartlocate -Genintern Constrintern Modintern Constrextern diff --git a/interp/constrintern.ml b/interp/constrintern.ml index cc4655315..fde5a11f1 100644 --- a/interp/constrintern.ml +++ b/interp/constrintern.ml @@ -531,21 +531,7 @@ let subst_aconstr_in_glob_constr loc intern lvar subst infos c = let rec aux (terms,binderopt as subst') (renaming,env) c = let subinfos = renaming,{env with tmp_scope = None} in match c with - | NVar id -> - begin - (* subst remembers the delimiters stack in the interpretation *) - (* of the notations *) - try - let (a,(scopt,subscopes)) = Id.Map.find id terms in - intern {env with tmp_scope = scopt; - scopes = subscopes @ env.scopes} a - with Not_found -> - try - GVar (loc, Id.Map.find id renaming) - with Not_found -> - (* Happens for local notation joint with inductive/fixpoint defs *) - GVar (loc,id) - end + | NVar id -> subst_var subst' (renaming, env) id | NList (x,_,iter,terminator,lassoc) -> (try (* All elements of the list are in scopes (scopt,subscopes) *) @@ -558,11 +544,34 @@ let subst_aconstr_in_glob_constr loc intern lvar subst infos c = List.fold_right fold (if lassoc then List.rev l else l) termin with Not_found -> anomaly (Pp.str "Inconsistent substitution of recursive notation")) - | NHole (Evar_kinds.BinderType (Name id as na)) -> - let na = - try snd (coerce_to_name (fst (Id.Map.find id terms))) - with Not_found -> na in - GHole (loc,Evar_kinds.BinderType na,None) + | NHole (knd, arg) -> + let knd = match knd with + | Evar_kinds.BinderType (Name id as na) -> + let na = + try snd (coerce_to_name (fst (Id.Map.find id terms))) + with Not_found -> na + in + Evar_kinds.BinderType na + | _ -> knd + in + let arg = match arg with + | None -> None + | Some arg -> + let open Tacexpr in + let open Genarg in + let mk_env id (c, (tmp_scope, subscopes)) accu = + let nenv = {env with tmp_scope; scopes = subscopes @ env.scopes} in + let gc = intern nenv c in + let c = ConstrMayEval (Genredexpr.ConstrTerm (gc, Some c)) in + ((loc, id), c) :: accu + in + let bindings = Id.Map.fold mk_env terms [] in + let body = TacArg (loc, TacGeneric arg) in + let tac = TacLetIn (false, bindings, body) in + let arg = in_gen (glbwit Constrarg.wit_tactic) tac in + Some arg + in + GHole (loc, knd, arg) | NBinderList (x,_,iter,terminator) -> (try (* All elements of the list are in scopes (scopt,subscopes) *) @@ -586,6 +595,19 @@ let subst_aconstr_in_glob_constr loc intern lvar subst infos c = | t -> glob_constr_of_notation_constr_with_binders loc (traverse_binder subst) (aux subst') subinfos t + and subst_var (terms, binderopt) (renaming, env) id = + (* subst remembers the delimiters stack in the interpretation *) + (* of the notations *) + try + let (a,(scopt,subscopes)) = Id.Map.find id terms in + intern {env with tmp_scope = scopt; + scopes = subscopes @ env.scopes} a + with Not_found -> + try + GVar (loc, Id.Map.find id renaming) + with Not_found -> + (* Happens for local notation joint with inductive/fixpoint defs *) + GVar (loc,id) in aux (terms,None) infos c let split_by_type ids = diff --git a/interp/interp.mllib b/interp/interp.mllib index 7f14fe42b..c9a031526 100644 --- a/interp/interp.mllib +++ b/interp/interp.mllib @@ -1,3 +1,5 @@ +Stdarg +Constrarg Genintern Constrexpr_ops Notation_ops @@ -16,5 +18,3 @@ Constrextern Coqlib Discharge Declare -Stdarg -Constrarg diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml index ce9deb0db..57fc15f8e 100644 --- a/interp/notation_ops.ml +++ b/interp/notation_ops.ml @@ -104,7 +104,7 @@ let glob_constr_of_notation_constr_with_binders loc g f e = function GRec (loc,fk,idl,dll,Array.map (f e) tl,Array.map (f e') bl) | NCast (c,k) -> GCast (loc,f e c,Miscops.map_cast_type (f e) k) | NSort x -> GSort (loc,x) - | NHole x -> GHole (loc, x, None) + | NHole (x, arg) -> GHole (loc, x, arg) | NPatVar n -> GPatVar (loc,(false,n)) | NRef x -> GRef (loc,x) @@ -287,7 +287,7 @@ let notation_constr_and_vars_of_glob_constr a = NRec (fk,idl,dll,Array.map aux tl,Array.map aux bl) | GCast (_,c,k) -> NCast (aux c,Miscops.map_cast_type aux k) | GSort (_,s) -> NSort s - | GHole (_,w,_) -> NHole w + | GHole (_,w,arg) -> NHole (w, arg) | GRef (_,r) -> NRef r | GPatVar (_,(_,n)) -> NPatVar n | GEvar _ -> @@ -465,14 +465,16 @@ let rec subst_notation_constr subst bound raw = | NPatVar _ | NSort _ -> raw - | NHole (Evar_kinds.ImplicitArg (ref,i,b)) -> - let ref',t = subst_global subst ref in - if ref' == ref then raw else - NHole (Evar_kinds.InternalHole) - | NHole (Evar_kinds.BinderType _ |Evar_kinds.QuestionMark _ - |Evar_kinds.CasesType |Evar_kinds.InternalHole - |Evar_kinds.TomatchTypeParameter _ |Evar_kinds.GoalEvar - |Evar_kinds.ImpossibleCase |Evar_kinds.MatchingVar _) -> raw + | NHole (knd, solve) -> + let nknd = match knd with + | Evar_kinds.ImplicitArg (ref, i, b) -> + let nref, _ = subst_global subst ref in + if nref == ref then knd else Evar_kinds.ImplicitArg (nref, i, b) + | _ -> knd + in + let nsolve = Option.smartmap (Genintern.generic_substitute subst) solve in + if nsolve == solve && nknd = knd then raw + else NHole (nknd, nsolve) | NCast (r1,k) -> let r1' = subst_notation_constr subst bound r1 in @@ -500,7 +502,7 @@ let abstract_return_type_context_glob_constr = let abstract_return_type_context_notation_constr = abstract_return_type_context snd - (fun na c -> NLambda(na,NHole Evar_kinds.InternalHole,c)) + (fun na c -> NLambda(na,NHole (Evar_kinds.InternalHole, None),c)) exception No_match diff --git a/intf/notation_term.mli b/intf/notation_term.mli index ac5e0f5f9..daf605ab2 100644 --- a/intf/notation_term.mli +++ b/intf/notation_term.mli @@ -24,7 +24,7 @@ type notation_constr = | NRef of global_reference | NVar of Id.t | NApp of notation_constr * notation_constr list - | NHole of Evar_kinds.t + | NHole of Evar_kinds.t * Genarg.glob_generic_argument option | NList of Id.t * Id.t * notation_constr * notation_constr * bool (** Part only in [glob_constr] *) | NLambda of Name.t * notation_constr * notation_constr diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml index b697d3635..712191a73 100644 --- a/tactics/tacinterp.ml +++ b/tactics/tacinterp.ml @@ -1185,6 +1185,9 @@ and tactic_of_value ist vle = let tac = eval_tactic ist t in catch_error_tac trace tac | (VFun _|VRec _) -> Proofview.tclZERO (UserError ("" , str "A fully applied tactic is expected.")) + else if has_type vle (topwit wit_tactic) then + let tac = out_gen (topwit wit_tactic) vle in + eval_tactic ist tac else Proofview.tclZERO (UserError ("" , str"Expression does not evaluate to a tactic.")) and eval_value ist tac = |