src/HOL/Library/Code_Test.thy
author Andreas Lochbihler
Wed Oct 08 09:09:12 2014 +0200 (2014-10-08)
changeset 58626 6c473ed0ac70
parent 58348 src/HOL/Codegenerator_Test/Code_Test.thy@2d47c7d10b62
child 58637 3094b0edd6b5
permissions -rw-r--r--
move Code_Test to HOL/Library;
add corresponding entries in NEWS and CONTRIBUTORS
Andreas@58039
     1
(*  Title:      Code_Test.thy
Andreas@58039
     2
    Author:     Andreas Lochbihler, ETH Zurich
Andreas@58039
     3
Andreas@58039
     4
Test infrastructure for the code generator
Andreas@58039
     5
*)
Andreas@58039
     6
Andreas@58039
     7
theory Code_Test
Andreas@58039
     8
imports Main
Andreas@58348
     9
keywords "test_code" :: diag
Andreas@58039
    10
begin
Andreas@58039
    11
Andreas@58039
    12
subsection {* YXML encoding for @{typ Code_Evaluation.term} *}
Andreas@58039
    13
Andreas@58626
    14
datatype (plugins del: code size "quickcheck") yxml_of_term = YXML
Andreas@58039
    15
Andreas@58039
    16
lemma yot_anything: "x = (y :: yxml_of_term)"
Andreas@58039
    17
by(cases x y rule: yxml_of_term.exhaust[case_product yxml_of_term.exhaust])(simp)
Andreas@58039
    18
Andreas@58039
    19
definition yot_empty :: yxml_of_term where [code del]: "yot_empty = YXML"
Andreas@58039
    20
definition yot_literal :: "String.literal \<Rightarrow> yxml_of_term"
Andreas@58039
    21
  where [code del]: "yot_literal _ = YXML"
Andreas@58039
    22
definition yot_append :: "yxml_of_term \<Rightarrow> yxml_of_term \<Rightarrow> yxml_of_term"
Andreas@58039
    23
  where [code del]: "yot_append _ _ = YXML"
Andreas@58039
    24
definition yot_concat :: "yxml_of_term list \<Rightarrow> yxml_of_term"
Andreas@58039
    25
  where [code del]: "yot_concat _ = YXML"
Andreas@58039
    26
Andreas@58039
    27
text {* Serialise @{typ yxml_of_term} to native string of target language *}
Andreas@58039
    28
Andreas@58039
    29
code_printing type_constructor yxml_of_term
Andreas@58039
    30
  \<rightharpoonup>  (SML) "string"
Andreas@58039
    31
  and (OCaml) "string"
Andreas@58039
    32
  and (Haskell) "String"
Andreas@58039
    33
  and (Scala) "String"
Andreas@58039
    34
| constant yot_empty
Andreas@58039
    35
  \<rightharpoonup>  (SML) "\"\""
Andreas@58039
    36
  and (OCaml) "\"\""
Andreas@58039
    37
  and (Haskell) "\"\""
Andreas@58039
    38
  and (Scala) "\"\""
Andreas@58039
    39
| constant yot_literal
Andreas@58039
    40
  \<rightharpoonup>  (SML) "_"
Andreas@58039
    41
  and (OCaml) "_"
Andreas@58039
    42
  and (Haskell) "_"
Andreas@58039
    43
  and (Scala) "_"
Andreas@58039
    44
| constant yot_append
Andreas@58039
    45
  \<rightharpoonup> (SML) "String.concat [(_), (_)]"
Andreas@58039
    46
  and (OCaml) "String.concat \"\" [(_); (_)]"
Andreas@58039
    47
  and (Haskell) infixr 5 "++"
Andreas@58039
    48
  and (Scala) infixl 5 "+"
Andreas@58039
    49
| constant yot_concat
Andreas@58039
    50
  \<rightharpoonup> (SML) "String.concat"
Andreas@58039
    51
  and (OCaml) "String.concat \"\""
