]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/grafite_parser/grafiteParser.ml
initial implementation of `ncoercion name : type := body on name : pat to pat`
[helm.git] / helm / software / components / grafite_parser / grafiteParser.ml
index 324231b50db3e0bdc9655036535acc93f9f8fbe1..dfef4d237a0ea34c8883b2b23b1e734fb46b8fcd 100644 (file)
@@ -39,20 +39,22 @@ type 'a localized_option =
 type ast_statement =
   (N.term, N.term, N.term G.reduction, N.term N.obj, string) G.statement
 
-type statement =
-  ?never_include:bool -> include_paths:string list -> LE.status ->
-    LE.status * ast_statement localized_option
+type 'status statement =
+  ?never_include:bool -> 
+    (* do not call LexiconEngine to do includes, always raise NoInclusionPerformed *) 
+  include_paths:string list -> (#LE.status as 'status) ->
+    'status * ast_statement localized_option
 
-type parser_status = {
+type 'status parser_status = {
   grammar : Grammar.g;
   term : N.term Grammar.Entry.e;
-  statement : statement Grammar.Entry.e;
+  statement : #LE.status as 'status statement Grammar.Entry.e;
 }
 
-let grafite_callback = ref (fun _ -> ())
+let grafite_callback = ref (fun _ -> ())
 let set_grafite_callback cb = grafite_callback := cb
 
-let lexicon_callback = ref (fun _ -> ())
+let lexicon_callback = ref (fun _ -> ())
 let set_lexicon_callback cb = lexicon_callback := cb
 
 let initial_parser () = 
@@ -68,7 +70,7 @@ let add_raw_attribute ~text t = N.AttributedTerm (`Raw text, t)
 
 let default_associativity = Gramext.NonA
         
-let mk_rec_corec ng ind_kind defs loc = 
+let mk_rec_corec ind_kind defs loc = 
  (* In case of mutual definitions here we produce just
     the syntax tree for the first one. The others will be
     generated from the completely specified term just before
@@ -76,15 +78,14 @@ let mk_rec_corec ng ind_kind defs loc =
     `MutualDefinition to rememer this. *)
   let name,ty = 
     match defs with
-    | (params,(N.Ident (name, None), Some ty),_,_) :: _ ->
+    | (params,(N.Ident (name, None), ty),_,_) :: _ ->
+        let ty = match ty with Some ty -> ty | None -> N.Implicit in
         let ty =
          List.fold_right
           (fun var ty -> N.Binder (`Pi,var,ty)
           ) params ty
         in
          name,ty
-    | (_,(N.Ident (name, None), None),_,_) :: _ ->
-        name, N.Implicit
     | _ -> assert false 
   in
   let body = N.Ident (name,None) in
@@ -94,12 +95,39 @@ let mk_rec_corec ng ind_kind defs loc =
    else
     `MutualDefinition
   in
-   if ng then
-    G.NObj (loc, N.Theorem(flavour, name, ty,
-     Some (N.LetRec (ind_kind, defs, body))))
-   else
-    G.Obj (loc, N.Theorem(flavour, name, ty,
-     Some (N.LetRec (ind_kind, defs, body))))
+   (loc, N.Theorem(flavour, name, ty, Some (N.LetRec (ind_kind, defs, body))))
+
+let nmk_rec_corec ind_kind defs loc = 
+ let loc,t = mk_rec_corec ind_kind defs loc in
+  G.NObj (loc,t)
+
+let mk_rec_corec ind_kind defs loc = 
+ let loc,t = mk_rec_corec ind_kind defs loc in
+  G.Obj (loc,t)
+
+let npunct_of_punct = function
+  | G.Branch loc -> G.NBranch loc
+  | G.Shift loc -> G.NShift loc
+  | G.Pos (loc, i) -> G.NPos (loc, i)
+  | G.Wildcard loc -> G.NWildcard loc
+  | G.Merge loc -> G.NMerge loc
+  | G.Semicolon loc -> G.NSemicolon loc
+  | G.Dot loc -> G.NDot loc
+;;
+let nnon_punct_of_punct = function
+  | G.Skip loc -> G.NSkip loc
+  | G.Unfocus loc -> G.NUnfocus loc
+  | G.Focus (loc,l) -> G.NFocus (loc,l)
+;;
+let npunct_of_punct = function
+  | G.Branch loc -> G.NBranch loc
+  | G.Shift loc -> G.NShift loc
+  | G.Pos (loc, i) -> G.NPos (loc, i)
+  | G.Wildcard loc -> G.NWildcard loc
+  | G.Merge loc -> G.NMerge loc
+  | G.Semicolon loc -> G.NSemicolon loc
+  | G.Dot loc -> G.NDot loc
+;;
 
 type by_continuation =
    BYC_done
@@ -118,8 +146,8 @@ EXTEND
   constructor: [ [ name = IDENT; SYMBOL ":"; typ = term -> (name, typ) ] ];
   tactic_term: [ [ t = term LEVEL "90" -> t ] ];
   new_name: [
-    [ id = IDENT -> Some id
-    | SYMBOL "_" -> None ]
+    [ SYMBOL "_" -> None
+    | id = IDENT -> Some id ]
     ];
   ident_list0: [ [ LPAREN; idents = LIST0 new_name; RPAREN -> idents ] ];
   tactic_term_list1: [
@@ -131,6 +159,15 @@ EXTEND
     | IDENT "unfold"; t = OPT tactic_term -> `Unfold t
     | IDENT "whd" -> `Whd ]
   ];
+  nreduction_kind: [
+    [ IDENT "nnormalize" ; delta = OPT [ IDENT "nodelta" -> () ] ->
+       let delta = match delta with None -> true | _ -> false in
+        `Normalize delta
+    (*| IDENT "unfold"; t = OPT tactic_term -> `Unfold t*)
+    | IDENT "nwhd" ; delta = OPT [ IDENT "nodelta" -> () ] ->
+       let delta = match delta with None -> true | _ -> false in
+        `Whd delta]
+  ];
   sequent_pattern_spec: [
    [ hyp_paths =
       LIST0
@@ -211,6 +248,7 @@ EXTEND
         SYMBOL <:unicode<vdash>>;
         concl = tactic_term -> (List.rev hyps,concl) ] ->
          G.NAssert (loc, seqs)
+    | IDENT "nauto"; params = auto_params -> G.NAuto (loc, params)
     | IDENT "ncases"; what = tactic_term ; where = pattern_spec ->
         G.NCases (loc, what, where)
     | IDENT "nchange"; what = pattern_spec; "with"; with_what = tactic_term -> 
@@ -222,12 +260,14 @@ EXTEND
     | IDENT "nletin"; name = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term;
         where = pattern_spec ->
         G.NLetIn (loc,where,t,name)
-    | IDENT "nrewrite"; dir = direction; what = tactic_term ; where = pattern_spec ->
+    | kind = nreduction_kind; p = pattern_spec ->
+        G.NReduce (loc, kind, p)
+    | IDENT "nrewrite"; dir = direction; what = tactic_term ; where = pattern_spec ->  
         G.NRewrite (loc, dir, what, where)
-    | IDENT "nwhd"; delta = OPT [ IDENT "nodelta" -> () ];
-      where = pattern_spec ->
-        let delta = match delta with None -> true | _ -> false in
-        G.NEval (loc, where, `Whd delta)
+    | IDENT "ntry"; tac = SELF -> G.NTry (loc,tac)
+    | IDENT "nrepeat"; tac = SELF -> G.NRepeat (loc,tac)
+    | LPAREN; l = LIST1 SELF; RPAREN -> G.NBlock (loc,l)
+    | IDENT "nassumption" -> G.NAssumption loc
     | SYMBOL "#"; n=IDENT -> G.NIntro (loc,n)
     | SYMBOL "#"; SYMBOL "_" -> G.NIntro (loc,"_")
     | SYMBOL "*" -> G.NCase1 (loc,"_")
@@ -436,7 +476,6 @@ EXTEND
    | IDENT "timeout"
    | IDENT "library"
    | IDENT "type"
-   | IDENT "steps"
    | IDENT "all"
    ]
 ];
