CookBook/FirstSteps.thy
changeset 47 4daf913fdbe1
parent 43 02f76f1b6e7b
child 48 609f9ef73494
equal deleted inserted replaced
46:81e2d73f7191 47:4daf913fdbe1
    22   \end{center}
    22   \end{center}
    23 *}
    23 *}
    24 
    24 
    25 section {* Including ML-Code *}
    25 section {* Including ML-Code *}
    26 
    26 
       
    27 
       
    28 
    27 text {*
    29 text {*
    28   The easiest and quickest way to include code in a theory is
    30   The easiest and quickest way to include code in a theory is
    29   by using the \isacommand{ML} command. For example\smallskip
    31   by using the \isacommand{ML} command. For example\smallskip
    30 
    32 
    31 \isa{\isacommand{ML}
    33 \isa{\isacommand{ML}
    35 @{ML_text "> 7"}\smallskip}
    37 @{ML_text "> 7"}\smallskip}
    36 
    38 
    37   Expressions inside \isacommand{ML} commands are immediately evaluated,
    39   Expressions inside \isacommand{ML} commands are immediately evaluated,
    38   like ``normal'' Isabelle proof scripts, by using the advance and undo buttons of 
    40   like ``normal'' Isabelle proof scripts, by using the advance and undo buttons of 
    39   your Isabelle environment. The code inside the \isacommand{ML} command 
    41   your Isabelle environment. The code inside the \isacommand{ML} command 
    40   can also contain value and function bindings. However on such \isacommand{ML}
    42   can also contain value and function bindings, and even those can be
    41   commands the undo operation behaves slightly counter-intuitive, because 
    43   undone when the proof script is retracted. From now on we will drop the 
    42   if you define\smallskip
       
    43  
       
    44 \isa{\isacommand{ML}
       
    45 \isacharverbatimopen\isanewline
       
    46 \hspace{5mm}@{ML_text "val foo = true"}\isanewline
       
    47 \isacharverbatimclose\isanewline
       
    48 @{ML_text "> true"}\smallskip}
       
    49 
       
    50   then Isabelle's undo operation has no effect on the definition of 
       
    51   @{ML_text "foo"}. Note that from now on we will drop the 
       
    52   \isacommand{ML} \isa{\isacharverbatimopen \ldots \isacharverbatimclose} whenever
    44   \isacommand{ML} \isa{\isacharverbatimopen \ldots \isacharverbatimclose} whenever
    53   we show code and its response.
    45   we show code and its response.
    54 
    46 
    55   Once a portion of code is relatively stable, one usually wants to 
    47   Once a portion of code is relatively stable, one usually wants to 
    56   export it to a separate ML-file. Such files can then be included in a 
    48   export it to a separate ML-file. Such files can then be included in a 
    76   in your code. This can be done in a ``quick-and-dirty'' fashion using 
    68   in your code. This can be done in a ``quick-and-dirty'' fashion using 
    77   the function @{ML "warning"}. For example 
    69   the function @{ML "warning"}. For example 
    78 
    70 
    79   @{ML [display] "warning \"any string\""}
    71   @{ML [display] "warning \"any string\""}
    80 
    72 
    81   will print out @{ML_text "\"any string\""} inside the response buffer of Isabelle.
    73   will print out @{ML_text [quotes] "any string"} inside the response buffer of Isabelle.
    82   If you develop under PolyML, then there is a convenient, though again 
    74   If you develop under PolyML, then there is a convenient, though again 
    83   ``quick-and-dirty'', method for converting values into strings, 
    75   ``quick-and-dirty'', method for converting values into strings, 
    84   for example: 
    76   for example: 
    85 
    77 
    86   @{ML [display] "warning (makestring 1)"} 
    78   @{ML [display] "warning (makestring 1)"} 
    99   It is also possible to redirect the channel where the @{ML_text "foo"} is 
    91   It is also possible to redirect the channel where the @{ML_text "foo"} is 
   100   printed to a separate file, e.g. to prevent Proof General from choking on massive 
    92   printed to a separate file, e.g. to prevent Proof General from choking on massive 
   101   amounts of trace output. This rediretion can be achieved using the code
    93   amounts of trace output. This rediretion can be achieved using the code
   102 *}
    94 *}
   103 
    95 
   104 ML {*
    96 ML{* 
   105 val strip_specials =
    97 val strip_specials =
   106 let
    98 let
   107   fun strip ("\^A" :: _ :: cs) = strip cs
    99   fun strip ("\^A" :: _ :: cs) = strip cs
   108     | strip (c :: cs) = c :: strip cs
   100     | strip (c :: cs) = c :: strip cs
   109     | strip [] = [];
   101     | strip [] = [];
   111 
   103 
   112 fun redirect_tracing stream =
   104 fun redirect_tracing stream =
   113  Output.tracing_fn := (fn s =>
   105  Output.tracing_fn := (fn s =>
   114     (TextIO.output (stream, (strip_specials s));
   106     (TextIO.output (stream, (strip_specials s));
   115      TextIO.output (stream, "\n");
   107      TextIO.output (stream, "\n");
   116      TextIO.flushOut stream));
   108      TextIO.flushOut stream)); 
   117 *}
   109 *}
   118 
   110 
   119 text {*
   111 text {*
   120 
   112 
   121   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   113   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   161   In a similar way you can use antiquotations to refer to theorems or simpsets:
   153   In a similar way you can use antiquotations to refer to theorems or simpsets:
   162 
   154 
   163   @{ML [display] "@{thm allI}"}
   155   @{ML [display] "@{thm allI}"}
   164   @{ML [display] "@{simpset}"}
   156   @{ML [display] "@{simpset}"}
   165 
   157 
   166   While antiquotations have many uses, they were introduced to avoid explicit
   158   While antiquotations have many applications, they were originally introduced to 
   167   bindings for theorems such as
   159   avoid explicit bindings for theorems such as
   168 *}
   160 *}
   169 
   161 
   170 ML {*
   162 ML {*
   171 val allI = thm "allI"
   163 val allI = thm "allI"
   172 *}
   164 *}
   173 
   165 
   174 text {*
   166 text {*
   175   These bindings were difficult to maintain and also could be overwritten
   167   These bindings were difficult to maintain and also could be accidentally overwritten
   176   by bindings introduced by the user. This had the potential to break
   168   by the user. This usually broke definitional packages. Antiquotations solve this
   177   definitional packages. This additional layer of maintenance complexity
   169   problem, since they are ``linked'' statically at compile time.  In the course of this 
   178   can be avoided by using antiquotations, since they are ``linked'' statically
   170   introduction, we will learn more about these antiquotations: they greatly simplify 
   179   at compile time.  In the course of this introduction, we will learn more about 
   171   Isabelle programming since one can directly access all kinds of logical elements 
   180   these antiquotations: they greatly simplify Isabelle programming since one
   172   from ML.
   181   can directly access all kinds of logical elements from ML.
       
   182 
       
   183 *}
   173 *}
   184 
   174 
   185 section {* Terms and Types *}
   175 section {* Terms and Types *}
   186 
   176 
   187 text {*
   177 text {*
   206   definition and many useful operations can be found in @{ML_file "Pure/term.ML"}.
   196   definition and many useful operations can be found in @{ML_file "Pure/term.ML"}.
   207   \end{readmore}
   197   \end{readmore}
   208 
   198 
   209   Sometimes the internal representation of terms can be surprisingly different
   199   Sometimes the internal representation of terms can be surprisingly different
   210   from what you see at the user level, because the layers of
   200   from what you see at the user level, because the layers of
   211   parsing/type checking/pretty printing can be quite elaborate. 
   201   parsing/type-checking/pretty printing can be quite elaborate. 
   212 *}
   202 
   213 
       
   214 text {*
       
   215   \begin{exercise}
   203   \begin{exercise}
   216   Look at the internal term representation of the following terms, and
   204   Look at the internal term representation of the following terms, and
   217   find out why they are represented like this.
   205   find out why they are represented like this.
   218 
   206 
   219   \begin{itemize}
   207   \begin{itemize}
   244   @{ML_response [display] "@{prop \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"}
   232   @{ML_response [display] "@{prop \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"}
   245 
   233 
   246   which does not. 
   234   which does not. 
   247 
   235 
   248   Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example
   236   Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example
   249   
       
   250   *}
       
   251 
       
   252 
       
   253 text {*
       
   254 
   237 
   255   @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   238   @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   256 
       
   257   (FIXME: Unlike the term antiquotation, @{text "@{typ \<dots>}"} does not print the
       
   258   internal representation. Is there a reason for this, that needs to be explained 
       
   259   here?)
       
   260 
   239 
   261   \begin{readmore}
   240   \begin{readmore}
   262   Types are described in detail in \isccite{sec:types}. Their
   241   Types are described in detail in \isccite{sec:types}. Their
   263   definition and many useful operations can be found in @{ML_file "Pure/type.ML"}.
   242   definition and many useful operations can be found in @{ML_file "Pure/type.ML"}.
   264   \end{readmore}
   243   \end{readmore}
   265 
   244 *}
   266   *}
       
   267 
   245 
   268 
   246 
   269 section {* Constructing Terms and Types Manually *} 
   247 section {* Constructing Terms and Types Manually *} 
   270 
   248 
   271 text {*
   249 text {*
   272 
   250 
   273   While antiquotations are very convenient for constructing terms and types, 
   251   While antiquotations are very convenient for constructing terms and types, 
   274   they can only construct fixed terms. Unfortunately, one often needs to construct them 
   252   they can only construct fixed terms. Unfortunately, one often needs to construct terms
   275   dynamically. For example, a function that returns the implication 
   253   dynamically. For example, a function that returns the implication 
   276   @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the typ @{term "\<tau>"}
   254   @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the typ @{term "\<tau>"}
   277   as arguments can only be written as
   255   as arguments can only be written as
   278 *}
   256 *}
   279 
   257 
   287 *}
   265 *}
   288 
   266 
   289 text {*
   267 text {*
   290 
   268 
   291   The reason is that one cannot pass the arguments @{term P}, @{term Q} and 
   269   The reason is that one cannot pass the arguments @{term P}, @{term Q} and 
   292   @{term "tau"} into an antiquotation. For example the following does not work.
   270   @{term "tau"} into an antiquotation. For example the following does not work as
       
   271   expected.
   293 *}
   272 *}
   294 
   273 
   295 ML {*
   274 ML {*
   296 fun make_wrong_imp P Q tau = @{prop "\<And>x. P x \<Longrightarrow> Q x"} 
   275 fun make_wrong_imp P Q tau = @{prop "\<And>x. P x \<Longrightarrow> Q x"} 
   297 *}
   276 *}
   347   \end{exercise}
   326   \end{exercise}
   348 
   327 
   349 *}
   328 *}
   350 
   329 
   351 section {* Type Checking *}
   330 section {* Type Checking *}
       
   331 
       
   332 ML {* cterm_of @{theory} @{term "a + b = c"} *}
   352 
   333 
   353 text {* 
   334 text {* 
   354   
   335   
   355   We can freely construct and manipulate terms, since they are just
   336   We can freely construct and manipulate terms, since they are just
   356   arbitrary unchecked trees. However, we eventually want to see if a
   337   arbitrary unchecked trees. However, we eventually want to see if a
   362   type-correct, and that can only be constructed via the official
   343   type-correct, and that can only be constructed via the official
   363   interfaces.
   344   interfaces.
   364 
   345 
   365   Type checking is always relative to a theory context. For now we can use
   346   Type checking is always relative to a theory context. For now we can use
   366   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   347   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   367   For example we can write:
   348   For example we can write
       
   349 
       
   350   @{ML_response_fake [display] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
       
   351 
       
   352   or use the antiquotation
   368 
   353 
   369   @{ML_response_fake [display] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   354   @{ML_response_fake [display] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   370 
   355 
   371   and 
   356   A slightly more elaborate example is
   372 
   357 
   373 @{ML_response_fake [display] 
   358 @{ML_response_fake [display] 
   374 "let
   359 "let
   375   val natT = @{typ \"nat\"}
   360   val natT = @{typ \"nat\"}
   376   val zero = @{term \"0::nat\"}
   361   val zero = @{term \"0::nat\"}