author | huffman |
Thu, 21 Oct 2010 12:51:36 -0700 | |
changeset 40084 | 23a1cfdb5acb |
parent 40028 | 9ee4e0ab2964 |
child 40322 | 707eb30e8a53 |
permissions | -rw-r--r-- |
1479 | 1 |
(* Title: HOLCF/ex/Loop.thy |
2 |
Author: Franz Regensburger |
|
244 | 3 |
*) |
4 |
||
17291 | 5 |
header {* Theory for a loop primitive like while *} |
244 | 6 |
|
17291 | 7 |
theory Loop |
8 |
imports HOLCF |
|
9 |
begin |
|
244 | 10 |
|
19763 | 11 |
definition |
21404
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
wenzelm
parents:
19763
diff
changeset
|
12 |
step :: "('a -> tr)->('a -> 'a)->'a->'a" where |
19763 | 13 |
"step = (LAM b g x. If b$x then g$x else x fi)" |
19742 | 14 |
|
21404
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
wenzelm
parents:
19763
diff
changeset
|
15 |
definition |
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
wenzelm
parents:
19763
diff
changeset
|
16 |
while :: "('a -> tr)->('a -> 'a)->'a->'a" where |
19763 | 17 |
"while = (LAM b g. fix$(LAM f x. If b$x then f$(g$x) else x fi))" |
244 | 18 |
|
19742 | 19 |
(* ------------------------------------------------------------------------- *) |
20 |
(* access to definitions *) |
|
21 |
(* ------------------------------------------------------------------------- *) |
|
22 |
||
23 |
||
24 |
lemma step_def2: "step$b$g$x = If b$x then g$x else x fi" |
|
25 |
apply (unfold step_def) |
|
26 |
apply simp |
|
27 |
done |
|
28 |
||
29 |
lemma while_def2: "while$b$g = fix$(LAM f x. If b$x then f$(g$x) else x fi)" |
|
30 |
apply (unfold while_def) |
|
31 |
apply simp |
|
32 |
done |
|
33 |
||
34 |
||
35 |
(* ------------------------------------------------------------------------- *) |
|
36 |
(* rekursive properties of while *) |
|
37 |
(* ------------------------------------------------------------------------- *) |
|
38 |
||
39 |
lemma while_unfold: "while$b$g$x = If b$x then while$b$g$(g$x) else x fi" |
|
40 |
apply (rule trans) |
|
41 |
apply (rule while_def2 [THEN fix_eq5]) |
|
42 |
apply simp |
|
43 |
done |
|
44 |
||
45 |
lemma while_unfold2: "ALL x. while$b$g$x = while$b$g$(iterate k$(step$b$g)$x)" |
|
46 |
apply (induct_tac k) |
|
47 |
apply simp |
|
48 |
apply (rule allI) |
|
49 |
apply (rule trans) |
|
50 |
apply (subst while_unfold) |
|
51 |
apply (rule_tac [2] refl) |
|
52 |
apply (subst iterate_Suc2) |
|
53 |
apply (rule trans) |
|
54 |
apply (erule_tac [2] spec) |
|
55 |
apply (subst step_def2) |
|
56 |
apply (rule_tac p = "b$x" in trE) |
|
57 |
apply simp |
|
58 |
apply (subst while_unfold) |
|
59 |
apply (rule_tac s = "UU" and t = "b$UU" in ssubst) |
|
60 |
apply (erule flat_codom [THEN disjE]) |
|
61 |
apply assumption |
|
62 |
apply (erule spec) |
|
63 |
apply simp |
|
64 |
apply simp |
|
65 |
apply simp |
|
66 |
apply (subst while_unfold) |
|
67 |
apply simp |
|
68 |
done |
|
69 |
||
70 |
lemma while_unfold3: "while$b$g$x = while$b$g$(step$b$g$x)" |
|
71 |
apply (rule_tac s = "while$b$g$ (iterate (Suc 0) $ (step$b$g) $x) " in trans) |
|
72 |
apply (rule while_unfold2 [THEN spec]) |
|
73 |
apply simp |
|
74 |
done |
|
75 |
||
76 |
||
77 |
(* ------------------------------------------------------------------------- *) |
|
78 |
(* properties of while and iterations *) |
|
79 |
(* ------------------------------------------------------------------------- *) |
|
80 |
||
81 |
lemma loop_lemma1: "[| EX y. b$y=FF; iterate k$(step$b$g)$x = UU |] |
|
82 |
==>iterate(Suc k)$(step$b$g)$x=UU" |
|
83 |
apply (simp (no_asm)) |
|
84 |
apply (rule trans) |
|
85 |
apply (rule step_def2) |
|
86 |
apply simp |
|
87 |
apply (erule exE) |
|
88 |
apply (erule flat_codom [THEN disjE]) |
|
89 |
apply simp_all |
|
90 |
done |
|
91 |
||
92 |
lemma loop_lemma2: "[|EX y. b$y=FF;iterate (Suc k)$(step$b$g)$x ~=UU |]==> |
|
93 |
iterate k$(step$b$g)$x ~=UU" |
|
94 |
apply (blast intro: loop_lemma1) |
|
95 |
done |
|
96 |
||
97 |
lemma loop_lemma3 [rule_format (no_asm)]: |
|
98 |
"[| ALL x. INV x & b$x=TT & g$x~=UU --> INV (g$x); |
|
99 |
EX y. b$y=FF; INV x |] |
|
100 |
==> iterate k$(step$b$g)$x ~=UU --> INV (iterate k$(step$b$g)$x)" |
|
101 |
apply (induct_tac "k") |
|
102 |
apply (simp (no_asm_simp)) |
|
103 |
apply (intro strip) |
|
104 |
apply (simp (no_asm) add: step_def2) |
|
105 |
apply (rule_tac p = "b$ (iterate n$ (step$b$g) $x) " in trE) |
|
106 |
apply (erule notE) |
|
40028 | 107 |
apply (simp add: step_def2) |
108 |
apply (simp (no_asm_simp)) |
|
19742 | 109 |
apply (rule mp) |
110 |
apply (erule spec) |
|
40028 | 111 |
apply (simp (no_asm_simp) del: iterate_Suc add: loop_lemma2) |
19742 | 112 |
apply (rule_tac s = "iterate (Suc n) $ (step$b$g) $x" |
113 |
and t = "g$ (iterate n$ (step$b$g) $x) " in ssubst) |
|
114 |
prefer 2 apply (assumption) |
|
115 |
apply (simp add: step_def2) |
|
35170 | 116 |
apply (drule (1) loop_lemma2, simp) |
19742 | 117 |
done |
118 |
||
119 |
lemma loop_lemma4 [rule_format]: |
|
120 |
"ALL x. b$(iterate k$(step$b$g)$x)=FF --> while$b$g$x= iterate k$(step$b$g)$x" |
|
121 |
apply (induct_tac k) |
|
122 |
apply (simp (no_asm)) |
|
123 |
apply (intro strip) |
|
124 |
apply (simplesubst while_unfold) |
|
125 |
apply simp |
|
126 |
apply (rule allI) |
|
127 |
apply (simplesubst iterate_Suc2) |
|
128 |
apply (intro strip) |
|
129 |
apply (rule trans) |
|
130 |
apply (rule while_unfold3) |
|
131 |
apply simp |
|
132 |
done |
|
133 |
||
134 |
lemma loop_lemma5 [rule_format (no_asm)]: |
|
135 |
"ALL k. b$(iterate k$(step$b$g)$x) ~= FF ==> |
|
136 |
ALL m. while$b$g$(iterate m$(step$b$g)$x)=UU" |
|
137 |
apply (simplesubst while_def2) |
|
138 |
apply (rule fix_ind) |
|
35948 | 139 |
apply simp |
140 |
apply simp |
|
19742 | 141 |
apply (rule allI) |
142 |
apply (simp (no_asm)) |
|
143 |
apply (rule_tac p = "b$ (iterate m$ (step$b$g) $x) " in trE) |
|
144 |
apply (simp (no_asm_simp)) |
|
145 |
apply (simp (no_asm_simp)) |
|
146 |
apply (rule_tac s = "xa$ (iterate (Suc m) $ (step$b$g) $x) " in trans) |
|
147 |
apply (erule_tac [2] spec) |
|
148 |
apply (rule cfun_arg_cong) |
|
149 |
apply (rule trans) |
|
150 |
apply (rule_tac [2] iterate_Suc [symmetric]) |
|
151 |
apply (simp add: step_def2) |
|
152 |
apply blast |
|
153 |
done |
|
154 |
||
155 |
lemma loop_lemma6: "ALL k. b$(iterate k$(step$b$g)$x) ~= FF ==> while$b$g$x=UU" |
|
156 |
apply (rule_tac t = "x" in iterate_0 [THEN subst]) |
|
157 |
apply (erule loop_lemma5) |
|
158 |
done |
|
159 |
||
160 |
lemma loop_lemma7: "while$b$g$x ~= UU ==> EX k. b$(iterate k$(step$b$g)$x) = FF" |
|
161 |
apply (blast intro: loop_lemma6) |
|
162 |
done |
|
163 |
||
164 |
||
165 |
(* ------------------------------------------------------------------------- *) |
|
166 |
(* an invariant rule for loops *) |
|
167 |
(* ------------------------------------------------------------------------- *) |
|
168 |
||
169 |
lemma loop_inv2: |
|
170 |
"[| (ALL y. INV y & b$y=TT & g$y ~= UU --> INV (g$y)); |
|
171 |
(ALL y. INV y & b$y=FF --> Q y); |
|
172 |
INV x; while$b$g$x~=UU |] ==> Q (while$b$g$x)" |
|
173 |
apply (rule_tac P = "%k. b$ (iterate k$ (step$b$g) $x) =FF" in exE) |
|
174 |
apply (erule loop_lemma7) |
|
175 |
apply (simplesubst loop_lemma4) |
|
176 |
apply assumption |
|
177 |
apply (drule spec, erule mp) |
|
178 |
apply (rule conjI) |
|
179 |
prefer 2 apply (assumption) |
|
180 |
apply (rule loop_lemma3) |
|
181 |
apply assumption |
|
182 |
apply (blast intro: loop_lemma6) |
|
183 |
apply assumption |
|
184 |
apply (rotate_tac -1) |
|
185 |
apply (simp add: loop_lemma4) |
|
186 |
done |
|
187 |
||
188 |
lemma loop_inv: |
|
189 |
assumes premP: "P(x)" |
|
190 |
and premI: "!!y. P y ==> INV y" |
|
191 |
and premTT: "!!y. [| INV y; b$y=TT; g$y~=UU|] ==> INV (g$y)" |
|
192 |
and premFF: "!!y. [| INV y; b$y=FF|] ==> Q y" |
|
193 |
and premW: "while$b$g$x ~= UU" |
|
194 |
shows "Q (while$b$g$x)" |
|
195 |
apply (rule loop_inv2) |
|
196 |
apply (rule_tac [3] premP [THEN premI]) |
|
197 |
apply (rule_tac [3] premW) |
|
198 |
apply (blast intro: premTT) |
|
199 |
apply (blast intro: premFF) |
|
200 |
done |
|
244 | 201 |
|
202 |
end |
|
17291 | 203 |