src/Pure/Tools/xml_syntax.ML
author wenzelm
Sat Mar 20 17:33:11 2010 +0100 (2010-03-20)
changeset 35845 e5980f0ad025
parent 33392 73c8987dc9f0
child 38228 ada3ab6b9085
permissions -rw-r--r--
renamed varify/unvarify operations to varify_global/unvarify_global to emphasize that these only work in a global situation;
berghofe@20658
     1
(*  Title:      Pure/Tools/xml_syntax.ML
berghofe@20658
     2
    Author:     Stefan Berghofer, TU Muenchen
berghofe@20658
     3
berghofe@20658
     4
Input and output of types, terms, and proofs in XML format.
berghofe@20658
     5
See isabelle.xsd for a description of the syntax.
berghofe@20658
     6
*)
berghofe@20658
     7
berghofe@20658
     8
signature XML_SYNTAX =
berghofe@20658
     9
sig
berghofe@20658
    10
  val xml_of_type: typ -> XML.tree
berghofe@20658
    11
  val xml_of_term: term -> XML.tree
berghofe@20658
    12
  val xml_of_proof: Proofterm.proof -> XML.tree
wenzelm@21645
    13
  val write_to_file: Path.T -> string -> XML.tree -> unit
berghofe@20658
    14
  exception XML of string * XML.tree
berghofe@20658
    15
  val type_of_xml: XML.tree -> typ
berghofe@20658
    16
  val term_of_xml: XML.tree -> term
berghofe@20658
    17
  val proof_of_xml: XML.tree -> Proofterm.proof
berghofe@20658
    18
end;
berghofe@20658
    19
wenzelm@33392
    20
structure XML_Syntax : XML_SYNTAX =
berghofe@20658
    21
struct
berghofe@20658
    22
berghofe@20658
    23
(**** XML output ****)
berghofe@20658
    24
berghofe@20658
    25
fun xml_of_class name = XML.Elem ("class", [("name", name)], []);
berghofe@20658
    26
berghofe@20658
    27
fun xml_of_type (TVar ((s, i), S)) = XML.Elem ("TVar",
berghofe@20658
    28
      ("name", s) :: (if i=0 then [] else [("index", string_of_int i)]),
berghofe@20658
    29
      map xml_of_class S)
berghofe@20658
    30
  | xml_of_type (TFree (s, S)) =
berghofe@20658
    31
      XML.Elem ("TFree", [("name", s)], map xml_of_class S)
berghofe@20658
    32
  | xml_of_type (Type (s, Ts)) =
berghofe@20658
    33
      XML.Elem ("Type", [("name", s)], map xml_of_type Ts);
berghofe@20658
    34
berghofe@20658
    35
fun xml_of_term (Bound i) =
berghofe@20658
    36
      XML.Elem ("Bound", [("index", string_of_int i)], [])
berghofe@20658
    37
  | xml_of_term (Free (s, T)) =
berghofe@20658
    38
      XML.Elem ("Free", [("name", s)], [xml_of_type T])
berghofe@20658
    39
  | xml_of_term (Var ((s, i), T)) = XML.Elem ("Var",
berghofe@20658
    40
      ("name", s) :: (if i=0 then [] else [("index", string_of_int i)]),
berghofe@20658
    41
      [xml_of_type T])
berghofe@20658
    42
  | xml_of_term (Const (s, T)) =
berghofe@20658
    43
      XML.Elem ("Const", [("name", s)], [xml_of_type T])
berghofe@20658
    44
  | xml_of_term (t $ u) =
berghofe@20658
    45
      XML.Elem ("App", [], [xml_of_term t, xml_of_term u])
berghofe@20658
    46
  | xml_of_term (Abs (s, T, t)) =
berghofe@20658
    47
      XML.Elem ("Abs", [("vname", s)], [xml_of_type T, xml_of_term t]);
berghofe@20658
    48
berghofe@20658
    49
fun xml_of_opttypes NONE = []
berghofe@20658
    50
  | xml_of_opttypes (SOME Ts) = [XML.Elem ("types", [], map xml_of_type Ts)];
berghofe@20658
    51
berghofe@20658
    52
(* FIXME: the t argument of PThm and PAxm is actually redundant, since *)
berghofe@20658
    53
(* it can be looked up in the theorem database. Thus, it could be      *)
berghofe@20658
    54
(* omitted from the xml representation.                                *)
berghofe@20658
    55
berghofe@20658
    56
fun xml_of_proof (PBound i) =
berghofe@20658
    57
      XML.Elem ("PBound", [("index", string_of_int i)], [])
berghofe@20658
    58
  | xml_of_proof (Abst (s, optT, prf)) =