@@ -450,6 +489,21 @@ EXTEND
       (match tl with Some l -> l | None -> []),
       params
    ]
+];
+  inline_params:[
+   [ params = LIST0 
+      [ IDENT "prefix"; SYMBOL "="; prefix = QSTRING -> G.IPPrefix prefix  
+      | flavour = inline_flavour -> G.IPAs flavour
+      | IDENT "coercions" -> G.IPCoercions
+      | IDENT "debug"; SYMBOL "="; debug = int -> G.IPDebug debug 
+      | IDENT "procedural" -> G.IPProcedural
+      | IDENT "nodefaults" -> G.IPNoDefaults
+      | IDENT "depth"; SYMBOL "="; depth = int -> G.IPDepth depth 
+      | IDENT "level"; SYMBOL "="; level = int -> G.IPLevel level 
+      | IDENT "comments" -> G.IPComments
+      | IDENT "cr" -> G.IPCR
+      ] -> params
+   ]
 ];
   by_continuation: [
     [ 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)
@@ -501,6 +555,17 @@ EXTEND
       | tac = tactic -> tac
         ]
       ];
+  npunctuation_tactical:
+    [
+      [ SYMBOL "[" -> G.NBranch loc
+      | SYMBOL "|" -> G.NShift loc
+      | i = LIST1 int SEP SYMBOL ","; SYMBOL ":" -> G.NPos (loc, i)
+      | SYMBOL "*"; SYMBOL ":" -> G.NWildcard loc
+      | SYMBOL "]" -> G.NMerge loc
+      | SYMBOL ";" -> G.NSemicolon loc
+      | SYMBOL "." -> G.NDot loc
+      ]
+    ];
   punctuation_tactical:
     [
       [ SYMBOL "[" -> G.Branch loc
@@ -538,7 +603,7 @@ EXTEND
   inline_flavour: [
      [ attr = theorem_flavour -> attr
      | [ IDENT "axiom"     ]  -> `Axiom
-     | [ IDENT "mutual"    ]  -> `MutualDefinition
+     | [ IDENT "variant"   ]  -> `Variant
      ]
   ];
   inductive_spec: [ [
@@ -593,16 +658,8 @@ EXTEND
           G.Check (loc, t)
       | [ IDENT "eval" ]; kind = reduction_kind; "on"; t = tactic_term ->
           G.Eval (loc, kind, t)
-      | [ IDENT "inline"]; 
-          style = OPT [ IDENT "procedural"; depth = OPT int -> depth ];
-          suri = QSTRING; prefix = OPT QSTRING;
-          flavour = OPT [ "as"; attr = inline_flavour -> attr ] ->
-           let style = match style with 
-              | None       -> G.Declarative
-              | Some depth -> G.Procedural depth
-           in
-           let prefix = match prefix with None -> "" | Some prefix -> prefix in
-           G.Inline (loc,style,suri,prefix, flavour)
+      | IDENT "inline"; suri = QSTRING; params = inline_params -> 
+           G.Inline (loc, suri, params)
       | [ IDENT "hint" ]; rew = OPT (IDENT "rewrite")  -> 
            if rew = None then G.Hint (loc, false) else G.Hint (loc,true)
       | IDENT "auto"; params = auto_params ->
@@ -655,7 +712,7 @@ EXTEND
           in
           L.Number_alias (instance, dsc)
       ]
-    ];
+     ];
     argument: [
       [ l = LIST0 [ SYMBOL <:unicode<eta>> (* η *); SYMBOL "." -> () ];
         id = IDENT ->
@@ -700,8 +757,9 @@ EXTEND
     ];
     level3_term: [
       [ u = URI -> N.UriPattern (UriManager.uri_of_string u)
+      | r = NREF -> N.NRefPattern (NReference.reference_of_string r)
+      | IMPLICIT -> N.ImplicitPattern
       | id = IDENT -> N.VarPattern id
-      | SYMBOL "_" -> N.ImplicitPattern
       | LPAREN; terms = LIST1 SELF; RPAREN ->
           (match terms with
           | [] -> assert false
@@ -717,26 +775,80 @@ EXTEND
     
     include_command: [ [
         IDENT "include" ; path = QSTRING -> 
-          loc,path,L.WithPreferences
+          loc,path,true,L.WithPreferences
+      | IDENT "include" ; IDENT "source" ; path = QSTRING -> 
+          loc,path,false,L.WithPreferences       
       | IDENT "include'" ; path = QSTRING -> 
-          loc,path,L.WithoutPreferences
+          loc,path,true,L.WithoutPreferences
      ]];
 
+  grafite_ncommand: [ [
+      IDENT "nqed" -> G.NQed loc
+    | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
+      body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
+        G.NObj (loc, N.Theorem (nflavour, name, typ, body))
+    | nflavour = ntheorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
+      body = term ->
+        G.NObj (loc, N.Theorem (nflavour, name, N.Implicit, Some body))
+    | IDENT "naxiom"; name = IDENT; SYMBOL ":"; typ = term ->
+        G.NObj (loc, N.Theorem (`Axiom, name, typ, None))
+    | NLETCOREC ; defs = let_defs -> 
+        nmk_rec_corec `CoInductive defs loc
+    | NLETREC ; defs = let_defs -> 
+        nmk_rec_corec `Inductive defs loc
+    | IDENT "ninductive"; spec = inductive_spec ->
+        let (params, ind_types) = spec in
+        G.NObj (loc, N.Inductive (params, ind_types))
+    | IDENT "ncoinductive"; spec = inductive_spec ->
+        let (params, ind_types) = spec in
+        let ind_types = (* set inductive flags to false (coinductive) *)
+          List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
+            ind_types
+        in
+        G.NObj (loc, N.Inductive (params, ind_types))
+    | IDENT "universe"; IDENT "constraint"; u1 = tactic_term; 
+        strict = [ SYMBOL <:unicode<lt>> -> true 
+                 | SYMBOL <:unicode<leq>> -> false ]; 
+        u2 = tactic_term ->
+        let u1 =
+          match u1 with
+          | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NType i)) ->
+              NUri.uri_of_string ("cic:/matita/pts/Type"^i^".univ")
+          | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NCProp i)) ->
+              NUri.uri_of_string ("cic:/matita/pts/CProp"^i^".univ")
+          | _ -> raise (Failure "only a sort can be constrained")
+        in
+        let u2 =
+          match u2 with
+          | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NType i)) ->
+              NUri.uri_of_string ("cic:/matita/pts/Type"^i^".univ")
+          | CicNotationPt.AttributedTerm (_, CicNotationPt.Sort (`NCProp i)) ->
+              NUri.uri_of_string ("cic:/matita/pts/CProp"^i^".univ")
+          | _ -> raise (Failure "only a sort can be constrained")
+        in
+         G.NUnivConstraint (loc, strict,u1,u2)
+    | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
+        G.UnificationHint (loc, t, n)
+    | IDENT "ncoercion"; name = IDENT; SYMBOL ":"; ty = term; 
+        SYMBOL <:unicode<def>>; t = term; "on"; 
+        id = [ IDENT | PIDENT ]; SYMBOL ":"; source = term;
+        "to"; target = term ->
+          G.NCoercion(loc,name,t,ty,(id,source),target)     
+    | IDENT "nrecord" ; (params,name,ty,fields) = record_spec ->
+        G.NObj (loc, N.Record (params,name,ty,fields))
+  ]];
+
   grafite_command: [ [
       IDENT "set"; n = QSTRING; v = QSTRING ->
         G.Set (loc, n, v)
     | IDENT "drop" -> G.Drop loc
     | IDENT "print"; s = IDENT -> G.Print (loc,s)
     | IDENT "qed" -> G.Qed loc
-    | IDENT "nqed" -> G.NQed loc
     | IDENT "variant" ; name = IDENT; SYMBOL ":"; 
       typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
         G.Obj (loc, 
           N.Theorem 
             (`Variant,name,typ,Some (N.Ident (newname, None))))
-    | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
-      body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
-        G.NObj (loc, N.Theorem (nflavour, name, typ, body))
     | flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
       body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
         G.Obj (loc, N.Theorem (flavour, name, typ, body))
@@ -746,22 +858,13 @@ EXTEND
           N.Theorem (flavour, name, N.Implicit, Some body))
     | IDENT "axiom"; name = IDENT; SYMBOL ":"; typ = term ->
         G.Obj (loc, N.Theorem (`Axiom, name, typ, None))
-    | IDENT "naxiom"; name = IDENT; SYMBOL ":"; typ = term ->
-        G.NObj (loc, N.Theorem (`Axiom, name, typ, None))
     | LETCOREC ; defs = let_defs -> 
-        mk_rec_corec false `CoInductive defs loc
+        mk_rec_corec `CoInductive defs loc
     | LETREC ; defs = let_defs -> 
-        mk_rec_corec false `Inductive defs loc
-    | NLETCOREC ; defs = let_defs -> 
-        mk_rec_corec true `CoInductive defs loc
-    | NLETREC ; defs = let_defs -> 
-        mk_rec_corec true `Inductive defs loc
+        mk_rec_corec `Inductive defs loc
     | IDENT "inductive"; spec = inductive_spec ->
         let (params, ind_types) = spec in
         G.Obj (loc, N.Inductive (params, ind_types))
