author | wenzelm |
Mon, 30 Nov 2015 14:24:51 +0100 | |
changeset 61757 | 0d399131008f |
parent 58889 | 5b7a9633cfa8 |
child 62910 | f37878ebba65 |
permissions | -rw-r--r-- |
53935 | 1 |
(* Title: HOL/ex/ML.thy |
2 |
Author: Makarius |
|
3 |
*) |
|
4 |
||
58889 | 5 |
section \<open>Isabelle/ML basics\<close> |
53935 | 6 |
|
7 |
theory "ML" |
|
8 |
imports Main |
|
9 |
begin |
|
10 |
||
58616 | 11 |
section \<open>ML expressions\<close> |
53935 | 12 |
|
58616 | 13 |
text \<open> |
61757 | 14 |
The Isabelle command \<^theory_text>\<open>ML\<close> allows to embed Isabelle/ML source into the |
15 |
formal text. It is type-checked, compiled, and run within that environment. |
|
53935 | 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. |
|
58616 | 21 |
\<close> |
53935 | 22 |
|
58616 | 23 |
ML \<open>1 + 1\<close> |
53935 | 24 |
|
58616 | 25 |
ML \<open>val a = 1\<close> |
26 |
ML \<open>val b = 1\<close> |
|
27 |
ML \<open>val c = a + b\<close> |
|
53935 | 28 |
|
29 |
||
58616 | 30 |
section \<open>Antiquotations\<close> |
53935 | 31 |
|
61757 | 32 |
text \<open> |
33 |
There are some language extensions (via antiquotations), as explained in the |
|
34 |
``Isabelle/Isar implementation manual'', chapter 0. |
|
35 |
\<close> |
|
53935 | 36 |
|
58616 | 37 |
ML \<open>length []\<close> |
38 |
ML \<open>@{assert} (length [] = 0)\<close> |
|
53935 | 39 |
|
40 |
||
58616 | 41 |
text \<open>Formal entities from the surrounding context may be referenced as |
42 |
follows:\<close> |
|
43 |
||
61757 | 44 |
term "1 + 1" \<comment> \<open>term within theory source\<close> |
58616 | 45 |
|
46 |
ML \<open>@{term "1 + 1"} (* term as symbolic ML datatype value *)\<close> |
|
53935 | 47 |
|
58616 | 48 |
ML \<open>@{term "1 + (1::int)"}\<close> |
49 |
||
50 |
||
61757 | 51 |
ML \<open> |
52 |
(* formal source with position information *) |
|
53 |
val s = \<open>1 + 1\<close>; |
|
54 |
||
55 |
(* read term via old-style string interface *) |
|
56 |
val t = Syntax.read_term @{context} (Syntax.implode_input s); |
|
57 |
\<close> |
|
58 |
||
58616 | 59 |
section \<open>IDE support\<close> |
60 |
||
61 |
text \<open> |
|
53935 | 62 |
ML embedded into the Isabelle environment is connected to the Prover IDE. |
63 |
Poly/ML provides: |
|
61757 | 64 |
|
65 |
\<^item> precise positions for warnings / errors |
|
66 |
\<^item> markup for defining positions of identifiers |
|
67 |
\<^item> markup for inferred types of sub-expressions |
|
68 |
\<^item> pretty-printing of ML values with markup |
|
69 |
\<^item> completion of ML names |
|
70 |
\<^item> source-level debugger |
|
58616 | 71 |
\<close> |
53935 | 72 |
|
58616 | 73 |
ML \<open>fn i => fn list => length list + i\<close> |
53935 | 74 |
|
75 |
||
58616 | 76 |
section \<open>Example: factorial and ackermann function in Isabelle/ML\<close> |
53935 | 77 |
|
58616 | 78 |
ML \<open> |
53935 | 79 |
fun factorial 0 = 1 |
80 |
| factorial n = n * factorial (n - 1) |
|
58616 | 81 |
\<close> |
53935 | 82 |
|
58616 | 83 |
ML \<open>factorial 42\<close> |
84 |
ML \<open>factorial 10000 div factorial 9999\<close> |
|
53935 | 85 |
|
58616 | 86 |
text \<open>See @{url "http://mathworld.wolfram.com/AckermannFunction.html"}\<close> |
87 |
||
88 |
ML \<open> |
|
53935 | 89 |
fun ackermann 0 n = n + 1 |
90 |
| ackermann m 0 = ackermann (m - 1) 1 |
|
91 |
| ackermann m n = ackermann (m - 1) (ackermann m (n - 1)) |
|
58616 | 92 |
\<close> |
53935 | 93 |
|
58616 | 94 |
ML \<open>timeit (fn () => ackermann 3 10)\<close> |
53935 | 95 |
|
96 |
||
58616 | 97 |
section \<open>Parallel Isabelle/ML\<close> |
53935 | 98 |
|
58616 | 99 |
text \<open> |
53935 | 100 |
Future.fork/join/cancel manage parallel evaluation. |
101 |
||
61757 | 102 |
Note that within Isabelle theory documents, the top-level command boundary |
103 |
may not be transgressed without special precautions. This is normally |
|
104 |
managed by the system when performing parallel proof checking. |
|
105 |
\<close> |
|
53935 | 106 |
|
58616 | 107 |
ML \<open> |
53935 | 108 |
val x = Future.fork (fn () => ackermann 3 10); |
109 |
val y = Future.fork (fn () => ackermann 3 10); |
|
110 |
val z = Future.join x + Future.join y |
|
58616 | 111 |
\<close> |
53935 | 112 |
|
61757 | 113 |
text \<open> |
114 |
The @{ML_structure Par_List} module provides high-level combinators for |
|
115 |
parallel list operations. |
|
116 |
\<close> |
|
53935 | 117 |
|
58616 | 118 |
ML \<open>timeit (fn () => map (fn n => ackermann 3 n) (1 upto 10))\<close> |
119 |
ML \<open>timeit (fn () => Par_List.map (fn n => ackermann 3 n) (1 upto 10))\<close> |
|
53935 | 120 |
|
121 |
||
58616 | 122 |
section \<open>Function specifications in Isabelle/HOL\<close> |
53935 | 123 |
|
124 |
fun factorial :: "nat \<Rightarrow> nat" |
|
125 |
where |
|
126 |
"factorial 0 = 1" |
|
127 |
| "factorial (Suc n) = Suc n * factorial n" |
|
128 |
||
61757 | 129 |
term "factorial 4" \<comment> \<open>symbolic term\<close> |
130 |
value "factorial 4" \<comment> \<open>evaluation via ML code generation in the background\<close> |
|
53935 | 131 |
|
56279
b4d874f6c6be
clarified options ML_source_trace and ML_exception_trace (NB: the latter needs to be a system option, since the context is sometimes not available, e.g. for 'theory' command);
wenzelm
parents:
55837
diff
changeset
|
132 |
declare [[ML_source_trace]] |
61757 | 133 |
ML \<open>@{term "factorial 4"}\<close> \<comment> \<open>symbolic term in ML\<close> |
134 |
ML \<open>@{code "factorial"}\<close> \<comment> \<open>ML code from function specification\<close> |
|
53935 | 135 |
|
136 |
||
137 |
fun ackermann :: "nat \<Rightarrow> nat \<Rightarrow> nat" |
|
138 |
where |
|
139 |
"ackermann 0 n = n + 1" |
|
140 |
| "ackermann (Suc m) 0 = ackermann m 1" |
|
141 |
| "ackermann (Suc m) (Suc n) = ackermann m (ackermann (Suc m) n)" |
|
142 |
||
143 |
value "ackermann 3 5" |
|
144 |
||
145 |
end |
|
146 |