1 (* Copyright (C) 2005, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://helm.cs.unibo.it/
31 module LE = LexiconEngine
33 exception NoInclusionPerformed of string (* full path *)
35 type 'a localized_option =
39 type ast_statement = G.statement
41 type 'status statement =
42 ?never_include:bool ->
43 (* do not call LexiconEngine to do includes, always raise NoInclusionPerformed *)
44 include_paths:string list -> (#LE.status as 'status) ->
45 'status * ast_statement localized_option
47 type 'status parser_status = {
49 term : N.term Grammar.Entry.e;
50 statement : #LE.status as 'status statement Grammar.Entry.e;
53 let grafite_callback = ref (fun _ -> ())
54 let set_grafite_callback cb = grafite_callback := cb
56 let lexicon_callback = ref (fun _ -> ())
57 let set_lexicon_callback cb = lexicon_callback := cb
59 let initial_parser () =
60 let grammar = CicNotationParser.level2_ast_grammar () in
61 let term = CicNotationParser.term () in
62 let statement = Grammar.Entry.create grammar "statement" in
63 { grammar = grammar; term = term; statement = statement }
66 let grafite_parser = ref (initial_parser ())
68 let add_raw_attribute ~text t = N.AttributedTerm (`Raw text, t)
70 let default_associativity = Gramext.NonA
72 let mk_rec_corec ind_kind defs loc =
73 (* In case of mutual definitions here we produce just
74 the syntax tree for the first one. The others will be
75 generated from the completely specified term just before
76 insertion in the environment. We use the flavour
77 `MutualDefinition to rememer this. *)
80 | (params,(N.Ident (name, None), ty),_,_) :: _ ->
81 let ty = match ty with Some ty -> ty | None -> N.Implicit `JustOne in
84 (fun var ty -> N.Binder (`Pi,var,ty)
90 let body = N.Ident (name,None) in
92 if List.length defs = 1 then
97 (loc, N.Theorem(flavour, name, ty, Some (N.LetRec (ind_kind, defs, body)), `Regular))
99 let nmk_rec_corec ind_kind defs loc =
100 let loc,t = mk_rec_corec ind_kind defs loc in
104 let npunct_of_punct = function
105 | G.Branch loc -> G.NBranch loc
106 | G.Shift loc -> G.NShift loc
107 | G.Pos (loc, i) -> G.NPos (loc, i)
108 | G.Wildcard loc -> G.NWildcard loc
109 | G.Merge loc -> G.NMerge loc
110 | G.Semicolon loc -> G.NSemicolon loc
111 | G.Dot loc -> G.NDot loc
114 let nnon_punct_of_punct = function
115 | G.Skip loc -> G.NSkip loc
116 | G.Unfocus loc -> G.NUnfocus loc
117 | G.Focus (loc,l) -> G.NFocus (loc,l)
122 | G.NTactic(loc,[t]) -> G.NTactic(loc,[t;p])
126 type by_continuation =
128 | BYC_weproved of N.term * string option * N.term option
129 | BYC_letsuchthat of string * N.term * string * N.term
130 | BYC_wehaveand of string * N.term * string * N.term
132 let initialize_parser () =
133 (* {{{ parser initialization *)
134 let term = !grafite_parser.term in
135 let statement = !grafite_parser.statement in
136 let let_defs = CicNotationParser.let_defs () in
137 let protected_binder_vars = CicNotationParser.protected_binder_vars () in
139 GLOBAL: term statement;
140 constructor: [ [ name = IDENT; SYMBOL ":"; typ = term -> (name, typ) ] ];
141 tactic_term: [ [ t = term LEVEL "90" -> t ] ];
144 | id = IDENT -> Some id ]
146 ident_list0: [ [ LPAREN; idents = LIST0 new_name; RPAREN -> idents ] ];
147 ident_list1: [ [ LPAREN; idents = LIST1 IDENT; RPAREN -> idents ] ];
149 [ tactic_terms = LIST1 tactic_term SEP SYMBOL "," -> tactic_terms ]
152 [ IDENT "normalize" -> `Normalize
153 | IDENT "simplify" -> `Simpl
154 | IDENT "unfold"; t = OPT tactic_term -> `Unfold t
155 | IDENT "whd" -> `Whd ]
158 [ IDENT "nnormalize" ; delta = OPT [ IDENT "nodelta" -> () ] ->
159 let delta = match delta with None -> true | _ -> false in
161 (*| IDENT "unfold"; t = OPT tactic_term -> `Unfold t*)
162 | IDENT "nwhd" ; delta = OPT [ IDENT "nodelta" -> () ] ->
163 let delta = match delta with None -> true | _ -> false in
166 sequent_pattern_spec: [
170 path = OPT [SYMBOL ":" ; path = tactic_term -> path ] ->
171 (id,match path with Some p -> p | None -> N.UserInput) ];
172 goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = tactic_term -> term ] ->
174 match goal_path, hyp_paths with
175 None, [] -> Some N.UserInput
177 | Some goal_path, _ -> Some goal_path
186 [ "match" ; wanted = tactic_term ;
187 sps = OPT [ "in"; sps = sequent_pattern_spec -> sps ] ->
189 | sps = sequent_pattern_spec ->
192 let wanted,hyp_paths,goal_path =
193 match wanted_and_sps with
194 wanted,None -> wanted, [], Some N.UserInput
195 | wanted,Some (hyp_paths,goal_path) -> wanted,hyp_paths,goal_path
197 wanted, hyp_paths, goal_path ] ->
199 None -> None,[],Some N.UserInput
202 inverter_param_list: [
203 [ params = tactic_term ->
204 let deannotate = function
205 | N.AttributedTerm (_,t) | t -> t
206 in match deannotate params with
207 | N.Implicit _ -> [false]
208 | N.UserInput -> [true]
210 List.map (fun x -> match deannotate x with
211 | N.Implicit _ -> false
212 | N.UserInput -> true
213 | _ -> raise (Invalid_argument "malformed target parameter list 1")) l
214 | _ -> raise (Invalid_argument ("malformed target parameter list 2\n" ^ NotationPp.pp_term params)) ]
217 [ SYMBOL ">" -> `LeftToRight
218 | SYMBOL "<" -> `RightToLeft ]
220 int: [ [ num = NUMBER -> int_of_string num ] ];
222 [ idents = OPT ident_list0 ->
223 match idents with None -> [] | Some idents -> idents
227 [ OPT [ IDENT "names" ];
228 num = OPT [ num = int -> num ];
229 idents = intros_names ->
233 using: [ [ using = OPT [ IDENT "using"; t = tactic_term -> t ] -> using ] ];
235 [ IDENT "napply"; t = tactic_term -> G.NTactic(loc,[G.NApply (loc, t)])
236 | IDENT "napplyS"; t = tactic_term -> G.NTactic(loc,[G.NSmartApply(loc, t)])
240 [ id = IDENT ; SYMBOL ":" ; ty = tactic_term -> id,`Decl ty
241 | id = IDENT ; SYMBOL ":" ; ty = tactic_term ;
242 SYMBOL <:unicode<def>> ; bo = tactic_term ->
244 SYMBOL <:unicode<vdash>>;
245 concl = tactic_term -> (List.rev hyps,concl) ] ->
246 G.NTactic(loc,[G.NAssert (loc, seqs)])
247 | IDENT "nauto"; params = auto_params ->
248 G.NTactic(loc,[G.NAuto (loc, params)])
249 | SYMBOL "/"; num = OPT NUMBER ;
250 params = nauto_params; SYMBOL "/" ;
251 just = OPT [ IDENT "by"; by =
252 [ univ = tactic_term_list1 -> `Univ univ
253 | SYMBOL "{"; SYMBOL "}" -> `EmptyUniv
254 | SYMBOL "_" -> `Trace ] -> by ] ->
255 let depth = match num with Some n -> n | None -> "1" in
259 [G.NAuto(loc,(None,["slir","";"depth",depth]@params))])
260 | Some (`Univ univ) ->
262 [G.NAuto(loc,(Some univ,["slir","";"depth",depth]@params))])
265 [G.NAuto(loc,(Some [],["slir","";"depth",depth]@params))])
268 G.NAutoInteractive (loc, (None,["slir","";"depth",depth]@params))))
269 | IDENT "nintros" -> G.NMacro (loc, G.NIntroGuess loc)
270 | IDENT "ncheck"; t = term -> G.NMacro(loc,G.NCheck (loc,t))
271 | IDENT "screenshot"; fname = QSTRING ->
272 G.NMacro(loc,G.Screenshot (loc, fname))
273 | IDENT "ncases"; what = tactic_term ; where = pattern_spec ->
274 G.NTactic(loc,[G.NCases (loc, what, where)])
275 | IDENT "nchange"; what = pattern_spec; "with"; with_what = tactic_term ->
276 G.NTactic(loc,[G.NChange (loc, what, with_what)])
277 | SYMBOL "@"; num = OPT NUMBER; l = LIST0 tactic_term ->
278 G.NTactic(loc,[G.NConstructor (loc, (match num with None -> None | Some x -> Some (int_of_string x)),l)])
279 | IDENT "ncut"; t = tactic_term -> G.NTactic(loc,[G.NCut (loc, t)])
280 (* | IDENT "ndiscriminate"; t = tactic_term -> G.NDiscriminate (loc, t)
281 | IDENT "nsubst"; t = tactic_term -> G.NSubst (loc, t) *)
282 | IDENT "ndestruct"; just = OPT [ dom = ident_list1 -> dom ];
283 exclude = OPT [ IDENT "skip"; skip = ident_list1 -> skip ]
284 -> let exclude' = match exclude with None -> [] | Some l -> l in
285 G.NTactic(loc,[G.NDestruct (loc,just,exclude')])
286 | IDENT "nelim"; what = tactic_term ; where = pattern_spec ->
287 G.NTactic(loc,[G.NElim (loc, what, where)])
288 | IDENT "ngeneralize"; p=pattern_spec ->
289 G.NTactic(loc,[G.NGeneralize (loc, p)])
290 | IDENT "ninversion"; what = tactic_term ; where = pattern_spec ->
291 G.NTactic(loc,[G.NInversion (loc, what, where)])
292 | IDENT "nlapply"; t = tactic_term -> G.NTactic(loc,[G.NLApply (loc, t)])
293 | IDENT "nletin"; name = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term;
294 where = pattern_spec ->
295 G.NTactic(loc,[G.NLetIn (loc,where,t,name)])
296 | kind = nreduction_kind; p = pattern_spec ->
297 G.NTactic(loc,[G.NReduce (loc, kind, p)])
298 | IDENT "nrewrite"; dir = direction; what = tactic_term ; where = pattern_spec ->
299 G.NTactic(loc,[G.NRewrite (loc, dir, what, where)])
300 | IDENT "ntry"; tac = SELF ->
301 let tac = match tac with G.NTactic(_,[t]) -> t | _ -> assert false in
302 G.NTactic(loc,[ G.NTry (loc,tac)])
303 | IDENT "nrepeat"; tac = SELF ->
304 let tac = match tac with G.NTactic(_,[t]) -> t | _ -> assert false in
305 G.NTactic(loc,[ G.NRepeat (loc,tac)])
306 | LPAREN; l = LIST1 SELF; RPAREN ->
309 (List.map (function G.NTactic(_,t) -> t | _ -> assert false) l) in
310 G.NTactic(loc,[G.NBlock (loc,l)])
311 | IDENT "nassumption" -> G.NTactic(loc,[ G.NAssumption loc])
312 | SYMBOL "#"; ns=LIST0 IDENT -> G.NTactic(loc,[ G.NIntros (loc,ns)])
313 | SYMBOL "#"; SYMBOL "_" -> G.NTactic(loc,[ G.NIntro (loc,"_")])
314 | SYMBOL "*" -> G.NTactic(loc,[ G.NCase1 (loc,"_")])
315 | SYMBOL "*"; n=IDENT -> G.NTactic(loc,[ G.NCase1 (loc,n)])
320 [ IDENT "absurd"; t = tactic_term ->
322 | IDENT "apply"; IDENT "rule"; t = tactic_term ->
324 | IDENT "apply"; t = tactic_term ->
326 | IDENT "applyP"; t = tactic_term ->
328 | IDENT "applyS"; t = tactic_term ; params = auto_params ->
329 G.ApplyS (loc, t, params)
330 | IDENT "assumption" ->
332 | IDENT "autobatch"; params = auto_params ->
333 G.AutoBatch (loc,params)
334 | IDENT "cases"; what = tactic_term;
335 pattern = OPT pattern_spec;
336 specs = intros_spec ->
337 let pattern = match pattern with
338 | None -> None, [], Some N.UserInput
339 | Some pattern -> pattern
341 G.Cases (loc, what, pattern, specs)
342 | IDENT "clear"; ids = LIST1 IDENT ->
344 | IDENT "clearbody"; id = IDENT ->
346 | IDENT "change"; what = pattern_spec; "with"; t = tactic_term ->
347 G.Change (loc, what, t)
348 | IDENT "compose"; times = OPT int; t1 = tactic_term; t2 =
349 OPT [ "with"; t = tactic_term -> t ]; specs = intros_spec ->
350 let times = match times with None -> 1 | Some i -> i in
351 G.Compose (loc, t1, t2, times, specs)
352 | IDENT "constructor"; n = int ->
353 G.Constructor (loc, n)
354 | IDENT "contradiction" ->
356 | IDENT "cut"; t = tactic_term; ident = OPT [ "as"; id = IDENT -> id] ->
357 G.Cut (loc, ident, t)
358 | IDENT "decompose"; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
359 let idents = match idents with None -> [] | Some idents -> idents in
360 G.Decompose (loc, idents)
361 | IDENT "demodulate"; p = auto_params -> G.Demodulate (loc, p)
362 | IDENT "destruct"; xts = OPT [ ts = tactic_term_list1 -> ts ] ->
363 G.Destruct (loc, xts)
364 | IDENT "elim"; what = tactic_term; using = using;
365 pattern = OPT pattern_spec;
366 ispecs = intros_spec ->
367 let pattern = match pattern with
368 | None -> None, [], Some N.UserInput
369 | Some pattern -> pattern
371 G.Elim (loc, what, using, pattern, ispecs)
372 | IDENT "elimType"; what = tactic_term; using = using;
373 (num, idents) = intros_spec ->
374 G.ElimType (loc, what, using, (num, idents))
375 | IDENT "exact"; t = tactic_term ->
379 | IDENT "fail" -> G.Fail loc
380 | IDENT "fold"; kind = reduction_kind; t = tactic_term; p = pattern_spec ->
383 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error
384 ("the pattern cannot specify the term to replace, only its"
385 ^ " paths in the hypotheses and in the conclusion")))
387 G.Fold (loc, kind, t, p)
390 | IDENT "fwd"; hyp = IDENT; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
391 let idents = match idents with None -> [] | Some idents -> idents in
392 G.FwdSimpl (loc, hyp, idents)
393 | IDENT "generalize"; p=pattern_spec; id = OPT ["as" ; id = IDENT -> id] ->
394 G.Generalize (loc,p,id)
395 | IDENT "id" -> G.IdTac loc
396 | IDENT "intro"; ident = OPT IDENT ->
397 let idents = match ident with None -> [] | Some id -> [Some id] in
398 G.Intros (loc, (Some 1, idents))
399 | IDENT "intros"; specs = intros_spec ->
400 G.Intros (loc, specs)
401 | IDENT "inversion"; t = tactic_term ->
404 linear = OPT [ IDENT "linear" ];
405 depth = OPT [ IDENT "depth"; SYMBOL "="; i = int -> i ];
407 to_what = OPT [ "to" ; t = tactic_term_list1 -> t ];
408 ident = OPT [ "as" ; ident = IDENT -> ident ] ->
409 let linear = match linear with None -> false | Some _ -> true in
410 let to_what = match to_what with None -> [] | Some to_what -> to_what in
411 G.LApply (loc, linear, depth, to_what, what, ident)
412 | IDENT "left" -> G.Left loc
413 | IDENT "letin"; where = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term ->
414 G.LetIn (loc, t, where)
415 | kind = reduction_kind; p = pattern_spec ->
416 G.Reduce (loc, kind, p)
417 | IDENT "reflexivity" ->
419 | IDENT "replace"; p = pattern_spec; "with"; t = tactic_term ->
420 G.Replace (loc, p, t)
421 | IDENT "rewrite" ; d = direction; t = tactic_term ; p = pattern_spec;
422 xnames = OPT [ "as"; n = ident_list0 -> n ] ->
426 (HExtlib.Localized (loc,
427 (CicNotationParser.Parse_error
428 "the pattern cannot specify the term to rewrite, only its paths in the hypotheses and in the conclusion")))
430 let n = match xnames with None -> [] | Some names -> names in
431 G.Rewrite (loc, d, t, p, n)
438 | IDENT "symmetry" ->
440 | IDENT "transitivity"; t = tactic_term ->
441 G.Transitivity (loc, t)
442 (* Produzioni Aggiunte *)
443 | IDENT "assume" ; id = IDENT ; SYMBOL ":" ; t = tactic_term ->
444 G.Assume (loc, id, t)
445 | IDENT "suppose" ; t = tactic_term ; LPAREN ; id = IDENT ; RPAREN ;
446 t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ;
447 t' = tactic_term -> t']->
448 G.Suppose (loc, t, id, t1)
449 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
450 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
451 id2 = IDENT ; RPAREN ->
452 G.ExistsElim (loc, `Auto (None,[]), id1, t1, id2, t2)
454 [ IDENT "using"; t=tactic_term -> `Term t
455 | params = auto_params -> `Auto params] ;
456 cont=by_continuation ->
458 BYC_done -> G.Bydone (loc, just)
459 | BYC_weproved (ty,id,t1) ->
460 G.By_just_we_proved(loc, just, ty, id, t1)
461 | BYC_letsuchthat (id1,t1,id2,t2) ->
462 G.ExistsElim (loc, just, id1, t1, id2, t2)
463 | BYC_wehaveand (id1,t1,id2,t2) ->
464 G.AndElim (loc, just, id1, t1, id2, t2))
465 | IDENT "we" ; IDENT "need" ; "to" ; IDENT "prove" ; t = tactic_term ; id = OPT [ LPAREN ; id = IDENT ; RPAREN -> id ] ; t1 = OPT [IDENT "or" ; IDENT "equivalently"; t' = tactic_term -> t']->
466 G.We_need_to_prove (loc, t, id, t1)
467 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "cases" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
468 G.We_proceed_by_cases_on (loc, t, t1)
469 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "induction" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
470 G.We_proceed_by_induction_on (loc, t, t1)
471 | IDENT "by" ; IDENT "induction" ; IDENT "hypothesis" ; IDENT "we" ; IDENT "know" ; t=tactic_term ; LPAREN ; id = IDENT ; RPAREN ->
472 G.Byinduction(loc, t, id)
473 | IDENT "the" ; IDENT "thesis" ; IDENT "becomes" ; t=tactic_term ->
474 G.Thesisbecomes(loc, t)
475 | IDENT "case" ; id = IDENT ; params=LIST0[LPAREN ; i=IDENT ;
476 SYMBOL":" ; t=tactic_term ; RPAREN -> i,t] ->
477 G.Case(loc,id,params)
478 (* DO NOT FACTORIZE with the two following, camlp5 sucks*)
480 termine = tactic_term;
484 [ IDENT "using"; t=tactic_term -> `Term t
485 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
486 | IDENT "proof" -> `Proof
487 | params = auto_params -> `Auto params];
488 cont = rewriting_step_continuation ->
489 G.RewritingStep(loc, Some (None,termine), t1, t2, cont)
490 | IDENT "obtain" ; name = IDENT;
491 termine = tactic_term;
495 [ IDENT "using"; t=tactic_term -> `Term t
496 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
497 | IDENT "proof" -> `Proof
498 | params = auto_params -> `Auto params];
499 cont = rewriting_step_continuation ->
500 G.RewritingStep(loc, Some (Some name,termine), t1, t2, cont)
504 [ IDENT "using"; t=tactic_term -> `Term t
505 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
506 | IDENT "proof" -> `Proof
507 | params = auto_params -> `Auto params];
508 cont = rewriting_step_continuation ->
509 G.RewritingStep(loc, None, t1, t2, cont)
514 | IDENT "fast_paramod"
528 i = auto_fixed_param -> i,""
529 | i = auto_fixed_param ; SYMBOL "="; v = [ v = int ->
530 string_of_int v | v = IDENT -> v ] -> i,v ];
531 tl = OPT [ IDENT "by"; tl = tactic_term_list1 -> tl] -> tl,
532 (* (match tl with Some l -> l | None -> []), *)
539 i = auto_fixed_param -> i,""
540 | i = auto_fixed_param ; SYMBOL "="; v = [ v = int ->
541 string_of_int v | v = IDENT -> v ] -> i,v ] ->
549 [ IDENT "prefix"; SYMBOL "="; prefix = QSTRING -> G.IPPrefix prefix
550 | flavour = inline_flavour -> G.IPAs flavour
551 | IDENT "coercions" -> G.IPCoercions
552 | IDENT "debug"; SYMBOL "="; debug = int -> G.IPDebug debug
553 | IDENT "procedural" -> G.IPProcedural
554 | IDENT "nodefaults" -> G.IPNoDefaults
555 | IDENT "depth"; SYMBOL "="; depth = int -> G.IPDepth depth
556 | IDENT "level"; SYMBOL "="; level = int -> G.IPLevel level
557 | IDENT "comments" -> G.IPComments
558 | IDENT "cr" -> G.IPCR
563 [ WEPROVED; ty = tactic_term ; LPAREN ; id = IDENT ; RPAREN ; t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ; t2 = tactic_term -> t2] -> BYC_weproved (ty,Some id,t1)
564 | WEPROVED; ty = tactic_term ; t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ; t2 = tactic_term -> t2] ;
565 "done" -> BYC_weproved (ty,None,t1)
567 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
568 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
569 id2 = IDENT ; RPAREN -> BYC_letsuchthat (id1,t1,id2,t2)
570 | WEHAVE; t1=tactic_term ; LPAREN ; id1=IDENT ; RPAREN ;"and" ; t2=tactic_term ; LPAREN ; id2=IDENT ; RPAREN ->
571 BYC_wehaveand (id1,t1,id2,t2)
574 rewriting_step_continuation : [
582 [ t1 = SELF; SYMBOL ";"; t2 = SELF ->
585 | G.Seq (_, l) -> l @ [ t2 ]
591 [ tac = SELF; SYMBOL ";";
592 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
593 (G.Then (loc, tac, tacs))
596 [ IDENT "do"; count = int; tac = SELF ->
597 G.Do (loc, count, tac)
598 | IDENT "repeat"; tac = SELF -> G.Repeat (loc, tac)
602 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
604 | IDENT "try"; tac = SELF -> G.Try (loc, tac)
606 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
608 | IDENT "progress"; tac = SELF -> G.Progress (loc, tac)
609 | LPAREN; tac = SELF; RPAREN -> tac
610 | tac = tactic -> tac
614 npunctuation_tactical:
616 [ SYMBOL "[" -> G.NBranch loc
617 | SYMBOL "|" -> G.NShift loc
618 | i = LIST1 int SEP SYMBOL ","; SYMBOL ":" -> G.NPos (loc, i)
619 | SYMBOL "*"; SYMBOL ":" -> G.NWildcard loc
620 | name = IDENT; SYMBOL ":" -> G.NPosbyname (loc, name)
621 | SYMBOL "]" -> G.NMerge loc
622 | SYMBOL ";" -> G.NSemicolon loc
623 | SYMBOL "." -> G.NDot loc
627 punctuation_tactical:
629 [ SYMBOL "[" -> G.Branch loc
630 | SYMBOL "|" -> G.Shift loc
631 | i = LIST1 int SEP SYMBOL ","; SYMBOL ":" -> G.Pos (loc, i)
632 | SYMBOL "*"; SYMBOL ":" -> G.Wildcard loc
633 | SYMBOL "]" -> G.Merge loc
634 | SYMBOL ";" -> G.Semicolon loc
635 | SYMBOL "." -> G.Dot loc
638 non_punctuation_tactical:
640 [ IDENT "focus"; goals = LIST1 int -> G.Focus (loc, goals)
641 | IDENT "unfocus" -> G.Unfocus loc
642 | IDENT "skip" -> G.Skip loc
646 nnon_punctuation_tactical:
648 [ IDENT "focus"; goals = LIST1 int -> G.NFocus (loc, goals)
649 | IDENT "unfocus" -> G.NUnfocus loc
650 | IDENT "skip" -> G.NSkip loc
654 [ [ IDENT "ndefinition" ] -> `Definition
655 | [ IDENT "nfact" ] -> `Fact
656 | [ IDENT "nlemma" ] -> `Lemma
657 | [ IDENT "nremark" ] -> `Remark
658 | [ IDENT "ntheorem" ] -> `Theorem
662 [ [ IDENT "definition" ] -> `Definition
663 | [ IDENT "fact" ] -> `Fact
664 | [ IDENT "lemma" ] -> `Lemma
665 | [ IDENT "remark" ] -> `Remark
666 | [ IDENT "theorem" ] -> `Theorem
670 [ attr = theorem_flavour -> attr
671 | [ IDENT "axiom" ] -> `Axiom
672 | [ IDENT "variant" ] -> `Variant
677 params = LIST0 protected_binder_vars;
678 SYMBOL ":"; fst_typ = term; SYMBOL <:unicode<def>>; OPT SYMBOL "|";
679 fst_constructors = LIST0 constructor SEP SYMBOL "|";
682 name = IDENT; SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>;
683 OPT SYMBOL "|"; constructors = LIST0 constructor SEP SYMBOL "|" ->
684 (name, true, typ, constructors) ] SEP "with" -> types
688 (fun (names, typ) acc ->
689 (List.map (fun name -> (name, typ)) names) @ acc)
692 let fst_ind_type = (fst_name, true, fst_typ, fst_constructors) in
693 let tl_ind_types = match tl with None -> [] | Some types -> types in
694 let ind_types = fst_ind_type :: tl_ind_types in
700 params = LIST0 protected_binder_vars;
701 SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>; SYMBOL "{" ;
705 SYMBOL ":" -> false,0
706 | SYMBOL ":"; SYMBOL ">" -> true,0
707 | SYMBOL ":"; arity = int ; SYMBOL ">" -> true,arity
710 let b,n = coercion in
712 ] SEP SYMBOL ";"; SYMBOL "}" ->
715 (fun (names, typ) acc ->
716 (List.map (fun name -> (name, typ)) names) @ acc)
719 (params,name,typ,fields)
723 [ IDENT "id"; id = QSTRING; SYMBOL "="; uri = QSTRING ->
724 let alpha = "[a-zA-Z]" in
725 let num = "[0-9]+" in
726 let ident_cont = "\\("^alpha^"\\|"^num^"\\|_\\|\\\\\\)" in
727 let decoration = "\\'" in
728 let ident = "\\("^alpha^ident_cont^"*"^decoration^"*\\|_"^ident_cont^"+"^decoration^"*\\)" in
729 let rex = Str.regexp ("^"^ident^"$") in
730 if Str.string_match rex id 0 then
731 if (try ignore (UriManager.uri_of_string uri); true
732 with UriManager.IllFormedUri _ -> false) ||
733 (try ignore (NReference.reference_of_string uri); true
734 with NReference.IllFormedReference _ -> false)
736 L.Ident_alias (id, uri)
739 (HExtlib.Localized (loc, CicNotationParser.Parse_error (Printf.sprintf "Not a valid uri: %s" uri)))
741 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error (
742 Printf.sprintf "Not a valid identifier: %s" id)))
743 | IDENT "symbol"; symbol = QSTRING;
744 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
745 SYMBOL "="; dsc = QSTRING ->
747 match instance with Some i -> i | None -> 0
749 L.Symbol_alias (symbol, instance, dsc)
751 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
752 SYMBOL "="; dsc = QSTRING ->
754 match instance with Some i -> i | None -> 0
756 L.Number_alias (instance, dsc)
760 [ l = LIST0 [ SYMBOL <:unicode<eta>> (* η *); SYMBOL "." -> () ];
762 N.IdentArg (List.length l, id)
766 [ IDENT "left"; IDENT "associative" -> Gramext.LeftA
767 | IDENT "right"; IDENT "associative" -> Gramext.RightA
768 | IDENT "non"; IDENT "associative" -> Gramext.NonA
772 [ "with"; IDENT "precedence"; n = NUMBER -> int_of_string n ]
775 [ dir = OPT direction; s = QSTRING;
776 assoc = OPT associativity; prec = precedence;
779 [ blob = UNPARSED_AST ->
780 add_raw_attribute ~text:(Printf.sprintf "@{%s}" blob)
781 (CicNotationParser.parse_level2_ast
782 (Ulexing.from_utf8_string blob))
783 | blob = UNPARSED_META ->
784 add_raw_attribute ~text:(Printf.sprintf "${%s}" blob)
785 (CicNotationParser.parse_level2_meta
786 (Ulexing.from_utf8_string blob))
790 | None -> default_associativity
791 | Some assoc -> assoc
794 add_raw_attribute ~text:s
795 (CicNotationParser.parse_level1_pattern prec
796 (Ulexing.from_utf8_string s))
798 (dir, p1, assoc, prec, p2)
802 [ u = URI -> N.UriPattern (UriManager.uri_of_string u)
803 | r = NREF -> N.NRefPattern (NReference.reference_of_string r)
804 | IMPLICIT -> N.ImplicitPattern
805 | id = IDENT -> N.VarPattern id
806 | LPAREN; terms = LIST1 SELF; RPAREN ->
810 | terms -> N.ApplPattern terms)
814 [ s = CSYMBOL; args = LIST0 argument; SYMBOL "="; t = level3_term ->
820 IDENT "include" ; path = QSTRING ->
821 loc,path,true,L.WithPreferences
822 | IDENT "include" ; IDENT "source" ; path = QSTRING ->
823 loc,path,false,L.WithPreferences
824 | IDENT "include'" ; path = QSTRING ->
825 loc,path,true,L.WithoutPreferences
828 grafite_ncommand: [ [
829 IDENT "nqed" -> G.NQed loc
830 | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
831 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
832 G.NObj (loc, N.Theorem (nflavour, name, typ, body,`Regular))
833 | nflavour = ntheorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
835 G.NObj (loc, N.Theorem (nflavour, name, N.Implicit `JustOne, Some body,`Regular))
836 | IDENT "naxiom"; name = IDENT; SYMBOL ":"; typ = term ->
837 G.NObj (loc, N.Theorem (`Axiom, name, typ, None, `Regular))
838 | IDENT "ndiscriminator" ; indty = tactic_term -> G.NDiscriminator (loc,indty)
839 | IDENT "ninverter"; name = IDENT; IDENT "for" ; indty = tactic_term ;
840 paramspec = OPT inverter_param_list ;
841 outsort = OPT [ SYMBOL ":" ; outsort = term -> outsort ] ->
842 G.NInverter (loc,name,indty,paramspec,outsort)
843 | NLETCOREC ; defs = let_defs ->
844 nmk_rec_corec `CoInductive defs loc
845 | NLETREC ; defs = let_defs ->
846 nmk_rec_corec `Inductive defs loc
847 | IDENT "ninductive"; spec = inductive_spec ->
848 let (params, ind_types) = spec in
849 G.NObj (loc, N.Inductive (params, ind_types))
850 | IDENT "ncoinductive"; spec = inductive_spec ->
851 let (params, ind_types) = spec in
852 let ind_types = (* set inductive flags to false (coinductive) *)
853 List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
856 G.NObj (loc, N.Inductive (params, ind_types))
857 | IDENT "universe"; IDENT "constraint"; u1 = tactic_term;
858 SYMBOL <:unicode<lt>> ; u2 = tactic_term ->
860 | NotationPt.AttributedTerm (_, NotationPt.Sort (`NType i)) ->
861 NUri.uri_of_string ("cic:/matita/pts/Type"^i^".univ")
862 | _ -> raise (Failure "only a Type[…] sort can be constrained")
866 G.NUnivConstraint (loc,u1,u2)
867 | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
868 G.UnificationHint (loc, t, n)
869 | IDENT "ncoercion"; name = IDENT; SYMBOL ":"; ty = term;
870 SYMBOL <:unicode<def>>; t = term; "on";
871 id = [ IDENT | PIDENT ]; SYMBOL ":"; source = term;
872 "to"; target = term ->
873 G.NCoercion(loc,name,t,ty,(id,source),target)
874 | IDENT "nrecord" ; (params,name,ty,fields) = record_spec ->
875 G.NObj (loc, N.Record (params,name,ty,fields))
876 | IDENT "ncopy" ; s = IDENT; IDENT "from"; u = URI; "with";
877 m = LIST0 [ u1 = URI; SYMBOL <:unicode<mapsto>>; u2 = URI -> u1,u2 ] ->
878 G.NCopy (loc,s,NUri.uri_of_string u,
879 List.map (fun a,b -> NUri.uri_of_string a, NUri.uri_of_string b) m)
883 IDENT "alias" ; spec = alias_spec ->
885 | IDENT "notation"; (dir, l1, assoc, prec, l2) = notation ->
886 L.Notation (loc, dir, l1, assoc, prec, l2)
887 | IDENT "interpretation"; id = QSTRING;
888 (symbol, args, l3) = interpretation ->
889 L.Interpretation (loc, id, (symbol, args), l3)
892 [ ncmd = grafite_ncommand; SYMBOL "." -> G.NCommand (loc, ncmd)
893 (* | tac = atomic_tactical LEVEL "loops"; punct = punctuation_tactical ->
894 G.Tactic (loc, Some tac, punct) *)
895 (* | punct = punctuation_tactical -> G.Tactic (loc, None, punct) *)
896 | tac = ntactic; OPT [ SYMBOL "#" ; SYMBOL "#" ] ;
897 punct = npunctuation_tactical -> cons_ntac tac punct
899 | tac = ntactic; punct = punctuation_tactical ->
900 cons_ntac tac (npunct_of_punct punct)
902 | SYMBOL "#" ; SYMBOL "#" ; punct = npunctuation_tactical ->
903 G.NTactic (loc, [punct])
904 | SYMBOL "#" ; SYMBOL "#" ; tac = nnon_punctuation_tactical;
905 SYMBOL "#" ; SYMBOL "#" ; punct = npunctuation_tactical ->
906 G.NTactic (loc, [tac; punct])
907 | SYMBOL "#" ; SYMBOL "#" ; tac = nnon_punctuation_tactical;
908 punct = npunctuation_tactical ->
909 G.NTactic (loc, [tac; punct])
913 [ BEGINCOMMENT ; ex = executable ; ENDCOMMENT ->
921 fun ?(never_include=false) ~include_paths status ->
922 let stm = G.Executable (loc, ex) in
923 !grafite_callback stm;
926 fun ?(never_include=false) ~include_paths status ->
927 let stm = G.Comment (loc, com) in
928 !grafite_callback stm;
930 | (iloc,fname,normal,mode) = include_command ; SYMBOL "." ->
931 fun ?(never_include=false) ~include_paths status ->
932 let _root, buri, fullpath, _rrelpath =
933 Librarian.baseuri_of_script ~include_paths fname in
934 if never_include then raise (NoInclusionPerformed fullpath)
939 (loc, G.Command (loc, G.Include (iloc,fname))) in
940 !grafite_callback stm;
942 LE.eval_command status (L.Include (iloc,buri,mode,fullpath)) in
945 (loc,G.Command (loc,G.Include (iloc,buri)))
949 | scom = lexicon_command ; SYMBOL "." ->
950 fun ?(never_include=false) ~include_paths status ->
951 !lexicon_callback scom;
952 let status = LE.eval_command status scom in
954 | EOI -> raise End_of_file
961 let _ = initialize_parser () ;;
963 let exc_located_wrapper f =
967 | Stdpp.Exc_located (_, End_of_file) -> raise End_of_file
968 | Stdpp.Exc_located (floc, Stream.Error msg) ->
969 raise (HExtlib.Localized (floc,CicNotationParser.Parse_error msg))
970 | Stdpp.Exc_located (floc, HExtlib.Localized(_,exn)) ->
972 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
973 | Stdpp.Exc_located (floc, exn) ->
975 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
977 let parse_statement lexbuf =
979 (fun () -> (Grammar.Entry.parse (Obj.magic !grafite_parser.statement) (Obj.magic lexbuf)))
981 let statement () = Obj.magic !grafite_parser.statement
983 let history = ref [] ;;
987 history := !grafite_parser :: !history;
988 grafite_parser := initial_parser ();
997 grafite_parser := gp;
1001 (* vim:set foldmethod=marker: *)