doc-src/Codegen/Thy/Program.thy
author wenzelm
Tue, 01 Jun 2010 17:27:38 +0200
changeset 37241 04d2521e79b0
parent 37211 32a6f471f090
child 37427 e482f206821e
permissions -rw-r--r--
basic support for sub/superscript token markup -- NB: need to maintain extended token types eagerly, since jEdit occasionally reinstalls a style array that is too short;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
     1
theory Program
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
     2
imports Introduction
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
     3
begin
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
     4
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
     5
section {* Turning Theories into Programs \label{sec:program} *}
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
     6
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
     7
subsection {* The @{text "Isabelle/HOL"} default setup *}
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
     8
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
     9
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    10
  We have already seen how by default equations stemming from
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
    11
  @{command definition}, @{command primrec} and @{command fun}
28447
haftmann
parents: 28428
diff changeset
    12
  statements are used for code generation.  This default behaviour
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
    13
  can be changed, e.g.\ by providing different code equations.
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
    14
  The customisations shown in this section are \emph{safe}
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
    15
  as regards correctness: all programs that can be generated are partially
28447
haftmann
parents: 28428
diff changeset
    16
  correct.
haftmann
parents: 28428
diff changeset
    17
*}
haftmann
parents: 28428
diff changeset
    18
haftmann
parents: 28428
diff changeset
    19
subsection {* Selecting code equations *}
haftmann
parents: 28428
diff changeset
    20
haftmann
parents: 28428
diff changeset
    21
