[ defs = LIST1 [
name = IDENT;
args = LIST1 [arg = arg -> arg];
- index_name = OPT [ IDENT "on"; idx = IDENT -> idx ];
+ index_name = OPT [ "on"; idx = IDENT -> idx ];
ty = OPT [ SYMBOL ":" ; t = term -> t ];
SYMBOL <:unicode<def>> (* ≝ *);
t1 = term ->
ident_list0: [
[ PAREN "["; idents = LIST0 IDENT SEP SYMBOL ";"; PAREN "]" -> idents ]
];
+ tactic_term_list1: [
+ [ tactic_terms = LIST1 tactic_term SEP SYMBOL "," -> tactic_terms ]
+ ];
reduction_kind: [
[ [ IDENT "reduce" ] -> `Reduce
| [ IDENT "simplify" ] -> `Simpl
| [ IDENT "whd" ] -> `Whd
| [ IDENT "normalize" ] -> `Normalize ]
];
+ sequent_pattern_spec : [
+ [ hyp_paths =
+ LIST0
+ [ id = IDENT ;
+ path = OPT [SYMBOL ":" ; path = term -> path ] ->
+ (id,match path with Some p -> p | None -> CicAst.UserInput) ]
+ SEP SYMBOL ";";
+ goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = term -> term ] ->
+ let goal_path =
+ match goal_path with
+ None -> CicAst.UserInput
+ | Some goal_path -> goal_path
+ in
+ hyp_paths,goal_path
+ ]
+ ];
pattern_spec: [
- [ wanted = OPT term;
- hyp_paths_and_goal_path =
- OPT [
- "in";
- hyp_paths =
- LIST0
- [ id = IDENT ;
- path = OPT [SYMBOL ":" ; path = term -> path ] ->
- (id,match path with Some p -> p | None -> CicAst.UserInput) ]
- SEP SYMBOL ";";
- goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = term -> term ] ->
- let goal_path =
- match goal_path with
- None -> CicAst.UserInput
- | Some goal_path -> goal_path
- in
- hyp_paths,goal_path
- ] ->
- let hyp_paths,goal_path =
- match hyp_paths_and_goal_path with
- None -> [], CicAst.UserInput
- | Some (hyp_paths,goal_path) -> hyp_paths,goal_path
+ [ res = OPT [
+ "in";
+ wanted_and_sps =
+ [ "match" ; wanted = term ;
+ sps = OPT [ "in"; sps = sequent_pattern_spec -> sps ] ->
+ Some wanted,sps
+ | sps = sequent_pattern_spec ->
+ None,Some sps
+ ] ->
+ let wanted,hyp_paths,goal_path =
+ match wanted_and_sps with
+ wanted,None -> wanted, [], CicAst.UserInput
+ | wanted,Some (hyp_paths,goal_path) -> wanted,hyp_paths,goal_path
in
- wanted, hyp_paths, goal_path ]
+ wanted, hyp_paths, goal_path ] ->
+ match res with
+ None -> None,[],CicAst.UserInput
+ | Some ps -> ps]
];
direction: [
[ SYMBOL ">" -> `LeftToRight
TacticAst.Assumption loc
| IDENT "auto";
depth = OPT [ IDENT "depth"; SYMBOL "="; i = NUM -> int_of_string i ];
- width = OPT [ IDENT "depth"; SYMBOL "="; i = NUM -> int_of_string i ] ->
+ width = OPT [ IDENT "width"; SYMBOL "="; i = NUM -> int_of_string i ] ->
TacticAst.Auto (loc,depth,width)
| IDENT "clear"; id = IDENT ->
TacticAst.Clear (loc,id)
TacticAst.Cut (loc, ident, t)
| IDENT "decide"; IDENT "equality" ->
TacticAst.DecideEquality loc
- | IDENT "decompose"; where = term ->
+ | IDENT "decompose"; where = tactic_term ->
TacticAst.Decompose (loc, where)
| IDENT "discriminate"; t = tactic_term ->
TacticAst.Discriminate (loc, t)
- | IDENT "elim"; t1 = tactic_term;
- using = OPT [ "using"; using = tactic_term -> using ] ->
- TacticAst.Elim (loc, t1, using)
- | IDENT "elimType"; t = tactic_term ->
- TacticAst.ElimType (loc, t)
+ | IDENT "elim"; what = tactic_term;
+ using = OPT [ "using"; using = tactic_term -> using ];
+ OPT "names"; num = OPT [num = int -> num]; idents = OPT ident_list0 ->
+ let idents = match idents with None -> [] | Some idents -> idents in
+ TacticAst.Elim (loc, what, using, num, idents)
+ | IDENT "elimType"; what = tactic_term;
+ using = OPT [ "using"; using = tactic_term -> using ];
+ OPT "names"; num = OPT [num = int -> num]; idents = OPT ident_list0 ->
+ let idents = match idents with None -> [] | Some idents -> idents in
+ TacticAst.ElimType (loc, what, using, num, idents)
| IDENT "exact"; t = tactic_term ->
TacticAst.Exact (loc, t)
| IDENT "exists" ->
TacticAst.Exists loc
| IDENT "fail" -> TacticAst.Fail loc
- | IDENT "fold"; kind = reduction_kind; p = pattern_spec ->
- TacticAst.Fold (loc, kind, p)
+ | IDENT "fold"; kind = reduction_kind; t = tactic_term; p = pattern_spec ->
+ let (pt,_,_) = p in
+ if pt <> None then
+ raise
+ (Parse_error
+ (loc,"the pattern cannot specify the term to replace, only its paths in the hypotheses and in the conclusion"))
+ else
+ TacticAst.Fold (loc, kind, t, p)
| IDENT "fourier" ->
TacticAst.Fourier loc
- | IDENT "fwd"; t = term ->
- TacticAst.FwdSimpl (loc, t)
+ | IDENT "fwd"; hyp = IDENT; idents = OPT ident_list0 ->
+ let idents = match idents with None -> [] | Some idents -> idents in
+ TacticAst.FwdSimpl (loc, hyp, idents)
| IDENT "generalize"; p=pattern_spec; id = OPT ["as" ; id = IDENT -> id] ->
TacticAst.Generalize (loc,p,id)
| IDENT "goal"; n = NUM ->
TacticAst.Goal (loc, int_of_string n)
| IDENT "id" -> TacticAst.IdTac loc
- | IDENT "injection"; t = term ->
+ | IDENT "injection"; t = tactic_term ->
TacticAst.Injection (loc, t)
- | IDENT "intros"; num = OPT [num = int -> num]; idents = OPT ident_list0 ->
- let idents = match idents with None -> [] | Some idents -> idents in
- TacticAst.Intros (loc, num, idents)
| IDENT "intro"; ident = OPT IDENT ->
let idents = match ident with None -> [] | Some id -> [id] in
TacticAst.Intros (loc, Some 1, idents)
- | IDENT "lapply"; what = tactic_term;
- to_what = OPT [ "to" ; t = tactic_term -> t ];
- ident = OPT [ "using" ; id = IDENT -> id ] ->
- TacticAst.LApply (loc, to_what, what, ident)
+ | IDENT "intros"; num = OPT [num = int -> num]; idents = OPT ident_list0 ->
+ let idents = match idents with None -> [] | Some idents -> idents in
+ TacticAst.Intros (loc, num, idents)
+ | IDENT "lapply";
+ depth = OPT [ IDENT "depth"; SYMBOL "="; i = NUM -> int_of_string i ];
+ what = tactic_term;
+ to_what = OPT [ "to" ; t = tactic_term_list1 -> t ];
+ ident = OPT [ "using" ; ident = IDENT -> ident ] ->
+ let to_what = match to_what with None -> [] | Some to_what -> to_what in
+ TacticAst.LApply (loc, depth, to_what, what, ident)
| IDENT "left" -> TacticAst.Left loc
| IDENT "letin"; where = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term ->
TacticAst.LetIn (loc, t, where)
TacticAst.Reflexivity loc
| IDENT "replace"; p = pattern_spec; "with"; t = tactic_term ->
TacticAst.Replace (loc, p, t)
- | IDENT "rewrite" ; d = direction; t = term ; p = pattern_spec ->
+ | IDENT "rewrite" ; d = direction; t = tactic_term ; p = pattern_spec ->
let (pt,_,_) = p in
if pt <> None then
raise
tactical:
[ "sequence" LEFTA
[ tacticals = LIST1 NEXT SEP SYMBOL ";" ->
- TacticAst.Seq (loc, tacticals)
+ match tacticals with
+ [] -> assert false
+ | [tac] -> tac
+ | l -> TacticAst.Seq (loc, l)
]
| "then" NONA
- [ tac = tactical;
- PAREN "["; tacs = LIST0 tactical SEP SYMBOL ";"; PAREN "]" ->
+ [ tac = tactical; SYMBOL ";";
+ PAREN "["; tacs = LIST0 tactical SEP SYMBOL "|"; PAREN "]" ->
(TacticAst.Then (loc, tac, tacs))
]
| "loops" RIGHTA
- [ [ IDENT "do" ]; count = int; tac = tactical ->
+ [ IDENT "do"; count = int; tac = tactical ->
TacticAst.Do (loc, count, tac)
- | [ IDENT "repeat" ]; tac = tactical ->
+ | IDENT "repeat"; tac = tactical ->
TacticAst.Repeat (loc, tac)
]
| "simple" NONA
- [ IDENT "tries";
- PAREN "["; tacs = LIST0 tactical SEP SYMBOL ";"; PAREN "]" ->
- TacticAst.Tries (loc, tacs)
+ [ IDENT "first";
+ PAREN "["; tacs = LIST0 tactical SEP SYMBOL "|"; PAREN "]" ->
+ TacticAst.First (loc, tacs)
| IDENT "try"; tac = NEXT ->
TacticAst.Try (loc, tac)
+ | IDENT "solve";
+ PAREN "["; tacs = LIST0 tactical SEP SYMBOL "|"; PAREN "]" ->
+ TacticAst.Solve (loc, tacs)
| PAREN "("; tac = tactical; PAREN ")" -> tac
| tac = tactic -> TacticAst.Tactic (loc, tac)
]
let ident = "\\("^alpha^ident_cont^"*\\|_"^ident_cont^"+\\)" in
let rex = Str.regexp ("^"^ident^"$") in
if Str.string_match rex id 0 then
- let rex = Str.regexp
- ("^\\(cic:/\\|theory:/\\)"^ident^
- "\\(/"^ident^"+\\)*\\(\\."^ident^"\\)+"^
- "\\(#xpointer("^ num^"\\(/"^num^"\\)+)\\)?$")
- in
- if Str.string_match rex uri 0 then
+ if (try ignore (UriManager.uri_of_string uri); true
+ with UriManager.IllFormedUri _ -> false)
+ then
TacticAst.Ident_alias (id, uri)
else
raise (Parse_error (loc,sprintf "Not a valid uri: %s" uri))
ind_types
in
TacticAst.Obj (loc,TacticAst.Inductive (params, ind_types))
- | [ IDENT "coercion" ] ; name = IDENT ->
+ | IDENT "coercion" ; name = IDENT ->
TacticAst.Coercion (loc, CicAst.Ident (name,Some []))
- | [ IDENT "coercion" ] ; name = URI ->
+ | IDENT "coercion" ; name = URI ->
TacticAst.Coercion (loc, CicAst.Uri (name,Some []))
- | [ IDENT "alias" ]; spec = alias_spec ->
+ | IDENT "alias" ; spec = alias_spec ->
TacticAst.Alias (loc, spec)
- | [ IDENT "record" ]; (params,name,ty,fields) = record_spec ->
+ | IDENT "record" ; (params,name,ty,fields) = record_spec ->
TacticAst.Obj (loc,TacticAst.Record (params,name,ty,fields))
+ | IDENT "include" ; path = QSTRING ->
+ TacticAst.Include (loc,path)
+ | IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
+ let uris = List.map UriManager.uri_of_string uris in
+ TacticAst.Default (loc,what,uris)
]];
executable: [
s :: acc)
env []
in
- String.concat "\n" (List.sort compare aliases)
+ String.concat "\n" (List.sort compare aliases) ^
+ (if aliases = [] then "" else "\n")
EXTEND
GLOBAL: aliases;