doc-src/Codegen/Thy/Further.thy
author haftmann
Mon, 14 Jun 2010 15:27:08 +0200
changeset 37401 04d58897bf90
parent 37208 1f1f9cbd23ae
child 37405 a77740fc3957
permissions -rw-r--r--
subsection on locale interpretation
haftmann@28213
     1
theory Further
haftmann@28213
     2
imports Setup
haftmann@28213
     3
begin
haftmann@28213
     4
haftmann@28447
     5
section {* Further issues \label{sec:further} *}
haftmann@28213
     6
haftmann@28419
     7
subsection {* Further reading *}
haftmann@28419
     8
haftmann@28419
     9
text {*
paulson@34155
    10
  To dive deeper into the issue of code generation, you should visit
paulson@34155
    11
  the Isabelle/Isar Reference Manual \cite{isabelle-isar-ref}, which
haftmann@28593
    12
  contains exhaustive syntax diagrams.
haftmann@28419
    13
*}
haftmann@28419
    14
haftmann@37401
    15
subsection {* Locales and interpretation *}
haftmann@37401
    16
haftmann@37401
    17
lemma funpow_mult: -- FIXME
haftmann@37401
    18
  fixes f :: "'a \<Rightarrow> 'a"
haftmann@37401
    19
  shows "(f ^^ m) ^^ n = f ^^ (m * n)"
haftmann@37401
    20
  by (induct n) (simp_all add: funpow_add)
haftmann@37401
    21
haftmann@37401
    22
text {*
haftmann@37401
    23
  A technical issue comes to surface when generating code from
haftmann@37401
    24
  specifications stemming from locale interpretation.
haftmann@37401
    25
haftmann@37401
    26
  Let us assume a locale specifying a power operation
haftmann@37401
    27
  on arbitrary types:
haftmann@37401
    28
*}
haftmann@37401
    29
haftmann@37401
    30
locale %quote power =
haftmann@37401
    31
  fixes power :: "'a \<Rightarrow> 'b \<Rightarrow> 'b"
haftmann@37401
    32
  assumes power_commute: "power x \<circ> power y = power y \<circ> power x"
haftmann@37401
    33
begin
haftmann@37401
    34
haftmann@37401
    35
text {*
haftmann@37401
    36
  \noindent Inside that locale we can lift @{text power} to exponent lists
haftmann@37401
    37
  by means of specification relative to that locale:
haftmann@37401
    38
*}
haftmann@37401
    39
haftmann@37401
    40
primrec %quote powers :: "'a list \<Rightarrow> 'b \<Rightarrow> 'b" where
haftmann@37401
    41
  "powers [] = id"
haftmann@37401
    42
| "powers (x # xs) = power x \<circ> powers xs"
haftmann@37401
    43
haftmann@37401
    44
lemma %quote powers_append:
haftmann@37401
    45
  "powers (xs @ ys) = powers xs \<circ> powers ys"
haftmann@37401
    46
  by (induct xs) simp_all
haftmann@37401
    47
haftmann@37401
    48
lemma %quote powers_power:
haftmann@37401
    49
  "powers xs \<circ> power x = power x \<circ> powers xs"
haftmann@37401
    50
  by (induct xs)
haftmann@37401
    51
    (simp_all del: o_apply id_apply add: o_assoc [symmetric],
haftmann@37401
    52
      simp del: o_apply add: o_assoc power_commute)
haftmann@37401
    53
haftmann@37401
    54
lemma %quote powers_rev:
haftmann@37401
    55
  "powers (rev xs) = powers xs"
haftmann@37401
    56
    by (induct xs) (simp_all add: powers_append powers_power)
haftmann@37401
    57
haftmann@37401
    58
end %quote
haftmann@37401
    59
haftmann@37401
    60
text {*
haftmann@37401
    61
  After an interpretation of this locale (say, @{command
haftmann@37401
    62
  interpretation} @{text "fun_power:"} @{term [source] "power (\<lambda>n (f ::
haftmann@37401
    63
  'a \<Rightarrow> 'a). f ^^ n)"}), one would expect to have a constant @{text
haftmann@37401
    64
  "fun_power.powers :: nat list \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a"} for which code