text {*
haftmann
parents: 28428
diff changeset
    22
  Coming back to our introductory example, we
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
    23
  could provide an alternative code equations for @{const dequeue}
28447
haftmann
parents: 28428
diff changeset
    24
  explicitly:
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    25
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    26
28564
haftmann
parents: 28562
diff changeset
    27
lemma %quote [code]:
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
    28
  "dequeue (AQueue xs []) =
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
    29
     (if xs = [] then (None, AQueue [] [])
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
    30
       else dequeue (AQueue [] (rev xs)))"
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
    31
  "dequeue (AQueue xs (y # ys)) =
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
    32
     (Some y, AQueue xs ys)"
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    33
  by (cases xs, simp_all) (cases "rev xs", simp_all)
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    34
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    35
text {*
28562
4e74209f113e `code func` now just `code`
haftmann
parents: 28462
diff changeset
    36
  \noindent The annotation @{text "[code]"} is an @{text Isar}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    37
  @{text attribute} which states that the given theorems should be
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
    38
  considered as code equations for a @{text fun} statement --
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    39
  the corresponding constant is determined syntactically.  The resulting code:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    40
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    41
28564
haftmann
parents: 28562
diff changeset
    42
text %quote {*@{code_stmts dequeue (consts) dequeue (Haskell)}*}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    43
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    44
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    45
  \noindent You may note that the equality test @{term "xs = []"} has been
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    46
  replaced by the predicate @{term "null xs"}.  This is due to the default
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    47
  setup in the \qn{preprocessor} to be discussed further below (\secref{sec:preproc}).
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    48
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    49
  Changing the default constructor set of datatypes is also
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
    50
  possible.  See \secref{sec:datatypes} for an example.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    51
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    52
  As told in \secref{sec:concept}, code generation is based
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    53
  on a structured collection of code theorems.
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
    54
  This collection
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    55
  may be inspected using the @{command code_thms} command:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    56
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    57
28564
haftmann
parents: 28562
diff changeset
    58
code_thms %quote dequeue
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    59
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    60
text {*
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
    61
  \noindent prints a table with \emph{all} code equations
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    62
  for @{const dequeue}, including
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
    63
  \emph{all} code equations those equations depend
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    64
  on recursively.
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    65
  
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    66
  Similarly, the @{command code_deps} command shows a graph
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
    67
  visualising dependencies between code equations.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    68
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    69
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    70
subsection {* @{text class} and @{text instantiation} *}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    71
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    72
text {*
28447
haftmann
parents: 28428
diff changeset
    73
  Concerning type classes and code generation, let us examine an example
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    74
  from abstract algebra:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    75
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    76
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
    77
class %quote semigroup =
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    78
  fixes mult :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<otimes>" 70)
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    79
  assumes assoc: "(x \<otimes> y) \<otimes> z = x \<otimes> (y \<otimes> z)"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    80
28564
haftmann
parents: 28562
diff changeset
    81
class %quote monoid = semigroup +
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    82
  fixes neutral :: 'a ("\<one>")
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    83
  assumes neutl: "\<one> \<otimes> x = x"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    84
    and neutr: "x \<otimes> \<one> = x"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    85
28564
haftmann
parents: 28562
diff changeset
    86
instantiation %quote nat :: monoid
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    87
begin
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    88
28564
haftmann
parents: 28562
diff changeset
    89
primrec %quote mult_nat where
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    90
    "0 \<otimes> n = (0\<Colon>nat)"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    91
  | "Suc m \<otimes> n = n + m \<otimes> n"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    92
28564
haftmann
parents: 28562
diff changeset
    93
definition %quote neutral_nat where
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    94
  "\<one> = Suc 0"
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
    95
28564
haftmann
parents: 28562
diff changeset
    96
lemma %quote add_mult_distrib:
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    97
  fixes n m q :: nat
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    98
  shows "(n + m) \<otimes> q = n \<otimes> q + m \<otimes> q"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
    99
  by (induct n) simp_all
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   100
28564
haftmann
parents: 28562
diff changeset
   101
instance %quote proof
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   102
  fix m n q :: nat
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   103
  show "m \<otimes> n \<otimes> q = m \<otimes> (n \<otimes> q)"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   104
    by (induct m) (simp_all add: add_mult_distrib)
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   105
  show "\<one> \<otimes> n = n"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   106
    by (simp add: neutral_nat_def)
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   107
  show "m \<otimes> \<one> = m"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   108
    by (induct m) (simp_all add: neutral_nat_def)
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   109
qed
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   110
28564
haftmann
parents: 28562
diff changeset
   111
end %quote
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   112
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   113
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   114
  \noindent We define the natural operation of the natural numbers
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   115
  on monoids:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   116
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   117
28564
haftmann
parents: 28562
diff changeset
   118
primrec %quote (in monoid) pow :: "nat \<Rightarrow> 'a \<Rightarrow> 'a" where
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   119
    "pow 0 a = \<one>"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   120
  | "pow (Suc n) a = a \<otimes> pow n a"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   121
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   122
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   123
  \noindent This we use to define the discrete exponentiation function:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   124
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   125
28564
haftmann
parents: 28562
diff changeset
   126
definition %quote bexp :: "nat \<Rightarrow> nat" where
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   127
  "bexp n = pow n (Suc (Suc 0))"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   128
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   129
text {*
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   130
  \noindent The corresponding code in Haskell uses that language's native classes:
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   131
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   132
28564
haftmann
parents: 28562
diff changeset
   133
text %quote {*@{code_stmts bexp (Haskell)}*}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   134
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   135
text {*
28447
haftmann
parents: 28428
diff changeset
   136
  \noindent This is a convenient place to show how explicit dictionary construction
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   137
  manifests in generated code (here, the same example in @{text SML}):
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   138
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   139
28564
haftmann
parents: 28562
diff changeset
   140
text %quote {*@{code_stmts bexp (SML)}*}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   141
28447
haftmann
parents: 28428
diff changeset
   142
text {*
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   143
  \noindent Note the parameters with trailing underscore (@{verbatim "A_"}),
28447
haftmann
parents: 28428
diff changeset
   144
    which are the dictionary parameters.
haftmann
parents: 28428
diff changeset
   145
*}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   146
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   147
subsection {* The preprocessor \label{sec:preproc} *}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   148
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   149
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   150
  Before selected function theorems are turned into abstract
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   151
  code, a chain of definitional transformation steps is carried
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   152
  out: \emph{preprocessing}.  In essence, the preprocessor
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   153
  consists of two components: a \emph{simpset} and \emph{function transformers}.
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   154
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   155
  The \emph{simpset} can apply the full generality of the
32000
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   156
  Isabelle simplifier.  Due to the interpretation of theorems as code
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   157
  equations, rewrites are applied to the right hand side and the
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   158
  arguments of the left hand side of an equation, but never to the
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   159
  constant heading the left hand side.  An important special case are
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   160
  \emph{unfold theorems},  which may be declared and removed using
32000
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   161
  the @{attribute code_unfold} or \emph{@{attribute code_unfold} del}
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   162
  attribute, respectively.
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   163
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   164
  Some common applications:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   165
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   166
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   167
text_raw {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   168
  \begin{itemize}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   169
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   170
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   171
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   172
     \item replacing non-executable constructs by executable ones:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   173
*}     
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   174
37211
32a6f471f090 clarified
haftmann
parents: 36259
diff changeset
   175
lemma %quote [code_unfold]:
32a6f471f090 clarified
haftmann
parents: 36259
diff changeset
   176
  "x \<in> set xs \<longleftrightarrow> member xs x" by (fact in_set_code)
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   177
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   178
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   179
     \item eliminating superfluous constants:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   180
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   181
37211
32a6f471f090 clarified
haftmann
parents: 36259
diff changeset
   182
lemma %quote [code_unfold]:
32a6f471f090 clarified
haftmann
parents: 36259
diff changeset
   183
  "1 = Suc 0" by (fact One_nat_def)
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   184
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   185
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   186
     \item replacing executable but inconvenient constructs:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   187
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   188
37211
32a6f471f090 clarified
haftmann
parents: 36259
diff changeset
   189
lemma %quote [code_unfold]:
32a6f471f090 clarified
haftmann
parents: 36259
diff changeset
   190
  "xs = [] \<longleftrightarrow> List.null xs" by (fact empty_null)
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   191
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   192
text_raw {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   193
  \end{itemize}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   194
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   195
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   196
text {*
28447
haftmann
parents: 28428
diff changeset
   197
  \noindent \emph{Function transformers} provide a very general interface,
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   198
  transforming a list of function theorems to another
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   199
  list of function theorems, provided that neither the heading
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   200
  constant nor its type change.  The @{term "0\<Colon>nat"} / @{const Suc}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   201
  pattern elimination implemented in
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   202
  theory @{text Efficient_Nat} (see \secref{eff_nat}) uses this
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   203
  interface.
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   204
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   205
  \noindent The current setup of the preprocessor may be inspected using
31254
03a35fbc9dc6 documented print_codeproc command
haftmann
parents: 30938
diff changeset
   206
  the @{command print_codeproc} command.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   207
  @{command code_thms} provides a convenient
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   208
  mechanism to inspect the impact of a preprocessor setup
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
   209
  on code equations.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   210
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   211
  \begin{warn}
32000
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   212
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   213
    Attribute @{attribute code_unfold} also applies to the
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   214
    preprocessor of the ancient @{text "SML code generator"}; in case
6f07563dc8a9 updated to changes in sources; tuned
haftmann
parents: 31254
diff changeset
   215
    this is not what you intend, use @{attribute code_inline} instead.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   216
  \end{warn}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   217
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   218
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   219
subsection {* Datatypes \label{sec:datatypes} *}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   220
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   221
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   222
  Conceptually, any datatype is spanned by a set of
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   223
  \emph{constructors} of type @{text "\<tau> = \<dots> \<Rightarrow> \<kappa> \<alpha>\<^isub>1 \<dots> \<alpha>\<^isub>n"} where @{text
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   224
  "{\<alpha>\<^isub>1, \<dots>, \<alpha>\<^isub>n}"} is exactly the set of \emph{all} type variables in
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   225
  @{text "\<tau>"}.  The HOL datatype package by default registers any new
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   226
  datatype in the table of datatypes, which may be inspected using the
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   227
  @{command print_codesetup} command.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   228
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   229
  In some cases, it is appropriate to alter or extend this table.  As
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   230
  an example, we will develop an alternative representation of the
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   231
  queue example given in \secref{sec:intro}.  The amortised
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   232
  representation is convenient for generating code but exposes its
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   233
  \qt{implementation} details, which may be cumbersome when proving
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   234
  theorems about it.  Therefore, here is a simple, straightforward
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   235
  representation of queues:
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   236
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   237
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   238
datatype %quote 'a queue = Queue "'a list"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   239
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   240
definition %quote empty :: "'a queue" where
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   241
  "empty = Queue []"
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   242
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   243
primrec %quote enqueue :: "'a \<Rightarrow> 'a queue \<Rightarrow> 'a queue" where
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   244
  "enqueue x (Queue xs) = Queue (xs @ [x])"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   245
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   246
fun %quote dequeue :: "'a queue \<Rightarrow> 'a option \<times> 'a queue" where
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   247
    "dequeue (Queue []) = (None, Queue [])"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   248
  | "dequeue (Queue (x # xs)) = (Some x, Queue xs)"
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   249
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   250
text {*
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   251
  \noindent This we can use directly for proving;  for executing,
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   252
  we provide an alternative characterisation:
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   253
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   254
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   255
definition %quote AQueue :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a queue" where
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   256
  "AQueue xs ys = Queue (ys @ rev xs)"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   257
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   258
code_datatype %quote AQueue
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   259
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   260
text {*
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   261
  \noindent Here we define a \qt{constructor} @{const "AQueue"} which
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   262
  is defined in terms of @{text "Queue"} and interprets its arguments
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   263
  according to what the \emph{content} of an amortised queue is supposed
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   264
  to be.  Equipped with this, we are able to prove the following equations
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   265
  for our primitive queue operations which \qt{implement} the simple
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   266
  queues in an amortised fashion:
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   267
*}
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   268
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   269
lemma %quote empty_AQueue [code]:
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   270
  "empty = AQueue [] []"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   271
  unfolding AQueue_def empty_def by simp
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   272
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   273
lemma %quote enqueue_AQueue [code]:
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   274
  "enqueue x (AQueue xs ys) = AQueue (x # xs) ys"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   275
  unfolding AQueue_def by simp
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   276
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   277
lemma %quote dequeue_AQueue [code]:
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   278
  "dequeue (AQueue xs []) =
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   279
    (if xs = [] then (None, AQueue [] [])
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   280
    else dequeue (AQueue [] (rev xs)))"
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   281
  "dequeue (AQueue xs (y # ys)) = (Some y, AQueue xs ys)"
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   282
  unfolding AQueue_def by simp_all
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   283
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   284
text {*
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   285
  \noindent For completeness, we provide a substitute for the
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   286
  @{text case} combinator on queues:
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   287
*}
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   288
30227
853abb4853cc tuned manuals
haftmann
parents: 30226
diff changeset
   289
lemma %quote queue_case_AQueue [code]:
853abb4853cc tuned manuals
haftmann
parents: 30226
diff changeset
   290
  "queue_case f (AQueue xs ys) = f (ys @ rev xs)"
853abb4853cc tuned manuals
haftmann
parents: 30226
diff changeset
   291
  unfolding AQueue_def by simp
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   292
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   293
text {*
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   294
  \noindent The resulting code looks as expected:
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   295
*}
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   296
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   297
text %quote {*@{code_stmts empty enqueue dequeue (SML)}*}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   298
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   299
text {*
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   300
  \noindent From this example, it can be glimpsed that using own
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   301
  constructor sets is a little delicate since it changes the set of
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   302
  valid patterns for values of that type.  Without going into much
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   303
  detail, here some practical hints:
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   304
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   305
  \begin{itemize}
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   306
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   307
    \item When changing the constructor set for datatypes, take care
30227
853abb4853cc tuned manuals
haftmann
parents: 30226
diff changeset
   308
      to provide alternative equations for the @{text case} combinator.
29794
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   309
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   310
    \item Values in the target language need not to be normalised --
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   311
      different values in the target language may represent the same
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   312
      value in the logic.
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   313
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   314
    \item Usually, a good methodology to deal with the subtleties of
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   315
      pattern matching is to see the type as an abstract type: provide
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   316
      a set of operations which operate on the concrete representation
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   317
      of the type, and derive further operations by combinations of
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   318
      these primitive ones, without relying on a particular
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   319
      representation.
32d00a2a6f28 added stub about datatype abstraction
haftmann
parents: 29560
diff changeset
   320
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   321
  \end{itemize}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   322
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   323
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   324
30938
c6c9359e474c wellsortedness is no issue for a user manual any more
haftmann
parents: 30227
diff changeset
   325
subsection {* Equality *}
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   326
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   327
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   328
  Surely you have already noticed how equality is treated
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   329
  by the code generator:
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   330
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   331
28564
haftmann
parents: 28562
diff changeset
   332
primrec %quote collect_duplicates :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
28447
haftmann
parents: 28428
diff changeset
   333
  "collect_duplicates xs ys [] = xs"
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   334
  | "collect_duplicates xs ys (z#zs) = (if z \<in> set xs
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   335
      then if z \<in> set ys
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   336
        then collect_duplicates xs ys zs
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   337
        else collect_duplicates xs (z#ys) zs
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   338
      else collect_duplicates (z#xs) (z#ys) zs)"
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   339
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   340
text {*
28428
haftmann
parents: 28419
diff changeset
   341
  \noindent The membership test during preprocessing is rewritten,
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   342
  resulting in @{const List.member}, which itself
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   343
  performs an explicit equality check.
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   344
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   345
28564
haftmann
parents: 28562
diff changeset
   346
text %quote {*@{code_stmts collect_duplicates (SML)}*}
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   347
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   348
text {*
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   349
  \noindent Obviously, polymorphic equality is implemented the Haskell
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   350
  way using a type class.  How is this achieved?  HOL introduces
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   351
  an explicit class @{class eq} with a corresponding operation
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   352
  @{const eq_class.eq} such that @{thm eq [no_vars]}.
28447
haftmann
parents: 28428
diff changeset
   353
  The preprocessing framework does the rest by propagating the
29560
fa6c5d62adf5 "code equation" replaces "defining equation"
haftmann
parents: 28593
diff changeset
   354
  @{class eq} constraints through all dependent code equations.
28419
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   355
  For datatypes, instances of @{class eq} are implicitly derived
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   356
  when possible.  For other types, you may instantiate @{text eq}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   357
  manually like any other type class.
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   358
*}
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   359
f65e8b318581 re-canibalised manual
haftmann
parents: 28213
diff changeset
   360
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   361
subsection {* Explicit partiality *}
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   362
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   363
text {*
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   364
  Partiality usually enters the game by partial patterns, as
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   365
  in the following example, again for amortised queues:
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   366
*}
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   367
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   368
definition %quote strict_dequeue :: "'a queue \<Rightarrow> 'a \<times> 'a queue" where
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   369
  "strict_dequeue q = (case dequeue q
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   370
    of (Some x, q') \<Rightarrow> (x, q'))"
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   371
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   372
lemma %quote strict_dequeue_AQueue [code]:
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   373
  "strict_dequeue (AQueue xs (y # ys)) = (y, AQueue xs ys)"
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   374
  "strict_dequeue (AQueue xs []) =
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   375
    (case rev xs of y # ys \<Rightarrow> (y, AQueue [] ys))"
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   376
  by (simp_all add: strict_dequeue_def dequeue_AQueue split: list.splits)
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   377
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   378
text {*
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   379
  \noindent In the corresponding code, there is no equation
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   380
  for the pattern @{term "AQueue [] []"}:
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   381
*}
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   382
28564
haftmann
parents: 28562
diff changeset
   383
text %quote {*@{code_stmts strict_dequeue (consts) strict_dequeue (Haskell)}*}
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   384
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   385
text {*
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   386
  \noindent In some cases it is desirable to have this
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   387
  pseudo-\qt{partiality} more explicitly, e.g.~as follows:
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   388
*}
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   389
28564
haftmann
parents: 28562
diff changeset
   390
axiomatization %quote empty_queue :: 'a
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   391
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   392
definition %quote strict_dequeue' :: "'a queue \<Rightarrow> 'a \<times> 'a queue" where
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   393
  "strict_dequeue' q = (case dequeue q of (Some x, q') \<Rightarrow> (x, q') | _ \<Rightarrow> empty_queue)"
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   394
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   395
lemma %quote strict_dequeue'_AQueue [code]:
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   396
  "strict_dequeue' (AQueue xs []) = (if xs = [] then empty_queue
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   397
     else strict_dequeue' (AQueue [] (rev xs)))"
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   398
  "strict_dequeue' (AQueue xs (y # ys)) =
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   399
     (y, AQueue xs ys)"
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   400
  by (simp_all add: strict_dequeue'_def dequeue_AQueue split: list.splits)
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   401
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   402
text {*
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   403
  Observe that on the right hand side of the definition of @{const
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   404
  "strict_dequeue'"}, the unspecified constant @{const empty_queue} occurs.
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   405
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   406
  Normally, if constants without any code equations occur in a
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   407
  program, the code generator complains (since in most cases this is
34155
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   408
  indeed an error).  But such constants can also be thought
14aaccb399b3 Polishing up the English
paulson
parents: 33926
diff changeset
   409
  of as function definitions which always fail,
29798
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   410
  since there is never a successful pattern match on the left hand
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   411
  side.  In order to categorise a constant into that category
6df726203e39 proper datatype abstraction example
haftmann
parents: 29796
diff changeset
   412
  explicitly, use @{command "code_abort"}:
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   413
*}
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   414
28564
haftmann
parents: 28562
diff changeset
   415
code_abort %quote empty_queue
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   416
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   417
text {*
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   418
  \noindent Then the code generator will just insert an error or
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   419
  exception at the appropriate position:
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   420
*}
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   421
28564
haftmann
parents: 28562
diff changeset
   422
text %quote {*@{code_stmts strict_dequeue' (consts) empty_queue strict_dequeue' (Haskell)}*}
28462
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   423
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   424
text {*
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   425
  \noindent This feature however is rarely needed in practice.
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   426
  Note also that the @{text HOL} default setup already declares
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   427
  @{const undefined} as @{command "code_abort"}, which is most
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   428
  likely to be used in such situations.
6ec603695aaf added partiality section
haftmann
parents: 28456
diff changeset
   429
*}
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   430
33926
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   431
subsection {* Inductive Predicates *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   432
(*<*)
36176
3fe7e97ccca8 replaced generic 'hide' command by more conventional 'hide_class', 'hide_type', 'hide_const', 'hide_fact' -- frees some popular keywords;
wenzelm
parents: 34155
diff changeset
   433
hide_const append
33926
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   434
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   435
inductive append
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   436
where
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   437
  "append [] ys ys"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   438
| "append xs ys zs ==> append (x # xs) ys (x # zs)"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   439
(*>*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   440
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   441
To execute inductive predicates, a special preprocessor, the predicate
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   442
 compiler, generates code equations from the introduction rules of the predicates.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   443
The mechanisms of this compiler are described in \cite{Berghofer-Bulwahn-Haftmann:2009:TPHOL}.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   444
Consider the simple predicate @{const append} given by these two
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   445
introduction rules:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   446
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   447
text %quote {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   448
@{thm append.intros(1)[of ys]}\\
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   449
\noindent@{thm append.intros(2)[of xs ys zs x]}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   450
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   451
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   452
\noindent To invoke the compiler, simply use @{command_def "code_pred"}:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   453
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   454
code_pred %quote append .
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   455
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   456
\noindent The @{command "code_pred"} command takes the name
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   457
of the inductive predicate and then you put a period to discharge
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   458
a trivial correctness proof. 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   459
The compiler infers possible modes 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   460
for the predicate and produces the derived code equations.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   461
Modes annotate which (parts of the) arguments are to be taken as input,
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   462
and which output. Modes are similar to types, but use the notation @{text "i"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   463
for input and @{text "o"} for output.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   464
 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   465
For @{term "append"}, the compiler can infer the following modes:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   466
\begin{itemize}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   467
\item @{text "i \<Rightarrow> i \<Rightarrow> i \<Rightarrow> bool"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   468
\item @{text "i \<Rightarrow> i \<Rightarrow> o \<Rightarrow> bool"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   469
\item @{text "o \<Rightarrow> o \<Rightarrow> i \<Rightarrow> bool"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   470
\end{itemize}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   471
You can compute sets of predicates using @{command_def "values"}:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   472
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   473
values %quote "{zs. append [(1::nat),2,3] [4,5] zs}"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   474
text {* \noindent outputs @{text "{[1, 2, 3, 4, 5]}"}, and *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   475
values %quote "{(xs, ys). append xs ys [(2::nat),3]}"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   476
text {* \noindent outputs @{text "{([], [2, 3]), ([2], [3]), ([2, 3], [])}"}. *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   477
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   478
\noindent If you are only interested in the first elements of the set
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   479
comprehension (with respect to a depth-first search on the introduction rules), you can
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   480
pass an argument to
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   481
@{command "values"} to specify the number of elements you want:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   482
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   483
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   484
values %quote 1 "{(xs, ys). append xs ys [(1::nat),2,3,4]}"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   485
values %quote 3 "{(xs, ys). append xs ys [(1::nat),2,3,4]}"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   486
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   487
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   488
\noindent The @{command "values"} command can only compute set
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   489
 comprehensions for which a mode has been inferred.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   490
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   491
The code equations for a predicate are made available as theorems with
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   492
 the suffix @{text "equation"}, and can be inspected with:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   493
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   494
thm %quote append.equation
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   495
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   496
\noindent More advanced options are described in the following subsections.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   497
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   498
subsubsection {* Alternative names for functions *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   499
text {* 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   500
By default, the functions generated from a predicate are named after the predicate with the
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   501
mode mangled into the name (e.g., @{text "append_i_i_o"}).
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   502
You can specify your own names as follows:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   503
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   504
code_pred %quote (modes: i => i => o => bool as concat,
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   505
  o => o => i => bool as split,
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   506
  i => o => i => bool as suffix) append .
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   507
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   508
subsubsection {* Alternative introduction rules *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   509
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   510
Sometimes the introduction rules of an predicate are not executable because they contain
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   511
non-executable constants or specific modes could not be inferred.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   512
It is also possible that the introduction rules yield a function that loops forever
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   513
due to the execution in a depth-first search manner.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   514
Therefore, you can declare alternative introduction rules for predicates with the attribute
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   515
@{attribute "code_pred_intro"}.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   516
For example, the transitive closure is defined by: 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   517
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   518
text %quote {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   519
@{thm tranclp.intros(1)[of r a b]}\\
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   520
\noindent @{thm tranclp.intros(2)[of r a b c]}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   521
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   522
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   523
\noindent These rules do not suit well for executing the transitive closure 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   524
with the mode @{text "(i \<Rightarrow> o \<Rightarrow> bool) \<Rightarrow> i \<Rightarrow> o \<Rightarrow> bool"}, as the second rule will
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   525
cause an infinite loop in the recursive call.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   526
This can be avoided using the following alternative rules which are
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   527
declared to the predicate compiler by the attribute @{attribute "code_pred_intro"}:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   528
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   529
lemma %quote [code_pred_intro]:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   530
  "r a b \<Longrightarrow> r\<^sup>+\<^sup>+ a b"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   531
  "r a b \<Longrightarrow> r\<^sup>+\<^sup>+ b c \<Longrightarrow> r\<^sup>+\<^sup>+ a c"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   532
by auto
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   533
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   534
\noindent After declaring all alternative rules for the transitive closure,
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   535
you invoke @{command "code_pred"} as usual.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   536
As you have declared alternative rules for the predicate, you are urged to prove that these
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   537
introduction rules are complete, i.e., that you can derive an elimination rule for the
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   538
alternative rules:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   539
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   540
code_pred %quote tranclp
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   541
proof -
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   542
  case tranclp
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   543
  from this converse_tranclpE[OF this(1)] show thesis by metis
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   544
qed
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   545
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   546
\noindent Alternative rules can also be used for constants that have not
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   547
been defined inductively. For example, the lexicographic order which
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   548
is defined as: *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   549
text %quote {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   550
@{thm [display] lexord_def[of "r"]}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   551
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   552
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   553
\noindent To make it executable, you can derive the following two rules and prove the
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   554
elimination rule:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   555
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   556
(*<*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   557
lemma append: "append xs ys zs = (xs @ ys = zs)"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   558
by (induct xs arbitrary: ys zs) (auto elim: append.cases intro: append.intros)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   559
(*>*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   560
lemma %quote [code_pred_intro]:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   561
  "append xs (a # v) ys \<Longrightarrow> lexord r (xs, ys)"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   562
(*<*)unfolding lexord_def Collect_def by (auto simp add: append)(*>*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   563
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   564
lemma %quote [code_pred_intro]:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   565
  "append u (a # v) xs \<Longrightarrow> append u (b # w) ys \<Longrightarrow> r (a, b)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   566
  \<Longrightarrow> lexord r (xs, ys)"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   567
(*<*)unfolding lexord_def Collect_def append mem_def apply simp
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   568
apply (rule disjI2) by auto
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   569
(*>*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   570
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   571
code_pred %quote lexord
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   572
(*<*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   573
proof -
36259
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   574
  fix r xs ys
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   575
  assume lexord: "lexord r (xs, ys)"
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   576
  assume 1: "\<And> r' xs' ys' a v. r = r' \<Longrightarrow> (xs, ys) = (xs', ys') \<Longrightarrow> append xs' (a # v) ys' \<Longrightarrow> thesis"
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   577
  assume 2: "\<And> r' xs' ys' u a v b w. r = r' \<Longrightarrow> (xs, ys) = (xs', ys') \<Longrightarrow> append u (a # v) xs' \<Longrightarrow> append u (b # w) ys' \<Longrightarrow> r' (a, b) \<Longrightarrow> thesis"
33926
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   578
  {
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   579
    assume "\<exists>a v. ys = xs @ a # v"
36259
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   580
    from this 1 have thesis
33926
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   581
        by (fastsimp simp add: append)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   582
  } moreover
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   583
  {
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   584
    assume "\<exists>u a b v w. (a, b) \<in> r \<and> xs = u @ a # v \<and> ys = u @ b # w"
36259
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   585
    from this 2 have thesis by (fastsimp simp add: append mem_def)
33926
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   586
  } moreover
36259
9f9b9b14cc7a adopting documentation of the predicate compiler
bulwahn
parents: 36176
diff changeset
   587
  note lexord
33926
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   588
  ultimately show thesis
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   589
    unfolding lexord_def
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   590
    by (fastsimp simp add: Collect_def)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   591
qed
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   592
(*>*)
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   593
subsubsection {* Options for values *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   594
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   595
In the presence of higher-order predicates, multiple modes for some predicate could be inferred
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   596
that are not disambiguated by the pattern of the set comprehension.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   597
To disambiguate the modes for the arguments of a predicate, you can state
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   598
the modes explicitly in the @{command "values"} command. 
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   599
Consider the simple predicate @{term "succ"}:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   600
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   601
inductive succ :: "nat \<Rightarrow> nat \<Rightarrow> bool"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   602
where
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   603
  "succ 0 (Suc 0)"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   604
| "succ x y \<Longrightarrow> succ (Suc x) (Suc y)"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   605
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   606
code_pred succ .
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   607
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   608
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   609
\noindent For this, the predicate compiler can infer modes @{text "o \<Rightarrow> o \<Rightarrow> bool"}, @{text "i \<Rightarrow> o \<Rightarrow> bool"},
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   610
  @{text "o \<Rightarrow> i \<Rightarrow> bool"} and @{text "i \<Rightarrow> i \<Rightarrow> bool"}.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   611
The invocation of @{command "values"} @{text "{n. tranclp succ 10 n}"} loops, as multiple
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   612
modes for the predicate @{text "succ"} are possible and here the first mode @{text "o \<Rightarrow> o \<Rightarrow> bool"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   613
is chosen. To choose another mode for the argument, you can declare the mode for the argument between
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   614
the @{command "values"} and the number of elements.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   615
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   616
values %quote [mode: i => o => bool] 20 "{n. tranclp succ 10 n}"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   617
values %quote [mode: o => i => bool] 10 "{n. tranclp succ n 10}"
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   618
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   619
subsubsection {* Embedding into functional code within Isabelle/HOL *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   620
text {*
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   621
To embed the computation of an inductive predicate into functions that are defined in Isabelle/HOL,
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   622
you have a number of options:
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   623
\begin{itemize}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   624
\item You want to use the first-order predicate with the mode
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   625
  where all arguments are input. Then you can use the predicate directly, e.g.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   626
\begin{quote}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   627
  @{text "valid_suffix ys zs = "}\\
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   628
  @{text "(if append [Suc 0, 2] ys zs then Some ys else None)"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   629
\end{quote}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   630
\item If you know that the execution returns only one value (it is deterministic), then you can
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   631
  use the combinator @{term "Predicate.the"}, e.g., a functional concatenation of lists
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   632
  is defined with
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   633
\begin{quote}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   634
  @{term "functional_concat xs ys = Predicate.the (append_i_i_o xs ys)"}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   635
\end{quote}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   636
  Note that if the evaluation does not return a unique value, it raises a run-time error
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   637
  @{term "not_unique"}.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   638
\end{itemize}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   639
*}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   640
subsubsection {* Further Examples *}
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   641
text {* Further examples for compiling inductive predicates can be found in
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   642
the @{text "HOL/ex/Predicate_Compile_ex"} theory file.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   643
There are also some examples in the Archive of Formal Proofs, notably
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   644
in the @{text "POPLmark-deBruijn"} and the @{text "FeatherweightJava"} sessions.
dd017d9db05f adding subsection about the predicate compiler to the code generator tutorial
bulwahn
parents: 33707
diff changeset
   645
*}
28213
b52f9205a02d New outline for codegen tutorial -- draft
haftmann
parents:
diff changeset
   646
end