-    | IDENT "ninductive"; spec = inductive_spec ->
-        let (params, ind_types) = spec in
-        G.NObj (loc, N.Inductive (params, ind_types))
     | IDENT "coinductive"; spec = inductive_spec ->
         let (params, ind_types) = spec in
         let ind_types = (* set inductive flags to false (coinductive) *)
@@ -769,13 +872,6 @@ EXTEND
             ind_types
         in
         G.Obj (loc, N.Inductive (params, ind_types))
-    | IDENT "ncoinductive"; spec = inductive_spec ->
-        let (params, ind_types) = spec in
-        let ind_types = (* set inductive flags to false (coinductive) *)
-          List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
-            ind_types
-        in
-        G.NObj (loc, N.Inductive (params, ind_types))
     | IDENT "coercion" ; 
       t = [ u = URI -> N.Uri (u,None) | t = tactic_term ; OPT "with" -> t ] ;
       arity = OPT int ; saturations = OPT int; 
@@ -789,13 +885,11 @@ EXTEND
         G.PreferCoercion (loc, t)
     | IDENT "pump" ; steps = int ->
         G.Pump(loc,steps)
-    | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
-        G.UnificationHint (loc, t, n)
     | IDENT "inverter"; name = IDENT; IDENT "for";
         indty = tactic_term; paramspec = inverter_param_list ->
           G.Inverter
             (loc, name, indty, paramspec)
