src/HOL/ex/ML.thy
changeset 53935 59c6dbdf0a38
child 53948 2a4c156e6d36
equal deleted inserted replaced
53934:787242dbb49e 53935:59c6dbdf0a38
       
     1 (*  Title:      HOL/ex/ML.thy
       
     2     Author:     Makarius
       
     3 *)
       
     4 
       
     5 header {* Isabelle/ML basics *}
       
     6 
       
     7 theory "ML"
       
     8 imports Main
       
     9 begin
       
    10 
       
    11 section {* ML expressions *}
       
    12 
       
    13 text {*
       
    14   The Isabelle command 'ML' allows to embed Isabelle/ML source into the formal
       
    15   text. It is type-checked, compiled, and run within that environment.
       
    16 
       
    17   Note that side-effects should be avoided, unless the intention is to change
       
    18   global parameters of the run-time environment (rare).
       
    19 
       
    20   ML top-level bindings are managed within the theory context.
       
    21 *}
       
    22 
       
    23 ML {* 1 + 1 *}
       
    24 
       
    25 ML {* val a = 1 *}
       
    26 ML {* val b = 1 *}
       
    27 ML {* val c = a + b *}
       
    28 
       
    29 
       
    30 section {* Antiquotations *}
       
    31 
       
    32 text {* There are some language extensions (via antiquotations), as explained in
       
    33   the "Isabelle/Isar implementation manual", chapter 0. *}
       
    34 
       
    35 ML {* length [] *}
       
    36 ML {* @{assert} (length [] = 0) *}
       
    37 
       
    38 
       
    39 text {* Formal entities from the surrounding context may be referenced as
       
    40   follows: *}
       
    41 
       
    42 term "1 + 1"   -- "term within theory source"
       
    43 
       
    44 ML {*
       
    45   @{term "1 + 1"}   (* term as symbolic ML datatype value *)
       
    46 *}
       
    47 
       
    48 ML {*
       
    49   @{term "1 + (1::int)"}
       
    50 *}
       
    51 
       
    52 
       
    53 section {* IDE support *}
       
    54 
       
    55 text {*
       
    56   ML embedded into the Isabelle environment is connected to the Prover IDE.
       
    57   Poly/ML provides:
       
    58     \<bullet> precise positions for warnings / errors
       
    59     \<bullet> markup for defining positions of identifiers
       
    60     \<bullet> markup for inferred types of sub-expressions
       
    61 *}
       
    62 
       
    63 ML {* fn i => fn list => length list + i *}
       
    64 
       
    65 
       
    66 section {* Example: factorial and ackermann function in Isabelle/ML *}
       
    67 
       
    68 ML {*
       
    69   fun factorial 0 = 1
       
    70     | factorial n = n * factorial (n - 1)
       
    71 *}
       
    72 
       
    73 ML "factorial 42"
       
    74 ML "factorial 10000 div factorial 9999"
       
    75 
       
    76 text {*
       
    77   See http://mathworld.wolfram.com/AckermannFunction.html
       
    78 *}
       
    79 
       
    80 ML {*
       
    81   fun ackermann 0 n = n + 1
       
    82     | ackermann m 0 = ackermann (m - 1) 1
       
    83     | ackermann m n = ackermann (m - 1) (ackermann m (n - 1))
       
    84 *}
       
    85 
       
    86 ML {* timeit (fn () => ackermann 3 10) *}
       
    87 
       
    88 
       
    89 section {* Parallel Isabelle/ML *}
       
    90 
       
    91 text {*
       
    92   Future.fork/join/cancel manage parallel evaluation.
       
    93 
       
    94   Note that within Isabelle theory documents, the top-level command boundary may
       
    95   not be transgressed without special precautions. This is normally managed by
       
    96   the system when performing parallel proof checking. *}
       
    97 
       
    98 ML {*
       
    99   val x = Future.fork (fn () => ackermann 3 10);
       
   100   val y = Future.fork (fn () => ackermann 3 10);
       
   101   val z = Future.join x + Future.join y
       
   102 *}
       
   103 
       
   104 text {*
       
   105   The @{ML_struct Par_List} module provides high-level combinators for
       
   106   parallel list operations. *}
       
   107 
       
   108 ML {* timeit (fn () => map (fn n => ackermann 3 n) (1 upto 10)) *}
       
   109 ML {* timeit (fn () => Par_List.map (fn n => ackermann 3 n) (1 upto 10)) *}
       
   110 
       
   111 
       
   112 section {* Function specifications in Isabelle/HOL *}
       
   113 
       
   114 fun factorial :: "nat \<Rightarrow> nat"
       
   115 where
       
   116   "factorial 0 = 1"
       
   117 | "factorial (Suc n) = Suc n * factorial n"
       
   118 
       
   119 term "factorial 4"  -- "symbolic term"
       
   120 value "factorial 4"  -- "evaluation via ML code generation in the background"
       
   121 
       
   122 declare [[ML_trace]]
       
   123 ML {* @{term "factorial 4"} *}  -- "symbolic term in ML"
       
   124 ML {* @{code "factorial"} *}  -- "ML code from function specification"
       
   125 
       
   126 
       
   127 fun ackermann :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
   128 where
       
   129   "ackermann 0 n = n + 1"
       
   130 | "ackermann (Suc m) 0 = ackermann m 1"
       
   131 | "ackermann (Suc m) (Suc n) = ackermann m (ackermann (Suc m) n)"
       
   132 
       
   133 value "ackermann 3 5"
       
   134 
       
   135 end
       
   136