src/Doc/Tutorial/Types/Pairs.thy
author wenzelm
Sat, 05 Jan 2019 17:24:33 +0100
changeset 69597 ff784d5a5bfb
parent 69505 cc2d676d5395
permissions -rw-r--r--
isabelle update -u control_cartouches;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27170
65bb0ddb0b9f Removed hide swap
nipkow
parents: 27169
diff changeset
     1
(*<*)theory Pairs imports Main begin(*>*)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
     2
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
     3
section\<open>Pairs and Tuples\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
     4
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
     5
text\<open>\label{sec:products}
11428
332347b9b942 tidying the index
paulson
parents: 11277
diff changeset
     6
Ordered pairs were already introduced in \S\ref{sec:pairs}, but only with a minimal
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
     7
repertoire of operations: pairing and the two projections \<^term>\<open>fst\<close> and
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
     8
\<^term>\<open>snd\<close>. In any non-trivial application of pairs you will find that this
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
     9
quickly leads to unreadable nests of projections. This
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    10
section introduces syntactic sugar to overcome this
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    11
problem: pattern matching with tuples.
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    12
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    13
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    14
subsection\<open>Pattern Matching with Tuples\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    15
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    16
text\<open>
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
    17
Tuples may be used as patterns in $\lambda$-abstractions,
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
    18
for example \<open>\<lambda>(x,y,z).x+y+z\<close> and \<open>\<lambda>((x,y),z).x+y+z\<close>. In fact,
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
    19
tuple patterns can be used in most variable binding constructs,
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
    20
and they can be nested. Here are
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    21
some typical examples:
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    22
\begin{quote}
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    23
\<^term>\<open>let (x,y) = f z in (y,x)\<close>\\
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    24
\<^term>\<open>case xs of [] => (0::nat) | (x,y)#zs => x+y\<close>\\
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
    25
\<open>\<forall>(x,y)\<in>A. x=y\<close>\\
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
    26
\<open>{(x,y,z). x=z}\<close>\\
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    27
\<^term>\<open>\<Union>(x,y)\<in>A. {x+y}\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    28
\end{quote}
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
    29
The intuitive meanings of these expressions should be obvious.
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    30
Unfortunately, we need to know in more detail what the notation really stands
10885
90695f46440b lcp's pass over the book, chapters 1-8
paulson
parents: 10824
diff changeset
    31
for once we have to reason about it.  Abstraction
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    32
over pairs and tuples is merely a convenient shorthand for a more complex
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    33
internal representation.  Thus the internal and external form of a term may
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    34
differ, which can affect proofs. If you want to avoid this complication,
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    35
stick to \<^term>\<open>fst\<close> and \<^term>\<open>snd\<close> and write \<^term>\<open>%p. fst p + snd p\<close>
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
    36
instead of \<open>\<lambda>(x,y). x+y\<close>.  These terms are distinct even though they
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    37
denote the same function.
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    38
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    39
Internally, \<^term>\<open>%(x,y). t\<close> becomes \<open>case_prod (\<lambda>x y. t)\<close>, where
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
    40
