doc-src/TutorialI/Misc/case_splits.thy
author wenzelm
Sat, 02 Sep 2000 22:19:03 +0200
changeset 9812 87ba969d069c
parent 9792 bbefb6ce5cb2
permissions -rw-r--r--
updated;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     1
(*<*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     2
theory case_splits = Main:;
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     3
(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     4
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     5
text{*
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
     6
Goals containing @{text"if"}-expressions are usually proved by case
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
     7
distinction on the condition of the @{text"if"}. For example the goal
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     8
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     9
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    10
lemma "\\<forall>xs. if xs = [] then rev xs = [] else rev xs \\<noteq> []";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    11
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    12
txt{*\noindent
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    13
can be split into
9723
a977245dfc8a *** empty log message ***
nipkow
parents: 9721
diff changeset
    14
\begin{isabelle}
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    15
~1.~{\isasymforall}xs.~(xs~=~[]~{\isasymlongrightarrow}~rev~xs~=~[])~{\isasymand}~(xs~{\isasymnoteq}~[]~{\isasymlongrightarrow}~rev~xs~{\isasymnoteq}~[])
9723
a977245dfc8a *** empty log message ***
nipkow
parents: 9721
diff changeset
    16
\end{isabelle}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    17
by a degenerate form of simplification
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    18
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    19
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    20
apply(simp only: split: split_if);
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    21
(*<*)oops;(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    22
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    23
text{*\noindent
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    24
where no simplification rules are included (@{text"only:"} is followed by the
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    25
empty list of theorems) but the rule \isaindexbold{split_if} for
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    26
splitting @{text"if"}s is added (via the modifier @{text"split:"}). Because
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    27
case-splitting on @{text"if"}s is almost always the right proof strategy, the
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    28
simplifier performs it automatically. Try \isacommand{apply}@{text"(simp)"}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    29
on the initial goal above.
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    30
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    31
This splitting idea generalizes from @{text"if"} to \isaindex{case}:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    32
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    33
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    34
lemma "(case xs of [] \\<Rightarrow> zs | y#ys \\<Rightarrow> y#(ys@zs)) = xs@zs";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    35
txt{*\noindent
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    36
becomes
9723
a977245dfc8a *** empty log message ***
nipkow
parents: 9721
diff changeset
    37
\begin{isabelle}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    38
~1.~(xs~=~[]~{\isasymlongrightarrow}~zs~=~xs~@~zs)~{\isasymand}\isanewline
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    39
~~~~({\isasymforall}a~list.~xs~=~a~\#~list~{\isasymlongrightarrow}~a~\#~list~@~zs~=~xs~@~zs)
9723
a977245dfc8a *** empty log message ***
nipkow
parents: 9721
diff changeset
    40
\end{isabelle}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    41
by typing
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    42
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    43
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    44
apply(simp only: split: list.split);
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    45
(*<*)oops;(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    46
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    47
text{*\noindent
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    48
In contrast to @{text"if"}-expressions, the simplifier does not split
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    49
@{text"case"}-expressions by default because this can lead to nontermination
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    50
in case of recursive datatypes. Again, if the @{text"only:"} modifier is
8771
026f37a86ea7 *** empty log message ***
nipkow
parents: 8745
diff changeset
    51
dropped, the above goal is solved,
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    52
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    53
(*<*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    54
lemma "(case xs of [] \\<Rightarrow> zs | y#ys \\<Rightarrow> y#(ys@zs)) = xs@zs";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    55
(*>*)
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    56
by(simp split: list.split);
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    57
8771
026f37a86ea7 *** empty log message ***
nipkow
parents: 8745
diff changeset
    58
text{*\noindent%
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    59
which \isacommand{apply}@{text"(simp)"} alone will not do.
8771
026f37a86ea7 *** empty log message ***
nipkow
parents: 8745
diff changeset
    60
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    61
In general, every datatype $t$ comes with a theorem
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    62
$t$@{text".split"} which can be declared to be a \bfindex{split rule} either
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    63
locally as above, or by giving it the @{text"split"} attribute globally:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    64
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    65
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    66
lemmas [split] = list.split;
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    67
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    68
text{*\noindent
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    69
The @{text"split"} attribute can be removed with the @{text"del"} modifier,
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    70
either locally
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    71
*}
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    72
(*<*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    73
lemma "dummy=dummy";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    74
(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    75
apply(simp split del: split_if);
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    76
(*<*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    77
oops;
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    78
(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    79
text{*\noindent
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    80
or globally:
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    81
*}
9541
d17c0b34d5c8 *** empty log message ***
nipkow
parents: 9458
diff changeset
    82
lemmas [split del] = list.split;
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    83
9721
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    84
text{*
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    85
The above split rules intentionally only affect the conclusion of a
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    86
subgoal.  If you want to split an @{text"if"} or @{text"case"}-expression in
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    87
the assumptions, you have to apply @{thm[source]split_if_asm} or
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    88
$t$@{text".split_asm"}:
9721
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    89
*}
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    90
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    91
lemma "if xs = [] then ys ~= [] else ys = [] ==> xs @ ys ~= []"
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    92
apply(simp only: split: split_if_asm);
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    93
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    94
txt{*\noindent
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    95
In contrast to splitting the conclusion, this actually creates two
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
    96
separate subgoals (which are solved by @{text"simp_all"}):
9721
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    97
\begin{isabelle}
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    98
\ \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
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
    99
\ \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}
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
   100
\end{isabelle}
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
   101
If you need to split both in the assumptions and the conclusion,
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   102
use $t$@{text".splits"} which subsumes $t$@{text".split"} and
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   103
$t$@{text".split_asm"}. Analogously, there is @{thm[source]if_splits}.
9721
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
   104
*}
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
   105
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   106
(*<*)
9721
7e51c9f3d5a0 *** empty log message ***
nipkow
parents: 9541
diff changeset
   107
by(simp_all)
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   108
end
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   109
(*>*)