-            | IDENT "record" ; (params,name,ty,fields) = record_spec ->
+    | IDENT "record" ; (params,name,ty,fields) = record_spec ->
         G.Obj (loc, N.Record (params,name,ty,fields))
     | IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
        let uris = List.map UriManager.uri_of_string uris in
@@ -821,15 +915,24 @@ EXTEND
   ]];
   executable: [
     [ cmd = grafite_command; SYMBOL "." -> G.Command (loc, cmd)
+    | ncmd = grafite_ncommand; SYMBOL "." -> G.NCommand (loc, ncmd)
     | tac = atomic_tactical LEVEL "loops"; punct = punctuation_tactical ->
         G.Tactic (loc, Some tac, punct)
     | punct = punctuation_tactical -> G.Tactic (loc, None, punct)
+    | tac = ntactic; SYMBOL "#" ; SYMBOL "#" ; punct = punctuation_tactical ->
+        G.NTactic (loc, [tac; npunct_of_punct punct])
     | tac = ntactic; punct = punctuation_tactical ->
-        G.NTactic (loc, tac, punct)
-    | SYMBOL "#" ; SYMBOL "#" ; punct = punctuation_tactical ->
-        G.NTactic (loc, G.NId loc, punct)
+        G.NTactic (loc, [tac; npunct_of_punct punct])
+    | SYMBOL "#" ; SYMBOL "#" ; punct = npunctuation_tactical ->
+        G.NTactic (loc, [punct])
     | tac = non_punctuation_tactical; punct = punctuation_tactical ->
         G.NonPunctuationTactical (loc, tac, punct)
+    | SYMBOL "#" ; SYMBOL "#" ; tac = non_punctuation_tactical; 
+        SYMBOL "#" ; SYMBOL "#" ; punct = punctuation_tactical ->
+          G.NTactic (loc, [nnon_punct_of_punct tac; npunct_of_punct punct])
+    | SYMBOL "#" ; SYMBOL "#" ; tac = non_punctuation_tactical; 
+        punct = punctuation_tactical ->
+          G.NTactic (loc, [nnon_punct_of_punct tac; npunct_of_punct punct])
     | mac = macro; SYMBOL "." -> G.Macro (loc, mac)
     ]
   ];