\cdx{split} is the uncurrying function of type \<open>('a \<Rightarrow> 'b
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
    41
\<Rightarrow> 'c) \<Rightarrow> 'a \<times> 'b \<Rightarrow> 'c\<close> defined as
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    42
\begin{center}
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    43
@{thm split_def}
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    44
\hfill(@{thm[source]split_def})
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    45
\end{center}
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    46
Pattern matching in
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    47
other variable binding constructs is translated similarly. Thus we need to
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    48
understand how to reason about such constructs.
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    49
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    50
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    51
subsection\<open>Theorem Proving\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    52
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    53
text\<open>
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    54
The most obvious approach is the brute force expansion of \<^term>\<open>split\<close>:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    55
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    56
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    57
lemma "(\<lambda>(x,y).x) p = fst p"
12815
wenzelm
parents: 12699
diff changeset
    58
by(simp add: split_def)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    59
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    60
text\<open>\noindent
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
    61
This works well if rewriting with @{thm[source]split_def} finishes the
11149
e258b536a137 *** empty log message ***
nipkow
parents: 10902
diff changeset
    62
proof, as it does above.  But if it does not, you end up with exactly what
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    63
we are trying to avoid: nests of \<^term>\<open>fst\<close> and \<^term>\<open>snd\<close>. Thus this
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    64
approach is neither elegant nor very practical in large examples, although it
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    65
can be effective in small ones.
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    66
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    67
If we consider why this lemma presents a problem, 
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    68
we realize that we need to replace variable~\<^term>\<open>p\<close> by some pair \<^term>\<open>(a,b)\<close>.  Then both sides of the
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    69
equation would simplify to \<^term>\<open>a\<close> by the simplification rules
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    70
@{thm split_conv[no_vars]} and @{thm fst_conv[no_vars]}.  
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    71
To reason about tuple patterns requires some way of
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    72
converting a variable of product type into a pair.
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    73
In case of a subterm of the form \<^term>\<open>case_prod f p\<close> this is easy: the split
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
    74
rule @{thm[source]prod.split} replaces \<^term>\<open>p\<close> by a pair:%
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    75
\index{*split (method)}
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    76
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    77
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    78
lemma "(\<lambda>(x,y).y) p = snd p"
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
    79
apply(split prod.split)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    80
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    81
txt\<open>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    82
@{subgoals[display,indent=0]}
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
    83
This subgoal is easily proved by simplification. Thus we could have combined
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
    84
simplification and splitting in one command that proves the goal outright:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    85
\<close>
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
    86
(*<*)
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
    87
by simp
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
    88
lemma "(\<lambda>(x,y).y) p = snd p"(*>*)
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
    89
by(simp split: prod.split)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    90
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    91
text\<open>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    92
Let us look at a second example:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    93
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    94
58860
fee7cfa69c50 eliminated spurious semicolons;
wenzelm
parents: 48985
diff changeset
    95
lemma "let (x,y) = p in fst p = x"
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
    96
apply(simp only: Let_def)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    97
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
    98
txt\<open>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
    99
@{subgoals[display,indent=0]}
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   100
A paired \<open>let\<close> reduces to a paired $\lambda$-abstraction, which
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   101
can be split as above. The same is true for paired set comprehension:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   102
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   103
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
   104
(*<*)by(simp split: prod.split)(*>*)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   105
lemma "p \<in> {(x,y). x=y} \<longrightarrow> fst p = snd p"
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   106
apply simp
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   107
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   108
txt\<open>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   109
@{subgoals[display,indent=0]}
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
   110
Again, simplification produces a term suitable for @{thm[source]prod.split}
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11161
diff changeset
   111
as above. If you are worried about the strange form of the premise:
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
   112
\<open>case_prod (=)\<close> is short for \<^term>\<open>\<lambda>(x,y). x=y\<close>.
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11161
diff changeset
   113
The same proof procedure works for
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   114
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   115
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
   116
(*<*)by(simp split: prod.split)(*>*)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   117
lemma "p \<in> {(x,y). x=y} \<Longrightarrow> fst p = snd p"
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   118
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   119
txt\<open>\noindent
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
   120
except that we now have to use @{thm[source]prod.split_asm}, because
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
   121
\<^term>\<open>split\<close> occurs in the assumptions.
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   122
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
   123
However, splitting \<^term>\<open>split\<close> is not always a solution, as no \<^term>\<open>split\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   124
may be present in the goal. Consider the following function:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   125
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   126
61424
c3658c18b7bc prod_case as canonical name for product type eliminator
haftmann
parents: 58860
diff changeset
   127
(*<*)by(simp split: prod.split_asm)(*>*)
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
   128
primrec swap :: "'a \<times> 'b \<Rightarrow> 'b \<times> 'a" where "swap (x,y) = (y,x)"
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   129
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   130
text\<open>\noindent
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   131
Note that the above \isacommand{primrec} definition is admissible
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   132
because \<open>\<times>\<close> is a datatype. When we now try to prove
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   133
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   134
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   135
lemma "swap(swap p) = p"
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   136
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   137
txt\<open>\noindent
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
   138
simplification will do nothing, because the defining equation for
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
   139
@{const[source] swap} expects a pair. Again, we need to turn \<^term>\<open>p\<close>
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 69505
diff changeset
   140
into a pair first, but this time there is no \<^term>\<open>split\<close> in sight.
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
   141
The only thing we can do is to split the term by hand:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   142
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   143
apply(case_tac p)
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   144
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   145
txt\<open>\noindent
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   146
@{subgoals[display,indent=0]}
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   147
Again, \methdx{case_tac} is applicable because \<open>\<times>\<close> is a datatype.
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   148
The subgoal is easily proved by \<open>simp\<close>.
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   149
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   150
Splitting by \<open>case_tac\<close> also solves the previous examples and may thus
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
   151
appear preferable to the more arcane methods introduced first. However, see
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   152
the warning about \<open>case_tac\<close> in \S\ref{sec:struct-ind-case}.
10824
4a212e635318 *** empty log message ***
nipkow
parents: 10654
diff changeset
   153
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   154
Alternatively, you can split \emph{all} \<open>\<And>\<close>-quantified variables
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
   155
in a goal with the rewrite rule @{thm[source]split_paired_all}:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   156
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   157
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   158
(*<*)by simp(*>*)
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   159
lemma "\<And>p q. swap(swap p) = q \<longrightarrow> p = q"
12631
wenzelm
parents: 11494
diff changeset
   160
apply(simp only: split_paired_all)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   161
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   162
txt\<open>\noindent
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
   163
@{subgoals[display,indent=0,margin=70]}
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   164
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   165
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   166
apply simp
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   167
done
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   168
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   169
text\<open>\noindent
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   170
Note that we have intentionally included only @{thm[source]split_paired_all}
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   171
in the first simplification step, and then we simplify again. 
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   172
This time the reason was not merely
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   173
pedagogical:
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   174
@{thm[source]split_paired_all} may interfere with other functions
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   175
of the simplifier.
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   176
The following command could fail (here it does not)
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   177
where two separate \isa{simp} applications succeed.
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   178
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   179
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   180
(*<*)
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   181
lemma "\<And>p q. swap(swap p) = q \<longrightarrow> p = q"
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   182
(*>*)
12815
wenzelm
parents: 12699
diff changeset
   183
apply(simp add: split_paired_all)
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   184
(*<*)done(*>*)
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   185
text\<open>\noindent
69505
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   186
Finally, the simplifier automatically splits all \<open>\<forall>\<close> and
cc2d676d5395 isabelle update_cartouches -t;
wenzelm
parents: 67406
diff changeset
   187
\<open>\<exists>\<close>-quantified variables:
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   188
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   189
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   190
lemma "\<forall>p. \<exists>q. swap p = swap q"
58860
fee7cfa69c50 eliminated spurious semicolons;
wenzelm
parents: 48985
diff changeset
   191
by simp
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   192
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   193
text\<open>\noindent
27027
63f0b638355c *** empty log message ***
nipkow
parents: 17914
diff changeset
   194
To turn off this automatic splitting, disable the
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   195
responsible simplification rules:
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   196
\begin{center}
10654
458068404143 *** empty log message ***
nipkow
parents: 10608
diff changeset
   197
@{thm split_paired_All[no_vars]}
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   198
\hfill
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   199
(@{thm[source]split_paired_All})\\
10654
458068404143 *** empty log message ***
nipkow
parents: 10608
diff changeset
   200
@{thm split_paired_Ex[no_vars]}
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   201
\hfill
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   202
(@{thm[source]split_paired_Ex})
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   203
\end{center}
67406
23307fd33906 isabelle update_cartouches -c;
wenzelm
parents: 67399
diff changeset
   204
\<close>
10560
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   205
(*<*)
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   206
end
f4da791d4850 *** empty log message ***
nipkow
parents:
diff changeset
   207
(*>*)