added example from Tobias and changed the title
authorChristian Urban <urbanc@in.tum.de>
Sat, 29 May 2010 12:30:02 +0200
changeset 427 94538ddcac9b
parent 426 d94755882e36
child 428 c2dde8c7174f
added example from Tobias and changed the title
ProgTutorial/Intro.thy
ProgTutorial/ROOT.ML
ProgTutorial/Recipes/CallML.thy
ProgTutorial/document/root.tex
progtutorial.pdf
--- a/ProgTutorial/Intro.thy	Thu May 27 10:39:07 2010 +0200
+++ b/ProgTutorial/Intro.thy	Sat May 29 12:30:02 2010 +0200
@@ -262,6 +262,8 @@
   \item {\bf Alexander Krauss} wrote a very early version of the ``first-steps'' 
   chapter and also contributed the material on @{ML_funct Named_Thms}.
 
+  \item {\bf Tobias Nipkow} contributed recipe \ref{rec:callml}.
+
   \item {\bf Michael Norrish} proofread parts of the text.
 
   \item {\bf Christian Sternagel} proofread the tutorial and made 
--- a/ProgTutorial/ROOT.ML	Thu May 27 10:39:07 2010 +0200
+++ b/ProgTutorial/ROOT.ML	Sat May 29 12:30:02 2010 +0200
@@ -2,6 +2,8 @@
 
 no_document use_thy "Base";
 no_document use_thy "Package/Simple_Inductive_Package";
+no_document use_thy "~~/src/HOL/Number_Theory/Primes"; 
+no_document use_thy "Efficient_Nat";
 
 use_thy "Intro";
 use_thy "FirstSteps";
@@ -23,6 +25,7 @@
 use_thy "Recipes/Antiquotes";
 use_thy "Recipes/TimeLimit";
 use_thy "Recipes/Timing";
+use_thy "Recipes/CallML";
 use_thy "Recipes/ExternalSolver";
 use_thy "Recipes/Oracle";
 use_thy "Recipes/Sat";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProgTutorial/Recipes/CallML.thy	Sat May 29 12:30:02 2010 +0200
