13 based on Berger, Schwichtenberg and Seisenberger @{cite "Berger-JAR-2001"}. |
13 based on Berger, Schwichtenberg and Seisenberger @{cite "Berger-JAR-2001"}. |
14 \<close> |
14 \<close> |
15 |
15 |
16 datatype b = T | F |
16 datatype b = T | F |
17 |
17 |
18 primrec |
18 primrec is_path' :: "('a \<Rightarrow> 'a \<Rightarrow> b) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool" |
19 is_path' :: "('a \<Rightarrow> 'a \<Rightarrow> b) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool" |
|
20 where |
19 where |
21 "is_path' r x [] z = (r x z = T)" |
20 "is_path' r x [] z \<longleftrightarrow> r x z = T" |
22 | "is_path' r x (y # ys) z = (r x y = T \<and> is_path' r y ys z)" |
21 | "is_path' r x (y # ys) z \<longleftrightarrow> r x y = T \<and> is_path' r y ys z" |
23 |
22 |
24 definition |
23 definition is_path :: "(nat \<Rightarrow> nat \<Rightarrow> b) \<Rightarrow> (nat * nat list * nat) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" |
25 is_path :: "(nat \<Rightarrow> nat \<Rightarrow> b) \<Rightarrow> (nat * nat list * nat) \<Rightarrow> |
24 where "is_path r p i j k \<longleftrightarrow> |
26 nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" |
25 fst p = j \<and> snd (snd p) = k \<and> |
27 where |
26 list_all (\<lambda>x. x < i) (fst (snd p)) \<and> |
28 "is_path r p i j k \<longleftrightarrow> fst p = j \<and> snd (snd p) = k \<and> |
27 is_path' r (fst p) (fst (snd p)) (snd (snd p))" |
29 list_all (\<lambda>x. x < i) (fst (snd p)) \<and> |
28 |
30 is_path' r (fst p) (fst (snd p)) (snd (snd p))" |
29 definition conc :: "'a \<times> 'a list \<times> 'a \<Rightarrow> 'a \<times> 'a list \<times> 'a \<Rightarrow> 'a \<times> 'a list * 'a" |
31 |
30 where "conc p q = (fst p, fst (snd p) @ fst q # fst (snd q), snd (snd q))" |
32 definition |
31 |
33 conc :: "('a * 'a list * 'a) \<Rightarrow> ('a * 'a list * 'a) \<Rightarrow> ('a * 'a list * 'a)" |
32 theorem is_path'_snoc [simp]: "\<And>x. is_path' r x (ys @ [y]) z = (is_path' r x ys y \<and> r y z = T)" |
34 where |
|
35 "conc p q = (fst p, fst (snd p) @ fst q # fst (snd q), snd (snd q))" |
|
36 |
|
37 theorem is_path'_snoc [simp]: |
|
38 "\<And>x. is_path' r x (ys @ [y]) z = (is_path' r x ys y \<and> r y z = T)" |
|
39 by (induct ys) simp+ |
33 by (induct ys) simp+ |
40 |
34 |
41 theorem list_all_scoc [simp]: "list_all P (xs @ [x]) \<longleftrightarrow> P x \<and> list_all P xs" |
35 theorem list_all_scoc [simp]: "list_all P (xs @ [x]) \<longleftrightarrow> P x \<and> list_all P xs" |
42 by (induct xs, simp+, iprover) |
36 by (induct xs) (simp+, iprover) |
43 |
37 |
44 theorem list_all_lemma: |
38 theorem list_all_lemma: "list_all P xs \<Longrightarrow> (\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> list_all Q xs" |
45 "list_all P xs \<Longrightarrow> (\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> list_all Q xs" |
|
46 proof - |
39 proof - |
47 assume PQ: "\<And>x. P x \<Longrightarrow> Q x" |
40 assume PQ: "\<And>x. P x \<Longrightarrow> Q x" |
48 show "list_all P xs \<Longrightarrow> list_all Q xs" |
41 show "list_all P xs \<Longrightarrow> list_all Q xs" |
49 proof (induct xs) |
42 proof (induct xs) |
50 case Nil |
43 case Nil |
51 show ?case by simp |
44 show ?case by simp |
52 next |
45 next |
53 case (Cons y ys) |
46 case (Cons y ys) |
54 hence Py: "P y" by simp |
47 then have Py: "P y" by simp |
55 from Cons have Pys: "list_all P ys" by simp |
48 from Cons have Pys: "list_all P ys" by simp |
56 show ?case |
49 show ?case |
57 by simp (rule conjI PQ Py Cons Pys)+ |
50 by simp (rule conjI PQ Py Cons Pys)+ |
58 qed |
51 qed |
59 qed |
52 qed |
60 |
53 |
61 theorem lemma1: "\<And>p. is_path r p i j k \<Longrightarrow> is_path r p (Suc i) j k" |
54 theorem lemma1: "\<And>p. is_path r p i j k \<Longrightarrow> is_path r p (Suc i) j k" |
62 apply (unfold is_path_def) |
55 unfolding is_path_def |
63 apply (simp cong add: conj_cong add: split_paired_all) |
56 apply (simp cong add: conj_cong add: split_paired_all) |
64 apply (erule conjE)+ |
57 apply (erule conjE)+ |
65 apply (erule list_all_lemma) |
58 apply (erule list_all_lemma) |
66 apply simp |
59 apply simp |
67 done |
60 done |
68 |
61 |
69 theorem lemma2: "\<And>p. is_path r p 0 j k \<Longrightarrow> r j k = T" |
62 theorem lemma2: "\<And>p. is_path r p 0 j k \<Longrightarrow> r j k = T" |
70 apply (unfold is_path_def) |
63 unfolding is_path_def |
71 apply (simp cong add: conj_cong add: split_paired_all) |
64 apply (simp cong add: conj_cong add: split_paired_all) |
72 apply (case_tac "aa") |
65 apply (case_tac "aa") |
73 apply simp+ |
66 apply simp+ |
74 done |
67 done |
75 |
68 |
78 proof - |
71 proof - |
79 assume pys: "is_path' r i ys k" |
72 assume pys: "is_path' r i ys k" |
80 show "\<And>j. is_path' r j xs i \<Longrightarrow> is_path' r j (xs @ i # ys) k" |
73 show "\<And>j. is_path' r j xs i \<Longrightarrow> is_path' r j (xs @ i # ys) k" |
81 proof (induct xs) |
74 proof (induct xs) |
82 case (Nil j) |
75 case (Nil j) |
83 hence "r j i = T" by simp |
76 then have "r j i = T" by simp |
84 with pys show ?case by simp |
77 with pys show ?case by simp |
85 next |
78 next |
86 case (Cons z zs j) |
79 case (Cons z zs j) |
87 hence jzr: "r j z = T" by simp |
80 then have jzr: "r j z = T" by simp |
88 from Cons have pzs: "is_path' r z zs i" by simp |
81 from Cons have pzs: "is_path' r z zs i" by simp |
89 show ?case |
82 show ?case |
90 by simp (rule conjI jzr Cons pzs)+ |
83 by simp (rule conjI jzr Cons pzs)+ |
91 qed |
84 qed |
92 qed |
85 qed |
93 |
86 |
94 theorem lemma3: |
87 theorem lemma3: |
95 "\<And>p q. is_path r p i j i \<Longrightarrow> is_path r q i i k \<Longrightarrow> |
88 "\<And>p q. is_path r p i j i \<Longrightarrow> is_path r q i i k \<Longrightarrow> |
96 is_path r (conc p q) (Suc i) j k" |
89 is_path r (conc p q) (Suc i) j k" |
97 apply (unfold is_path_def conc_def) |
90 apply (unfold is_path_def conc_def) |
98 apply (simp cong add: conj_cong add: split_paired_all) |
91 apply (simp cong add: conj_cong add: split_paired_all) |
99 apply (erule conjE)+ |
92 apply (erule conjE)+ |
100 apply (rule conjI) |
93 apply (rule conjI) |
101 apply (erule list_all_lemma) |
94 apply (erule list_all_lemma) |
122 have "\<And>j. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow> |
115 have "\<And>j. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow> |
123 \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow> |
116 \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow> |
124 \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r j ys i" (is "PROP ?ih xs") |
117 \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r j ys i" (is "PROP ?ih xs") |
125 proof (induct xs) |
118 proof (induct xs) |
126 case Nil |
119 case Nil |
127 thus ?case by simp |
120 then show ?case by simp |
128 next |
121 next |
129 case (Cons a as j) |
122 case (Cons a as j) |
130 show ?case |
123 show ?case |
131 proof (cases "a=i") |
124 proof (cases "a=i") |
132 case True |
125 case True |
133 show ?thesis |
126 show ?thesis |
134 proof |
127 proof |
135 from True and Cons have "r j i = T" by simp |
128 from True and Cons have "r j i = T" by simp |
136 thus "list_all (\<lambda>x. x < i) [] \<and> is_path' r j [] i" by simp |
129 then show "list_all (\<lambda>x. x < i) [] \<and> is_path' r j [] i" by simp |
137 qed |
130 qed |
138 next |
131 next |
139 case False |
132 case False |
140 have "PROP ?ih as" by (rule Cons) |
133 have "PROP ?ih as" by (rule Cons) |
141 then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r a ys i" |
134 then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r a ys i" |
155 have "\<And>k. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow> |
148 have "\<And>k. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow> |
156 \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow> |
149 \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow> |
157 \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys k" (is "PROP ?ih xs") |
150 \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys k" (is "PROP ?ih xs") |
158 proof (induct xs rule: rev_induct) |
151 proof (induct xs rule: rev_induct) |
159 case Nil |
152 case Nil |
160 thus ?case by simp |
153 then show ?case by simp |
161 next |
154 next |
162 case (snoc a as k) |
155 case (snoc a as k) |
163 show ?case |
156 show ?case |
164 proof (cases "a=i") |
157 proof (cases "a=i") |
165 case True |
158 case True |
166 show ?thesis |
159 show ?thesis |
167 proof |
160 proof |
168 from True and snoc have "r i k = T" by simp |
161 from True and snoc have "r i k = T" by simp |
169 thus "list_all (\<lambda>x. x < i) [] \<and> is_path' r i [] k" by simp |
162 then show "list_all (\<lambda>x. x < i) [] \<and> is_path' r i [] k" by simp |
170 qed |
163 qed |
171 next |
164 next |
172 case False |
165 case False |
173 have "PROP ?ih as" by (rule snoc) |
166 have "PROP ?ih as" by (rule snoc) |
174 then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys a" |
167 then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys a" |
189 qed |
182 qed |
190 qed |
183 qed |
191 |
184 |
192 theorem lemma5': |
185 theorem lemma5': |
193 "\<And>p. is_path r p (Suc i) j k \<Longrightarrow> \<not> is_path r p i j k \<Longrightarrow> |
186 "\<And>p. is_path r p (Suc i) j k \<Longrightarrow> \<not> is_path r p i j k \<Longrightarrow> |
194 \<not> (\<forall>q. \<not> is_path r q i j i) \<and> \<not> (\<forall>q'. \<not> is_path r q' i i k)" |
187 \<not> (\<forall>q. \<not> is_path r q i j i) \<and> \<not> (\<forall>q'. \<not> is_path r q' i i k)" |
195 by (iprover dest: lemma5) |
188 by (iprover dest: lemma5) |
196 |
189 |
197 theorem warshall: |
190 theorem warshall: "\<And>j k. \<not> (\<exists>p. is_path r p i j k) \<or> (\<exists>p. is_path r p i j k)" |
198 "\<And>j k. \<not> (\<exists>p. is_path r p i j k) \<or> (\<exists>p. is_path r p i j k)" |
|
199 proof (induct i) |
191 proof (induct i) |
200 case (0 j k) |
192 case (0 j k) |
201 show ?case |
193 show ?case |
202 proof (cases "r j k") |
194 proof (cases "r j k") |
203 assume "r j k = T" |
195 assume "r j k = T" |
204 hence "is_path r (j, [], k) 0 j k" |
196 then have "is_path r (j, [], k) 0 j k" |
205 by (simp add: is_path_def) |
197 by (simp add: is_path_def) |
206 hence "\<exists>p. is_path r p 0 j k" .. |
198 then have "\<exists>p. is_path r p 0 j k" .. |
207 thus ?thesis .. |
199 then show ?thesis .. |
208 next |
200 next |
209 assume "r j k = F" |
201 assume "r j k = F" |
210 hence "r j k ~= T" by simp |
202 then have "r j k \<noteq> T" by simp |
211 hence "\<not> (\<exists>p. is_path r p 0 j k)" |
203 then have "\<not> (\<exists>p. is_path r p 0 j k)" |
212 by (iprover dest: lemma2) |
204 by (iprover dest: lemma2) |
213 thus ?thesis .. |
205 then show ?thesis .. |
214 qed |
206 qed |
215 next |
207 next |
216 case (Suc i j k) |
208 case (Suc i j k) |
217 thus ?case |
209 then show ?case |
218 proof |
210 proof |
219 assume h1: "\<not> (\<exists>p. is_path r p i j k)" |
211 assume h1: "\<not> (\<exists>p. is_path r p i j k)" |
220 from Suc show ?case |
212 from Suc show ?case |
221 proof |
213 proof |
222 assume "\<not> (\<exists>p. is_path r p i j i)" |
214 assume "\<not> (\<exists>p. is_path r p i j i)" |
223 with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)" |
215 with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)" |
224 by (iprover dest: lemma5') |
216 by (iprover dest: lemma5') |
225 thus ?case .. |
217 then show ?case .. |
226 next |
218 next |
227 assume "\<exists>p. is_path r p i j i" |
219 assume "\<exists>p. is_path r p i j i" |
228 then obtain p where h2: "is_path r p i j i" .. |
220 then obtain p where h2: "is_path r p i j i" .. |
229 from Suc show ?case |
221 from Suc show ?case |
230 proof |
222 proof |
231 assume "\<not> (\<exists>p. is_path r p i i k)" |
223 assume "\<not> (\<exists>p. is_path r p i i k)" |
232 with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)" |
224 with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)" |
233 by (iprover dest: lemma5') |
225 by (iprover dest: lemma5') |
234 thus ?case .. |
226 then show ?case .. |
235 next |
227 next |
236 assume "\<exists>q. is_path r q i i k" |
228 assume "\<exists>q. is_path r q i i k" |
237 then obtain q where "is_path r q i i k" .. |
229 then obtain q where "is_path r q i i k" .. |
238 with h2 have "is_path r (conc p q) (Suc i) j k" |
230 with h2 have "is_path r (conc p q) (Suc i) j k" |
239 by (rule lemma3) |
231 by (rule lemma3) |
240 hence "\<exists>pq. is_path r pq (Suc i) j k" .. |
232 then have "\<exists>pq. is_path r pq (Suc i) j k" .. |
241 thus ?case .. |
233 then show ?case .. |
242 qed |
234 qed |
243 qed |
235 qed |
244 next |
236 next |
245 assume "\<exists>p. is_path r p i j k" |
237 assume "\<exists>p. is_path r p i j k" |
246 hence "\<exists>p. is_path r p (Suc i) j k" |
238 then have "\<exists>p. is_path r p (Suc i) j k" |
247 by (iprover intro: lemma1) |
239 by (iprover intro: lemma1) |
248 thus ?case .. |
240 then show ?case .. |
249 qed |
241 qed |
250 qed |
242 qed |
251 |
243 |
252 extract warshall |
244 extract warshall |
253 |
245 |