Andreas@58039
    52
  and (Haskell) "Prelude.concat"
Andreas@58039
    53
  and (Scala) "_.mkString(\"\")"
Andreas@58039
    54
Andreas@58039
    55
text {*
Andreas@58039
    56
  Stripped-down implementations of Isabelle's XML tree with YXML encoding
Andreas@58039
    57
  as defined in @{file "~~/src/Pure/PIDE/xml.ML"}, @{file "~~/src/Pure/PIDE/yxml.ML"}
Andreas@58039
    58
  sufficient to encode @{typ "Code_Evaluation.term"} as in @{file "~~/src/Pure/term_xml.ML"}.
Andreas@58039
    59
*}
Andreas@58039
    60
Andreas@58626
    61
datatype (plugins del: code size "quickcheck") xml_tree = XML_Tree
Andreas@58039
    62
Andreas@58039
    63
lemma xml_tree_anything: "x = (y :: xml_tree)"
Andreas@58039
    64
by(cases x y rule: xml_tree.exhaust[case_product xml_tree.exhaust])(simp)
Andreas@58039
    65
Andreas@58039
    66
context begin
Andreas@58039
    67
local_setup {* Local_Theory.map_naming (Name_Space.mandatory_path "xml") *}
Andreas@58039
    68
Andreas@58039
    69
type_synonym attributes = "(String.literal \<times> String.literal) list"
Andreas@58039
    70
type_synonym body = "xml_tree list"
Andreas@58039
    71
Andreas@58039
    72
definition Elem :: "String.literal \<Rightarrow> attributes \<Rightarrow> xml_tree list \<Rightarrow> xml_tree"
Andreas@58039
    73
where [code del]: "Elem _ _ _ = XML_Tree"
Andreas@58039
    74
Andreas@58039
    75
definition Text :: "String.literal \<Rightarrow> xml_tree"
Andreas@58039
    76
where [code del]: "Text _ = XML_Tree"
Andreas@58039
    77
Andreas@58039
    78
definition node :: "xml_tree list \<Rightarrow> xml_tree"
Andreas@58039
    79
where "node ts = Elem (STR '':'') [] ts"
Andreas@58039
    80
Andreas@58039
    81
definition tagged :: "String.literal \<Rightarrow> String.literal option \<Rightarrow> xml_tree list \<Rightarrow> xml_tree"
Andreas@58039
    82
where "tagged tag x ts = Elem tag (case x of None \<Rightarrow> [] | Some x' \<Rightarrow> [(STR ''0'', x')]) ts"
Andreas@58039
    83
Andreas@58039
    84
definition list where "list f xs = map (node \<circ> f) xs"
Andreas@58039
    85
Andreas@58039
    86
definition X :: yxml_of_term where "X = yot_literal (STR [Char Nibble0 Nibble5])"
Andreas@58039
    87
definition Y :: yxml_of_term where "Y = yot_literal (STR [Char Nibble0 Nibble6])"
Andreas@58039
    88
definition XY :: yxml_of_term where "XY = yot_append X Y"
Andreas@58039
    89
definition XYX :: yxml_of_term where "XYX = yot_append XY X"
Andreas@58039
    90
Andreas@58039
    91
end
Andreas@58039
    92
Andreas@58039
    93
code_datatype xml.Elem xml.Text
Andreas@58039
    94
Andreas@58039
    95
definition yxml_string_of_xml_tree :: "xml_tree \<Rightarrow> yxml_of_term \<Rightarrow> yxml_of_term"
Andreas@58039
    96
where [code del]: "yxml_string_of_xml_tree _ _ = YXML"
Andreas@58039
    97
Andreas@58039
    98
lemma yxml_string_of_xml_tree_code [code]:
Andreas@58039
    99
  "yxml_string_of_xml_tree (xml.Elem name atts ts) rest =