@@ -0,0 +1,162 @@
+(*<*)
+theory CallML
+imports "~~/src/HOL/Number_Theory/Primes" Efficient_Nat
+begin
+(*>*)
+
+section {* Calling ML Functions from within HOL \label{rec:callml} *}
+
+text{* 
+  {\bf Problem:} 
+  How to call ML functions from within HOL?\smallskip
+
+  {\bf Solution:} This can be achieved with \isacommand{code\_const}
+  and \isacommand{code\_reflect}.\smallskip
+
+
+  To make it clear we mean here calling unverified ML functions from within
+  HOL! The motivation is the paradigm of \emph{result checking}: rather than
+  verify some complicated algorithm, have the algorithm produce an easily
+  checkable certificate. For example, rather than verify a primality test,
+  have the test produce a factor of the input as a witness to
+  non-primality. This is only an example, and we ignore the converse
+  certificate, that for primality, although it, too, can be treated in the
+  same manner. 
+
+  The example we looking at here is an ML function for finding a factor 
+  of a number. We first declare its type:
+*}
+
+consts factor :: "nat \<Rightarrow> nat"
+
+text{* 
+  Its definition will be given in ML below. But the whole point is that
+  we can prove non-primality via @{const factor}, no matter what its
+  actual definition is: 
+*}
+
+lemma factor_non_prime:
+  assumes "let k = factor n in k \<noteq> 1 \<and> k \<noteq> n \<and> k dvd n"
+  shows "\<not> prime n"
+using assms by(auto simp: prime_nat_def Let_def)
+
+text{* 
+  Note that the premise is executable once we have defined 
+  @{const factor}. Here is a trivial definition in ML: 
+*}
+
+ML{*fun factor n = if n = 4 then 2 else 1*}
+
+text{* 
+  Of course this trivial definition of @{const factor} could have been given
+  directly in HOL rather than ML. But by going to the ML level, all of ML is
+  at our disposal, including arrays and references, features that are less
+  easily emulated in HOL. In fact, we could even call some external software
+  from ML, e.g.\ a computer algebra system.
+
+  It should be noted, however, that in this example you need to import the
+  theory @{theory Efficient_Nat} in order to force the HOL-type @{typ nat} to
+  be implemented by the ML-type @{text "int"}. Thus the ML implementation of
+  @{const factor} must be and is of type @{text "int -> int"}. Now it is time
+  to connect the two levels:
+*}
+
+code_const factor (SML "factor")
+
+text{* 
+  The result of this declaration is that the HOL-function @{const factor} 
+  is executable and command 
+*}
+
+value "factor 4"
+
+text{* 
+  yields the expected result @{text 2}. Similarly we can prove that
+  @{text 4} is not prime: 
+*}
+
+lemma "\<not> prime(4::nat)"
+  apply(rule factor_non_prime)
+  apply eval
+  done
+
+text{* 
+  Note, hawever, the command \isacommand{code\_const} cannot check that the ML function
+  has the required type. Therefore in the worst case a type mismatch will be detected by
+  the ML-compiler when we try to evaluate an expression involving @{const
+  factor}. It could also happen that @{const factor} is (accidentally)
+  redefined on the ML level later on. But remember that we do not assume
+  anything about @{const factor} on the HOL-level. Hence no definition of
+  @{const factor} can ever lead to an incorrect proof. Of course ``wrong''
+  definitions can lead to compile time or run time exceptions, or to failed
+  proofs.
+
+  The above example was easy because we forced Iabelle (via the inclusion of @{theory
+  Efficient_Nat}) to implement @{typ nat} by @{text int}, a predefined 
+  ML-type.  By default, Isabelle implements, for example, the HOL-type 
+  @{text list} by the corresponding ML-type. Thus the following variation 
+  on @{const factor} also works: 
+*}
+
+consts factor2 :: "nat \<Rightarrow> nat list" (*<*)(*>*)
+ML{*fun factor2 n = if n = 4 then [2] else []*}(*<*)(*>*)
+code_const factor2 (SML "factor2")
+
+value "factor2 4"
+
+text{* 
+  The first line declares the type of @{const factor2}; the second
+  gives its implementation in ML; the third makes it executable 
+  in HOL, and the last is just a test.  In this way, you can easily 
+  interface with ML-functions whose types involve 
+  @{text bool}, @{text int}, @{text list}, @{text option} and @{text pairs}, 
+  only. If you have arbitrary tuples, for example, then you have to code 
+  them as nested pairs.
+
+  Let us now look at how to refer to user-defined HOL-datatypes from the
+  ML-level. We modify our @{const factor} example a little by introducing a new
+  datatype for the result: 
+*}
+
+datatype result = Factor nat | Prime
+
+consts factor' :: "nat \<Rightarrow> result"
+
+text{* 
+  In order to write ML-code that uses this datatype, we need to define
+  this datatype at the ML-level first. The following command does just that. 
+*}
+
+code_reflect Result
+  datatypes result = Factor | Prime
+
+text{* 
+  This creates an ML-structure called @{text Result} (the name can be
+  arbitrarily chosen) that contains the datatype @{typ result}. The list 
+  of constructors (but not their types) needs to be given. Now we can 
+  write ML-code that uses this datatype: 
+*}
+
+ML{*fun factor' n = if n = 4 then Result.Factor 2 else Result.Prime*}
+
+text{* 
+  Finally we can link the HOL and ML version of @{const factor'} as
+  before: 
+*}
+
+code_const factor' (SML "factor'")
+
+text{* 
+  Now any evaluation of the HOL function @{const factor'} will use the
+  corresponding ML-function, like in the examples for @{const factor} above.
+
+  In general, \isacommand{code\_reflect} can export multiple datatypes 
+  (separated by \isacommand{and}) and also HOL-functions: simply add a line
+  \isacommand{functions} $f_1$ $f_2$ and so on.
+*}
+
+(*<*)
+value "factor' 4"
+
+end
+(*>*)
\ No newline at end of file
--- a/ProgTutorial/document/root.tex	Thu May 27 10:39:07 2010 +0200
+++ b/ProgTutorial/document/root.tex	Sat May 29 12:30:02 2010 +0200
@@ -152,7 +152,8 @@
 
 \title{\mbox{}\\[-10ex]
        \includegraphics[scale=0.5]{tutorial-logo.jpg}\\[3ex]
-       The Isabelle Programming Tutorial (draft)}
+       {\huge\bf The Isabelle Cookbook}\\
+       \mbox{A Tutorial for Programming on the ML-Level of Isabelle}\\ (draft)}
 
 \author{by Christian Urban with contributions from:\\[2ex] 
         \begin{tabular}{r@{\hspace{1.8mm}}l}
@@ -162,6 +163,7 @@
         Lukas & Bulwahn\\
         Jeremy & Dawson\\
         Alexander & Krauss\\
+        Tobias & Nipkow\\
         Christian & Sternagel\\ 
         \end{tabular}}
 
Binary file progtutorial.pdf has changed