427
|
1 |
(*<*)
|
|
2 |
theory CallML
|
459
|
3 |
imports "~~/src/HOL/Number_Theory/Primes"
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
4 |
"~~/src/HOL/Library/Code_Target_Numeral"
|
427
|
5 |
begin
|
|
6 |
(*>*)
|
|
7 |
|
|
8 |
section {* Calling ML Functions from within HOL \label{rec:callml} *}
|
|
9 |
|
|
10 |
text{*
|
|
11 |
{\bf Problem:}
|
|
12 |
How to call ML functions from within HOL?\smallskip
|
|
13 |
|
|
14 |
{\bf Solution:} This can be achieved with \isacommand{code\_const}
|
|
15 |
and \isacommand{code\_reflect}.\smallskip
|
|
16 |
|
|
17 |
|
|
18 |
To make it clear we mean here calling unverified ML functions from within
|
|
19 |
HOL! The motivation is the paradigm of \emph{result checking}: rather than
|
441
|
20 |
verifying some complicated algorithm, have the algorithm produce an easily
|
|
21 |
checkable certificate. For example, instead of verifying an algorithm for
|
|
22 |
testing non-primality, have an algorithm that produces a factor as a witness to
|
|
23 |
non-primality.
|
427
|
24 |
|
441
|
25 |
The algorithm is an ML function finding a factor of a number. We first
|
|
26 |
declare its type:
|
427
|
27 |
*}
|
|
28 |
|
|
29 |
consts factor :: "nat \<Rightarrow> nat"
|
|
30 |
|
|
31 |
text{*
|
441
|
32 |
Its definition will be given below in ML. But the whole point is that
|
427
|
33 |
we can prove non-primality via @{const factor}, no matter what its
|
|
34 |
actual definition is:
|
|
35 |
*}
|
|
36 |
|
|
37 |
lemma factor_non_prime:
|
428
|
38 |
"let k = factor n in k \<noteq> 1 \<and> k \<noteq> n \<and> k dvd n \<Longrightarrow> \<not> prime n"
|
|
39 |
by (auto simp: prime_nat_def Let_def)
|
427
|
40 |
|
|
41 |
text{*
|
|
42 |
Note that the premise is executable once we have defined
|
|
43 |
@{const factor}. Here is a trivial definition in ML:
|
|
44 |
*}
|
|
45 |
|
517
d8c376662bb4
removed special ML-setup and replaced it by explicit markups (i.e., %grayML)
Christian Urban <urbanc@in.tum.de>
diff
changeset
|
46 |
ML %grayML{*fun factor n = if n = 4 then 2 else 1*}
|
427
|
47 |
|
|
48 |
text{*
|
|
49 |
Of course this trivial definition of @{const factor} could have been given
|
|
50 |
directly in HOL rather than ML. But by going to the ML level, all of ML is
|
|
51 |
at our disposal, including arrays and references, features that are less
|
|
52 |
easily emulated in HOL. In fact, we could even call some external software
|
|
53 |
from ML, e.g.\ a computer algebra system.
|
|
54 |
|
|
55 |
It should be noted, however, that in this example you need to import the
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
56 |
theory @{theory Code_Target_Numeral} in order to force the HOL-type @{typ nat} to
|
531
|
57 |
be implemented by the ML-type @{text "int"}.
|
|
58 |
|
|
59 |
\begin{graybox}\small
|
|
60 |
\isacommand{theory}~@{text CallML}\\
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
61 |
\isacommand{imports}~@{text Main} @{text [quotes] "~~/src/HOL/Library/Code_Target_Numeral"}\\
|
531
|
62 |
...
|
|
63 |
\end{graybox}
|
|
64 |
|
|
65 |
|
|
66 |
Thus the ML implementation of
|
427
|
67 |
@{const factor} must be and is of type @{text "int -> int"}. Now it is time
|
|
68 |
to connect the two levels:
|
|
69 |
*}
|
|
70 |
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
71 |
definition factor_integer :: "integer \<Rightarrow> integer"
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
72 |
where
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
73 |
[code del]: "factor_integer = integer_of_nat \<circ> factor \<circ> nat_of_integer"
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
74 |
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
75 |
lemma [code]:
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
76 |
"factor = nat_of_integer \<circ> factor_integer \<circ> integer_of_nat"
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
77 |
by (simp add: factor_integer_def fun_eq_iff)
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
78 |
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
79 |
code_const factor_integer (SML "factor")
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
80 |
code_reserved SML factor
|
427
|
81 |
|
|
82 |
text{*
|
|
83 |
The result of this declaration is that the HOL-function @{const factor}
|
|
84 |
is executable and command
|
|
85 |
*}
|
|
86 |
|
|
87 |
value "factor 4"
|
|
88 |
|
|
89 |
text{*
|
|
90 |
yields the expected result @{text 2}. Similarly we can prove that
|
|
91 |
@{text 4} is not prime:
|
|
92 |
*}
|
|
93 |
|
448
|
94 |
lemma "\<not> prime (4::nat)"
|
427
|
95 |
apply(rule factor_non_prime)
|
|
96 |
apply eval
|
|
97 |
done
|
|
98 |
|
|
99 |
text{*
|
428
|
100 |
Note, however, the command \isacommand{code\_const} cannot check that the ML function
|
427
|
101 |
has the required type. Therefore in the worst case a type mismatch will be detected by
|
|
102 |
the ML-compiler when we try to evaluate an expression involving @{const
|
|
103 |
factor}. It could also happen that @{const factor} is (accidentally)
|
|
104 |
redefined on the ML level later on. But remember that we do not assume
|
|
105 |
anything about @{const factor} on the HOL-level. Hence no definition of
|
|
106 |
@{const factor} can ever lead to an incorrect proof. Of course ``wrong''
|
|
107 |
definitions can lead to compile time or run time exceptions, or to failed
|
|
108 |
proofs.
|
|
109 |
|
428
|
110 |
The above example was easy because we forced Isabelle (via the inclusion of the
|
|
111 |
theory @{theory
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
112 |
Code_Target_Numeral}) to implement @{typ nat} by @{text int}, a predefined
|
427
|
113 |
ML-type. By default, Isabelle implements, for example, the HOL-type
|
|
114 |
@{text list} by the corresponding ML-type. Thus the following variation
|
|
115 |
on @{const factor} also works:
|
|
116 |
*}
|
|
117 |
|
|
118 |
consts factor2 :: "nat \<Rightarrow> nat list" (*<*)(*>*)
|
517
d8c376662bb4
removed special ML-setup and replaced it by explicit markups (i.e., %grayML)
Christian Urban <urbanc@in.tum.de>
diff
changeset
|
119 |
ML %grayML{*fun factor2 n = if n = 4 then [2] else []*}(*<*)(*>*)
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
120 |
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
121 |
definition factor2_integer :: "integer \<Rightarrow> integer list"
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
122 |
where
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
123 |
[code del]: "factor2_integer = map integer_of_nat \<circ> factor2 \<circ> nat_of_integer"
|
427
|
124 |
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
125 |
lemma [code]:
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
126 |
"factor2 = map nat_of_integer \<circ> factor2_integer \<circ> integer_of_nat"
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
127 |
by (simp add: factor2_integer_def fun_eq_iff comp_def)
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
128 |
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
129 |
code_const factor2_integer (SML "factor2")
|
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
130 |
code_reserved SML factor2
|
427
|
131 |
|
|
132 |
text{*
|
|
133 |
The first line declares the type of @{const factor2}; the second
|
|
134 |
gives its implementation in ML; the third makes it executable
|
|
135 |
in HOL, and the last is just a test. In this way, you can easily
|
|
136 |
interface with ML-functions whose types involve
|
428
|
137 |
@{text bool}, @{text int}, @{text list}, @{text option} and pairs,
|
427
|
138 |
only. If you have arbitrary tuples, for example, then you have to code
|
|
139 |
them as nested pairs.
|
|
140 |
*}
|
|
141 |
|
542
4b96e3c8b33e
updated the CallML section with the help from Florian
Christian Urban <christian dot urban at kcl dot ac dot uk>
diff
changeset
|
142 |
value "factor2 4"
|
427
|
143 |
|
|
144 |
end
|
517
d8c376662bb4
removed special ML-setup and replaced it by explicit markups (i.e., %grayML)
Christian Urban <urbanc@in.tum.de>
diff
changeset
|
145 |
(*>*)
|