doc-src/TutorialI/Misc/case_exprs.thy
author chaieb
Wed, 19 May 2004 11:23:59 +0200
changeset 14758 af3b71a46a1c
parent 12699 deae80045527
child 16417 9bc16273c2d4
permissions -rw-r--r--
A new implementation for presburger arithmetic following the one suggested in technical report Chaieb Amine and Tobias Nipkow. It is generic an smaller. the tactic has also changed and allows the abstaction over fuction occurences whose type is nat or int.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
     1
(*<*)
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
     2
theory case_exprs = Main:
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
     3
(*>*)
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
     4
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
     5
subsection{*Case Expressions*}
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
     6
11456
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
     7
text{*\label{sec:case-expressions}\index{*case expressions}%
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
     8
HOL also features \isa{case}-expressions for analyzing
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
     9
elements of a datatype. For example,
12699
deae80045527 *** empty log message ***
nipkow
parents: 11457
diff changeset
    10
@{term[display]"case xs of [] => [] | y#ys => y"}
deae80045527 *** empty log message ***
nipkow
parents: 11457
diff changeset
    11
evaluates to @{term"[]"} if @{term"xs"} is @{term"[]"} and to @{term"y"} if 
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    12
@{term"xs"} is @{term"y#ys"}. (Since the result in both branches must be of
12699
deae80045527 *** empty log message ***
nipkow
parents: 11457
diff changeset
    13
the same type, it follows that @{term y} is of type @{typ"'a list"} and hence
deae80045527 *** empty log message ***
nipkow
parents: 11457
diff changeset
    14
that @{term xs} is of type @{typ"'a list list"}.)
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    15
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    16
In general, if $e$ is a term of the datatype $t$ defined in
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    17
\S\ref{sec:general-datatype} above, the corresponding
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9742
diff changeset
    18
@{text"case"}-expression analyzing $e$ is
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    19
\[
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    20
\begin{array}{rrcl}
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9742
diff changeset
    21
@{text"case"}~e~@{text"of"} & C@1~x@ {11}~\dots~x@ {1k@1} & \To & e@1 \\
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    22
                           \vdots \\
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    23
                           \mid & C@m~x@ {m1}~\dots~x@ {mk@m} & \To & e@m
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    24
\end{array}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    25
\]
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    26
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    27
\begin{warn}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    28
\emph{All} constructors must be present, their order is fixed, and nested
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    29
patterns are not supported.  Violating these restrictions results in strange
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    30
error messages.
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    31
\end{warn}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    32
\noindent
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9742
diff changeset
    33
Nested patterns can be simulated by nested @{text"case"}-expressions: instead
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    34
of
12699
deae80045527 *** empty log message ***
nipkow
parents: 11457
diff changeset
    35
@{text[display]"case xs of [] => [] | [x] => x | x # (y # zs) => y"}
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    36
write
12699
deae80045527 *** empty log message ***
nipkow
parents: 11457
diff changeset
    37
@{term[display,eta_contract=false,margin=50]"case xs of [] => [] | x#ys => (case ys of [] => x | y#zs => y)"}
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    38
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9742
diff changeset
    39
Note that @{text"case"}-expressions may need to be enclosed in parentheses to
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    40
indicate their scope
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    41
*}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    42
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
    43
subsection{*Structural Induction and Case Distinction*}
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    44
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    45
text{*\label{sec:struct-ind-case}
11456
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    46
\index{case distinctions}\index{induction!structural}%
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    47
Induction is invoked by \methdx{induct_tac}, as we have seen above; 
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    48
it works for any datatype.  In some cases, induction is overkill and a case
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    49
distinction over all constructors of the datatype suffices.  This is performed
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    50
by \methdx{case_tac}.  Here is a trivial example:
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    51
*}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    52
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    53
lemma "(case xs of [] \<Rightarrow> [] | y#ys \<Rightarrow> xs) = xs";
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    54
apply(case_tac xs);
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    55
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    56
txt{*\noindent
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    57
results in the proof state
10420
ef006735bee8 *** empty log message ***
nipkow
parents: 10171
diff changeset
    58
@{subgoals[display,indent=0,margin=65]}
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    59
which is solved automatically:
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    60
*}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    61
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9834
diff changeset
    62
apply(auto)
59d6633835fa *** empty log message ***
nipkow
parents: 9834
diff changeset
    63
(*<*)done(*>*)
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    64
text{*
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    65
Note that we do not need to give a lemma a name if we do not intend to refer
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    66
to it explicitly in the future.
11456
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    67
Other basic laws about a datatype are applied automatically during
7eb63f63e6c6 revisions and indexing
paulson
parents: 11428
diff changeset
    68
simplification, so no special methods are provided for them.
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    69
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    70
\begin{warn}
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    71
  Induction is only allowed on free (or \isasymAnd-bound) variables that
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    72
  should not occur among the assumptions of the subgoal; see
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    73
  \S\ref{sec:ind-var-in-prems} for details. Case distinction
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    74
  (@{text"case_tac"}) works for arbitrary terms, which need to be
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    75
  quoted if they are non-atomic. However, apart from @{text"\<And>"}-bound
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    76
  variables, the terms must not contain variables that are bound outside.
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    77
  For example, given the goal @{prop"\<forall>xs. xs = [] \<or> (\<exists>y ys. xs = y#ys)"},
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    78
  @{text"case_tac xs"} will not work as expected because Isabelle interprets
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    79
  the @{term xs} as a new free variable distinct from the bound
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    80
  @{term xs} in the goal.
4a212e635318 *** empty log message ***
nipkow
parents: 10420
diff changeset
    81
\end{warn}
9742
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    82
*}
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    83
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    84
(*<*)
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    85
end
98d3ca2c18f7 *** empty log message ***
nipkow
parents:
diff changeset
    86
(*>*)