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/
28 module N = CicNotationPt
31 module LE = LexiconEngine
33 exception NoInclusionPerformed of string (* full path *)
35 type 'a localized_option =
40 (N.term, N.term, N.term G.reduction, N.term N.obj, string) G.statement
43 ?never_include:bool -> include_paths:string list -> LE.status ->
44 LE.status * ast_statement localized_option
46 type parser_status = {
48 term : N.term Grammar.Entry.e;
49 statement : statement Grammar.Entry.e;
52 let grafite_callback = ref (fun _ _ -> ())
53 let set_grafite_callback cb = grafite_callback := cb
55 let lexicon_callback = ref (fun _ _ -> ())
56 let set_lexicon_callback cb = lexicon_callback := cb
58 let initial_parser () =
59 let grammar = CicNotationParser.level2_ast_grammar () in
60 let term = CicNotationParser.term () in
61 let statement = Grammar.Entry.create grammar "statement" in
62 { grammar = grammar; term = term; statement = statement }
65 let grafite_parser = ref (initial_parser ())
67 let add_raw_attribute ~text t = N.AttributedTerm (`Raw text, t)
69 let default_associativity = Gramext.NonA
71 let mk_rec_corec ng ind_kind defs loc =
72 (* In case of mutual definitions here we produce just
73 the syntax tree for the first one. The others will be
74 generated from the completely specified term just before
75 insertion in the environment. We use the flavour
76 `MutualDefinition to rememer this. *)
79 | (params,(N.Ident (name, None), ty),_,_) :: _ ->
80 let ty = match ty with Some ty -> ty | None -> N.Implicit in
83 (fun var ty -> N.Binder (`Pi,var,ty)
89 let body = N.Ident (name,None) in
91 if List.length defs = 1 then
97 G.NObj (loc, N.Theorem(flavour, name, ty,
98 Some (N.LetRec (ind_kind, defs, body))))
100 G.Obj (loc, N.Theorem(flavour, name, ty,
101 Some (N.LetRec (ind_kind, defs, body))))
103 type by_continuation =
105 | BYC_weproved of N.term * string option * N.term option
106 | BYC_letsuchthat of string * N.term * string * N.term
107 | BYC_wehaveand of string * N.term * string * N.term
109 let initialize_parser () =
110 (* {{{ parser initialization *)
111 let term = !grafite_parser.term in
112 let statement = !grafite_parser.statement in
113 let let_defs = CicNotationParser.let_defs () in
114 let protected_binder_vars = CicNotationParser.protected_binder_vars () in
116 GLOBAL: term statement;
117 constructor: [ [ name = IDENT; SYMBOL ":"; typ = term -> (name, typ) ] ];
118 tactic_term: [ [ t = term LEVEL "90" -> t ] ];
121 | id = IDENT -> Some id ]
123 ident_list0: [ [ LPAREN; idents = LIST0 new_name; RPAREN -> idents ] ];
125 [ tactic_terms = LIST1 tactic_term SEP SYMBOL "," -> tactic_terms ]
128 [ IDENT "normalize" -> `Normalize
129 | IDENT "simplify" -> `Simpl
130 | IDENT "unfold"; t = OPT tactic_term -> `Unfold t
131 | IDENT "whd" -> `Whd ]
134 [ IDENT "nnormalize" ; delta = OPT [ IDENT "nodelta" -> () ] ->
135 let delta = match delta with None -> true | _ -> false in
137 (*| IDENT "unfold"; t = OPT tactic_term -> `Unfold t*)
138 | IDENT "nwhd" ; delta = OPT [ IDENT "nodelta" -> () ] ->
139 let delta = match delta with None -> true | _ -> false in
142 sequent_pattern_spec: [
146 path = OPT [SYMBOL ":" ; path = tactic_term -> path ] ->
147 (id,match path with Some p -> p | None -> N.UserInput) ];
148 goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = tactic_term -> term ] ->
150 match goal_path, hyp_paths with
151 None, [] -> Some N.UserInput
153 | Some goal_path, _ -> Some goal_path
162 [ "match" ; wanted = tactic_term ;
163 sps = OPT [ "in"; sps = sequent_pattern_spec -> sps ] ->
165 | sps = sequent_pattern_spec ->
168 let wanted,hyp_paths,goal_path =
169 match wanted_and_sps with
170 wanted,None -> wanted, [], Some N.UserInput
171 | wanted,Some (hyp_paths,goal_path) -> wanted,hyp_paths,goal_path
173 wanted, hyp_paths, goal_path ] ->
175 None -> None,[],Some N.UserInput
178 inverter_param_list: [
179 [ params = tactic_term ->
180 let deannotate = function
181 | N.AttributedTerm (_,t) | t -> t
182 in match deannotate params with
183 | N.Implicit -> [false]
184 | N.UserInput -> [true]
186 List.map (fun x -> match deannotate x with
187 | N.Implicit -> false
188 | N.UserInput -> true
189 | _ -> raise (Invalid_argument "malformed target parameter list 1")) l
190 | _ -> raise (Invalid_argument ("malformed target parameter list 2\n" ^ CicNotationPp.pp_term params)) ]
193 [ SYMBOL ">" -> `LeftToRight
194 | SYMBOL "<" -> `RightToLeft ]
196 int: [ [ num = NUMBER -> int_of_string num ] ];
198 [ idents = OPT ident_list0 ->
199 match idents with None -> [] | Some idents -> idents
203 [ OPT [ IDENT "names" ];
204 num = OPT [ num = int -> num ];
205 idents = intros_names ->
209 using: [ [ using = OPT [ IDENT "using"; t = tactic_term -> t ] -> using ] ];
211 [ IDENT "napply"; t = tactic_term -> G.NApply (loc, t)
215 [ id = IDENT ; SYMBOL ":" ; ty = tactic_term -> id,`Decl ty
216 | id = IDENT ; SYMBOL ":" ; ty = tactic_term ;
217 SYMBOL <:unicode<def>> ; bo = tactic_term ->
219 SYMBOL <:unicode<vdash>>;
220 concl = tactic_term -> (List.rev hyps,concl) ] ->
221 G.NAssert (loc, seqs)
222 | IDENT "nauto"; params = auto_params -> G.NAuto (loc, params)
223 | IDENT "ncases"; what = tactic_term ; where = pattern_spec ->
224 G.NCases (loc, what, where)
225 | IDENT "nchange"; what = pattern_spec; "with"; with_what = tactic_term ->
226 G.NChange (loc, what, with_what)
227 | IDENT "nelim"; what = tactic_term ; where = pattern_spec ->
228 G.NElim (loc, what, where)
229 | IDENT "ngeneralize"; p=pattern_spec ->
230 G.NGeneralize (loc, p)
231 | IDENT "nletin"; name = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term;
232 where = pattern_spec ->
233 G.NLetIn (loc,where,t,name)
234 | kind = nreduction_kind; p = pattern_spec ->
235 G.NReduce (loc, kind, p)
236 | IDENT "nrewrite"; dir = direction; what = tactic_term ; where = pattern_spec ->
237 G.NRewrite (loc, dir, what, where)
238 | SYMBOL "#"; n=IDENT -> G.NIntro (loc,n)
239 | SYMBOL "#"; SYMBOL "_" -> G.NIntro (loc,"_")
240 | SYMBOL "*" -> G.NCase1 (loc,"_")
241 | SYMBOL "*"; n=IDENT ->
246 [ IDENT "absurd"; t = tactic_term ->
248 | IDENT "apply"; IDENT "rule"; t = tactic_term ->
250 | IDENT "apply"; t = tactic_term ->
252 | IDENT "applyP"; t = tactic_term ->
254 | IDENT "applyS"; t = tactic_term ; params = auto_params ->
255 G.ApplyS (loc, t, params)
256 | IDENT "assumption" ->
258 | IDENT "autobatch"; params = auto_params ->
259 G.AutoBatch (loc,params)
260 | IDENT "cases"; what = tactic_term;
261 pattern = OPT pattern_spec;
262 specs = intros_spec ->
263 let pattern = match pattern with
264 | None -> None, [], Some N.UserInput
265 | Some pattern -> pattern
267 G.Cases (loc, what, pattern, specs)
268 | IDENT "clear"; ids = LIST1 IDENT ->
270 | IDENT "clearbody"; id = IDENT ->
272 | IDENT "change"; what = pattern_spec; "with"; t = tactic_term ->
273 G.Change (loc, what, t)
274 | IDENT "compose"; times = OPT int; t1 = tactic_term; t2 =
275 OPT [ "with"; t = tactic_term -> t ]; specs = intros_spec ->
276 let times = match times with None -> 1 | Some i -> i in
277 G.Compose (loc, t1, t2, times, specs)
278 | IDENT "constructor"; n = int ->
279 G.Constructor (loc, n)
280 | IDENT "contradiction" ->
282 | IDENT "cut"; t = tactic_term; ident = OPT [ "as"; id = IDENT -> id] ->
283 G.Cut (loc, ident, t)
284 | IDENT "decompose"; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
285 let idents = match idents with None -> [] | Some idents -> idents in
286 G.Decompose (loc, idents)
287 | IDENT "demodulate"; p = auto_params -> G.Demodulate (loc, p)
288 | IDENT "destruct"; xts = OPT [ ts = tactic_term_list1 -> ts ] ->
289 G.Destruct (loc, xts)
290 | IDENT "elim"; what = tactic_term; using = using;
291 pattern = OPT pattern_spec;
292 ispecs = intros_spec ->
293 let pattern = match pattern with
294 | None -> None, [], Some N.UserInput
295 | Some pattern -> pattern
297 G.Elim (loc, what, using, pattern, ispecs)
298 | IDENT "elimType"; what = tactic_term; using = using;
299 (num, idents) = intros_spec ->
300 G.ElimType (loc, what, using, (num, idents))
301 | IDENT "exact"; t = tactic_term ->
305 | IDENT "fail" -> G.Fail loc
306 | IDENT "fold"; kind = reduction_kind; t = tactic_term; p = pattern_spec ->
309 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error
310 ("the pattern cannot specify the term to replace, only its"
311 ^ " paths in the hypotheses and in the conclusion")))
313 G.Fold (loc, kind, t, p)
316 | IDENT "fwd"; hyp = IDENT; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
317 let idents = match idents with None -> [] | Some idents -> idents in
318 G.FwdSimpl (loc, hyp, idents)
319 | IDENT "generalize"; p=pattern_spec; id = OPT ["as" ; id = IDENT -> id] ->
320 G.Generalize (loc,p,id)
321 | IDENT "id" -> G.IdTac loc
322 | IDENT "intro"; ident = OPT IDENT ->
323 let idents = match ident with None -> [] | Some id -> [Some id] in
324 G.Intros (loc, (Some 1, idents))
325 | IDENT "intros"; specs = intros_spec ->
326 G.Intros (loc, specs)
327 | IDENT "inversion"; t = tactic_term ->
330 linear = OPT [ IDENT "linear" ];
331 depth = OPT [ IDENT "depth"; SYMBOL "="; i = int -> i ];
333 to_what = OPT [ "to" ; t = tactic_term_list1 -> t ];
334 ident = OPT [ "as" ; ident = IDENT -> ident ] ->
335 let linear = match linear with None -> false | Some _ -> true in
336 let to_what = match to_what with None -> [] | Some to_what -> to_what in
337 G.LApply (loc, linear, depth, to_what, what, ident)
338 | IDENT "left" -> G.Left loc
339 | IDENT "letin"; where = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term ->
340 G.LetIn (loc, t, where)
341 | kind = reduction_kind; p = pattern_spec ->
342 G.Reduce (loc, kind, p)
343 | IDENT "reflexivity" ->
345 | IDENT "replace"; p = pattern_spec; "with"; t = tactic_term ->
346 G.Replace (loc, p, t)
347 | IDENT "rewrite" ; d = direction; t = tactic_term ; p = pattern_spec;
348 xnames = OPT [ "as"; n = ident_list0 -> n ] ->
352 (HExtlib.Localized (loc,
353 (CicNotationParser.Parse_error
354 "the pattern cannot specify the term to rewrite, only its paths in the hypotheses and in the conclusion")))
356 let n = match xnames with None -> [] | Some names -> names in
357 G.Rewrite (loc, d, t, p, n)
364 | IDENT "symmetry" ->
366 | IDENT "transitivity"; t = tactic_term ->
367 G.Transitivity (loc, t)
368 (* Produzioni Aggiunte *)
369 | IDENT "assume" ; id = IDENT ; SYMBOL ":" ; t = tactic_term ->
370 G.Assume (loc, id, t)
371 | IDENT "suppose" ; t = tactic_term ; LPAREN ; id = IDENT ; RPAREN ;
372 t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ;
373 t' = tactic_term -> t']->
374 G.Suppose (loc, t, id, t1)
375 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
376 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
377 id2 = IDENT ; RPAREN ->
378 G.ExistsElim (loc, `Auto ([],[]), id1, t1, id2, t2)
380 [ IDENT "using"; t=tactic_term -> `Term t
381 | params = auto_params -> `Auto params] ;
382 cont=by_continuation ->
384 BYC_done -> G.Bydone (loc, just)
385 | BYC_weproved (ty,id,t1) ->
386 G.By_just_we_proved(loc, just, ty, id, t1)
387 | BYC_letsuchthat (id1,t1,id2,t2) ->
388 G.ExistsElim (loc, just, id1, t1, id2, t2)
389 | BYC_wehaveand (id1,t1,id2,t2) ->
390 G.AndElim (loc, just, id1, t1, id2, t2))
391 | 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']->
392 G.We_need_to_prove (loc, t, id, t1)
393 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "cases" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
394 G.We_proceed_by_cases_on (loc, t, t1)
395 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "induction" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
396 G.We_proceed_by_induction_on (loc, t, t1)
397 | IDENT "by" ; IDENT "induction" ; IDENT "hypothesis" ; IDENT "we" ; IDENT "know" ; t=tactic_term ; LPAREN ; id = IDENT ; RPAREN ->
398 G.Byinduction(loc, t, id)
399 | IDENT "the" ; IDENT "thesis" ; IDENT "becomes" ; t=tactic_term ->
400 G.Thesisbecomes(loc, t)
401 | IDENT "case" ; id = IDENT ; params=LIST0[LPAREN ; i=IDENT ;
402 SYMBOL":" ; t=tactic_term ; RPAREN -> i,t] ->
403 G.Case(loc,id,params)
404 (* DO NOT FACTORIZE with the two following, camlp5 sucks*)
406 termine = tactic_term;
410 [ IDENT "using"; t=tactic_term -> `Term t
411 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
412 | IDENT "proof" -> `Proof
413 | params = auto_params -> `Auto params];
414 cont = rewriting_step_continuation ->
415 G.RewritingStep(loc, Some (None,termine), t1, t2, cont)
416 | IDENT "obtain" ; name = IDENT;
417 termine = tactic_term;
421 [ IDENT "using"; t=tactic_term -> `Term t
422 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
423 | IDENT "proof" -> `Proof
424 | params = auto_params -> `Auto params];
425 cont = rewriting_step_continuation ->
426 G.RewritingStep(loc, Some (Some name,termine), t1, t2, cont)
430 [ IDENT "using"; t=tactic_term -> `Term t
431 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
432 | IDENT "proof" -> `Proof
433 | params = auto_params -> `Auto params];
434 cont = rewriting_step_continuation ->
435 G.RewritingStep(loc, None, t1, t2, cont)
439 [ IDENT "paramodulation"
452 i = auto_fixed_param -> i,""
453 | i = auto_fixed_param ; SYMBOL "="; v = [ v = int ->
454 string_of_int v | v = IDENT -> v ] -> i,v ];
455 tl = OPT [ IDENT "by"; tl = tactic_term_list1 -> tl] ->
456 (match tl with Some l -> l | None -> []),
462 [ IDENT "prefix"; SYMBOL "="; prefix = QSTRING -> G.IPPrefix prefix
463 | flavour = inline_flavour -> G.IPAs flavour
464 | IDENT "procedural" -> G.IPProcedural
465 | IDENT "nodefaults" -> G.IPNoDefaults
466 | IDENT "depth"; SYMBOL "="; depth = int -> G.IPDepth depth
467 | IDENT "level"; SYMBOL "="; level = int -> G.IPLevel level
468 | IDENT "comments" -> G.IPComments
469 | IDENT "coercions" -> G.IPCoercions
470 | IDENT "debug"; SYMBOL "="; debug = int -> G.IPDebug debug
475 [ 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)
476 | WEPROVED; ty = tactic_term ; t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ; t2 = tactic_term -> t2] ;
477 "done" -> BYC_weproved (ty,None,t1)
479 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
480 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
481 id2 = IDENT ; RPAREN -> BYC_letsuchthat (id1,t1,id2,t2)
482 | WEHAVE; t1=tactic_term ; LPAREN ; id1=IDENT ; RPAREN ;"and" ; t2=tactic_term ; LPAREN ; id2=IDENT ; RPAREN ->
483 BYC_wehaveand (id1,t1,id2,t2)
486 rewriting_step_continuation : [
493 [ t1 = SELF; SYMBOL ";"; t2 = SELF ->
496 | G.Seq (_, l) -> l @ [ t2 ]
502 [ tac = SELF; SYMBOL ";";
503 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
504 (G.Then (loc, tac, tacs))
507 [ IDENT "do"; count = int; tac = SELF ->
508 G.Do (loc, count, tac)
509 | IDENT "repeat"; tac = SELF -> G.Repeat (loc, tac)
513 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
515 | IDENT "try"; tac = SELF -> G.Try (loc, tac)
517 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
519 | IDENT "progress"; tac = SELF -> G.Progress (loc, tac)
520 | LPAREN; tac = SELF; RPAREN -> tac
521 | tac = tactic -> tac
524 punctuation_tactical:
526 [ SYMBOL "[" -> G.Branch loc
527 | SYMBOL "|" -> G.Shift loc
528 | i = LIST1 int SEP SYMBOL ","; SYMBOL ":" -> G.Pos (loc, i)
529 | SYMBOL "*"; SYMBOL ":" -> G.Wildcard loc
530 | SYMBOL "]" -> G.Merge loc
531 | SYMBOL ";" -> G.Semicolon loc
532 | SYMBOL "." -> G.Dot loc
535 non_punctuation_tactical:
537 [ IDENT "focus"; goals = LIST1 int -> G.Focus (loc, goals)
538 | IDENT "unfocus" -> G.Unfocus loc
539 | IDENT "skip" -> G.Skip loc
543 [ [ IDENT "ndefinition" ] -> `Definition
544 | [ IDENT "nfact" ] -> `Fact
545 | [ IDENT "nlemma" ] -> `Lemma
546 | [ IDENT "nremark" ] -> `Remark
547 | [ IDENT "ntheorem" ] -> `Theorem
551 [ [ IDENT "definition" ] -> `Definition
552 | [ IDENT "fact" ] -> `Fact
553 | [ IDENT "lemma" ] -> `Lemma
554 | [ IDENT "remark" ] -> `Remark
555 | [ IDENT "theorem" ] -> `Theorem
559 [ attr = theorem_flavour -> attr
560 | [ IDENT "axiom" ] -> `Axiom
561 | [ IDENT "variant" ] -> `Variant
566 params = LIST0 protected_binder_vars;
567 SYMBOL ":"; fst_typ = term; SYMBOL <:unicode<def>>; OPT SYMBOL "|";
568 fst_constructors = LIST0 constructor SEP SYMBOL "|";
571 name = IDENT; SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>;
572 OPT SYMBOL "|"; constructors = LIST0 constructor SEP SYMBOL "|" ->
573 (name, true, typ, constructors) ] SEP "with" -> types
577 (fun (names, typ) acc ->
578 (List.map (fun name -> (name, typ)) names) @ acc)
581 let fst_ind_type = (fst_name, true, fst_typ, fst_constructors) in
582 let tl_ind_types = match tl with None -> [] | Some types -> types in
583 let ind_types = fst_ind_type :: tl_ind_types in
589 params = LIST0 protected_binder_vars;
590 SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>; SYMBOL "{" ;
594 SYMBOL ":" -> false,0
595 | SYMBOL ":"; SYMBOL ">" -> true,0
596 | SYMBOL ":"; arity = int ; SYMBOL ">" -> true,arity
599 let b,n = coercion in
601 ] SEP SYMBOL ";"; SYMBOL "}" ->
604 (fun (names, typ) acc ->
605 (List.map (fun name -> (name, typ)) names) @ acc)
608 (params,name,typ,fields)
612 [ [ IDENT "check" ]; t = term ->
614 | [ IDENT "eval" ]; kind = reduction_kind; "on"; t = tactic_term ->
615 G.Eval (loc, kind, t)
616 | IDENT "inline"; suri = QSTRING; params = inline_params ->
617 G.Inline (loc, suri, params)
618 | [ IDENT "hint" ]; rew = OPT (IDENT "rewrite") ->
619 if rew = None then G.Hint (loc, false) else G.Hint (loc,true)
620 | IDENT "auto"; params = auto_params ->
621 G.AutoInteractive (loc,params)
622 | [ IDENT "whelp"; "match" ] ; t = term ->
624 | [ IDENT "whelp"; IDENT "instance" ] ; t = term ->
626 | [ IDENT "whelp"; IDENT "locate" ] ; id = QSTRING ->
628 | [ IDENT "whelp"; IDENT "elim" ] ; t = term ->
630 | [ IDENT "whelp"; IDENT "hint" ] ; t = term ->
635 [ IDENT "id"; id = QSTRING; SYMBOL "="; uri = QSTRING ->
636 let alpha = "[a-zA-Z]" in
637 let num = "[0-9]+" in
638 let ident_cont = "\\("^alpha^"\\|"^num^"\\|_\\|\\\\\\)" in
639 let decoration = "\\'" in
640 let ident = "\\("^alpha^ident_cont^"*"^decoration^"*\\|_"^ident_cont^"+"^decoration^"*\\)" in
641 let rex = Str.regexp ("^"^ident^"$") in
642 if Str.string_match rex id 0 then
643 if (try ignore (UriManager.uri_of_string uri); true
644 with UriManager.IllFormedUri _ -> false) ||
645 (try ignore (NReference.reference_of_string uri); true
646 with NReference.IllFormedReference _ -> false)
648 L.Ident_alias (id, uri)
651 (HExtlib.Localized (loc, CicNotationParser.Parse_error (Printf.sprintf "Not a valid uri: %s" uri)))
653 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error (
654 Printf.sprintf "Not a valid identifier: %s" id)))
655 | IDENT "symbol"; symbol = QSTRING;
656 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
657 SYMBOL "="; dsc = QSTRING ->
659 match instance with Some i -> i | None -> 0
661 L.Symbol_alias (symbol, instance, dsc)
663 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
664 SYMBOL "="; dsc = QSTRING ->
666 match instance with Some i -> i | None -> 0
668 L.Number_alias (instance, dsc)
672 [ l = LIST0 [ SYMBOL <:unicode<eta>> (* η *); SYMBOL "." -> () ];
674 N.IdentArg (List.length l, id)
678 [ IDENT "left"; IDENT "associative" -> Gramext.LeftA
679 | IDENT "right"; IDENT "associative" -> Gramext.RightA
680 | IDENT "non"; IDENT "associative" -> Gramext.NonA
684 [ "with"; IDENT "precedence"; n = NUMBER -> int_of_string n ]
687 [ dir = OPT direction; s = QSTRING;
688 assoc = OPT associativity; prec = precedence;
691 [ blob = UNPARSED_AST ->
692 add_raw_attribute ~text:(Printf.sprintf "@{%s}" blob)
693 (CicNotationParser.parse_level2_ast
694 (Ulexing.from_utf8_string blob))
695 | blob = UNPARSED_META ->
696 add_raw_attribute ~text:(Printf.sprintf "${%s}" blob)
697 (CicNotationParser.parse_level2_meta
698 (Ulexing.from_utf8_string blob))
702 | None -> default_associativity
703 | Some assoc -> assoc
706 add_raw_attribute ~text:s
707 (CicNotationParser.parse_level1_pattern prec
708 (Ulexing.from_utf8_string s))
710 (dir, p1, assoc, prec, p2)
714 [ u = URI -> N.UriPattern (UriManager.uri_of_string u)
715 | r = NREF -> N.NRefPattern (NReference.reference_of_string r)
716 | IMPLICIT -> N.ImplicitPattern
717 | id = IDENT -> N.VarPattern id
718 | LPAREN; terms = LIST1 SELF; RPAREN ->
722 | terms -> N.ApplPattern terms)
726 [ s = CSYMBOL; args = LIST0 argument; SYMBOL "="; t = level3_term ->
732 IDENT "include" ; path = QSTRING ->
733 loc,path,true,L.WithPreferences
734 | IDENT "include" ; IDENT "source" ; path = QSTRING ->
735 loc,path,false,L.WithPreferences
736 | IDENT "include'" ; path = QSTRING ->
737 loc,path,true,L.WithoutPreferences
741 IDENT "set"; n = QSTRING; v = QSTRING ->
743 | IDENT "drop" -> G.Drop loc
744 | IDENT "print"; s = IDENT -> G.Print (loc,s)
745 | IDENT "qed" -> G.Qed loc
746 | IDENT "nqed" -> G.NQed loc
747 | IDENT "variant" ; name = IDENT; SYMBOL ":";
748 typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
751 (`Variant,name,typ,Some (N.Ident (newname, None))))
752 | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
753 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
754 G.NObj (loc, N.Theorem (nflavour, name, typ, body))
755 | nflavour = ntheorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
757 G.NObj (loc, N.Theorem (nflavour, name, N.Implicit, Some body))
758 | flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
759 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
760 G.Obj (loc, N.Theorem (flavour, name, typ, body))
761 | flavour = theorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
764 N.Theorem (flavour, name, N.Implicit, Some body))
765 | IDENT "axiom"; name = IDENT; SYMBOL ":"; typ = term ->
766 G.Obj (loc, N.Theorem (`Axiom, name, typ, None))
767 | IDENT "naxiom"; name = IDENT; SYMBOL ":"; typ = term ->
768 G.NObj (loc, N.Theorem (`Axiom, name, typ, None))
769 | LETCOREC ; defs = let_defs ->
770 mk_rec_corec false `CoInductive defs loc
771 | LETREC ; defs = let_defs ->
772 mk_rec_corec false `Inductive defs loc
773 | NLETCOREC ; defs = let_defs ->
774 mk_rec_corec true `CoInductive defs loc
775 | NLETREC ; defs = let_defs ->
776 mk_rec_corec true `Inductive defs loc
777 | IDENT "inductive"; spec = inductive_spec ->
778 let (params, ind_types) = spec in
779 G.Obj (loc, N.Inductive (params, ind_types))
780 | IDENT "ninductive"; spec = inductive_spec ->
781 let (params, ind_types) = spec in
782 G.NObj (loc, N.Inductive (params, ind_types))
783 | IDENT "coinductive"; spec = inductive_spec ->
784 let (params, ind_types) = spec in
785 let ind_types = (* set inductive flags to false (coinductive) *)
786 List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
789 G.Obj (loc, N.Inductive (params, ind_types))
790 | IDENT "ncoinductive"; spec = inductive_spec ->
791 let (params, ind_types) = spec in
792 let ind_types = (* set inductive flags to false (coinductive) *)
793 List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
796 G.NObj (loc, N.Inductive (params, ind_types))
797 | IDENT "universe"; IDENT "constraint"; u1 = tactic_term;
798 strict = [ SYMBOL <:unicode<lt>> -> true
799 | SYMBOL <:unicode<leq>> -> false ];
803 | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NType i)) ->
804 NUri.uri_of_string ("cic:/matita/pts/Type"^i^".univ")
805 | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NCProp i)) ->
806 NUri.uri_of_string ("cic:/matita/pts/CProp"^i^".univ")
807 | _ -> raise (Failure "only a sort can be constrained")
811 | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NType i)) ->
812 NUri.uri_of_string ("cic:/matita/pts/Type"^i^".univ")
813 | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NCProp i)) ->
814 NUri.uri_of_string ("cic:/matita/pts/CProp"^i^".univ")
815 | _ -> raise (Failure "only a sort can be constrained")
817 G.NUnivConstraint (loc, strict,u1,u2)
819 t = [ u = URI -> N.Uri (u,None) | t = tactic_term ; OPT "with" -> t ] ;
820 arity = OPT int ; saturations = OPT int;
821 composites = OPT (IDENT "nocomposites") ->
822 let arity = match arity with None -> 0 | Some x -> x in
823 let saturations = match saturations with None -> 0 | Some x -> x in
824 let composites = match composites with None -> true | Some _ -> false in
826 (loc, t, composites, arity, saturations)
827 | IDENT "prefer" ; IDENT "coercion"; t = tactic_term ->
828 G.PreferCoercion (loc, t)
829 | IDENT "pump" ; steps = int ->
831 | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
832 G.UnificationHint (loc, t, n)
833 | IDENT "inverter"; name = IDENT; IDENT "for";
834 indty = tactic_term; paramspec = inverter_param_list ->
836 (loc, name, indty, paramspec)
837 | IDENT "record" ; (params,name,ty,fields) = record_spec ->
838 G.Obj (loc, N.Record (params,name,ty,fields))
839 | IDENT "nrecord" ; (params,name,ty,fields) = record_spec ->
840 G.NObj (loc, N.Record (params,name,ty,fields))
841 | IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
842 let uris = List.map UriManager.uri_of_string uris in
843 G.Default (loc,what,uris)
844 | IDENT "relation" ; aeq = tactic_term ; "on" ; a = tactic_term ;
845 refl = OPT [ IDENT "reflexivity" ; IDENT "proved" ; IDENT "by" ;
846 refl = tactic_term -> refl ] ;
847 sym = OPT [ IDENT "symmetry" ; IDENT "proved" ; IDENT "by" ;
848 sym = tactic_term -> sym ] ;
849 trans = OPT [ IDENT "transitivity" ; IDENT "proved" ; IDENT "by" ;
850 trans = tactic_term -> trans ] ;
852 G.Relation (loc,id,a,aeq,refl,sym,trans)
855 IDENT "alias" ; spec = alias_spec ->
857 | IDENT "notation"; (dir, l1, assoc, prec, l2) = notation ->
858 L.Notation (loc, dir, l1, assoc, prec, l2)
859 | IDENT "interpretation"; id = QSTRING;
860 (symbol, args, l3) = interpretation ->
861 L.Interpretation (loc, id, (symbol, args), l3)
864 [ cmd = grafite_command; SYMBOL "." -> G.Command (loc, cmd)
865 | tac = atomic_tactical LEVEL "loops"; punct = punctuation_tactical ->
866 G.Tactic (loc, Some tac, punct)
867 | punct = punctuation_tactical -> G.Tactic (loc, None, punct)
868 | tac = ntactic; punct = punctuation_tactical ->
869 G.NTactic (loc, tac, punct)
870 | SYMBOL "#" ; SYMBOL "#" ; punct = punctuation_tactical ->
871 G.NTactic (loc, G.NId loc, punct)
872 | tac = non_punctuation_tactical; punct = punctuation_tactical ->
873 G.NonPunctuationTactical (loc, tac, punct)
874 | SYMBOL "#" ; SYMBOL "#" ; tac = non_punctuation_tactical; punct = punctuation_tactical ->
875 G.NNonPunctuationTactical (loc, tac, punct)
876 | mac = macro; SYMBOL "." -> G.Macro (loc, mac)
880 [ BEGINCOMMENT ; ex = executable ; ENDCOMMENT ->
888 fun ?(never_include=false) ~include_paths status ->
889 let stm = G.Executable (loc, ex) in
890 !grafite_callback status stm;
893 fun ?(never_include=false) ~include_paths status ->
894 let stm = G.Comment (loc, com) in
895 !grafite_callback status stm;
897 | (iloc,fname,normal,mode) = include_command ; SYMBOL "." ->
898 fun ?(never_include=false) ~include_paths status ->
900 G.Executable (loc, G.Command (loc, G.Include (iloc, normal, fname)))
902 !grafite_callback status stm;
903 let _root, buri, fullpath, _rrelpath =
904 Librarian.baseuri_of_script ~include_paths fname
907 if never_include then raise (NoInclusionPerformed fullpath)
908 else LE.eval_command status (L.Include (iloc,buri,mode,fullpath))
911 G.Executable (loc, G.Command (loc, G.Include (iloc, normal, buri)))
914 | scom = lexicon_command ; SYMBOL "." ->
915 fun ?(never_include=false) ~include_paths status ->
916 !lexicon_callback status scom;
917 let status = LE.eval_command status scom in
919 | EOI -> raise End_of_file
926 let _ = initialize_parser () ;;
928 let exc_located_wrapper f =
932 | Stdpp.Exc_located (_, End_of_file) -> raise End_of_file
933 | Stdpp.Exc_located (floc, Stream.Error msg) ->
934 raise (HExtlib.Localized (floc,CicNotationParser.Parse_error msg))
935 | Stdpp.Exc_located (floc, HExtlib.Localized(_,exn)) ->
937 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
938 | Stdpp.Exc_located (floc, exn) ->
940 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
942 let parse_statement lexbuf =
944 (fun () -> (Grammar.Entry.parse !grafite_parser.statement (Obj.magic lexbuf)))
946 let statement () = !grafite_parser.statement
948 let history = ref [] ;;
952 history := !grafite_parser :: !history;
953 grafite_parser := initial_parser ();
962 grafite_parser := gp;
966 (* vim:set foldmethod=marker: *)