@@ -844,33 +947,35 @@ EXTEND
     [ ex = executable ->
        fun ?(never_include=false) ~include_paths status ->
           let stm = G.Executable (loc, ex) in
-          !grafite_callback status stm;
+          !grafite_callback stm;
          status, LSome stm
     | com = comment ->
        fun ?(never_include=false) ~include_paths status -> 
           let stm = G.Comment (loc, com) in
-          !grafite_callback status stm;
+          !grafite_callback stm;
          status, LSome stm
-    | (iloc,fname,mode) = include_command ; SYMBOL "."  ->
+    | (iloc,fname,normal,mode) = include_command ; SYMBOL "."  ->
        fun ?(never_include=false) ~include_paths status ->
+       let _root, buri, fullpath, _rrelpath = 
+          Librarian.baseuri_of_script ~include_paths fname in
+        if never_include then raise (NoInclusionPerformed fullpath)
+        else
+         begin
          let stm =
-            G.Executable (loc, G.Command (loc, G.Include (iloc, fname)))
-         in
-          !grafite_callback status stm;
-         let _root, buri, fullpath, _rrelpath = 
-            Librarian.baseuri_of_script ~include_paths fname 
-          in
+          G.Executable
+            (loc, G.Command (loc, G.Include (iloc,normal,`OldAndNew,fname))) in
+          !grafite_callback stm;
+         let status =
+           LE.eval_command status (L.Include (iloc,buri,mode,fullpath)) in
           let stm =
-            G.Executable (loc, G.Command (loc, G.Include (iloc, buri)))
+          G.Executable
+            (loc,G.Command (loc,G.Include (iloc,normal,`OldAndNew,buri)))
          in
-         let status =
-            if never_include then raise (NoInclusionPerformed fullpath)
-            else LE.eval_command status (L.Include (iloc,buri,mode,fullpath))
-          in
-         status, LSome stm
+          status, LSome stm
+         end
     | scom = lexicon_command ; SYMBOL "." ->
        fun ?(never_include=false) ~include_paths status ->
-          !lexicon_callback status scom;         
+          !lexicon_callback scom;        
          let status = LE.eval_command status scom in
           status, LNone loc
     | EOI -> raise End_of_file
@@ -898,9 +1003,9 @@ let exc_located_wrapper f =
 
 let parse_statement lexbuf =
   exc_located_wrapper
-    (fun () -> (Grammar.Entry.parse !grafite_parser.statement (Obj.magic lexbuf)))
+    (fun () -> (Grammar.Entry.parse (Obj.magic !grafite_parser.statement) (Obj.magic lexbuf)))
 
-let statement () = !grafite_parser.statement
+let statement () = Obj.magic !grafite_parser.statement
 
 let history = ref [] ;;