haftmann@37401
    65
  can be generated.  But this not the case: internally, the term
haftmann@37401
    66
  @{text "fun_power.powers"} is an abbreviation for the foundational
haftmann@37401
    67
  term @{term [source] "power.powers (\<lambda>n (f :: 'a \<Rightarrow> 'a). f ^^ n)"}
haftmann@37401
    68
  (see \cite{isabelle-locale} for the details behind).
haftmann@37401
    69
haftmann@37401
    70
  Furtunately, with minor effort the desired behaviour can be achieved.
haftmann@37401
    71
  First, a dedicated definition of the constant on which the local @{text "powers"}
haftmann@37401
    72
  after interpretation is supposed to be mapped on:
haftmann@37401
    73
*}
haftmann@37401
    74
haftmann@37401
    75
definition %quote funpows :: "nat list \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a" where
haftmann@37401
    76
  [code del]: "funpows = power.powers (\<lambda>n f. f ^^ n)"
haftmann@37401
    77
haftmann@37401
    78
text {*
haftmann@37401
    79
  \noindent In general, the pattern is @{text "c = t"} where @{text c} is
haftmann@37401
    80
  the name of the future constant and @{text t} the foundational term
haftmann@37401
    81
  corresponding to the local constant after interpretation.
haftmann@37401
    82
haftmann@37401
    83
  The interpretation itself is enriched with an equation @{text "t = c"}:
haftmann@37401
    84
*}
haftmann@37401
    85
haftmann@37401
    86
interpretation %quote fun_power: power "\<lambda>n (f :: 'a \<Rightarrow> 'a). f ^^ n" where
haftmann@37401
    87
  "power.powers (\<lambda>n f. f ^^ n) = funpows"
haftmann@37401
    88
  by unfold_locales
haftmann@37401
    89
    (simp_all add: expand_fun_eq funpow_mult mult_commute funpows_def)
haftmann@37401
    90
haftmann@37401
    91
text {*
haftmann@37401
    92
  \noindent This additional equation is trivially proved by the definition
haftmann@37401
    93
  itself.
haftmann@37401
    94
haftmann@37401
    95
  After this setup procedure, code generation can continue as usual:
haftmann@37401
    96
*}
haftmann@37401
    97
haftmann@37401
    98
text %quote {*@{code_stmts funpows (consts) Nat.funpow funpows (Haskell)}*}
haftmann@37401
    99
haftmann@37401
   100
haftmann@28419
   101
subsection {* Modules *}
haftmann@28419
   102
haftmann@28419
   103
text {*
haftmann@28419
   104
  When invoking the @{command export_code} command it is possible to leave
haftmann@28419
   105
  out the @{keyword "module_name"} part;  then code is distributed over
haftmann@28419
   106
  different modules, where the module name space roughly is induced
haftmann@28635
   107
  by the @{text Isabelle} theory name space.
haftmann@28419
   108
haftmann@28419
   109
  Then sometimes the awkward situation occurs that dependencies between
haftmann@28419
   110
  definitions introduce cyclic dependencies between modules, which in the
haftmann@28419
   111
  @{text Haskell} world leaves you to the mercy of the @{text Haskell} implementation
haftmann@28419
   112
  you are using,  while for @{text SML}/@{text OCaml} code generation is not possible.
haftmann@28419
   113
haftmann@28419
   114
  A solution is to declare module names explicitly.
haftmann@28419
   115
  Let use assume the three cyclically dependent
haftmann@28419
   116
  modules are named \emph{A}, \emph{B} and \emph{C}.
haftmann@28419
   117
  Then, by stating
haftmann@28419
   118
*}
haftmann@28419
   119
haftmann@28593
   120
code_modulename %quote SML
haftmann@28419
   121
  A ABC
haftmann@28419
   122
  B ABC
haftmann@28419
   123
  C ABC
haftmann@28419
   124
paulson@34155
   125
text {*\noindent
haftmann@28419
   126
  we explicitly map all those modules on \emph{ABC},
haftmann@28419
   127
  resulting in an ad-hoc merge of this three modules
haftmann@28419
   128
  at serialisation time.
haftmann@28419
   129
*}
haftmann@28213
   130
