diff options
-rw-r--r-- | interp/constrextern.ml | 23 | ||||
-rw-r--r-- | interp/constrintern.ml | 71 | ||||
-rw-r--r-- | parsing/egrammar.ml | 12 | ||||
-rw-r--r-- | parsing/egrammar.mli | 4 | ||||
-rw-r--r-- | parsing/g_constrnew.ml4 | 4 | ||||
-rw-r--r-- | parsing/g_vernacnew.ml4 | 2 | ||||
-rw-r--r-- | parsing/lexer.ml4 | 96 | ||||
-rw-r--r-- | parsing/lexer.mli | 8 | ||||
-rw-r--r-- | toplevel/metasyntax.ml | 42 | ||||
-rw-r--r-- | translate/ppconstrnew.ml | 17 | ||||
-rw-r--r-- | translate/pptacticnew.ml | 6 | ||||
-rw-r--r-- | translate/pptacticnew.mli | 2 |
12 files changed, 168 insertions, 119 deletions
diff --git a/interp/constrextern.ml b/interp/constrextern.ml index 3eec91520..3fd4f121a 100644 --- a/interp/constrextern.ml +++ b/interp/constrextern.ml @@ -1131,13 +1131,18 @@ let rec match_cases_pattern metas sigma a1 a2 = match (a1,a2) with | PatCstr (loc,(ind,_ as r1),args1,Anonymous), _ -> let nparams = (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in - let params1 = list_tabulate (fun _ -> PatVar (loc,Anonymous)) nparams in - (match params1@args1, a2 with - | [], ARef (ConstructRef r2) when r1 = r2 -> sigma - | l1, AApp (ARef (ConstructRef r2),l2) - when r1 = r2 & List.length l1 = List.length l2 -> - List.fold_left2 (match_cases_pattern metas) sigma l1 l2 - | _ -> raise No_match) + let l2 = + match a2 with + | ARef (ConstructRef r2) when r1 = r2 -> [] + | AApp (ARef (ConstructRef r2),l2) when r1 = r2 -> l2 + | _ -> raise No_match in + if List.length l2 <> nparams + List.length args1 + then raise No_match + else + let (p2,args2) = list_chop nparams l2 in + (* All parameters must be _ *) + List.iter (function AHole _ -> () | _ -> raise No_match) p2; + List.fold_left2 (match_cases_pattern metas) sigma args1 args2 | _ -> raise No_match let match_aconstr_cases_pattern c (metas_scl,pat) = @@ -1205,8 +1210,8 @@ and extern_symbol_pattern (tmp_scope,scopes as allscopes) vars t = function insert_pat_delimiters (make_pat_notation loc ntn l) key) | SynDefRule kn -> CPatAtom (loc,Some (Qualid (loc, shortest_qualid_of_syndef kn))) - with - No_match -> extern_symbol_pattern allscopes vars t rules + with + No_match -> extern_symbol_pattern allscopes vars t rules (**********************************************************************) (* Externalising applications *) diff --git a/interp/constrintern.ml b/interp/constrintern.ml index 372ac0b7b..de5659c38 100644 --- a/interp/constrintern.ml +++ b/interp/constrintern.ml @@ -371,35 +371,53 @@ let subst_cases_pattern loc aliases intern subst scopes a = (* Differentiating between constructors and matching variables *) type pattern_qualid_kind = - | ConstrPat of constructor + | ConstrPat of (constructor * cases_pattern list) | VarPat of identifier +let rec patt_of_rawterm loc cstr = + match cstr with + | RRef (_,(ConstructRef c as x)) -> + if !dump then add_glob loc x; + (c,[]) + | RApp (_,RApp(_,h,l1),l2) -> patt_of_rawterm loc (RApp(loc,h,l1@l2)) + | RApp (_,RRef(_,(ConstructRef c as x)),pl) -> + if !dump then add_glob loc x; + let (_,mib) = Inductive.lookup_mind_specif (Global.env()) (fst c) in + let npar = mib.Declarations.mind_nparams in + let (params,args) = + if List.length pl <= npar then (pl,[]) else + list_chop npar pl in + (* All parameters must be _ *) + List.iter + (function RHole _ -> () + | _ -> raise Not_found) params; + let pl' = List.map + (fun c -> + let (c,pl) = patt_of_rawterm loc c in + PatCstr(loc,c,pl,Anonymous)) args in + (c,pl') + | _ -> raise Not_found + let find_constructor ref = let (loc,qid) = qualid_of_reference ref in - try match extended_locate qid with + let gref = + try extended_locate qid + with Not_found -> + raise (InternalisationError (loc,NotAConstructor ref)) in + match gref with | SyntacticDef sp -> - (match Syntax_def.search_syntactic_definition loc sp with - | RRef (_,(ConstructRef c as x)) -> - if !dump then add_glob loc x; - c - | _ -> - raise (InternalisationError (loc,NotAConstructor ref))) + let sdef = Syntax_def.search_syntactic_definition loc sp in + patt_of_rawterm loc sdef | TrueGlobal r -> let rec unf = function | ConstRef cst -> - (try - let v = Environ.constant_value (Global.env()) cst in - unf (reference_of_constr v) - with - Environ.NotEvaluableConst _ | Not_found -> - raise (InternalisationError (loc,NotAConstructor ref))) + let v = Environ.constant_value (Global.env()) cst in + unf (reference_of_constr v) | ConstructRef c -> if !dump then add_glob loc r; - c - | _ -> raise (InternalisationError (loc,NotAConstructor ref)) + c, [] + | _ -> raise Not_found in unf r - with Not_found -> - raise (InternalisationError (loc,NotAConstructor ref)) let find_pattern_variable = function | Ident (loc,id) -> id @@ -407,20 +425,27 @@ let find_pattern_variable = function let maybe_constructor ref = try ConstrPat (find_constructor ref) - with InternalisationError _ -> VarPat (find_pattern_variable ref) + with + (* patt var does not exists globally *) + | InternalisationError _ -> VarPat (find_pattern_variable ref) + (* patt var also exists globally but does not satisfy preconditions *) + | (Environ.NotEvaluableConst _ | Not_found) -> + warn (str "pattern " ++ pr_reference ref ++ + str " is understood as a pattern variable"); + VarPat (find_pattern_variable ref) let rec intern_cases_pattern scopes aliases tmp_scope = function | CPatAlias (loc, p, id) -> let aliases' = merge_aliases aliases id in intern_cases_pattern scopes aliases' tmp_scope p | CPatCstr (loc, head, pl) -> - let c = find_constructor head in + let c,pl0 = find_constructor head in let argscs = simple_adjust_scopes (find_arguments_scope (ConstructRef c), pl) in let (idsl,pl') = List.split (List.map2 (intern_cases_pattern scopes ([],[])) argscs pl) in - (aliases::(List.flatten idsl), PatCstr (loc,c,pl',alias_of aliases)) + (aliases::(List.flatten idsl), PatCstr (loc,c,pl0@pl',alias_of aliases)) | CPatNotation (loc,"- _",[CPatNumeral(_,Bignat.POS p)]) -> let scopes = option_cons tmp_scope scopes in ([aliases], @@ -443,8 +468,8 @@ let rec intern_cases_pattern scopes aliases tmp_scope = function aliases None e | CPatAtom (loc, Some head) -> (match maybe_constructor head with - | ConstrPat c -> - ([aliases], PatCstr (loc,c,[],alias_of aliases)) + | ConstrPat (c,args) -> + ([aliases], PatCstr (loc,c,args,alias_of aliases)) | VarPat id -> let aliases = merge_aliases aliases id in ([aliases], PatVar (loc,alias_of aliases))) diff --git a/parsing/egrammar.ml b/parsing/egrammar.ml index 132dc7704..5880c0263 100644 --- a/parsing/egrammar.ml +++ b/parsing/egrammar.ml @@ -21,7 +21,9 @@ open Nameops (* State of the grammar extensions *) type all_grammar_command = - | Notation of (int * Gramext.g_assoc option * notation * prod_item list) + | Notation of + (int * Gramext.g_assoc option * notation * prod_item list * + int list option) | Grammar of grammar_command | TacticGrammar of (string * (string * grammar_production list) * Tacexpr.raw_tactic_expr) @@ -301,8 +303,12 @@ let extend_constr entry (n,assoc,pos,p4assoc,name) make_act (forpat,pt) = let act = make_act ntl in grammar_extend entry pos [(name, p4assoc, [symbs, act])] -let extend_constr_notation (n,assoc,ntn,rule) = - let mkact loc env = CNotation (loc,ntn,List.map snd env) in +let extend_constr_notation (n,assoc,ntn,rule,permut) = + let mkact = + match permut with + None -> (fun loc env -> CNotation (loc,ntn,List.map snd env)) + | Some p -> (fun loc env -> + CNotation (loc,ntn,List.map (fun i -> snd (List.nth env i)) p)) in let (e,level,keepassoc) = get_constr_entry false (ETConstr (n,())) in let pos,p4assoc,name = find_position false keepassoc assoc level in extend_constr e (ETConstr(n,()),assoc,pos,p4assoc,name) diff --git a/parsing/egrammar.mli b/parsing/egrammar.mli index 362b9350a..e1f4dc6b1 100644 --- a/parsing/egrammar.mli +++ b/parsing/egrammar.mli @@ -18,7 +18,9 @@ open Rawterm (*i*) type all_grammar_command = - | Notation of (int * Gramext.g_assoc option * notation * prod_item list) + | Notation of + (int * Gramext.g_assoc option * notation * prod_item list * + int list option) | Grammar of grammar_command | TacticGrammar of (string * (string * grammar_production list) * Tacexpr.raw_tactic_expr) list diff --git a/parsing/g_constrnew.ml4 b/parsing/g_constrnew.ml4 index 5ee178112..4cf3f25ab 100644 --- a/parsing/g_constrnew.ml4 +++ b/parsing/g_constrnew.ml4 @@ -304,7 +304,9 @@ GEXTEND Gram [ r = Prim.reference -> CPatAtom (loc,Some r) | "_" -> CPatAtom (loc,None) | "("; p = pattern LEVEL "200"; ")" -> - CPatNotation(loc,"( _ )",[p]) + (match p with + CPatNumeral(_,Bignat.POS _) -> CPatNotation(loc,"( _ )",[p]) + | _ -> p) | n = INT -> CPatNumeral (loc,Bignat.POS(Bignat.of_string n)) ] ] ; binder_list: diff --git a/parsing/g_vernacnew.ml4 b/parsing/g_vernacnew.ml4 index e866d0172..cf89300bb 100644 --- a/parsing/g_vernacnew.ml4 +++ b/parsing/g_vernacnew.ml4 @@ -76,7 +76,7 @@ END let test_plurial_form = function - | [_] -> + | [(_,([_],_))] -> Options.if_verbose warning "Keywords Variables/Hypotheses/Parameters expect more than one assumption" | _ -> () diff --git a/parsing/lexer.ml4 b/parsing/lexer.ml4 index 6424cb3d9..0a0228ac0 100644 --- a/parsing/lexer.ml4 +++ b/parsing/lexer.ml4 @@ -68,71 +68,64 @@ exception Error of error let bad_token str = raise (Error (Bad_token str)) let check_special_token str = - let rec loop = parser + let rec loop_symb = parser | [< ' (' ' | '\n' | '\r' | '\t' | '"') >] -> bad_token str | [< _ = Stream.empty >] -> () - | [< '_ ; s >] -> loop s + | [< '_ ; s >] -> loop_symb s in - loop (Stream.of_string str) + loop_symb (Stream.of_string str) let check_ident str = - let rec loop = parser - | [< ' ('$' | 'a'..'z' | 'A'..'Z' | '0'..'9' | ''' | '_'); s >] -> loop s + let first_letter = function + (''' | '0'..'9') -> false + | _ -> true in + let rec loop_id = parser + | [< ' ('$' | 'a'..'z' | 'A'..'Z' | '0'..'9' | ''' | '_'); s >] -> + loop_id s (* Greek utf-8 letters [CE80-CEBF and CF80-CFBF] (CE=206; BF=191) *) - | [< ' ('\206' | '\207'); ' ('\128'..'\191'); s >] -> loop s - (* iso 8859-1 accentuated letters *) - | [< ' ('\192'..'\214' | '\216'..'\246' | '\248'..'\255'); s >] -> loop s + | [< ' ('\206' | '\207'); ' ('\128'..'\191'); s >] -> loop_id s + | [< ''\226'; 'c2; 'c3; s >] -> + (match c2, c3 with + (* utf8 letter-like unicode 2100-214F *) + | (('\132', '\128'..'\191') | ('\133', '\128'..'\143')) -> + loop_id s + (* utf8 symbols (see [parse_226_tail]) *) + | (('\134'..'\143' | '\152'..'\155' + | '\164'..'\165' | '\168'..'\171'),_) -> + bad_token str + | _ -> (* default to iso 8859-1 "â" *) + if !Options.v7 then loop_id [< 'c2; 'c3; s >] + else bad_token str) + (* iso 8859-1 accentuated letters *) + | [< ' ('\192'..'\214' | '\216'..'\246' | '\248'..'\255'); s >] -> + if !Options.v7 then loop_id s else bad_token str | [< _ = Stream.empty >] -> () | [< >] -> bad_token str in - loop (Stream.of_string str) + if String.length str > 0 && first_letter str.[0] then + loop_id (Stream.of_string str) + else + bad_token str -(* Special token dictionary *) -let token_tree = ref empty_ttree +let check_keyword str = + try check_special_token str + with Error _ -> check_ident str -let add_special_token str = - check_special_token str; - token_tree := ttree_add !token_tree str +(* Keyword and symbol dictionary *) +let token_tree = ref empty_ttree -(* Keyword identifier dictionary *) -let keywords = ref empty_ttree +let find_keyword s = ttree_find !token_tree s -let find_keyword s = ttree_find !keywords s +let is_keyword s = + try let _ = ttree_find !token_tree s in true with Not_found -> false let add_keyword str = - check_ident str; - keywords := ttree_add !keywords str - -let is_keyword s = - try let _ = ttree_find !keywords s in true with Not_found -> false - -let is_normal_token str = - if String.length str > 0 then - match str.[0] with - | ' ' | '\n' | '\r' | '\t' | '"' -> bad_token str - | '$' | 'a'..'z' | 'A'..'Z' | '_' -> true - (* utf-8 symbols of the form "E2 xx xx" [E2=226] *) - | '\226' when String.length str > 2 -> - (match str.[1], str.[2] with - | ('\132', '\128'..'\191') | ('\133', '\128'..'\143') -> - (* utf8 letter-like unicode 2100-214F *) true - | (('\134'..'\143' | '\152'..'\155' - | '\164'..'\165' | '\168'..'\171'),_) -> - (* utf8 symbols (see [parse_226_tail] *) - false - | _ -> - (* default to iso 8859-1 "â" *) - !Options.v7) - (* iso 8859-1 accentuated letters *) - | '\192'..'\214' | '\216'..'\246' | '\248'..'\255' -> !Options.v7 - | _ -> false - else - bad_token str + check_keyword str; + token_tree := ttree_add !token_tree str (* Adding a new token (keyword or special token). *) let add_token (con, str) = match con with - | "" -> - if is_normal_token str then add_keyword str else add_special_token str + | "" -> add_keyword str | "METAIDENT" | "IDENT" | "FIELD" | "INT" | "STRING" | "EOI" -> () | _ -> @@ -141,16 +134,15 @@ the constructor \"" ^ con ^ "\" is not recognized by Lexer")) (* Freeze and unfreeze the state of the lexer *) -type frozen_t = ttree * ttree +type frozen_t = ttree -let freeze () = (!keywords, !token_tree) +let freeze () = !token_tree -let unfreeze (kw,tt) = - keywords := kw; +let unfreeze tt = token_tree := tt let init () = - unfreeze (empty_ttree, empty_ttree) + unfreeze empty_ttree let _ = init() diff --git a/parsing/lexer.mli b/parsing/lexer.mli index b44e62eb9..b8004d58a 100644 --- a/parsing/lexer.mli +++ b/parsing/lexer.mli @@ -19,7 +19,7 @@ type error = exception Error of error -val add_keyword : string -> unit +val add_token : string * string -> unit val is_keyword : string -> bool val func : char Stream.t -> (string * string) Stream.t * (int -> int * int) @@ -31,11 +31,7 @@ val location_table : unit -> location_table val restore_location_table : location_table -> unit val check_ident : string -> unit -val check_special_token : string -> unit - -val is_normal_token : string -> bool - -val add_token : Token.pattern -> unit +val check_keyword : string -> unit val tparse : string * string -> ((string * string) Stream.t -> string) option diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml index f5016c7d3..538c7563a 100644 --- a/toplevel/metasyntax.ml +++ b/toplevel/metasyntax.ml @@ -357,15 +357,19 @@ let unquote_notation_token s = let n = String.length s in if n > 2 & s.[0] = '\'' & s.[n-1] = '\'' then String.sub s 1 (n-2) else s +let is_normal_token str = + try let _ = Lexer.check_ident str in true with Lexer.Error _ -> false + (* To protect alphabetic tokens and quotes from being seen as variables *) let quote_notation_token x = let n = String.length x in - if (n > 0 & Lexer.is_normal_token x) or (n > 2 & x.[0] = '\'') then "'"^x^"'" + let norm = is_normal_token x in + if (n > 0 & norm) or (n > 2 & x.[0] = '\'') then "'"^x^"'" else x let rec analyse_notation_tokens = function | [] -> [], [] - | String x :: sl when Lexer.is_normal_token x -> + | String x :: sl when is_normal_token x -> Lexer.check_ident x; let id = Names.id_of_string x in let (vars,l) = analyse_notation_tokens sl in @@ -373,7 +377,7 @@ let rec analyse_notation_tokens = function error ("Variable "^x^" occurs more than once"); (id::vars, NonTerminal id :: l) | String s :: sl -> - Lexer.check_special_token s; + Lexer.check_keyword s; let (vars,l) = analyse_notation_tokens sl in (vars, Terminal (unquote_notation_token s) :: l) | WhiteSpace n :: sl -> @@ -629,10 +633,10 @@ let recompute_assoc typs = | _, Some Gramext.RightA -> Some Gramext.RightA | _ -> None -let make_grammar_rule n typs symbols ntn = +let make_grammar_rule n typs symbols ntn perm = let assoc = recompute_assoc typs in let prod = make_production typs symbols in - (n,assoc,ntn,prod) + (n,assoc,ntn,prod, perm) (* For old ast printer *) let metas_of sl = @@ -882,7 +886,7 @@ let add_syntax_extension local mv mv8 = let prec,gram_rule = match data with | None -> None, None | Some ((_,_,notation),prec,(n,typs,symbols,_),_) -> - Some prec, Some (make_grammar_rule n typs symbols notation) in + Some prec, Some (make_grammar_rule n typs symbols notation None) in match data, data8 with | None, None -> (* Nothing to do: V8Notation while not translating *) () | _, Some d | Some d, None -> @@ -962,6 +966,17 @@ let make_old_pp_rule n symbols typs r ntn scope vars = let rule_name = ntn^"_"^scope_name^"_notation" in make_syntax_rule n rule_name symbols typs ast ntn scope +(* maps positions in v8-notation into positions in v7-notation (used + for parsing). + For instance Notation "x < y < z" := .. V8only "y < z < x" + yields [1; 2; 0] (y is the second arg in v7; z is 3rd; x is fst) *) +let mk_permut vars7 vars8 = + if vars7=vars8 then None else + Some + (List.fold_right + (fun v8 subs -> list_index v8 vars7 - 1 :: subs) + vars8 []) + let add_notation_in_scope local df c mods omodv8 scope toks = let ((onlyparse,vars,notation),prec,(n,typs,symbols,_ as ppdata),df') = compute_syntax_data !Options.v7 (df,mods) in @@ -974,32 +989,33 @@ let add_notation_in_scope local df c mods omodv8 scope toks = (* In short: parsing does not depend on omodv8 *) (* Printing depends on mv8 if defined, otherwise of mods (scaled by 10) *) (* if in v7, or of mods without scaling if in v8 *) - let ppnot,ppprec,pp_rule = + let ppnot,ppvars,ppprec,pp_rule = match omodv8 with | Some mv8 -> - let (_,_,ntn8),p,d,_ = compute_syntax_data false mv8 in - ntn8,p,make_pp_rule d + let (_,vars8,ntn8),p,d,_ = compute_syntax_data false mv8 in + ntn8,vars8,p,make_pp_rule d | _ -> (* means the rule already exists: recover it *) try let _, oldprec8 = Symbols.level_of_notation notation in let rule,_ = Symbols.find_notation_printing_rule notation in - notation,oldprec8,rule + notation,vars,oldprec8,rule with Not_found -> error "No known parsing rule for this notation in V8" in - let gram_rule = make_grammar_rule n typs symbols ppnot in + let permut = mk_permut vars ppvars in + let gram_rule = make_grammar_rule n typs symbols ppnot permut in Lib.add_anonymous_leaf (inSyntaxExtension (local,(Some prec,ppprec),ppnot,Some gram_rule,pp_rule)); (* Declare interpretation *) - let a = interp_aconstr [] vars c in + let a = interp_aconstr [] ppvars c in let old_pp_rule = (* Used only by v7 *) if onlyparse then None else let r = interp_global_rawconstr_with_vars vars c in - Some (make_old_pp_rule n symbols typs r notation scope vars) in + Some (make_old_pp_rule n symbols typs r ppnot scope vars) in let onlyparse = onlyparse or !Options.v7_only in let vars = List.map (fun id -> id,[] (* insert the right scope *)) vars in Lib.add_anonymous_leaf diff --git a/translate/ppconstrnew.ml b/translate/ppconstrnew.ml index 1da57f920..8a2ce3765 100644 --- a/translate/ppconstrnew.ml +++ b/translate/ppconstrnew.ml @@ -262,11 +262,14 @@ let split_product na' = function rename na na' t (CProdN(loc,(nal,t)::bl,c)) | _ -> anomaly "ill-formed fixpoint body" -let merge_binders (na1,ty1) (na2,ty2) = +let merge_binders (na1,ty1) (na2,ty2) codom = let na = match snd na1, snd na2 with Anonymous, Name id -> na2 - | Name id, Anonymous -> na1 + | Name id, Anonymous -> + if occur_var_constr_expr id codom then + failwith "avoid capture" + else na1 | Anonymous, Anonymous -> na1 | Name id1, Name id2 -> if id1 <> id2 then failwith "not same name" else na1 in @@ -277,18 +280,18 @@ let merge_binders (na1,ty1) (na2,ty2) = | _ -> Constrextern.check_same_type ty1 ty2; ty2 in - LocalRawAssum ([na],ty) + (LocalRawAssum ([na],ty), codom) let rec strip_domain bvar c = match c with | CArrow(loc,a,b) -> - (merge_binders bvar ((dummy_loc,Anonymous),a), b) + merge_binders bvar ((dummy_loc,Anonymous),a) b | CProdN(loc,[([na],ty)],c') -> - (merge_binders bvar (na,ty), c') + merge_binders bvar (na,ty) c' | CProdN(loc,([na],ty)::bl,c') -> - (merge_binders bvar (na,ty), CProdN(loc,bl,c')) + merge_binders bvar (na,ty) (CProdN(loc,bl,c')) | CProdN(loc,(na::nal,ty)::bl,c') -> - (merge_binders bvar (na,ty), CProdN(loc,(nal,ty)::bl,c')) + merge_binders bvar (na,ty) (CProdN(loc,(nal,ty)::bl,c')) | _ -> failwith "not a product" (* Note: binder sharing is lost *) diff --git a/translate/pptacticnew.ml b/translate/pptacticnew.ml index b4002994f..63423b7b5 100644 --- a/translate/pptacticnew.ml +++ b/translate/pptacticnew.ml @@ -145,7 +145,7 @@ let id_of_ltac_v7_id id = let pr_ltac_or_var pr = function | ArgArg x -> pr x | ArgVar (loc,id) -> - pr_with_comments loc (Nameops.pr_id (id_of_ltac_v7_id id)) + pr_with_comments loc (pr_id (id_of_ltac_v7_id id)) let pr_arg pr x = spc () ++ pr x @@ -331,9 +331,9 @@ let pr_seq_body pr tl = let duplicate force pr = function | [] -> pr (ref false,[]) - | [x] -> pr x + | x::l when List.for_all (fun y -> snd x=snd y) l -> pr x | l -> - if List.exists (fun (b,ids) -> !b) l & (force or + if List.exists (fun (b,ids) -> !b) l & (force or List.exists (fun (_,ids) -> ids <> (snd (List.hd l))) (List.tl l)) then pr_seq_body pr (List.rev l) else pr (ref false,[]) diff --git a/translate/pptacticnew.mli b/translate/pptacticnew.mli index b6861f816..88f57f61a 100644 --- a/translate/pptacticnew.mli +++ b/translate/pptacticnew.mli @@ -24,3 +24,5 @@ val pr_glob_tactic : Environ.env -> glob_tactic_expr -> std_ppcmds val pr_tactic : Environ.env -> Proof_type.tactic_expr -> std_ppcmds val id_of_ltac_v7_id : identifier -> identifier + + |