doc-src/IsarAdvanced/Codegen/Thy/Program.thy
changeset 28447 df77ed974a78
parent 28428 fd007794561f
child 28456 7a558c872104
equal deleted inserted replaced
28446:a01de3b3fa2e 28447:df77ed974a78
     4 
     4 
     5 section {* Turning Theories into Programs \label{sec:program} *}
     5 section {* Turning Theories into Programs \label{sec:program} *}
     6 
     6 
     7 subsection {* The @{text "Isabelle/HOL"} default setup *}
     7 subsection {* The @{text "Isabelle/HOL"} default setup *}
     8 
     8 
     9 subsection {* Selecting code equations *}
       
    10 
       
    11 text {*
     9 text {*
    12   We have already seen how by default equations stemming from
    10   We have already seen how by default equations stemming from
    13   @{command definition}/@{command primrec}/@{command fun}
    11   @{command definition}/@{command primrec}/@{command fun}
    14   statements are used for code generation.  Deviating from this
    12   statements are used for code generation.  This default behaviour
    15   \emph{default} behaviour is always possible -- e.g.~we
    13   can be changed, e.g. by providing different defining equations.
    16   could provide an alternative @{text fun} for @{const dequeue} proving
    14   All kinds of customization shown in this section is \emph{safe}
    17   the following equations explicitly:
    15   in the sense that the user does not have to worry about
       
    16   correctness -- all programs generatable that way are partially
       
    17   correct.
       
    18 *}
       
    19 
       
    20 subsection {* Selecting code equations *}
       
    21 
       
    22 text {*
       
    23   Coming back to our introductory example, we
       
    24   could provide an alternative defining equations for @{const dequeue}
       
    25   explicitly:
    18 *}
    26 *}
    19 
    27 
    20 lemma %quoteme [code func]:
    28 lemma %quoteme [code func]:
    21   "dequeue (Queue xs []) = (if xs = [] then (None, Queue [] []) else dequeue (Queue [] (rev xs)))"
    29   "dequeue (Queue xs []) =
    22   "dequeue (Queue xs (y # ys)) = (Some y, Queue xs ys)"
    30      (if xs = [] then (None, Queue [] []) else dequeue (Queue [] (rev xs)))"
       
    31   "dequeue (Queue xs (y # ys)) =
       
    32      (Some y, Queue xs ys)"
    23   by (cases xs, simp_all) (cases "rev xs", simp_all)
    33   by (cases xs, simp_all) (cases "rev xs", simp_all)
    24 
    34 
    25 text {*
    35 text {*
    26   \noindent The annotation @{text "[code func]"} is an @{text Isar}
    36   \noindent The annotation @{text "[code func]"} is an @{text Isar}
    27   @{text attribute} which states that the given theorems should be
    37   @{text attribute} which states that the given theorems should be
    58 *}
    68 *}
    59 
    69 
    60 subsection {* @{text class} and @{text instantiation} *}
    70 subsection {* @{text class} and @{text instantiation} *}
    61 
    71 
    62 text {*
    72 text {*
    63   Concerning type classes and code generation, let us again examine an example
    73   Concerning type classes and code generation, let us examine an example
    64   from abstract algebra:
    74   from abstract algebra:
    65 *}
    75 *}
    66 
    76 
    67 class %quoteme semigroup = type +
    77 class %quoteme semigroup = type +
    68   fixes mult :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<otimes>" 70)
    78   fixes mult :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<otimes>" 70)
   103 text {*
   113 text {*
   104   \noindent We define the natural operation of the natural numbers
   114   \noindent We define the natural operation of the natural numbers
   105   on monoids:
   115   on monoids:
   106 *}
   116 *}
   107 
   117 
   108 primrec %quoteme pow :: "nat \<Rightarrow> 'a\<Colon>monoid \<Rightarrow> 'a\<Colon>monoid" where
   118 primrec %quoteme (in monoid) pow :: "nat \<Rightarrow> 'a \<Rightarrow> 'a" where
   109     "pow 0 a = \<one>"
   119     "pow 0 a = \<one>"
   110   | "pow (Suc n) a = a \<otimes> pow n a"
   120   | "pow (Suc n) a = a \<otimes> pow n a"
   111 
   121 
   112 text {*
   122 text {*
   113   \noindent This we use to define the discrete exponentiation function:
   123   \noindent This we use to define the discrete exponentiation function:
   121 *}
   131 *}
   122 
   132 
   123 text %quoteme {*@{code_stmts bexp (Haskell)}*}
   133 text %quoteme {*@{code_stmts bexp (Haskell)}*}
   124 
   134 
   125 text {*
   135 text {*
   126   \noindent An inspection reveals that the equations stemming from the
   136   \noindent This is a convenient place to show how explicit dictionary construction
   127   @{command primrec} statement within instantiation of class
       
   128   @{class semigroup} with type @{typ nat} are mapped to a separate
       
   129   function declaration @{verbatim mult_nat} which in turn is used
       
   130   to provide the right hand side for the @{verbatim "instance Semigroup Nat"}.
       
   131   This perfectly
       
   132   agrees with the restriction that @{text inst} statements may
       
   133   only contain one single equation for each class class parameter
       
   134   The @{command instantiation} mechanism manages that for each
       
   135   overloaded constant @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}
       
   136   a \emph{shadow constant} @{text "f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} is
       
   137   declared satisfying @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>] \<equiv> f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}.
       
   138   this equation is indeed the one used for the statement;
       
   139   using it as a rewrite rule, defining equations for 
       
   140   @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} can be turned into
       
   141   defining equations for @{text "f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}.  This
       
   142   happens transparently, providing the illusion that class parameters
       
   143   can be instantiated with more than one equation.
       
   144 
       
   145   This is a convenient place to show how explicit dictionary construction
       
   146   manifests in generated code (here, the same example in @{text SML}):
   137   manifests in generated code (here, the same example in @{text SML}):
   147 *}
   138 *}
   148 
   139 
   149 text %quoteme {*@{code_stmts bexp (SML)}*}
   140 text %quoteme {*@{code_stmts bexp (SML)}*}
   150 
   141 
       
   142 text {*
       
   143   \noindent Note the parameters with trailing underscore (@{verbatim "A_"})
       
   144     which are the dictionary parameters.
       
   145 *}
   151 
   146 
   152 subsection {* The preprocessor \label{sec:preproc} *}
   147 subsection {* The preprocessor \label{sec:preproc} *}
   153 
   148 
   154 text {*
   149 text {*
   155   Before selected function theorems are turned into abstract
   150   Before selected function theorems are turned into abstract
   197 text_raw {*
   192 text_raw {*
   198   \end{itemize}
   193   \end{itemize}
   199 *}
   194 *}
   200 
   195 
   201 text {*
   196 text {*
   202   \emph{Function transformers} provide a very general interface,
   197   \noindent \emph{Function transformers} provide a very general interface,
   203   transforming a list of function theorems to another
   198   transforming a list of function theorems to another
   204   list of function theorems, provided that neither the heading
   199   list of function theorems, provided that neither the heading
   205   constant nor its type change.  The @{term "0\<Colon>nat"} / @{const Suc}
   200   constant nor its type change.  The @{term "0\<Colon>nat"} / @{const Suc}
   206   pattern elimination implemented in
   201   pattern elimination implemented in
   207   theory @{text Efficient_Nat} (see \secref{eff_nat}) uses this
   202   theory @{text Efficient_Nat} (see \secref{eff_nat}) uses this
   213   mechanism to inspect the impact of a preprocessor setup
   208   mechanism to inspect the impact of a preprocessor setup
   214   on defining equations.
   209   on defining equations.
   215 
   210 
   216   \begin{warn}
   211   \begin{warn}
   217     The attribute \emph{code unfold}
   212     The attribute \emph{code unfold}
   218     associated with the existing code generator also applies to
   213     associated with the @{text "SML code generator"} also applies to
   219     the new one: \emph{code unfold} implies \emph{code inline}.
   214     the @{text "generic code generator"}:
       
   215     \emph{code unfold} implies \emph{code inline}.
   220   \end{warn}
   216   \end{warn}
   221 *}
   217 *}
   222 
   218 
   223 subsection {* Datatypes \label{sec:datatypes} *}
   219 subsection {* Datatypes \label{sec:datatypes} *}
   224 
   220 
   244 
   240 
   245 definition %quoteme  Dig1 :: "nat \<Rightarrow> nat" where
   241 definition %quoteme  Dig1 :: "nat \<Rightarrow> nat" where
   246   "Dig1 n = Suc (2 * n)"
   242   "Dig1 n = Suc (2 * n)"
   247 
   243 
   248 text {*
   244 text {*
   249   \noindent We will use these two ">digits"< to represent natural numbers
   245   \noindent We will use these two \qt{digits} to represent natural numbers
   250   in binary digits, e.g.:
   246   in binary digits, e.g.:
   251 *}
   247 *}
   252 
   248 
   253 lemma %quoteme 42: "42 = Dig0 (Dig1 (Dig0 (Dig1 (Dig0 1))))"
   249 lemma %quoteme 42: "42 = Dig0 (Dig1 (Dig0 (Dig1 (Dig0 1))))"
   254   by (simp add: Dig0_def Dig1_def)
   250   by (simp add: Dig0_def Dig1_def)
   297 *}
   293 *}
   298 
   294 
   299 text %quoteme {*@{code_stmts "op + \<Colon> nat \<Rightarrow> nat \<Rightarrow> nat" (SML)}*}
   295 text %quoteme {*@{code_stmts "op + \<Colon> nat \<Rightarrow> nat \<Rightarrow> nat" (SML)}*}
   300 
   296 
   301 text {*
   297 text {*
   302   \medskip
   298   \noindent From this example, it can be easily glimpsed that using own constructor sets
   303 
       
   304   From this example, it can be easily glimpsed that using own constructor sets
       
   305   is a little delicate since it changes the set of valid patterns for values
   299   is a little delicate since it changes the set of valid patterns for values
   306   of that type.  Without going into much detail, here some practical hints:
   300   of that type.  Without going into much detail, here some practical hints:
   307 
   301 
   308   \begin{itemize}
   302   \begin{itemize}
   309     \item When changing the constructor set for datatypes, take care to
   303     \item When changing the constructor set for datatypes, take care to
   332 text {*
   326 text {*
   333   Surely you have already noticed how equality is treated
   327   Surely you have already noticed how equality is treated
   334   by the code generator:
   328   by the code generator:
   335 *}
   329 *}
   336 
   330 
   337 primrec %quoteme
   331 primrec %quoteme collect_duplicates :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   338   collect_duplicates :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   332   "collect_duplicates xs ys [] = xs"
   339     "collect_duplicates xs ys [] = xs"
       
   340   | "collect_duplicates xs ys (z#zs) = (if z \<in> set xs
   333   | "collect_duplicates xs ys (z#zs) = (if z \<in> set xs
   341       then if z \<in> set ys
   334       then if z \<in> set ys
   342         then collect_duplicates xs ys zs
   335         then collect_duplicates xs ys zs
   343         else collect_duplicates xs (z#ys) zs
   336         else collect_duplicates xs (z#ys) zs
   344       else collect_duplicates (z#xs) (z#ys) zs)"
   337       else collect_duplicates (z#xs) (z#ys) zs)"
   354 text {*
   347 text {*
   355   \noindent Obviously, polymorphic equality is implemented the Haskell
   348   \noindent Obviously, polymorphic equality is implemented the Haskell
   356   way using a type class.  How is this achieved?  HOL introduces
   349   way using a type class.  How is this achieved?  HOL introduces
   357   an explicit class @{class eq} with a corresponding operation
   350   an explicit class @{class eq} with a corresponding operation
   358   @{const eq_class.eq} such that @{thm eq [no_vars]}.
   351   @{const eq_class.eq} such that @{thm eq [no_vars]}.
   359   The preprocessing framework does the rest.
   352   The preprocessing framework does the rest by propagating the
       
   353   @{class eq} constraints through all dependent defining equations.
   360   For datatypes, instances of @{class eq} are implicitly derived
   354   For datatypes, instances of @{class eq} are implicitly derived
   361   when possible.  For other types, you may instantiate @{text eq}
   355   when possible.  For other types, you may instantiate @{text eq}
   362   manually like any other type class.
   356   manually like any other type class.
   363 
   357 
   364   Though this @{text eq} class is designed to get rarely in
   358   Though this @{text eq} class is designed to get rarely in
   365   the way, a subtlety
   359   the way, a subtlety
   366   enters the stage when definitions of overloaded constants
   360   enters the stage when definitions of overloaded constants
   367   are dependent on operational equality.  For example, let
   361   are dependent on operational equality.  For example, let
   368   us define a lexicographic ordering on tuples:
   362   us define a lexicographic ordering on tuples
   369 *}
   363   (also see theory @{theory Product_ord}):
   370 
   364 *}
   371 instantiation %quoteme * :: (ord, ord) ord
   365 
       
   366 instantiation %quoteme "*" :: (order, order) order
   372 begin
   367 begin
   373 
   368 
   374 definition %quoteme [code func del]:
   369 definition %quoteme [code func del]:
   375   "p1 < p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in x1 < x2 \<or> (x1 = x2 \<and> y1 < y2))"
   370   "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y"
   376 
   371 
   377 definition %quoteme [code func del]:
   372 definition %quoteme [code func del]:
   378   "p1 \<le> p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2))"
   373   "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y"
   379 
   374 
   380 instance %quoteme ..
   375 instance %quoteme proof
       
   376 qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans)
   381 
   377 
   382 end %quoteme
   378 end %quoteme
   383 
   379 
   384 lemma %quoteme ord_prod [code func]:
   380 lemma %quoteme order_prod [code func]:
   385   "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) < (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)"
   381   "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
   386   "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) \<le> (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2)"
   382      x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
   387   unfolding less_prod_def less_eq_prod_def by simp_all
   383   "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
       
   384      x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
       
   385   by (simp_all add: less_prod_def less_eq_prod_def)
   388 
   386 
   389 text {*
   387 text {*
   390   \noindent Then code generation will fail.  Why?  The definition
   388   \noindent Then code generation will fail.  Why?  The definition
   391   of @{term "op \<le>"} depends on equality on both arguments,
   389   of @{term "op \<le>"} depends on equality on both arguments,
   392   which are polymorphic and impose an additional @{class eq}
   390   which are polymorphic and impose an additional @{class eq}
   393   class constraint, which the preprocessort does not propagate for technical
   391   class constraint, which the preprocessor does not propagate
   394   reasons.
   392   (for technical reasons).
   395 
   393 
   396   The solution is to add @{class eq} explicitly to the first sort arguments in the
   394   The solution is to add @{class eq} explicitly to the first sort arguments in the
   397   code theorems:
   395   code theorems:
   398 *}
   396 *}
   399 
   397 
   400 lemma ord_prod_code [code func]:
   398 lemma %quoteme order_prod_code [code func]:
   401   "(x1 \<Colon> 'a\<Colon>{ord, eq}, y1 \<Colon> 'b\<Colon>ord) < (x2, y2) \<longleftrightarrow>
   399   "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
   402     x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)"
   400      x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
   403   "(x1 \<Colon> 'a\<Colon>{ord, eq}, y1 \<Colon> 'b\<Colon>ord) \<le> (x2, y2) \<longleftrightarrow>
   401   "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
   404     x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2)"
   402      x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
   405   unfolding ord_prod by rule+
   403   by (simp_all add: less_prod_def less_eq_prod_def)
   406 
   404 
   407 text {*
   405 text {*
   408   \noindent Then code generation succeeds:
   406   \noindent Then code generation succeeds:
   409 *}
   407 *}
   410 
   408 
   411 text %quoteme {*@{code_stmts "op \<le> \<Colon> 'a\<Colon>{eq, ord} \<times> 'b\<Colon>ord \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool" (SML)}*}
   409 text %quoteme {*@{code_stmts "op \<le> \<Colon> _ \<times> _ \<Rightarrow> _ \<times> _ \<Rightarrow> bool" (SML)}*}
   412 
   410 
   413 text {*
   411 text {*
   414   In some cases, the automatically derived defining equations
   412   In some cases, the automatically derived defining equations
   415   for equality on a particular type may not be appropriate.
   413   for equality on a particular type may not be appropriate.
   416   As example, watch the following datatype representing
   414   As example, watch the following datatype representing
   432   instance @{text "monotype \<Colon> eq"}, which itself requires
   430   instance @{text "monotype \<Colon> eq"}, which itself requires
   433   @{thm monotype_eq [no_vars]};  Haskell has no problem with mutually
   431   @{thm monotype_eq [no_vars]};  Haskell has no problem with mutually
   434   recursive @{text inst} and @{text fun} definitions,
   432   recursive @{text inst} and @{text fun} definitions,
   435   but the SML serializer does not support this.
   433   but the SML serializer does not support this.
   436 
   434 
   437   In such cases, you have to provide you own equality equations
   435   In such cases, you have to provide your own equality equations
   438   involving auxiliary constants.  In our case,
   436   involving auxiliary constants.  In our case,
   439   @{const [show_types] list_all2} can do the job:
   437   @{const [show_types] list_all2} can do the job:
   440 *}
   438 *}
   441 
   439 
   442 lemma %quoteme monotype_eq_list_all2 [code func]:
   440 lemma %quoteme monotype_eq_list_all2 [code func]: