152 |
152 |
153 apply(simp only:exor_def); |
153 apply(simp only:exor_def); |
154 |
154 |
155 txt{*\noindent |
155 txt{*\noindent |
156 In this particular case, the resulting goal |
156 In this particular case, the resulting goal |
157 \begin{isabelle} |
157 @{subgoals[display,indent=0]} |
158 ~1.~A~{\isasymand}~{\isasymnot}~{\isasymnot}~A~{\isasymor}~{\isasymnot}~A~{\isasymand}~{\isasymnot}~A% |
|
159 \end{isabelle} |
|
160 can be proved by simplification. Thus we could have proved the lemma outright by |
158 can be proved by simplification. Thus we could have proved the lemma outright by |
161 *}(*<*)oops;lemma "exor A (\<not>A)";(*>*) |
159 *}(*<*)oops;lemma "exor A (\<not>A)";(*>*) |
162 apply(simp add: exor_def) |
160 apply(simp add: exor_def) |
163 (*<*)done(*>*) |
161 (*<*)done(*>*) |
164 text{*\noindent |
162 text{*\noindent |
235 *} |
233 *} |
236 |
234 |
237 lemma "\<forall>xs. if xs = [] then rev xs = [] else rev xs \<noteq> []"; |
235 lemma "\<forall>xs. if xs = [] then rev xs = [] else rev xs \<noteq> []"; |
238 |
236 |
239 txt{*\noindent |
237 txt{*\noindent |
240 can be split into |
238 can be split by a degenerate form of simplification |
241 \begin{isabelle} |
|
242 ~1.~{\isasymforall}xs.~(xs~=~[]~{\isasymlongrightarrow}~rev~xs~=~[])~{\isasymand}~(xs~{\isasymnoteq}~[]~{\isasymlongrightarrow}~rev~xs~{\isasymnoteq}~[]) |
|
243 \end{isabelle} |
|
244 by a degenerate form of simplification |
|
245 *} |
239 *} |
246 |
240 |
247 apply(simp only: split: split_if); |
241 apply(simp only: split: split_if); |
248 (*<*)oops;(*>*) |
242 |
249 |
243 txt{*\noindent |
250 text{*\noindent |
244 @{subgoals[display,indent=0]} |
251 where no simplification rules are included (@{text"only:"} is followed by the |
245 where no simplification rules are included (@{text"only:"} is followed by the |
252 empty list of theorems) but the rule \isaindexbold{split_if} for |
246 empty list of theorems) but the rule \isaindexbold{split_if} for |
253 splitting @{text"if"}s is added (via the modifier @{text"split:"}). Because |
247 splitting @{text"if"}s is added (via the modifier @{text"split:"}). Because |
254 case-splitting on @{text"if"}s is almost always the right proof strategy, the |
248 case-splitting on @{text"if"}s is almost always the right proof strategy, the |
255 simplifier performs it automatically. Try \isacommand{apply}@{text"(simp)"} |
249 simplifier performs it automatically. Try \isacommand{apply}@{text"(simp)"} |
256 on the initial goal above. |
250 on the initial goal above. |
257 |
251 |
258 This splitting idea generalizes from @{text"if"} to \isaindex{case}: |
252 This splitting idea generalizes from @{text"if"} to \isaindex{case}: |
259 *} |
253 *}(*<*)oops;(*>*) |
260 |
254 |
261 lemma "(case xs of [] \<Rightarrow> zs | y#ys \<Rightarrow> y#(ys@zs)) = xs@zs"; |
255 lemma "(case xs of [] \<Rightarrow> zs | y#ys \<Rightarrow> y#(ys@zs)) = xs@zs"; |
262 txt{*\noindent |
|
263 becomes |
|
264 \begin{isabelle}\makeatother |
|
265 ~1.~(xs~=~[]~{\isasymlongrightarrow}~zs~=~xs~@~zs)~{\isasymand}\isanewline |
|
266 ~~~~({\isasymforall}a~list.~xs~=~a~\#~list~{\isasymlongrightarrow}~a~\#~list~@~zs~=~xs~@~zs) |
|
267 \end{isabelle} |
|
268 by typing |
|
269 *} |
|
270 |
|
271 apply(simp only: split: list.split); |
256 apply(simp only: split: list.split); |
272 (*<*)oops;(*>*) |
257 |
273 |
258 txt{* |
274 text{*\noindent |
259 @{subgoals[display,indent=0]} |
275 In contrast to @{text"if"}-expressions, the simplifier does not split |
260 In contrast to @{text"if"}-expressions, the simplifier does not split |
276 @{text"case"}-expressions by default because this can lead to nontermination |
261 @{text"case"}-expressions by default because this can lead to nontermination |
277 in case of recursive datatypes. Again, if the @{text"only:"} modifier is |
262 in case of recursive datatypes. Again, if the @{text"only:"} modifier is |
278 dropped, the above goal is solved, |
263 dropped, the above goal is solved, |
279 *} |
264 *} |
280 (*<*) |
265 (*<*)oops; |
281 lemma "(case xs of [] \<Rightarrow> zs | y#ys \<Rightarrow> y#(ys@zs)) = xs@zs"; |
266 lemma "(case xs of [] \<Rightarrow> zs | y#ys \<Rightarrow> y#(ys@zs)) = xs@zs"; |
282 (*>*) |
267 (*>*) |
283 apply(simp split: list.split); |
268 apply(simp split: list.split); |
284 (*<*)done(*>*) |
269 (*<*)done(*>*) |
285 text{*\noindent% |
270 text{*\noindent% |
315 $t$@{text".split_asm"}: |
300 $t$@{text".split_asm"}: |
316 *} |
301 *} |
317 |
302 |
318 lemma "if xs = [] then ys ~= [] else ys = [] ==> xs @ ys ~= []" |
303 lemma "if xs = [] then ys ~= [] else ys = [] ==> xs @ ys ~= []" |
319 apply(simp only: split: split_if_asm); |
304 apply(simp only: split: split_if_asm); |
320 (*<*) |
305 |
321 by(simp_all) |
306 txt{*\noindent |
322 (*>*) |
|
323 |
|
324 text{*\noindent |
|
325 In contrast to splitting the conclusion, this actually creates two |
307 In contrast to splitting the conclusion, this actually creates two |
326 separate subgoals (which are solved by @{text"simp_all"}): |
308 separate subgoals (which are solved by @{text"simp_all"}): |
327 \begin{isabelle} |
309 @{subgoals[display,indent=0]} |
328 \ \isadigit{1}{\isachardot}\ {\isasymlbrakk}\mbox{xs}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isacharsemicolon}\ \mbox{ys}\ {\isasymnoteq}\ {\isacharbrackleft}{\isacharbrackright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharat}\ \mbox{ys}\ {\isasymnoteq}\ {\isacharbrackleft}{\isacharbrackright}\isanewline |
|
329 \ \isadigit{2}{\isachardot}\ {\isasymlbrakk}\mbox{xs}\ {\isasymnoteq}\ {\isacharbrackleft}{\isacharbrackright}{\isacharsemicolon}\ \mbox{ys}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ \mbox{xs}\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}\ {\isasymnoteq}\ {\isacharbrackleft}{\isacharbrackright} |
|
330 \end{isabelle} |
|
331 If you need to split both in the assumptions and the conclusion, |
310 If you need to split both in the assumptions and the conclusion, |
332 use $t$@{text".splits"} which subsumes $t$@{text".split"} and |
311 use $t$@{text".splits"} which subsumes $t$@{text".split"} and |
333 $t$@{text".split_asm"}. Analogously, there is @{thm[source]if_splits}. |
312 $t$@{text".split_asm"}. Analogously, there is @{thm[source]if_splits}. |
334 |
313 |
335 \begin{warn} |
314 \begin{warn} |