53 text{* |
53 text{* |
54 The most obvious approach is the brute force expansion of @{term split}: |
54 The most obvious approach is the brute force expansion of @{term split}: |
55 *} |
55 *} |
56 |
56 |
57 lemma "(\<lambda>(x,y).x) p = fst p" |
57 lemma "(\<lambda>(x,y).x) p = fst p" |
58 by(simp add:split_def) |
58 by(simp add: split_def) |
59 |
59 |
60 text{* This works well if rewriting with @{thm[source]split_def} finishes the |
60 text{* This works well if rewriting with @{thm[source]split_def} finishes the |
61 proof, as it does above. But if it does not, you end up with exactly what |
61 proof, as it does above. But if it does not, you end up with exactly what |
62 we are trying to avoid: nests of @{term fst} and @{term snd}. Thus this |
62 we are trying to avoid: nests of @{term fst} and @{term snd}. Thus this |
63 approach is neither elegant nor very practical in large examples, although it |
63 approach is neither elegant nor very practical in large examples, although it |
100 @{subgoals[display,indent=0]} |
100 @{subgoals[display,indent=0]} |
101 A paired @{text let} reduces to a paired $\lambda$-abstraction, which |
101 A paired @{text let} reduces to a paired $\lambda$-abstraction, which |
102 can be split as above. The same is true for paired set comprehension: |
102 can be split as above. The same is true for paired set comprehension: |
103 *} |
103 *} |
104 |
104 |
105 (*<*)by(simp split:split_split)(*>*) |
105 (*<*)by(simp split: split_split)(*>*) |
106 lemma "p \<in> {(x,y). x=y} \<longrightarrow> fst p = snd p" |
106 lemma "p \<in> {(x,y). x=y} \<longrightarrow> fst p = snd p" |
107 apply simp |
107 apply simp |
108 |
108 |
109 txt{* |
109 txt{* |
110 @{subgoals[display,indent=0]} |
110 @{subgoals[display,indent=0]} |
112 as above. If you are worried about the strange form of the premise: |
112 as above. If you are worried about the strange form of the premise: |
113 @{term"split (op =)"} is short for @{text"\<lambda>(x,y). x=y"}. |
113 @{term"split (op =)"} is short for @{text"\<lambda>(x,y). x=y"}. |
114 The same proof procedure works for |
114 The same proof procedure works for |
115 *} |
115 *} |
116 |
116 |
117 (*<*)by(simp split:split_split)(*>*) |
117 (*<*)by(simp split: split_split)(*>*) |
118 lemma "p \<in> {(x,y). x=y} \<Longrightarrow> fst p = snd p" |
118 lemma "p \<in> {(x,y). x=y} \<Longrightarrow> fst p = snd p" |
119 |
119 |
120 txt{*\noindent |
120 txt{*\noindent |
121 except that we now have to use @{thm[source]split_split_asm}, because |
121 except that we now have to use @{thm[source]split_split_asm}, because |
122 @{term split} occurs in the assumptions. |
122 @{term split} occurs in the assumptions. |
123 |
123 |
124 However, splitting @{term split} is not always a solution, as no @{term split} |
124 However, splitting @{term split} is not always a solution, as no @{term split} |
125 may be present in the goal. Consider the following function: |
125 may be present in the goal. Consider the following function: |
126 *} |
126 *} |
127 |
127 |
128 (*<*)by(simp split:split_split_asm)(*>*) |
128 (*<*)by(simp split: split_split_asm)(*>*) |
129 consts swap :: "'a \<times> 'b \<Rightarrow> 'b \<times> 'a" |
129 consts swap :: "'a \<times> 'b \<Rightarrow> 'b \<times> 'a" |
130 primrec |
130 primrec |
131 "swap (x,y) = (y,x)" |
131 "swap (x,y) = (y,x)" |
132 |
132 |
133 text{*\noindent |
133 text{*\noindent |