|
13267
|
1 |
(*<*)theory Logic = Main:(*>*)
|
|
13310
|
2 |
text{* We begin by looking at a simplified grammar for Isar proofs
|
|
|
3 |
where paranthesis are used for grouping and $^?$ indicates an optional item:
|
|
13267
|
4 |
\begin{center}
|
|
|
5 |
\begin{tabular}{lrl}
|
|
13307
|
6 |
\emph{proof} & ::= & \isakeyword{proof} \emph{method}$^?$
|
|
13267
|
7 |
\emph{statement}*
|
|
13307
|
8 |
\isakeyword{qed} \\
|
|
|
9 |
&$\mid$& \isakeyword{by} \emph{method}\\[1ex]
|
|
|
10 |
\emph{statement} &::= & \isakeyword{fix} \emph{variables} \\
|
|
13310
|
11 |
&$\mid$& \isakeyword{assume} \emph{proposition}
|
|
|
12 |
(\isakeyword{and} \emph{proposition})*\\
|
|
13307
|
13 |
&$\mid$& (\isakeyword{from} \emph{label}$^*$ $\mid$
|
|
13310
|
14 |
\isakeyword{then})$^?$
|
|
|
15 |
(\isakeyword{show} $\mid$ \isakeyword{have})
|
|
|
16 |
\emph{string} \emph{proof} \\[1ex]
|
|
13267
|
17 |
\emph{proposition} &::=& (\emph{label}{\bf:})$^?$ \emph{string}
|
|
|
18 |
\end{tabular}
|
|
|
19 |
\end{center}
|
|
|
20 |
|
|
|
21 |
This is a typical proof skeleton:
|
|
|
22 |
\begin{center}
|
|
|
23 |
\begin{tabular}{@ {}ll}
|
|
13307
|
24 |
\isakeyword{proof}\\
|
|
|
25 |
\hspace*{3ex}\isakeyword{assume} @{text"\""}\emph{the-assm}@{text"\""}\\
|
|
13310
|
26 |
\hspace*{3ex}\isakeyword{have} @{text"\""}\dots@{text"\""} & -- intermediate result\\
|
|
13267
|
27 |
\hspace*{3ex}\vdots\\
|
|
13310
|
28 |
\hspace*{3ex}\isakeyword{have} @{text"\""}\dots@{text"\""} & -- intermediate result\\
|
|
13307
|
29 |
\hspace*{3ex}\isakeyword{show} @{text"\""}\emph{the-concl}@{text"\""}\\
|
|
|
30 |
\isakeyword{qed}
|
|
13267
|
31 |
\end{tabular}
|
|
|
32 |
\end{center}
|
|
13310
|
33 |
It proves \emph{the-assm}~@{text"\<Longrightarrow>"}~\emph{the-concl}.
|
|
|
34 |
Text starting with ``--'' is a comment.
|
|
|
35 |
*}
|
|
13267
|
36 |
|
|
|
37 |
section{*Logic*}
|
|
|
38 |
|
|
|
39 |
subsection{*Propositional logic*}
|
|
|
40 |
|
|
13294
|
41 |
subsubsection{*Introduction rules*}
|
|
|
42 |
|
|
13310
|
43 |
text{* We start with a really trivial toy proof to introduce the basic
|
|
|
44 |
features of structured proofs. *}
|
|
|
45 |
|
|
13267
|
46 |
lemma "A \<longrightarrow> A"
|
|
|
47 |
proof (rule impI)
|
|
13307
|
48 |
assume a: "A"
|
|
|
49 |
show "A" by(rule a)
|
|
13267
|
50 |
qed
|
|
|
51 |
|
|
|
52 |
text{*\noindent
|
|
13310
|
53 |
The operational reading: the \isakeyword{assume}-\isakeyword{show} block
|
|
|
54 |
proves @{prop"A \<Longrightarrow> A"},
|
|
13267
|
55 |
which rule @{thm[source]impI} turns into the desired @{prop"A \<longrightarrow> A"}.
|
|
|
56 |
However, this text is much too detailled for comfort. Therefore Isar
|
|
|
57 |
implements the following principle:
|
|
|
58 |
\begin{quote}\em
|
|
13310
|
59 |
Command \isakeyword{proof} automatically tries to select an introduction rule
|
|
13294
|
60 |
based on the goal and a predefined list of rules.
|
|
13267
|
61 |
\end{quote}
|
|
|
62 |
Here @{thm[source]impI} is applied automatically:
|
|
|
63 |
*}
|
|
|
64 |
|
|
|
65 |
lemma "A \<longrightarrow> A"
|
|
|
66 |
proof
|
|
13307
|
67 |
assume a: "A"
|
|
|
68 |
show "A" by(rule a)
|
|
13267
|
69 |
qed
|
|
|
70 |
|
|
13294
|
71 |
text{* Trivial proofs, in particular those by assumption, should be trivial
|
|
13307
|
72 |
to perform. Method ``.'' does just that (and a bit more --- see later). Thus
|
|
13294
|
73 |
naming of assumptions is often superfluous: *}
|
|
13267
|
74 |
|
|
|
75 |
lemma "A \<longrightarrow> A"
|
|
|
76 |
proof
|
|
|
77 |
assume "A"
|
|
13307
|
78 |
show "A" .
|
|
13267
|
79 |
qed
|
|
|
80 |
|
|
13307
|
81 |
text{* To hide proofs by assumption further, \isakeyword{by}@{text"(method)"}
|
|
13294
|
82 |
first applies @{text method} and then tries to solve all remaining subgoals
|
|
|
83 |
by assumption: *}
|
|
13267
|
84 |
|
|
13307
|
85 |
lemma "A \<longrightarrow> A \<and> A"
|
|
13267
|
86 |
proof
|
|
|
87 |
assume A
|
|
13307
|
88 |
show "A \<and> A" by(rule conjI)
|
|
13267
|
89 |
qed
|
|
|
90 |
|
|
13294
|
91 |
text{*\noindent A drawback of these implicit proofs by assumption is that it
|
|
|
92 |
is no longer obvious where an assumption is used.
|
|
13267
|
93 |
|
|
13310
|
94 |
Proofs of the form \isakeyword{by}@{text"(rule"}~\emph{name}@{text")"} can be
|
|
|
95 |
abbreviated to ``..''
|
|
|
96 |
if \emph{name} is one of the predefined introduction rules:
|
|
13294
|
97 |
*}
|
|
|
98 |
|
|
|
99 |
lemma "A \<longrightarrow> A \<and> A"
|
|
13267
|
100 |
proof
|
|
|
101 |
assume A
|
|
13294
|
102 |
show "A \<and> A" ..
|
|
13267
|
103 |
qed
|
|
|
104 |
|
|
13294
|
105 |
text{*\noindent
|
|
13310
|
106 |
This is what happens: first the matching introduction rule @{thm[source]conjI}
|
|
|
107 |
is applied (first ``.''), then the two subgoals are solved by assumption
|
|
|
108 |
(second ``.''). *}
|
|
13267
|
109 |
|
|
13294
|
110 |
subsubsection{*Elimination rules*}
|
|
13267
|
111 |
|
|
13294
|
112 |
text{*A typical elimination rule is @{thm[source]conjE}, $\land$-elimination:
|
|
|
113 |
@{thm[display,indent=5]conjE[no_vars]} In the following proof it is applied
|
|
|
114 |
by hand, after its first (``\emph{major}'') premise has been eliminated via
|
|
|
115 |
@{text"[OF AB]"}: *}
|
|
|
116 |
|
|
|
117 |
lemma "A \<and> B \<longrightarrow> B \<and> A"
|
|
13267
|
118 |
proof
|
|
13294
|
119 |
assume AB: "A \<and> B"
|
|
|
120 |
show "B \<and> A"
|
|
13310
|
121 |
proof (rule conjE[OF AB]) -- {*@{prop"(A \<Longrightarrow> B \<Longrightarrow> R) \<Longrightarrow> R"}*}
|
|
13267
|
122 |
assume A and B
|
|
13294
|
123 |
show ?thesis ..
|
|
13267
|
124 |
qed
|
|
|
125 |
qed
|
|
|
126 |
|
|
13294
|
127 |
text{*\noindent Note that the term @{text"?thesis"} always stands for the
|
|
13307
|
128 |
``current goal'', i.e.\ the enclosing \isakeyword{show} (or
|
|
|
129 |
\isakeyword{have}).
|
|
13267
|
130 |
|
|
13294
|
131 |
This is too much proof text. Elimination rules should be selected
|
|
|
132 |
automatically based on their major premise, the formula or rather connective
|
|
|
133 |
to be eliminated. In Isar they are triggered by propositions being fed
|
|
|
134 |
\emph{into} a proof block. Syntax:
|
|
|
135 |
\begin{center}
|
|
13307
|
136 |
\isakeyword{from} \emph{fact} \isakeyword{show} \emph{proposition}
|
|
13294
|
137 |
\end{center}
|
|
13307
|
138 |
where \emph{fact} stands for the name of a previously proved
|
|
13294
|
139 |
proposition, e.g.\ an assumption, an intermediate result or some global
|
|
|
140 |
theorem. The fact may also be modified with @{text of}, @{text OF} etc.
|
|
13307
|
141 |
This command applies an elimination rule (from a predefined list)
|
|
13294
|
142 |
whose first premise is solved by the fact. Thus: *}
|
|
13267
|
143 |
|
|
13294
|
144 |
lemma "A \<and> B \<longrightarrow> B \<and> A"
|
|
13267
|
145 |
proof
|
|
13294
|
146 |
assume AB: "A \<and> B"
|
|
|
147 |
from AB show "B \<and> A"
|
|
13267
|
148 |
proof
|
|
|
149 |
assume A and B
|
|
|
150 |
show ?thesis ..
|
|
|
151 |
qed
|
|
|
152 |
qed
|
|
|
153 |
|
|
13294
|
154 |
text{* Now we come a second important principle:
|
|
|
155 |
\begin{quote}\em
|
|
|
156 |
Try to arrange the sequence of propositions in a UNIX-like pipe,
|
|
|
157 |
such that the proof of each proposition builds on the previous proposition.
|
|
|
158 |
\end{quote}
|
|
|
159 |
The previous proposition can be referred to via the fact @{text this}.
|
|
|
160 |
This greatly reduces the need for explicit naming of propositions:
|
|
|
161 |
*}
|
|
|
162 |
|
|
|
163 |
lemma "A \<and> B \<longrightarrow> B \<and> A"
|
|
13267
|
164 |
proof
|
|
13294
|
165 |
assume "A \<and> B"
|
|
|
166 |
from this show "B \<and> A"
|
|
13267
|
167 |
proof
|
|
|
168 |
assume A and B
|
|
|
169 |
show ?thesis ..
|
|
|
170 |
qed
|
|
|
171 |
qed
|
|
|
172 |
|
|
13294
|
173 |
text{*\noindent
|
|
13307
|
174 |
A final simplification: \isakeyword{from}~@{text this} can be
|
|
|
175 |
abbreviated to \isakeyword{thus}.
|
|
13310
|
176 |
\medskip
|
|
13267
|
177 |
|
|
13294
|
178 |
Here is an alternative proof that operates purely by forward reasoning: *}
|
|
|
179 |
|
|
|
180 |
lemma "A \<and> B \<longrightarrow> B \<and> A"
|
|
13267
|
181 |
proof
|
|
13294
|
182 |
assume ab: "A \<and> B"
|
|
13267
|
183 |
from ab have a: A ..
|
|
|
184 |
from ab have b: B ..
|
|
13294
|
185 |
from b a show "B \<and> A" ..
|
|
13267
|
186 |
qed
|
|
|
187 |
|
|
13294
|
188 |
text{*\noindent
|
|
|
189 |
It is worth examining this text in detail because it exhibits a number of new features.
|
|
13267
|
190 |
|
|
13294
|
191 |
For a start, this is the first time we have proved intermediate propositions
|
|
13307
|
192 |
(\isakeyword{have}) on the way to the final \isakeyword{show}. This is the
|
|
13294
|
193 |
norm in any nontrival proof where one cannot bridge the gap between the
|
|
13307
|
194 |
assumptions and the conclusion in one step. Both \isakeyword{have}s above are
|
|
13294
|
195 |
proved automatically via @{thm[source]conjE} triggered by
|
|
13307
|
196 |
\isakeyword{from}~@{text ab}.
|
|
13267
|
197 |
|
|
13307
|
198 |
The \isakeyword{show} command illustrates two things:
|
|
13294
|
199 |
\begin{itemize}
|
|
13307
|
200 |
\item \isakeyword{from} can be followed by any number of facts.
|
|
|
201 |
Given \isakeyword{from}~@{text f}$_1$~\dots~@{text f}$_n$, \isakeyword{show}
|
|
13294
|
202 |
tries to find an elimination rule whose first $n$ premises can be proved
|
|
|
203 |
by the given facts in the given order.
|
|
|
204 |
\item If there is no matching elimination rule, introduction rules are tried,
|
|
|
205 |
again using the facts to prove the premises.
|
|
|
206 |
\end{itemize}
|
|
13310
|
207 |
In this case, the proof succeeds with @{thm[source]conjI}. Note that the proof
|
|
|
208 |
would fail if we had written \isakeyword{from}~@{text"a b"}
|
|
13307
|
209 |
instead of \isakeyword{from}~@{text"b a"}.
|
|
13294
|
210 |
|
|
|
211 |
This treatment of facts fed into a proof is not restricted to implicit
|
|
|
212 |
application of introduction and elimination rules but applies to explicit
|
|
|
213 |
application of rules as well. Thus you could replace the final ``..'' above
|
|
13307
|
214 |
with \isakeyword{by}@{text"(rule conjI)"}.
|
|
13294
|
215 |
|
|
13310
|
216 |
Note that Isar's predefined introduction and elimination rules include all the
|
|
13294
|
217 |
usual natural deduction rules for propositional logic. We conclude this
|
|
|
218 |
section with an extended example --- which rules are used implicitly where?
|
|
|
219 |
Rule @{thm[source]ccontr} is @{thm ccontr[no_vars]}.
|
|
|
220 |
*}
|
|
|
221 |
|
|
|
222 |
lemma "\<not>(A \<and> B) \<longrightarrow> \<not>A \<or> \<not>B"
|
|
13267
|
223 |
proof
|
|
13294
|
224 |
assume n: "\<not>(A \<and> B)"
|
|
|
225 |
show "\<not>A \<or> \<not>B"
|
|
13267
|
226 |
proof (rule ccontr)
|
|
13310
|
227 |
assume nn: "\<not>(\<not>A \<or> \<not>B)"
|
|
13267
|
228 |
from n show False
|
|
|
229 |
proof
|
|
13294
|
230 |
show "A \<and> B"
|
|
13267
|
231 |
proof
|
|
|
232 |
show A
|
|
|
233 |
proof (rule ccontr)
|
|
13294
|
234 |
assume "\<not>A"
|
|
13310
|
235 |
have "\<not>A \<or> \<not>B" ..
|
|
13267
|
236 |
from nn this show False ..
|
|
|
237 |
qed
|
|
|
238 |
next
|
|
|
239 |
show B
|
|
|
240 |
proof (rule ccontr)
|
|
13294
|
241 |
assume "\<not>B"
|
|
13310
|
242 |
have "\<not>A \<or> \<not>B" ..
|
|
13267
|
243 |
from nn this show False ..
|
|
|
244 |
qed
|
|
|
245 |
qed
|
|
|
246 |
qed
|
|
|
247 |
qed
|
|
|
248 |
qed;
|
|
|
249 |
|
|
13294
|
250 |
text{*\noindent Apart from demonstrating the strangeness of classical
|
|
|
251 |
arguments by contradiction, this example also introduces a new language
|
|
13307
|
252 |
feature to deal with multiple subgoals: \isakeyword{next}. When showing
|
|
13294
|
253 |
@{term"A \<and> B"} we need to show both @{term A} and @{term B}. Each subgoal
|
|
|
254 |
is proved separately, in \emph{any} order. The individual proofs are
|
|
13307
|
255 |
separated by \isakeyword{next}. *}
|
|
13267
|
256 |
|
|
13310
|
257 |
subsection{*Avoiding duplication*}
|
|
13267
|
258 |
|
|
13294
|
259 |
text{* So far our examples have been a bit unnatural: normally we want to
|
|
|
260 |
prove rules expressed with @{text"\<Longrightarrow>"}, not @{text"\<longrightarrow>"}. Here is an example:
|
|
|
261 |
*}
|
|
13267
|
262 |
|
|
13310
|
263 |
lemma "(A \<Longrightarrow> False) \<Longrightarrow> \<not> A"
|
|
13267
|
264 |
proof
|
|
13294
|
265 |
assume "A \<Longrightarrow> False" "A"
|
|
13267
|
266 |
thus False .
|
|
|
267 |
qed
|
|
|
268 |
|
|
13307
|
269 |
text{*\noindent The \isakeyword{proof} always works on the conclusion,
|
|
13294
|
270 |
@{prop"\<not>A"} in our case, thus selecting $\neg$-introduction. Hence we can
|
|
13310
|
271 |
additionally assume @{prop"A"}. Why does ``.'' prove @{prop False}? Because
|
|
|
272 |
``.'' tries any of the assumptions, including proper rules (here: @{prop"A \<Longrightarrow>
|
|
|
273 |
False"}), such that all of its premises can be solved directly by some other
|
|
|
274 |
assumption (here: @{prop A}).
|
|
13267
|
275 |
|
|
13294
|
276 |
This is all very well as long as formulae are small. Let us now look at some
|
|
|
277 |
devices to avoid repeating (possibly large) formulae. A very general method
|
|
|
278 |
is pattern matching: *}
|
|
13267
|
279 |
|
|
13294
|
280 |
lemma "(large_formula \<Longrightarrow> False) \<Longrightarrow> \<not> large_formula"
|
|
13267
|
281 |
(is "(?P \<Longrightarrow> _) \<Longrightarrow> _")
|
|
|
282 |
proof
|
|
|
283 |
assume "?P \<Longrightarrow> False" ?P
|
|
|
284 |
thus False .
|
|
|
285 |
qed
|
|
|
286 |
|
|
13294
|
287 |
text{*\noindent Any formula may be followed by
|
|
13307
|
288 |
@{text"("}\isakeyword{is}~\emph{pattern}@{text")"} which causes the pattern
|
|
13310
|
289 |
to be matched against the formula, instantiating the @{text"?"}-variables in
|
|
|
290 |
the pattern. Subsequent uses of these variables in other terms simply causes
|
|
|
291 |
them to be replaced by the terms they stand for.
|
|
13294
|
292 |
|
|
|
293 |
We can simplify things even more by stating the theorem by means of the
|
|
13307
|
294 |
\isakeyword{assumes} and \isakeyword{shows} primitives which allow direct
|
|
13294
|
295 |
naming of assumptions: *}
|
|
13267
|
296 |
|
|
|
297 |
lemma assumes A: "large_formula \<Longrightarrow> False"
|
|
13310
|
298 |
shows "\<not> large_formula" (is "\<not> ?P")
|
|
13267
|
299 |
proof
|
|
|
300 |
assume ?P
|
|
13294
|
301 |
with A show False .
|
|
13267
|
302 |
qed
|
|
|
303 |
|
|
13294
|
304 |
text{*\noindent Here we have used the abbreviation
|
|
|
305 |
\begin{center}
|
|
13307
|
306 |
\isakeyword{with}~\emph{facts} \quad = \quad
|
|
|
307 |
\isakeyword{from}~\emph{facts} \isakeyword{and} @{text this}
|
|
13294
|
308 |
\end{center}
|
|
|
309 |
|
|
|
310 |
Sometimes it is necessary to supress the implicit application of rules in a
|
|
13307
|
311 |
\isakeyword{proof}. For example \isakeyword{show}~@{prop"A \<or> B"} would
|
|
13294
|
312 |
trigger $\lor$-introduction, requiring us to prove @{prop A}. A simple
|
|
|
313 |
``@{text"-"}'' prevents this \emph{faut pas}: *}
|
|
|
314 |
|
|
|
315 |
lemma assumes AB: "A \<or> B" shows "B \<or> A"
|
|
13267
|
316 |
proof -
|
|
13294
|
317 |
from AB show ?thesis
|
|
|
318 |
proof
|
|
|
319 |
assume A show ?thesis ..
|
|
|
320 |
next
|
|
|
321 |
assume B show ?thesis ..
|
|
13267
|
322 |
qed
|
|
|
323 |
qed
|
|
|
324 |
|
|
13294
|
325 |
subsection{*Predicate calculus*}
|
|
|
326 |
|
|
13307
|
327 |
text{* Command \isakeyword{fix} introduces new local variables into a
|
|
13294
|
328 |
proof. It corresponds to @{text"\<And>"} (the universal quantifier at the
|
|
13307
|
329 |
meta-level) just like \isakeyword{assume}-\isakeyword{show} corresponds to
|
|
13294
|
330 |
@{text"\<Longrightarrow>"}. Here is a sample proof, annotated with the rules that are
|
|
|
331 |
applied implictly: *}
|
|
|
332 |
|
|
|
333 |
lemma assumes P: "\<forall>x. P x" shows "\<forall>x. P(f x)"
|
|
|
334 |
proof -- "@{thm[source]allI}: @{thm allI[no_vars]}"
|
|
|
335 |
fix a
|
|
|
336 |
from P show "P(f a)" .. --"@{thm[source]allE}: @{thm allE[no_vars]}"
|
|
|
337 |
qed
|
|
|
338 |
|
|
|
339 |
text{*\noindent Note that in the proof we have chosen to call the bound
|
|
|
340 |
variable @{term a} instead of @{term x} merely to show that the choice of
|
|
|
341 |
names is irrelevant.
|
|
|
342 |
|
|
|
343 |
Next we look at @{text"\<exists>"} which is a bit more tricky.
|
|
13267
|
344 |
*}
|
|
|
345 |
|
|
13294
|
346 |
lemma assumes Pf: "\<exists>x. P(f x)" shows "\<exists>y. P y"
|
|
13267
|
347 |
proof -
|
|
13294
|
348 |
from Pf show ?thesis
|
|
|
349 |
proof -- "@{thm[source]exE}: @{thm exE[no_vars]}"
|
|
|
350 |
fix a
|
|
|
351 |
assume "P(f a)"
|
|
|
352 |
show ?thesis .. --"@{thm[source]exI}: @{thm exI[no_vars]}"
|
|
|
353 |
qed
|
|
13267
|
354 |
qed
|
|
|
355 |
|
|
13294
|
356 |
text {*\noindent
|
|
|
357 |
Explicit $\exists$-elimination as seen above can become
|
|
|
358 |
cumbersome in practice. The derived Isar language element
|
|
13310
|
359 |
\isakeyword{obtain} provides a more handsome way to perform
|
|
13294
|
360 |
generalized existence reasoning:
|
|
13267
|
361 |
*}
|
|
|
362 |
|
|
13294
|
363 |
lemma assumes Pf: "\<exists>x. P(f x)" shows "\<exists>y. P y"
|
|
|
364 |
proof -
|
|
13310
|
365 |
from Pf obtain a where "P(f a)" ..
|
|
13294
|
366 |
thus "\<exists>y. P y" ..
|
|
13267
|
367 |
qed
|
|
|
368 |
|
|
13294
|
369 |
text {*\noindent Note how the proof text follows the usual mathematical style
|
|
13310
|
370 |
of concluding $P(x)$ from $\exists x. P(x)$, while carefully introducing $x$
|
|
|
371 |
as a new local variable. Technically, \isakeyword{obtain} is similar to
|
|
|
372 |
\isakeyword{fix} and \isakeyword{assume} together with a soundness proof of
|
|
|
373 |
the elimination involved. Thus it behaves similar to any other forward proof
|
|
|
374 |
element.
|
|
13267
|
375 |
|
|
13294
|
376 |
Here is a proof of a well known tautology which employs another useful
|
|
|
377 |
abbreviation: \isakeyword{hence} abbreviates \isakeyword{from}~@{text
|
|
|
378 |
this}~\isakeyword{have}. Figure out which rule is used where! *}
|
|
|
379 |
|
|
|
380 |
lemma assumes ex: "\<exists>x. \<forall>y. P x y" shows "\<forall>y. \<exists>x. P x y"
|
|
13267
|
381 |
proof
|
|
13294
|
382 |
fix y
|
|
|
383 |
from ex obtain x where "\<forall>y. P x y" ..
|
|
|
384 |
hence "P x y" ..
|
|
|
385 |
thus "\<exists>x. P x y" ..
|
|
|
386 |
qed
|
|
|
387 |
|
|
|
388 |
text{* So far we have confined ourselves to single step proofs. Of course
|
|
|
389 |
powerful automatic methods can be used just as well. Here is an example,
|
|
|
390 |
Cantor's theorem that there is no surjective function from a set to its
|
|
|
391 |
powerset: *}
|
|
|
392 |
|
|
|
393 |
theorem "\<exists>S. S \<notin> range (f :: 'a \<Rightarrow> 'a set)"
|
|
|
394 |
proof
|
|
|
395 |
let ?S = "{x. x \<notin> f x}"
|
|
|
396 |
show "?S \<notin> range f"
|
|
13267
|
397 |
proof
|
|
13294
|
398 |
assume "?S \<in> range f"
|
|
13267
|
399 |
then obtain y where fy: "?S = f y" ..
|
|
|
400 |
show False
|
|
13310
|
401 |
proof cases
|
|
13294
|
402 |
assume "y \<in> ?S"
|
|
13267
|
403 |
with fy show False by blast
|
|
|
404 |
next
|
|
13294
|
405 |
assume "y \<notin> ?S"
|
|
13267
|
406 |
with fy show False by blast
|
|
|
407 |
qed
|
|
|
408 |
qed
|
|
|
409 |
qed
|
|
|
410 |
|
|
13294
|
411 |
text{*\noindent
|
|
|
412 |
For a start, the example demonstrates two new language elements:
|
|
|
413 |
\begin{itemize}
|
|
|
414 |
\item \isakeyword{let} introduces an abbreviation for a term, in our case
|
|
|
415 |
the witness for the claim, because the term occurs multiple times in the proof.
|
|
13310
|
416 |
\item Proof by @{text"cases"} starts a proof by cases. Note that it remains
|
|
13294
|
417 |
implicit what the two cases are: it is merely expected that the two subproofs
|
|
|
418 |
prove @{prop"P \<Longrightarrow> Q"} and @{prop"\<not>P \<Longrightarrow> Q"} for suitable @{term P} and
|
|
|
419 |
@{term Q}.
|
|
|
420 |
\end{itemize}
|
|
|
421 |
If you wonder how to \isakeyword{obtain} @{term y}:
|
|
|
422 |
via the predefined elimination rule @{thm rangeE[no_vars]}.
|
|
|
423 |
|
|
|
424 |
Method @{text blast} is used because the contradiction does not follow easily
|
|
|
425 |
by just a single rule. If you find the proof too cryptic for human
|
|
|
426 |
consumption, here is a more detailed version; the beginning up to
|
|
|
427 |
\isakeyword{obtain} stays unchanged. *}
|
|
|
428 |
|
|
|
429 |
theorem "\<exists>S. S \<notin> range (f :: 'a \<Rightarrow> 'a set)"
|
|
13267
|
430 |
proof
|
|
13294
|
431 |
let ?S = "{x. x \<notin> f x}"
|
|
|
432 |
show "?S \<notin> range f"
|
|
13267
|
433 |
proof
|
|
13294
|
434 |
assume "?S \<in> range f"
|
|
|
435 |
then obtain y where fy: "?S = f y" ..
|
|
13267
|
436 |
show False
|
|
13310
|
437 |
proof cases
|
|
13294
|
438 |
assume A: "y \<in> ?S"
|
|
|
439 |
hence isin: "y \<in> f y" by(simp add:fy)
|
|
|
440 |
from A have "y \<notin> f y" by simp
|
|
13267
|
441 |
with isin show False by contradiction
|
|
|
442 |
next
|
|
13294
|
443 |
assume A: "y \<notin> ?S"
|
|
|
444 |
hence notin: "y \<notin> f y" by(simp add:fy)
|
|
|
445 |
from A have "y \<in> f y" by simp
|
|
13267
|
446 |
with notin show False by contradiction
|
|
|
447 |
qed
|
|
|
448 |
qed
|
|
|
449 |
qed
|
|
|
450 |
|
|
13294
|
451 |
text {*\noindent Method @{text contradiction} succeeds if both $P$ and
|
|
|
452 |
$\neg P$ are among the assumptions and the facts fed into that step.
|
|
|
453 |
|
|
|
454 |
As it happens, Cantor's theorem can be proved automatically by best-first
|
|
|
455 |
search. Depth-first search would diverge, but best-first search successfully
|
|
|
456 |
navigates through the large search space:
|
|
13267
|
457 |
*}
|
|
|
458 |
|
|
13294
|
459 |
theorem "\<exists>S. S \<notin> range (f :: 'a \<Rightarrow> 'a set)"
|
|
|
460 |
by best
|
|
13267
|
461 |
|
|
13294
|
462 |
text{*\noindent Of course this only works in the context of HOL's carefully
|
|
|
463 |
constructed introduction and elimination rules for set theory.
|
|
|
464 |
|
|
|
465 |
Finally, whole scripts may appear in the leaves of the proof tree, although
|
|
|
466 |
this is best avoided. Here is a contrived example: *}
|
|
13267
|
467 |
|
|
|
468 |
lemma "A \<longrightarrow> (A \<longrightarrow>B) \<longrightarrow> B"
|
|
|
469 |
proof
|
|
13294
|
470 |
assume a: A
|
|
13267
|
471 |
show "(A \<longrightarrow>B) \<longrightarrow> B"
|
|
|
472 |
apply(rule impI)
|
|
|
473 |
apply(erule impE)
|
|
13294
|
474 |
apply(rule a)
|
|
13267
|
475 |
apply assumption
|
|
|
476 |
done
|
|
|
477 |
qed
|
|
|
478 |
|
|
13294
|
479 |
text{*\noindent You may need to resort to this technique if an automatic step
|
|
|
480 |
fails to prove the desired proposition. *}
|
|
13305
|
481 |
|
|
13307
|
482 |
|
|
|
483 |
section{*Case distinction and induction*}
|
|
|
484 |
|
|
|
485 |
|
|
|
486 |
subsection{*Case distinction*}
|
|
|
487 |
|
|
|
488 |
text{* We have already met the @{text cases} method for performing
|
|
|
489 |
binary case splits. Here is another example: *}
|
|
|
490 |
|
|
|
491 |
lemma "P \<or> \<not> P"
|
|
|
492 |
proof cases
|
|
|
493 |
assume "P" thus ?thesis ..
|
|
|
494 |
next
|
|
|
495 |
assume "\<not> P" thus ?thesis ..
|
|
|
496 |
qed
|
|
|
497 |
|
|
|
498 |
text{*\noindent As always, the cases can be tackled in any order.
|
|
|
499 |
|
|
|
500 |
This form is appropriate if @{term P} is textually small. However, if
|
|
|
501 |
@{term P} is large, we don't want to repeat it. This can be avoided by
|
|
|
502 |
the following idiom *}
|
|
|
503 |
|
|
|
504 |
lemma "P \<or> \<not> P"
|
|
|
505 |
proof (cases "P")
|
|
|
506 |
case True thus ?thesis ..
|
|
|
507 |
next
|
|
|
508 |
case False thus ?thesis ..
|
|
|
509 |
qed
|
|
|
510 |
|
|
|
511 |
text{*\noindent which is simply a shorthand for the previous
|
|
|
512 |
proof. More precisely, the phrases \isakeyword{case}~@{prop
|
|
|
513 |
True}/@{prop False} abbreviate the corresponding assumptions @{prop P}
|
|
|
514 |
and @{prop"\<not>P"}.
|
|
|
515 |
|
|
|
516 |
The same game can be played with other datatypes, for example lists:
|
|
|
517 |
*}
|
|
|
518 |
(*<*)declare length_tl[simp del](*>*)
|
|
|
519 |
lemma "length(tl xs) = length xs - 1"
|
|
|
520 |
proof (cases xs)
|
|
|
521 |
case Nil thus ?thesis by simp
|
|
|
522 |
next
|
|
|
523 |
case Cons thus ?thesis by simp
|
|
|
524 |
qed
|
|
|
525 |
|
|
|
526 |
text{*\noindent Here \isakeyword{case}~@{text Nil} abbreviates
|
|
|
527 |
\isakeyword{assume}~@{prop"x = []"} and \isakeyword{case}~@{text Cons}
|
|
13310
|
528 |
abbreviates \isakeyword{assume}~@{text"xs = _ # _"}. The names of the head
|
|
|
529 |
and tail of @{text xs} have been chosen by the system. Therefore we cannot
|
|
|
530 |
refer to them (this would lead to brittle proofs) and have not even shown
|
|
|
531 |
them. Luckily, the proof is simple enough we do not need to refer to them.
|
|
|
532 |
However, in general one may have to. Hence Isar offers a simple scheme for
|
|
|
533 |
naming those variables: Replace the anonymous @{text Cons} by, for example,
|
|
|
534 |
@{text"(Cons y ys)"}, which abbreviates \isakeyword{fix}~@{text"y ys"}
|
|
|
535 |
\isakeyword{assume}~@{text"xs = Cons y ys"}, i.e.\ @{prop"xs = y # ys"}. Here
|
|
|
536 |
is a (somewhat contrived) example: *}
|
|
13307
|
537 |
|
|
|
538 |
lemma "length(tl xs) = length xs - 1"
|
|
|
539 |
proof (cases xs)
|
|
|
540 |
case Nil thus ?thesis by simp
|
|
|
541 |
next
|
|
|
542 |
case (Cons y ys)
|
|
13310
|
543 |
hence "length(tl xs) = length ys \<and> length xs = length ys + 1"
|
|
|
544 |
by simp
|
|
13307
|
545 |
thus ?thesis by simp
|
|
|
546 |
qed
|
|
|
547 |
|
|
|
548 |
text{* New case distincion rules can be declared any time, even with
|
|
|
549 |
named cases. *}
|
|
|
550 |
|
|
|
551 |
|
|
|
552 |
subsection{*Induction*}
|
|
|
553 |
|
|
|
554 |
|
|
|
555 |
subsubsection{*Structural induction*}
|
|
|
556 |
|
|
|
557 |
text{* We start with a simple inductive proof where both cases are proved automatically: *}
|
|
13305
|
558 |
|
|
|
559 |
lemma "2 * (\<Sum>i<n+1. i) = n*(n+1)"
|
|
|
560 |
by (induct n, simp_all)
|
|
|
561 |
|
|
13307
|
562 |
text{*\noindent If we want to expose more of the structure of the
|
|
|
563 |
proof, we can use pattern matching to avoid having to repeat the goal
|
|
|
564 |
statement: *}
|
|
|
565 |
|
|
13305
|
566 |
lemma "2 * (\<Sum>i<n+1. i) = n*(n+1)" (is "?P n")
|
|
|
567 |
proof (induct n)
|
|
|
568 |
show "?P 0" by simp
|
|
|
569 |
next
|
|
|
570 |
fix n assume "?P n"
|
|
|
571 |
thus "?P(Suc n)" by simp
|
|
|
572 |
qed
|
|
|
573 |
|
|
13307
|
574 |
text{* \noindent We could refine this further to show more of the equational
|
|
|
575 |
proof. Instead we explore the same avenue as for case distinctions:
|
|
|
576 |
introducing context via the \isakeyword{case} command: *}
|
|
13305
|
577 |
|
|
|
578 |
lemma "2 * (\<Sum>i<n+1. i) = n*(n+1)"
|
|
|
579 |
proof (induct n)
|
|
|
580 |
case 0 show ?case by simp
|
|
|
581 |
next
|
|
|
582 |
case Suc thus ?case by simp
|
|
|
583 |
qed
|
|
|
584 |
|
|
13307
|
585 |
text{* \noindent The implicitly defined @{text ?case} refers to the
|
|
13310
|
586 |
corresponding case to be proved, i.e.\ @{text"?P 0"} in the first case and
|
|
|
587 |
@{text"?P(Suc n)"} in the second case. Context \isakeyword{case}~@{text 0} is
|
|
|
588 |
empty whereas \isakeyword{case}~@{text Suc} assumes @{text"?P n"}. Again we
|
|
|
589 |
have the same problem as with case distinctions: we cannot refer to @{term n}
|
|
|
590 |
in the induction step because it has not been introduced via \isakeyword{fix}
|
|
|
591 |
(in contrast to the previous proof). The solution is the same as above:
|
|
|
592 |
replace @{term Suc} by @{text"(Suc i)"}: *}
|
|
13305
|
593 |
|
|
13307
|
594 |
lemma fixes n::nat shows "n < n*n + 1"
|
|
|
595 |
proof (induct n)
|
|
|
596 |
case 0 show ?case by simp
|
|
|
597 |
next
|
|
|
598 |
case (Suc i) thus "Suc i < Suc i * Suc i + 1" by simp
|
|
|
599 |
qed
|
|
13305
|
600 |
|
|
13307
|
601 |
text{* \noindent Of course we could again have written
|
|
|
602 |
\isakeyword{thus}~@{text ?case} instead of giving the term explicitly
|
|
|
603 |
but we wanted to use @{term i} somewehere.
|
|
13305
|
604 |
|
|
13307
|
605 |
Let us now tackle a more ambitious lemma: proving complete induction
|
|
|
606 |
@{prop[display,indent=5]"(\<And>n. (\<And>m. m < n \<Longrightarrow> P m) \<Longrightarrow> P n) \<Longrightarrow> P n"}
|
|
|
607 |
via structural induction. It is well known that one needs to prove
|
|
|
608 |
something more general first: *}
|
|
13305
|
609 |
|
|
13307
|
610 |
lemma cind_lemma:
|
|
|
611 |
assumes A: "(\<And>n. (\<And>m. m < n \<Longrightarrow> P m) \<Longrightarrow> P n)"
|
|
13305
|
612 |
shows "\<And>m. m < n \<Longrightarrow> P(m::nat)"
|
|
|
613 |
proof (induct n)
|
|
13307
|
614 |
case 0 thus ?case by simp
|
|
13305
|
615 |
next
|
|
|
616 |
case (Suc n m)
|
|
|
617 |
show ?case
|
|
13310
|
618 |
proof cases
|
|
13305
|
619 |
assume eq: "m = n"
|
|
13307
|
620 |
from Suc A have "P n" by blast
|
|
13305
|
621 |
with eq show "P m" by simp
|
|
|
622 |
next
|
|
|
623 |
assume neq: "m \<noteq> n"
|
|
|
624 |
with Suc have "m < n" by simp
|
|
|
625 |
with Suc show "P m" by blast
|
|
|
626 |
qed
|
|
13307
|
627 |
qed
|
|
13305
|
628 |
|
|
13310
|
629 |
text{* \noindent Let us first examine the statement of the lemma.
|
|
|
630 |
In contrast to the style advertized in the
|
|
13307
|
631 |
Tutorial~\cite{LNCS2283}, structured Isar proofs do not need to
|
|
|
632 |
introduce @{text"\<forall>"} or @{text"\<longrightarrow>"} into a theorem to strengthen it
|
|
|
633 |
for induction --- we use @{text"\<And>"} and @{text"\<Longrightarrow>"} instead. This
|
|
|
634 |
simplifies the proof and means we don't have to convert between the
|
|
|
635 |
two kinds of connectives. As usual, at the end of the proof
|
|
|
636 |
@{text"\<And>"} disappears and the bound variable is turned into a
|
|
|
637 |
@{text"?"}-variable. Thus @{thm[source]cind_lemma} becomes
|
|
|
638 |
@{thm[display,indent=5] cind_lemma} Complete induction is an easy
|
|
|
639 |
corollary: instantiation followed by
|
|
13310
|
640 |
simplification, @{thm[source] cind_lemma[of _ n "Suc n", simplified]},
|
|
13307
|
641 |
yields @{thm[display,indent=5] cind_lemma[of _ n "Suc n", simplified]}
|
|
13305
|
642 |
|
|
13310
|
643 |
Now we examine the proof. So what is this funny case @{text"(Suc n m)"}? It
|
|
|
644 |
looks confusing at first and reveals that the very suggestive @{text"(Suc
|
|
|
645 |
n)"} used above is not the whole truth. The variable names after the case
|
|
|
646 |
name (here: @{term Suc}) are the names of the parameters of that subgoal. So
|
|
|
647 |
far the only parameters where the arguments to the constructor, but now we
|
|
|
648 |
have an additonal parameter coming from the @{text"\<And>m"} in the main
|
|
|
649 |
\isakeyword{shows} clause. Thus Thus @{text"(Suc n m)"} does not mean that
|
|
13307
|
650 |
constructor @{term Suc} is applied to two arguments but that the two
|
|
13310
|
651 |
parameters in the @{term Suc} case are to be named @{text n} and @{text
|
|
|
652 |
m}. *}
|
|
13305
|
653 |
|
|
13307
|
654 |
subsubsection{*Rule induction*}
|
|
|
655 |
|
|
|
656 |
text{* We define our own version of reflexive transitive closure of a
|
|
|
657 |
relation *}
|
|
13305
|
658 |
|
|
|
659 |
consts rtc :: "('a \<times> 'a)set \<Rightarrow> ('a \<times> 'a)set" ("_*" [1000] 999)
|
|
|
660 |
inductive "r*"
|
|
|
661 |
intros
|
|
13307
|
662 |
refl: "(x,x) \<in> r*"
|
|
|
663 |
step: "\<lbrakk> (x,y) \<in> r; (y,z) \<in> r* \<rbrakk> \<Longrightarrow> (x,z) \<in> r*"
|
|
|
664 |
|
|
|
665 |
text{* \noindent and prove that @{term"r*"} is indeed transitive: *}
|
|
13305
|
666 |
|
|
13307
|
667 |
lemma assumes A: "(x,y) \<in> r*"
|
|
13310
|
668 |
shows "(y,z) \<in> r* \<Longrightarrow> (x,z) \<in> r*" (is "PROP ?P x y")
|
|
13307
|
669 |
proof -
|
|
|
670 |
from A show "PROP ?P x y"
|
|
|
671 |
proof induct
|
|
|
672 |
fix x show "PROP ?P x x" .
|
|
|
673 |
next
|
|
|
674 |
fix x' x y
|
|
|
675 |
assume "(x',x) \<in> r" and
|
|
|
676 |
"PROP ?P x y" -- "The induction hypothesis"
|
|
|
677 |
thus "PROP ?P x' y" by(blast intro: rtc.step)
|
|
|
678 |
qed
|
|
|
679 |
qed
|
|
13305
|
680 |
|
|
13307
|
681 |
text{*\noindent Rule induction is triggered by a fact $(x_1,\dots,x_n) \in R$
|
|
13310
|
682 |
piped into the proof, here \isakeyword{from}~@{text A}. The proof itself
|
|
|
683 |
follows the two rules of the inductive definition very closely. The only
|
|
|
684 |
surprising thing should be the keyword @{text PROP}: because of certain
|
|
|
685 |
syntactic subleties it is required in front of terms of type @{typ prop} (the
|
|
|
686 |
type of meta-level propositions) which are not obviously of type @{typ prop}
|
|
|
687 |
(e.g.\ @{text"?P x y"}) because they do not contain a tell-tale constant such
|
|
|
688 |
as @{text"\<And>"} or @{text"\<Longrightarrow>"}.
|
|
13307
|
689 |
|
|
13310
|
690 |
However, the proof is rather terse. Here is a more readable version:
|
|
13307
|
691 |
*}
|
|
|
692 |
|
|
13310
|
693 |
lemma assumes A: "(x,y) \<in> r*" and B: "(y,z) \<in> r*"
|
|
|
694 |
shows "(x,z) \<in> r*"
|
|
13305
|
695 |
proof -
|
|
|
696 |
from A B show ?thesis
|
|
13307
|
697 |
proof induct
|
|
13312
|
698 |
fix x assume "(x,z) \<in> r*" -- {*@{text B}[@{text y} := @{text x}]*}
|
|
13307
|
699 |
thus "(x,z) \<in> r*" .
|
|
13305
|
700 |
next
|
|
13307
|
701 |
fix x' x y
|
|
13313
|
702 |
assume 1: "(x',x) \<in> r" and
|
|
13307
|
703 |
IH: "(y,z) \<in> r* \<Longrightarrow> (x,z) \<in> r*" and
|
|
|
704 |
B: "(y,z) \<in> r*"
|
|
13313
|
705 |
from 1 IH[OF B] show "(x',z) \<in> r*" by(rule rtc.step)
|
|
13307
|
706 |
qed
|
|
13305
|
707 |
qed
|
|
|
708 |
|
|
13307
|
709 |
text{*\noindent We start the proof with \isakeyword{from}~@{text"A
|
|
|
710 |
B"}. Only @{text A} is ``consumed'' by the first proof step, here
|
|
|
711 |
induction. Since @{text B} is left over we don't just prove @{text
|
|
13311
|
712 |
?thesis} but @{text"B \<Longrightarrow> ?thesis"}, just as in the previous
|
|
13307
|
713 |
proof, only more elegantly. The base case is trivial. In the
|
|
|
714 |
assumptions for the induction step we can see very clearly how things
|
|
|
715 |
fit together and permit ourselves the obvious forward step
|
|
|
716 |
@{text"IH[OF B]"}. *}
|
|
13305
|
717 |
|
|
13294
|
718 |
(*<*)end(*>*)
|