berghofe@20658
    59
      XML.Elem ("Abst", [("vname", s)],
berghofe@20658
    60
        (case optT of NONE => [] | SOME T => [xml_of_type T]) @
berghofe@20658
    61
        [xml_of_proof prf])
berghofe@20658
    62
  | xml_of_proof (AbsP (s, optt, prf)) =
berghofe@20658
    63
      XML.Elem ("AbsP", [("vname", s)],
berghofe@20658
    64
        (case optt of NONE => [] | SOME t => [xml_of_term t]) @
berghofe@20658
    65
        [xml_of_proof prf])
berghofe@20658
    66
  | xml_of_proof (prf % optt) =
berghofe@20658
    67
      XML.Elem ("Appt", [],
berghofe@20658
    68
        xml_of_proof prf ::
berghofe@20658
    69
        (case optt of NONE => [] | SOME t => [xml_of_term t]))
berghofe@20658
    70
  | xml_of_proof (prf %% prf') =
berghofe@20658
    71
      XML.Elem ("AppP", [], [xml_of_proof prf, xml_of_proof prf'])
berghofe@20658
    72
  | xml_of_proof (Hyp t) = XML.Elem ("Hyp", [], [xml_of_term t])
wenzelm@28811
    73
  | xml_of_proof (PThm (_, ((s, t, optTs), _))) =
berghofe@20658
    74
      XML.Elem ("PThm", [("name", s)], xml_of_term t :: xml_of_opttypes optTs)
berghofe@20658
    75
  | xml_of_proof (PAxm (s, t, optTs)) =
berghofe@20658
    76
      XML.Elem ("PAxm", [("name", s)], xml_of_term t :: xml_of_opttypes optTs)
berghofe@20658
    77
  | xml_of_proof (Oracle (s, t, optTs)) =
berghofe@20658
    78
      XML.Elem ("Oracle", [("name", s)], xml_of_term t :: xml_of_opttypes optTs)
wenzelm@28811
    79
  | xml_of_proof MinProof =
berghofe@20658
    80
      XML.Elem ("MinProof", [], []);
berghofe@20658
    81
berghofe@20658
    82
(* useful for checking the output against a schema file *)
berghofe@20658
    83
wenzelm@21645
    84
fun write_to_file path elname x =
wenzelm@21645
    85
  File.write path
berghofe@20658
    86
    ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ^
wenzelm@26544
    87
     XML.string_of (XML.Elem (elname,
berghofe@20658
    88
       [("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"),
berghofe@20658
    89
        ("xsi:noNamespaceSchemaLocation", "isabelle.xsd")],
berghofe@20658
    90
       [x])));
berghofe@20658
    91
berghofe@20658
    92
berghofe@20658
    93
(**** XML input ****)
berghofe@20658
    94
berghofe@20658
    95
exception XML of string * XML.tree;
berghofe@20658
    96
berghofe@20658
    97
fun class_of_xml (XML.Elem ("class", [("name", name)], [])) = name
berghofe@20658
    98
  | class_of_xml tree = raise XML ("class_of_xml: bad tree", tree);
berghofe@20658
    99
berghofe@20658
   100
fun index_of_string s tree idx = (case Int.fromString idx of
berghofe@20658
   101
  NONE => raise XML (s ^ ": bad index", tree) | SOME i => i);
berghofe@20658
   102
berghofe@20658
   103
fun type_of_xml (tree as XML.Elem ("TVar", atts, classes)) = TVar
wenzelm@28017
   104
      ((case Properties.get atts "name" of
berghofe@20658
   105
          NONE => raise XML ("type_of_xml: name of TVar missing", tree)
berghofe@20658
   106
        | SOME name => name,
berghofe@20658
   107
        the_default 0 (Option.map (index_of_string "type_of_xml" tree)
wenzelm@28017
   108
          (Properties.get atts "index"))),
berghofe@20658
   109
       map class_of_xml classes)
berghofe@20658
   110
  | type_of_xml (XML.Elem ("TFree", [("name", s)], classes)) =
berghofe@20658
   111
      TFree (s, map class_of_xml classes)
berghofe@20658
   112
  | type_of_xml (XML.Elem ("Type", [("name", s)], types)) =
berghofe@20658
   113
      Type (s, map type_of_xml types)
berghofe@20658
   114
  | type_of_xml tree = raise XML ("type_of_xml: bad tree", tree);
berghofe@20658
   115
berghofe@20658
   116
fun term_of_xml (tree as XML.Elem ("Bound", [("index", idx)], [])) =
berghofe@20658
   117
      Bound (index_of_string "bad variable index" tree idx)
berghofe@20658
   118
  | term_of_xml (XML.Elem ("Free", [("name", s)], [typ])) =
berghofe@20658
   119
      Free (s, type_of_xml typ)
berghofe@20658
   120
  | term_of_xml (tree as XML.Elem ("Var", atts, [typ])) = Var
wenzelm@28017
   121
      ((case Properties.get atts "name" of
berghofe@20658
   122
          NONE => raise XML ("type_of_xml: name of Var missing", tree)
berghofe@20658
   123
        | SOME name => name,
berghofe@20658
   124
        the_default 0 (Option.map (index_of_string "term_of_xml" tree)
wenzelm@28017
   125
          (Properties.get atts "index"))),
berghofe@20658
   126
       type_of_xml typ)
berghofe@20658
   127
  | term_of_xml (XML.Elem ("Const", [("name", s)], [typ])) =
berghofe@20658
   128
      Const (s, type_of_xml typ)
berghofe@20658
   129
  | term_of_xml (XML.Elem ("App", [], [term, term'])) =
berghofe@20658
   130
      term_of_xml term $ term_of_xml term'
berghofe@20658
   131
  | term_of_xml (XML.Elem ("Abs", [("vname", s)], [typ, term])) =
berghofe@20658
   132
      Abs (s, type_of_xml typ, term_of_xml term)
berghofe@20658
   133
  | term_of_xml tree = raise XML ("term_of_xml: bad tree", tree);
berghofe@20658
   134
berghofe@20658
   135
fun opttypes_of_xml [] = NONE
berghofe@20658
   136
  | opttypes_of_xml [XML.Elem ("types", [], types)] =
berghofe@20658
   137
      SOME (map type_of_xml types)
berghofe@20658
   138
  | opttypes_of_xml (tree :: _) = raise XML ("opttypes_of_xml: bad tree", tree);
berghofe@20658
   139
berghofe@20658
   140
fun proof_of_xml (tree as XML.Elem ("PBound", [("index", idx)], [])) =
berghofe@20658
   141
      PBound (index_of_string "proof_of_xml" tree idx)
berghofe@20658
   142
  | proof_of_xml (XML.Elem ("Abst", [("vname", s)], [proof])) =
berghofe@20658
   143
      Abst (s, NONE, proof_of_xml proof)
berghofe@20658
   144
  | proof_of_xml (XML.Elem ("Abst", [("vname", s)], [typ, proof])) =
berghofe@20658
   145
      Abst (s, SOME (type_of_xml typ), proof_of_xml proof)
berghofe@20658
   146
  | proof_of_xml (XML.Elem ("AbsP", [("vname", s)], [proof])) =
berghofe@20658
   147
      AbsP (s, NONE, proof_of_xml proof)
berghofe@20658
   148
  | proof_of_xml (XML.Elem ("AbsP", [("vname", s)], [term, proof])) =
berghofe@20658
   149
      AbsP (s, SOME (term_of_xml term), proof_of_xml proof)
berghofe@20658
   150
  | proof_of_xml (XML.Elem ("Appt", [], [proof])) =
berghofe@20658
   151
      proof_of_xml proof % NONE
berghofe@20658
   152
  | proof_of_xml (XML.Elem ("Appt", [], [proof, term])) =
berghofe@20658
   153
      proof_of_xml proof % SOME (term_of_xml term)
berghofe@20658
   154
  | proof_of_xml (XML.Elem ("AppP", [], [proof, proof'])) =
berghofe@20658
   155
      proof_of_xml proof %% proof_of_xml proof'
berghofe@23831
   156
  | proof_of_xml (XML.Elem ("Hyp", [], [term])) =
berghofe@23831
   157
      Hyp (term_of_xml term)
berghofe@20658
   158
  | proof_of_xml (XML.Elem ("PThm", [("name", s)], term :: opttypes)) =
wenzelm@28811
   159
      (* FIXME? *)
wenzelm@28811
   160
      PThm (serial (), ((s, term_of_xml term, opttypes_of_xml opttypes),
wenzelm@30718
   161
        Future.value (Proofterm.approximate_proof_body MinProof)))
berghofe@20658
   162
  | proof_of_xml (XML.Elem ("PAxm", [("name", s)], term :: opttypes)) =
berghofe@20658
   163
      PAxm (s, term_of_xml term, opttypes_of_xml opttypes)
berghofe@20658
   164
  | proof_of_xml (XML.Elem ("Oracle", [("name", s)], term :: opttypes)) =
berghofe@20658
   165
      Oracle (s, term_of_xml term, opttypes_of_xml opttypes)
wenzelm@28811
   166
  | proof_of_xml (XML.Elem ("MinProof", _, _)) = MinProof
berghofe@20658
   167
  | proof_of_xml tree = raise XML ("proof_of_xml: bad tree", tree);
berghofe@20658
   168
berghofe@20658
   169
end;