haftmann@28213
   131
subsection {* Evaluation oracle *}
haftmann@28213
   132
haftmann@28593
   133
text {*
haftmann@28593
   134
  Code generation may also be used to \emph{evaluate} expressions
haftmann@28593
   135
  (using @{text SML} as target language of course).
paulson@34155
   136
  For instance, the @{command value} reduces an expression to a
haftmann@28593
   137
  normal form with respect to the underlying code equations:
haftmann@28593
   138
*}
haftmann@28593
   139
haftmann@28593
   140
value %quote "42 / (12 :: rat)"
haftmann@28593
   141
haftmann@28593
   142
text {*
haftmann@28593
   143
  \noindent will display @{term "7 / (2 :: rat)"}.
haftmann@28593
   144
haftmann@28593
   145
  The @{method eval} method tries to reduce a goal by code generation to @{term True}
haftmann@28593
   146
  and solves it in that case, but fails otherwise:
haftmann@28593
   147
*}
haftmann@28593
   148
haftmann@28593
   149
lemma %quote "42 / (12 :: rat) = 7 / 2"
haftmann@28593
   150
  by %quote eval
haftmann@28593
   151
haftmann@28593
   152
text {*
haftmann@28593
   153
  \noindent The soundness of the @{method eval} method depends crucially 
haftmann@28593
   154
  on the correctness of the code generator;  this is one of the reasons
haftmann@31050
   155
  why you should not use adaptation (see \secref{sec:adaptation}) frivolously.
haftmann@28593
   156
*}
haftmann@28593
   157
haftmann@28213
   158
subsection {* Code antiquotation *}
haftmann@28213
   159
haftmann@28593
   160
text {*
haftmann@28593
   161
  In scenarios involving techniques like reflection it is quite common
haftmann@28593
   162
  that code generated from a theory forms the basis for implementing
haftmann@28593
   163
  a proof procedure in @{text SML}.  To facilitate interfacing of generated code
haftmann@28593
   164
  with system code, the code generator provides a @{text code} antiquotation:
haftmann@28593
   165
*}
haftmann@28213
   166
haftmann@30880
   167
datatype %quote form = T | F | And form form | Or form form (*<*)
haftmann@30880
   168
haftmann@30880
   169
(*>*) ML %quotett {*
haftmann@28593
   170
  fun eval_form @{code T} = true
haftmann@28593
   171
    | eval_form @{code F} = false
haftmann@28593
   172
    | eval_form (@{code And} (p, q)) =
haftmann@28593
   173
        eval_form p andalso eval_form q
haftmann@28593
   174
    | eval_form (@{code Or} (p, q)) =
haftmann@28593
   175
        eval_form p orelse eval_form q;
haftmann@28593
   176
*}
haftmann@28593
   177
haftmann@28593
   178
text {*
haftmann@28593
   179
  \noindent @{text code} takes as argument the name of a constant;  after the
haftmann@28593
   180
  whole @{text SML} is read, the necessary code is generated transparently
haftmann@28593
   181
  and the corresponding constant names are inserted.  This technique also
haftmann@28593
   182
  allows to use pattern matching on constructors stemming from compiled
haftmann@37208
   183
  @{text "datatypes"}.
haftmann@28593
   184
haftmann@29733
   185
  For a less simplistic example, theory @{theory Ferrack} is
haftmann@28593
   186
  a good reference.
haftmann@28593
   187
*}
haftmann@28213
   188
haftmann@28419
   189
subsection {* Imperative data structures *}
haftmann@28419
   190
haftmann@28593
   191
text {*
haftmann@28593
   192
  If you consider imperative data structures as inevitable for a specific
haftmann@28593
   193
  application, you should consider
haftmann@28593
   194
  \emph{Imperative Functional Programming with Isabelle/HOL}
paulson@34155
   195
  \cite{bulwahn-et-al:2008:imperative};
haftmann@28593
   196
  the framework described there is available in theory @{theory Imperative_HOL}.
haftmann@28593
   197
*}
haftmann@28593
   198
haftmann@28213
   199
end