Andreas@58039
   100
   yot_append xml.XY (
Andreas@58039
   101
   yot_append (yot_literal name) (
Andreas@58039
   102
   foldr (\<lambda>(a, x) rest. 
Andreas@58039
   103
     yot_append xml.Y (
Andreas@58039
   104
     yot_append (yot_literal a) (
Andreas@58039
   105
     yot_append (yot_literal (STR ''='')) (
Andreas@58039
   106
     yot_append (yot_literal x) rest)))) atts (
Andreas@58039
   107
   foldr yxml_string_of_xml_tree ts (
Andreas@58039
   108
   yot_append xml.XYX rest))))"
Andreas@58039
   109
  "yxml_string_of_xml_tree (xml.Text s) rest = yot_append (yot_literal s) rest"
Andreas@58039
   110
by(rule yot_anything)+
Andreas@58039
   111
Andreas@58039
   112
definition yxml_string_of_body :: "xml.body \<Rightarrow> yxml_of_term"
Andreas@58039
   113
where "yxml_string_of_body ts = foldr yxml_string_of_xml_tree ts yot_empty"
Andreas@58039
   114
Andreas@58039
   115
text {*
Andreas@58039
   116
  Encoding @{typ Code_Evaluation.term} into XML trees
Andreas@58039
   117
  as defined in @{file "~~/src/Pure/term_xml.ML"}
Andreas@58039
   118
*}
Andreas@58039
   119
Andreas@58039
   120
definition xml_of_typ :: "Typerep.typerep \<Rightarrow> xml.body"
Andreas@58039
   121
where [code del]: "xml_of_typ _ = [XML_Tree]"
Andreas@58039
   122
Andreas@58039
   123
definition xml_of_term :: "Code_Evaluation.term \<Rightarrow> xml.body"
Andreas@58039
   124
where [code del]: "xml_of_term _ = [XML_Tree]"
Andreas@58039
   125
Andreas@58039
   126
lemma xml_of_typ_code [code]:
Andreas@58039
   127
  "xml_of_typ (typerep.Typerep t args) = [xml.tagged (STR ''0'') (Some t) (xml.list xml_of_typ args)]"
Andreas@58039
   128
by(simp add: xml_of_typ_def xml_tree_anything)
Andreas@58039
   129
Andreas@58039
   130
lemma xml_of_term_code [code]:
Andreas@58039
   131
  "xml_of_term (Code_Evaluation.Const x ty) = [xml.tagged (STR ''0'') (Some x) (xml_of_typ ty)]"
Andreas@58039
   132
  "xml_of_term (Code_Evaluation.App t1 t2)  = [xml.tagged (STR ''5'') None [xml.node (xml_of_term t1), xml.node (xml_of_term t2)]]"
Andreas@58039
   133
  "xml_of_term (Code_Evaluation.Abs x ty t) = [xml.tagged (STR ''4'') (Some x) [xml.node (xml_of_typ ty), xml.node (xml_of_term t)]]"
Andreas@58039
   134
  -- {*
Andreas@58039
   135
    FIXME: @{const Code_Evaluation.Free} is used only in Quickcheck_Narrowing to represent
Andreas@58039
   136
    uninstantiated parameters in constructors. Here, we always translate them to @{ML Free} variables.
Andreas@58039
   137
  *}
Andreas@58039
   138
  "xml_of_term (Code_Evaluation.Free x ty)  = [xml.tagged (STR ''1'') (Some x) (xml_of_typ ty)]"
Andreas@58039
   139
by(simp_all add: xml_of_term_def xml_tree_anything)
Andreas@58039
   140
Andreas@58039
   141
definition yxml_string_of_term :: "Code_Evaluation.term \<Rightarrow> yxml_of_term"
Andreas@58039
   142
where "yxml_string_of_term = yxml_string_of_body \<circ> xml_of_term"
Andreas@58039
   143
Andreas@58039
   144
subsection {* Test engine and drivers *}
Andreas@58039
   145
Andreas@58039
   146
ML_file "code_test.ML"
Andreas@58039
   147
Andreas@58039
   148
end