src/Doc/Codegen/Computations.thy
author wenzelm
Sat, 27 Jan 2018 17:27:06 +0100
changeset 67516 656720e8f443
parent 67327 89be5a4f514b
child 67526 a585c5b53576
permissions -rw-r--r--
tuned;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
     1
theory Computations
66453
cc19f7ca2ed6 session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
wenzelm
parents: 65044
diff changeset
     2
  imports Codegen_Basics.Setup
cc19f7ca2ed6 session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
wenzelm
parents: 65044
diff changeset
     3
    "HOL-Library.Code_Target_Int"
cc19f7ca2ed6 session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
wenzelm
parents: 65044
diff changeset
     4
    "HOL-Library.Code_Char"
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
     5
begin
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
     6
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
     7
section \<open>Computations \label{sec:computations}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
     8
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
     9
subsection \<open>Prelude -- The @{text code} antiquotation \label{sec:code_antiq}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    10
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    11
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    12
  The @{ML_antiquotation_def code} antiquotation allows to include constants
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    13
  from
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    14
  generated code directly into ML system code, as in the following toy
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    15
  example:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    16
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    17
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    18
datatype %quote form = T | F | And form form | Or form form (*<*)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    19
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    20
(*>*) ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    21
  fun eval_form @{code T} = true
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    22
    | eval_form @{code F} = false
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    23
    | eval_form (@{code And} (p, q)) =
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    24
        eval_form p andalso eval_form q
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    25
    | eval_form (@{code Or} (p, q)) =
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    26
        eval_form p orelse eval_form q;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    27
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    28
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    29
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    30
  \noindent The antiquotation @{ML_antiquotation code} takes
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    31
  the name of a constant as argument;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    32
  the required code is generated
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    33
  transparently and the corresponding constant names are inserted
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    34
  for the given antiquotations.  This technique allows to use pattern
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    35
  matching on constructors stemming from compiled datatypes.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    36
  Note that the @{ML_antiquotation code}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    37
  antiquotation may not refer to constants which carry adaptations;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    38
  here you have to refer to the corresponding adapted code directly.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    39
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    40
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    41
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    42
subsection \<open>The concept of computations\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    43
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    44
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    45
  Computations embody the simple idea that for each
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    46
  monomorphic Isabelle/HOL term of type @{text \<tau>} by virtue of
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    47
  code generation there exists an corresponding ML type @{text T} and
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    48
  a morphism @{text "\<Phi> :: \<tau> \<rightarrow> T"} satisfying
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    49
  @{text "\<Phi> (t\<^sub>1 \<cdot> t\<^sub>2) = \<Phi> t\<^sub>1 \<cdot> \<Phi> t\<^sub>2"}, with @{text \<cdot>} denoting
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    50
  term application.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    51
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    52
  For a given Isabelle/HOL type @{text \<tau>}, parts of @{text \<Phi>} can be
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    53
  implemented by a corresponding ML function @{text "\<phi>\<^sub>\<tau> :: term \<rightarrow> T"}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    54
  How?
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    55
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    56
    \<^descr> \<open>Let input be a constant C :: \<tau>.\<close> \\
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    57
      Then @{text "\<phi>\<^sub>\<tau> C = f\<^sub>C"} with @{text "f\<^sub>C"} being
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    58
      the image of @{text C} under code generation.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    59
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    60
    \<^descr> \<open>Let input be an application (t\<^sub>1 \<cdot> t\<^sub>2) :: \<tau>.\<close> \\
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    61
      Then @{text "\<phi>\<^sub>\<tau> (t\<^sub>1 \<cdot> t\<^sub>2) = \<phi>\<^sub>\<tau> t\<^sub>1 (\<phi>\<^sub>\<tau> t\<^sub>2)"}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    62
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    63
  \noindent Using these trivial properties, each monomorphic constant
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    64
  @{text "C : \<^vec>\<tau>\<^sub>n \<rightarrow> \<tau>"} yields the following
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    65
  equations:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    66
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    67
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    68
text %quote \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    69
  @{text "\<phi>\<^bsub>(\<tau>\<^sub>1 \<rightarrow> \<tau>\<^sub>2 \<rightarrow> \<dots> \<rightarrow> \<tau>\<^sub>n \<rightarrow> \<tau>)\<^esub> C = f\<^sub>C"} \\
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    70
  @{text "\<phi>\<^bsub>(\<tau>\<^sub>2 \<rightarrow> \<dots> \<rightarrow> \<tau>\<^sub>n \<rightarrow> \<tau>)\<^esub> (C \<cdot> t\<^sub>1) = f\<^sub>C (\<phi>\<^bsub>\<tau>\<^sub>1\<^esub> t\<^sub>1)"} \\
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    71
  @{text "\<dots>"} \\
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    72
  @{text "\<phi>\<^bsub>\<tau>\<^esub> (C \<cdot> t\<^sub>1 \<cdot> \<dots> \<cdot> t\<^sub>n) = f\<^sub>C (\<phi>\<^bsub>\<tau>\<^sub>1\<^esub> t\<^sub>1) \<dots> (\<phi>\<^bsub>\<tau>\<^sub>n\<^esub> t\<^sub>n)"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    73
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    74
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    75
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    76
  \noindent Hence a computation is characterized as follows:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    77
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    78
    \<^item> Let @{text "input constants"} denote a set of monomorphic constants.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    79
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    80
    \<^item> Let @{text \<tau>} denote a monomorphic type and @{text "'ml"} be a schematic
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    81
      placeholder for its corresponding type in ML under code generation.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    82
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    83
    \<^item> Then the corresponding computation is an ML function of type
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    84
      @{ML_type "Proof.context -> term -> 'ml"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    85
      partially implementing the morphism @{text "\<Phi> :: \<tau> \<rightarrow> T"} for all
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    86
      \<^emph>\<open>input terms\<close> consisting only of input constants and applications.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    87
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    88
  \noindent The charming idea is that all required code is automatically generated
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    89
  by the code generator for givens input constants and types;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    90
  that code is directly inserted into the Isabelle/ML runtime system
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    91
  by means of antiquotations.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    92
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    93
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    94
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    95
subsection \<open>The @{text computation} antiquotation\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    96
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    97
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    98
  The following example illustrates its basic usage:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
    99
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   100
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   101
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   102
  local
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   103
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   104
  fun int_of_nat @{code "0 :: nat"} = 0
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   105
    | int_of_nat (@{code Suc} n) = int_of_nat n + 1;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   106
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   107
  in
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   108
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   109
  val comp_nat = @{computation nat terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   110
    "plus :: nat \<Rightarrow> nat \<Rightarrow> nat" "times :: nat \<Rightarrow> nat \<Rightarrow> nat"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   111
    "sum_list :: nat list \<Rightarrow> nat" "prod_list :: nat list \<Rightarrow> nat"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   112
    datatypes: nat "nat list"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   113
    (fn post => post o HOLogic.mk_nat o int_of_nat o the);
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   114
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   115
  end
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   116
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   117
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   118
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   119
    \<^item> Antiquotations occurring in the
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   120
      same ML block always refer to the same transparently generated code;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   121
      particularly, they share the same transparently generated datatype
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   122
      declarations.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   123
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   124
    \<^item> The type of a computation is specified as first argument.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   125
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   126
    \<^item> Input constants are specified the following ways:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   127
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   128
        \<^item> Each term following @{text "terms:"} specifies all constants
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   129
          it contains as input constants.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   130
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   131
        \<^item> Each type following @{text "datatypes:"} specifies all constructors
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   132
          of the corresponding code datatype as input constants.  Note that
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   133
          this does not increase expressiveness but succinctness for datatypes
67327
89be5a4f514b skip abstract constructors silently in datatype clauses of computations
haftmann
parents: 67299
diff changeset
   134
          with many constructors.  Abstract type constructors are skipped
89be5a4f514b skip abstract constructors silently in datatype clauses of computations
haftmann
parents: 67299
diff changeset
   135
          silently.
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   136
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   137
    \<^item> The code generated by a @{text computation} antiquotation takes a functional argument
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   138
      which describes how to conclude the computation.  What's the rationale
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   139
      behind this?
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   140
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   141
        \<^item> There is no automated way to generate a reconstruction function
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   142
          from the resulting ML type to a Isabelle term -- this is in the
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   143
          responsibility of the implementor.  One possible approach
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   144
          for robust term reconstruction is the @{text code} antiquotation.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   145
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   146
        \<^item> Both statically specified input constants and dynamically provided input
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   147
          terms are subject to preprocessing.  Likewise the result
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   148
          is supposed to be subject to postprocessing; the implementor
65044
0940a741adf7 more correct wording
haftmann
parents: 65043
diff changeset
   149
          is expected to take care for this explicitly.
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   150
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   151
        \<^item> Computations follow the partiality principle (cf.~\secref{sec:partiality_principle}):
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   152
          failures due to pattern matching or unspecified functions
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   153
          are interpreted as partiality; therefore resulting ML values
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   154
          are optional. 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   155
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   156
      Hence the functional argument accepts the following parameters
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   157
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   158
        \<^item> A postprocessor function @{ML_type "term -> term"}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   159
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   160
        \<^item> The resulting value as optional argument.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   161
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   162
      The functional argument is supposed to compose the final result
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   163
      from these in a suitable manner.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   164
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   165
  \noindent A simple application:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   166
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   167
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   168
ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   169
  comp_nat @{context} @{term "sum_list [Suc 0, Suc (Suc 0)] * Suc (Suc 0)"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   170
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   171
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   172
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   173
  \noindent A single ML block may contain an arbitrary number of computation
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   174
  antiquotations.  These share the \<^emph>\<open>same\<close> set of possible
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   175
  input constants.  In other words, it does not matter in which
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   176
  antiquotation constants are specified;  in the following example,
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   177
  \<^emph>\<open>all\<close> constants are specified by the first antiquotation once
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   178
  and for all:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   179
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   180
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   181
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   182
  local
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   183
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   184
  fun int_of_nat @{code "0 :: nat"} = 0
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   185
    | int_of_nat (@{code Suc} n) = int_of_nat n + 1;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   186
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   187
  in
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   188
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   189
  val comp_nat = @{computation nat terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   190
    "plus :: nat \<Rightarrow> nat \<Rightarrow> nat" "times :: nat \<Rightarrow> nat \<Rightarrow> nat"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   191
    "sum_list :: nat list \<Rightarrow> nat" "prod_list :: nat list \<Rightarrow> nat"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   192
    "replicate :: nat \<Rightarrow> nat \<Rightarrow> nat list"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   193
    datatypes: nat "nat list"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   194
    (fn post => post o HOLogic.mk_nat o int_of_nat o the);
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   195
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   196
  val comp_nat_list = @{computation "nat list"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   197
    (fn post => post o HOLogic.mk_list @{typ nat} o
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   198
      map (HOLogic.mk_nat o int_of_nat) o the);
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   199
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   200
  end
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   201
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   202
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   203
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   204
subsection \<open>Pitfalls when specifying input constants \label{sec:input_constants_pitfalls}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   205
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   206
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   207
    \<^descr> \<open>Complete type coverage.\<close> Specified input constants must
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   208
      be \<^emph>\<open>complete\<close> in the sense that for each
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   209
      required type @{text \<tau>} there is at least one corresponding
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   210
      input constant which can actually \<^emph>\<open>construct\<close> a concrete
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   211
      value of type @{text \<tau>}, potentially requiring more types recursively;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   212
      otherwise the system of equations cannot be generated properly.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   213
      Hence such incomplete input constants sets are rejected immediately.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   214
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   215
    \<^descr> \<open>Unsuitful right hand sides.\<close> The generated code for a computation
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   216
      must compile in the strict ML runtime environment.  This imposes
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   217
      the technical restriction that each compiled input constant
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   218
      @{text f\<^sub>C} on the right hand side of a generated equations
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   219
      must compile without throwing an exception.  That rules
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   220
      out pathological examples like @{term [source] "undefined :: nat"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   221
      as input constants, as well as abstract constructors (cf. \secref{sec:invariant}).
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   222
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   223
    \<^descr> \<open>Preprocessing.\<close> For consistency, input constants are subject
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   224
      to preprocessing;  however, the overall approach requires
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   225
      to operate on constants @{text C} and their respective compiled images
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   226
      @{text f\<^sub>C}.\footnote{Technical restrictions of the implementation
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   227
      enforce this, although those could be lifted in the future.}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   228
      This is a problem whenever preprocessing maps an input constant
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   229
      to a non-constant.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   230
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   231
      To circumvent these situations, the computation machinery
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   232
      has a dedicated preprocessor which is applied \<^emph>\<open>before\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   233
      the regular preprocessing, both to input constants as well as
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   234
      input terms.  This can be used to map problematic constants
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   235
      to other ones that are not subject to regular preprocessing. 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   236
      Rewrite rules are added using attribute @{attribute code_computation_unfold}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   237
      There should rarely be a need to use this beyond the few default
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   238
      setups in HOL, which deal with literals (see also \secref{sec:literal_input}).
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   239
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   240
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   241
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   242
subsection \<open>Pitfalls concerning input terms\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   243
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   244
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   245
    \<^descr> \<open>No polymorphims.\<close> Input terms must be monomorphic: compilation
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   246
      to ML requires dedicated choice of monomorphic types.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   247
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   248
    \<^descr> \<open>No abstractions.\<close> Only constants and applications are admissible
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   249
      as input; abstractions are not possible.  In theory, the
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   250
      compilation schema could be extended to cover abstractions also,
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   251
      but this would increase the trusted code base.  If abstractions
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   252
      are required, they can always be eliminated by a dedicated preprocessing
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   253
      step, e.g.~using combinatorial logic.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   254
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   255
    \<^descr> \<open>Potential interfering of the preprocessor.\<close> As described in \secref{sec:input_constants_pitfalls}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   256
      regular preprocessing can have a disruptive effect for input constants.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   257
      The same also applies to input terms; however the same measures 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   258
      to circumvent that problem for input constants apply to input terms also.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   259
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   260
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   261
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   262
subsection \<open>Computations using the @{text computation_conv} antiquotation\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   263
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   264
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   265
  Computations are a device to implement fast proof procedures.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   266
  Then results of a computation are often assumed to be trustable
67299
ba52a058942f prefer formal citations;
wenzelm
parents: 66453
diff changeset
   267
  and thus wrapped in oracles (see @{cite "isabelle-isar-ref"}),
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   268
  as in the following example:\footnote{
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   269
  The technical details how numerals are dealt with are given later in
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   270
  \secref{sec:literal_input}.}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   271
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   272
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   273
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   274
  local
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   275
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   276
  fun raw_dvd (b, ct) = Thm.mk_binop @{cterm "Pure.eq :: bool \<Rightarrow> bool \<Rightarrow> prop"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   277
    ct (if b then @{cterm True} else @{cterm False});
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   278
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   279
  val (_, dvd_oracle) = Context.>>> (Context.map_theory_result
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   280
    (Thm.add_oracle (@{binding dvd}, raw_dvd)));
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   281
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   282
  in
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   283
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   284
  val conv_dvd = @{computation_conv bool terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   285
    "Rings.dvd :: int \<Rightarrow> int \<Rightarrow> bool"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   286
    "plus :: int \<Rightarrow> int \<Rightarrow> int"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   287
    "minus :: int \<Rightarrow> int \<Rightarrow> int"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   288
    "times :: int \<Rightarrow> int \<Rightarrow> int"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   289
    "0 :: int" "1 :: int" "2 :: int" "3 :: int" "-1 :: int"
65043
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   290
  } (K (curry dvd_oracle))
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   291
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   292
  end
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   293
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   294
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   295
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   296
    \<^item> Antiquotation @{ML_antiquotation computation_conv} basically yields
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   297
      a conversion of type @{ML_type "Proof.context -> cterm -> thm"}
67299
ba52a058942f prefer formal citations;
wenzelm
parents: 66453
diff changeset
   298
      (see further @{cite "isabelle-implementation"}).
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   299
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   300
    \<^item> The antiquotation expects one functional argument to bridge the
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   301
      \qt{untrusted gap};  this can be done e.g.~using an oracle.  Since that oracle
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   302
      will only yield \qt{valid} results in the context of that particular
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   303
      computation, the implementor must make sure that it does not leave
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   304
      the local ML scope;  in this example, this is achieved using
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   305
      an explicit @{text local} ML block.  The very presence of the oracle
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   306
      in the code acknowledges that each computation requires explicit thinking
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   307
      before it can be considered trustworthy!
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   308
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   309
    \<^item> Postprocessing just operates as further conversion after normalization.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   310
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   311
    \<^item> Partiality makes the whole conversion fall back to reflexivity.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   312
\<close> (*<*)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   313
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   314
(*>*) ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   315
  conv_dvd @{context} @{cterm "7 dvd ( 62437867527846782 :: int)"};
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   316
  conv_dvd @{context} @{cterm "7 dvd (-62437867527846783 :: int)"};
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   317
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   318
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   319
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   320
  \noindent An oracle is not the only way to construct a valid theorem.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   321
  A computation result can be used to construct an appropriate certificate:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   322
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   323
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   324
lemma %quote conv_div_cert:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   325
  "(Code_Target_Int.positive r * Code_Target_Int.positive s)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   326
     div Code_Target_Int.positive s \<equiv> (numeral r :: int)" (is "?lhs \<equiv> ?rhs")
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   327
proof (rule eq_reflection)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   328
  have "?lhs = numeral r * numeral s div numeral s"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   329
    by simp
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   330
  also have "numeral r * numeral s div numeral s = ?rhs"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   331
    by (rule nonzero_mult_div_cancel_right) simp
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   332
  finally show "?lhs = ?rhs" .
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   333
qed
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   334
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   335
lemma %quote positive_mult:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   336
  "Code_Target_Int.positive r * Code_Target_Int.positive s = 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   337
    Code_Target_Int.positive (r * s)"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   338
  by simp
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   339
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   340
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   341
  local
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   342
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   343
  fun integer_of_int (@{code int_of_integer} k) = k
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   344
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   345
  val cterm_of_int = Thm.cterm_of @{context} o HOLogic.mk_numeral o integer_of_int;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   346
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   347
  val divisor = Thm.dest_arg o Thm.dest_arg;
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   348
65043
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   349
  val evaluate_simps = map mk_eq @{thms arith_simps positive_mult};
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   350
65043
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   351
  fun evaluate ctxt = 
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   352
    Simplifier.rewrite_rule ctxt evaluate_simps;
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   353
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   354
  fun revaluate ctxt k ct =
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   355
    @{thm conv_div_cert}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   356
    |> Thm.instantiate' [] [SOME (cterm_of_int k), SOME (divisor ct)]
65043
fd753468786f explicit dynamic context for gap-bridging function
haftmann
parents: 65041
diff changeset
   357
    |> evaluate ctxt;
65041
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   358
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   359
  in
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   360
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   361
  val conv_div = @{computation_conv int terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   362
    "divide :: int \<Rightarrow> int \<Rightarrow> int"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   363
    "0 :: int" "1 :: int" "2 :: int" "3 :: int"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   364
  } revaluate
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   365
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   366
  end
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   367
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   368
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   369
ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   370
  conv_div @{context}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   371
    @{cterm "46782454343499999992777742432342242323423425 div (7 :: int)"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   372
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   373
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   374
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   375
  \noindent The example is intentionally kept simple: only positive
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   376
  integers are covered, only remainder-free divisions are feasible,
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   377
  and the input term is expected to have a particular shape.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   378
  This exhibits the idea more clearly:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   379
  the result of the computation is used as a mere
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   380
  hint how to instantiate @{fact conv_div_cert}, from which the required
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   381
  theorem is obtained by performing multiplication using the
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   382
  simplifier;  hence that theorem is built of proper inferences,
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   383
  with no oracles involved.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   384
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   385
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   386
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   387
subsection \<open>Computations using the @{text computation_check} antiquotation\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   388
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   389
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   390
  The @{text computation_check} antiquotation is convenient if
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   391
  only a positive checking of propositions is desired, because then
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   392
  the result type is fixed (@{typ prop}) and all the technical
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   393
  matter concerning postprocessing and oracles is done in the framework
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   394
  once and for all:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   395
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   396
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   397
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   398
  val check_nat = @{computation_check terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   399
    Trueprop "less :: nat \<Rightarrow> nat \<Rightarrow> bool" "plus :: nat \<Rightarrow> nat \<Rightarrow> nat" 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   400
    "times :: nat \<Rightarrow> nat \<Rightarrow> nat"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   401
    "0 :: nat" Suc
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   402
  }
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   403
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   404
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   405
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   406
  \noindent The HOL judgement @{term Trueprop} embeds an expression
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   407
  of type @{typ bool} into @{typ prop}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   408
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   409
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   410
ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   411
  check_nat @{context} @{cprop "less (Suc (Suc 0)) (Suc (Suc (Suc 0)))"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   412
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   413
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   414
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   415
  \noindent Note that such computations can only \<^emph>\<open>check\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   416
  for @{typ prop}s to hold but not \<^emph>\<open>decide\<close>.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   417
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   418
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   419
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   420
subsection \<open>Some practical hints\<close>  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   421
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   422
subsubsection \<open>Inspecting generated code\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   423
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   424
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   425
  The antiquotations for computations attempt to produce meaningful error
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   426
  messages.  If these are not sufficient, it might by useful to
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   427
  inspect the generated code, which can be achieved using
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   428
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   429
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   430
declare %quote [[ML_source_trace]] (*<*) declare %quote [[ML_source_trace = false]] (*>*)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   431
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   432
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   433
subsubsection \<open>Literals as input constants \label{sec:literal_input}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   434
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   435
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   436
  Literals (characters, numerals) in computations cannot be processed
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   437
  naively: the compilation pattern for computations fails whenever
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   438
  target-language literals are involved; since various
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   439
  common code generator setups (see \secref{sec:common_adaptation})
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   440
  implement @{typ nat} and @{typ int} by target-language literals,
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   441
  this problem manifests whenever numeric types are involved.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   442
  In practice, this is circumvented with a dedicated preprocessor
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   443
  setup for literals (see also \secref{sec:input_constants_pitfalls}).
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   444
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   445
  The following examples illustrate the pattern
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   446
  how to specify input constants when literals are involved, without going into
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   447
  too much detail:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   448
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   449
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   450
paragraph \<open>An example for @{typ nat}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   451
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   452
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   453
  val check_nat = @{computation_check terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   454
    Trueprop "even :: nat \<Rightarrow> bool" "plus :: nat \<Rightarrow> nat \<Rightarrow> nat" 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   455
    "0 :: nat" Suc "1 :: nat" "2 :: nat" "3 :: nat"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   456
  }
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   457
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   458
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   459
ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   460
  check_nat @{context} @{cprop "even (Suc 0 + 1 + 2 + 3 + 4 + 5)"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   461
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   462
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   463
paragraph \<open>An example for @{typ int}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   464
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   465
ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   466
  val check_int = @{computation_check terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   467
    Trueprop "even :: int \<Rightarrow> bool" "plus :: int \<Rightarrow> int \<Rightarrow> int" 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   468
    "0 :: int" "1 :: int" "2 :: int" "3 :: int" "-1 :: int"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   469
  }
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   470
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   471
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   472
ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   473
  check_int @{context} @{cprop "even ((0::int) + 1 + 2 + 3 + -1 + -2 + -3)"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   474
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   475
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   476
paragraph \<open>An example for @{typ char}\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   477
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   478
definition %quote is_cap_letter :: "char \<Rightarrow> bool"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   479
  where "is_cap_letter c \<longleftrightarrow> (let n = nat_of_char c in 65 \<le> n \<and> n \<le> 90)" (*<*)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   480
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   481
(*>*) ML %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   482
  val check_char = @{computation_check terms:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   483
    Trueprop is_cap_letter
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   484
    Char datatypes: num
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   485
  }
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   486
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   487
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   488
ML_val %quotetypewriter \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   489
  check_char @{context} @{cprop "is_cap_letter (CHR ''Y'')"}
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   490
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   491
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   492
  
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   493
subsubsection \<open>Preprocessing HOL terms into evaluable shape\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   494
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   495
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   496
  When integrating decision procedures developed inside HOL into HOL itself,
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   497
  a common approach is to use a deep embedding where operators etc.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   498
  are represented by datatypes in Isabelle/HOL.  Then it is necessary
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   499
  to turn generic shallowly embedded statements into that particular
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   500
  deep embedding (\qt{reification}).
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   501
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   502
  One option is to hardcode using code antiquotations (see \secref{sec:code_antiq}).
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   503
  Another option is to use pre-existing infrastructure in HOL:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   504
  @{ML "Reification.conv"} and @{ML "Reification.tac"}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   505
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   506
  A simplistic example:
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   507
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   508
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   509
datatype %quote form_ord = T | F | Less nat nat
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   510
  | And form_ord form_ord | Or form_ord form_ord | Neg form_ord
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   511
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   512
primrec %quote interp :: "form_ord \<Rightarrow> 'a::order list \<Rightarrow> bool"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   513
where
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   514
  "interp T vs \<longleftrightarrow> True"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   515
| "interp F vs \<longleftrightarrow> False"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   516
| "interp (Less i j) vs \<longleftrightarrow> vs ! i < vs ! j"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   517
| "interp (And f1 f2) vs \<longleftrightarrow> interp f1 vs \<and> interp f2 vs"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   518
| "interp (Or f1 f2) vs \<longleftrightarrow> interp f1 vs \<or> interp f2 vs"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   519
| "interp (Neg f) vs \<longleftrightarrow> \<not> interp f vs"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   520
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   521
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   522
  \noindent The datatype @{type form_ord} represents formulae whose semantics is given by
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   523
  @{const interp}.  Note that values are represented by variable indices (@{typ nat})
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   524
  whose concrete values are given in list @{term vs}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   525
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   526
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   527
ML %quotetypewriter (*<*) \<open>\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   528
lemma "thm": fixes x y z :: "'a::order" shows "x < y \<and> x < z \<equiv> interp (And (Less (Suc 0) (Suc (Suc 0))) (Less (Suc 0) 0)) [z, x, y]"
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   529
ML_prf %quotetypewriter
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   530
(*>*) \<open>val thm =
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   531
  Reification.conv @{context} @{thms interp.simps} @{cterm "x < y \<and> x < z"}\<close> (*<*)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   532
by (tactic \<open>ALLGOALS (resolve_tac @{context} [thm])\<close>)
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   533
(*>*) 
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   534
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   535
text \<open>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   536
  \noindent By virtue of @{fact interp.simps}, @{ML "Reification.conv"} provides a conversion
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   537
  which, for this concrete example, yields @{thm thm [no_vars]}.  Note that the argument
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   538
  to @{const interp} does not contain any free variables and can thus be evaluated
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   539
  using evaluation.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   540
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   541
  A less meager example can be found in the AFP, session @{text "Regular-Sets"},
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   542
  theory @{text Regexp_Method}.
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   543
\<close>
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   544
2525e680f94f basic documentation for computations
haftmann
parents:
diff changeset
   545
end