@@ -58,18 +58,36 @@ lemma cost_of_path_eq_cost:
5858 shows "cost_of_path (\<lambda>u v. c\<^sub>1 {u,v}) P = cost_of_path (\<lambda>u v. c\<^sub>2 {u,v}) P"
5959 using assms by ( induction P rule : list012.induct ) auto
6060
61- lemma cost_of_path_append :
61+ lemma cost_of_path_append_last :
6262 fixes c :: "'a \<Rightarrow> 'a \<Rightarrow> ('b::ordered_semiring_0)" \<comment> \<open>Needed for associativity.\<close>
6363 assumes "P\<^sub>1 \<noteq> []"
6464 shows "cost_of_path c (P\<^sub>1 @ P\<^sub>2) = cost_of_path c P\<^sub>1 + cost_of_path c (last P\<^sub>1#P\<^sub>2)"
65- using assms by ( induction P \<^sub >1 arbitrary : P \<^sub >2 rule : list012.induct )
65+ using assms by ( induction P \<^sub >1 arbitrary : P \<^sub >2 rule : list012_induct )
6666 ( auto simp : cost_of_path_cons add.assoc )
6767
68- lemma cost_of_path_append2 :
68+ lemma cost_of_path_append_hd :
69+ fixes c :: "'a \<Rightarrow> 'a \<Rightarrow> ('b::ordered_semiring_0)" \<comment> \<open>Needed for associativity.\<close>
70+ assumes "P\<^sub>2 \<noteq> []"
71+ shows "cost_of_path c (P\<^sub>1 @ P\<^sub>2) = cost_of_path c (P\<^sub>1 @ [hd P\<^sub>2]) + cost_of_path c P\<^sub>2"
72+ using assms proof ( induction P \<^sub >1 arbitrary : P \<^sub >2 rule : list012_induct )
73+ case Nil
74+ then show ?case by auto
75+ next
76+ case ( Singleton v )
77+ then show ?case by ( auto simp : cost_of_path_cons add.assoc )
78+ next
79+ case ( CCons u v P \<^sub >1 )
80+ have "cost_of_path c (u#v#P\<^sub>1 @ P\<^sub>2) = c u v + cost_of_path c (v#P\<^sub>1 @ [hd P\<^sub>2]) + cost_of_path c P\<^sub>2"
81+ using CCons.IH [ of "P\<^sub>2" , OF CCons.prems ] by ( auto simp : cost_of_path_cons add.assoc )
82+ thus ?case
83+ by ( auto simp : cost_of_path_cons add.assoc )
84+ qed
85+
86+ lemma cost_of_path_append :
6987 fixes c :: "'a \<Rightarrow> 'a \<Rightarrow> ('b::ordered_semiring_0)" \<comment> \<open>Needed for associativity.\<close>
7088 assumes "P\<^sub>1 \<noteq> []" "P\<^sub>2 \<noteq> []"
7189 shows "cost_of_path c (P\<^sub>1 @ P\<^sub>2) = cost_of_path c P\<^sub>1 + c (last P\<^sub>1) (hd P\<^sub>2) + cost_of_path c P\<^sub>2"
72- using assms by ( auto simp add : cost_of_path_append cost_of_path_cons add.assoc )
90+ using assms by ( auto simp add : cost_of_path_append_last cost_of_path_cons add.assoc )
7391
7492lemma cost_of_path_append_geq_0 :
7593 assumes "\<And>x y. c x y \<ge> (0::'b::{ordered_semiring_0})"
@@ -78,7 +96,7 @@ lemma cost_of_path_append_geq_0:
7896proof cases
7997 assume "P\<^sub>1 \<noteq> [] \<and> P\<^sub>2 \<noteq> []"
8098 hence "cost_of_path c (P\<^sub>1 @ P\<^sub>2) = cost_of_path c P\<^sub>1 + c (last P\<^sub>1) (hd P\<^sub>2) + cost_of_path c P\<^sub>2"
81- by ( auto simp add : cost_of_path_append2 )
99+ by ( auto simp add : cost_of_path_append )
82100 also have "... = c (last P\<^sub>1) (hd P\<^sub>2) + (cost_of_path c P\<^sub>1 + cost_of_path c P\<^sub>2)"
83101 apply ( subst add.commute )
84102 apply ( subst add.assoc )
@@ -118,7 +136,7 @@ proof (induction xs arbitrary: acc rule: list012.induct)
118136 hence "cost_of_path c (rotate_tour_acc acc f (x#y#xs)) = cost_of_path c ((y#xs @ acc) @ [y])"
119137 using 3 by auto
120138 also have "... = cost_of_path c ((y#xs) @ acc) + c (last ((y#xs) @ acc)) y"
121- using cost_of_path_append2 [ of "(y#xs) @ acc" "[y]" ] by auto
139+ using cost_of_path_append [ of "(y#xs) @ acc" "[y]" ] by auto
122140 also have "... = cost_of_path c ((x#y#xs) @ acc)"
123141 using 3 by ( auto simp add : add.commute )
124142 finally show ?thesis by auto
@@ -131,7 +149,7 @@ lemma cost_rotate_tour:
131149 shows "cost_of_path c (rotate_tour f xs) = cost_of_path c xs"
132150 using assms by ( auto simp add : cost_rotate_tour_acc )
133151
134- lemma rotate_tour_acc_cost_0 :
152+ (* lemma rotate_tour_acc_cost_0:
135153 assumes "xs \<noteq> []" "hd (xs @ acc) = last (xs @ acc)"
136154 and "cost_of_path (\<lambda>x y. if f x y then (1::nat) else 0) xs = 0"
137155 shows "rotate_tour_acc acc f xs = (last xs)#acc @ tl xs"
@@ -181,42 +199,112 @@ proof (induction xs arbitrary: thesis rule: list012.induct)
181199 ultimately show ?thesis
182200 using 3 by auto
183201 qed
184- qed auto
202+ qed auto *)
185203
186204lemma not_hd_snd_rotate_tour_acc :
187- assumes "cost_of_path (\<lambda>x y. if \<not> f x \<and> f y then (1::nat) else 0) xs > 0"
188- ( is "cost_of_path ?c xs > 0" ) and "rotate_tour_acc acc (\<lambda>x y. \<not> f x \<and> f y) xs = x#y#xs'"
189- shows "\<not> f x" "f y"
190- using assms by ( induction xs arbitrary : acc rule : list012.induct ) ( auto split : if_splits )
205+ assumes "cost_of_path (\<lambda>x y. if f x y then (1::nat) else 0) xs > 0"
206+ ( is "cost_of_path ?c xs > 0" ) and "rotate_tour_acc acc f xs = x#y#xs'"
207+ shows "f x y"
208+ using assms by ( induction xs arbitrary : acc rule : list012_induct ) ( auto split : if_splits )
191209
192210lemma not_hd_snd_rotate_tour :
193- assumes "cost_of_path (\<lambda>x y. if \<not> f x \<and> f y then (1::nat) else 0) xs > 0"
194- and "rotate_tour (\<lambda>x y. \<not> f x \<and> f y) xs = x#y#xs'"
195- shows "\<not> f x" "f y"
211+ assumes "cost_of_path (\<lambda>x y. if f x y then (1::nat) else 0) xs > 0"
212+ and "rotate_tour f xs = x#y#xs'"
213+ shows "f x y"
196214 using assms ( 2 ) not_hd_snd_rotate_tour_acc [ OF assms ( 1 ), of "[]" x y xs' ] by auto
197215
198216lemma rotate_tour_invariant :
199- assumes "\<not> f x" "f y"
200- shows "cost_of_path (\<lambda>x y. if \<not> f x \<and> f y then (1::nat) else 0) (x#xs @ [y]) > 0"
201- using assms cost_of_path_geq_0 by ( induction xs arbitrary : x y ) auto
217+ assumes "\<not> f x y" and trans : "\<And>x y z. f x y \<Longrightarrow> f y z \<Longrightarrow> f x z" and "y \<in> set xs"
218+ shows "cost_of_path (\<lambda>x y. if \<not> f x y then (1::nat) else 0) (x#xs) > 0"
219+ ( is "cost_of_path ?h _ > 0" )
220+ using assms
221+ proof ( induction xs arbitrary : x y )
222+ case Nil
223+ then show ?case by auto
224+ next
225+ case ( Cons x \<^sub >1 xs )
226+ consider "f x x\<^sub>1" | "\<not> f x x\<^sub>1"
227+ by auto
228+ then show ?case
229+ using cost_of_path_geq_0
230+ proof cases
231+ assume "f x x\<^sub>1"
232+ hence "\<not> f x\<^sub>1 y" and "x\<^sub>1 \<noteq> y"
233+ using Cons by blast +
234+ moreover hence "y \<in> set xs"
235+ using Cons set_ConsD by metis
236+ ultimately have "cost_of_path ?h (x\<^sub>1#xs) > 0"
237+ using Cons by blast
238+ thus ?thesis
239+ by auto
240+ qed auto
241+ qed
202242
203243lemma rotate_tour_invariant_intro :
204- assumes "xs = xs\<^sub>1 @ x#xs\<^sub>2 @ y#xs\<^sub>3" "\<not> f x" "f y"
205- shows "cost_of_path (\<lambda>x y. if \<not> f x \<and> f y then (1::nat) else 0) xs > 0" ( is "cost_of_path ?c xs > 0" )
206- proof -
207- have "0 < cost_of_path ?c (x#xs\<^sub>2 @ [y])"
244+ assumes sym : "\<And>x y. f x y \<Longrightarrow> f y x"
245+ and trans : "\<And>x y z. f x y \<Longrightarrow> f y z \<Longrightarrow> f x z"
246+ and "x \<in> set xs" "y \<in> set xs" "x \<noteq> y" "\<not> f x y"
247+ shows "cost_of_path (\<lambda>x y. if \<not> f x y then (1::nat) else 0) xs > 0"
248+ ( is "cost_of_path ?h xs > 0" )
249+ using assms ( 3 - 5 )
250+ proof ( rule list_split_for_2elems )
251+ fix xs \<^sub >1 xs \<^sub >2
252+ assume [ simp ]: "xs = xs\<^sub>1 @ x#xs\<^sub>2" and "y \<in> set xs\<^sub>2"
253+ hence "0 < cost_of_path ?h (x#xs\<^sub>2)"
208254 using assms by ( intro rotate_tour_invariant )
209- also have "... \<le> cost_of_path ?c (x# xs\<^sub>2 @ [y]) + cost_of_path ?c xs\<^sub>3 "
255+ also have "... \<le> cost_of_path ?h xs\<^sub>1 + cost_of_path ?h (x# xs\<^sub>2) "
210256 using cost_of_path_geq_0 by auto
211- also have "... \<le> cost_of_path ?c ((x# xs\<^sub>2 @ [y]) @ xs\<^sub>3 )"
257+ also have "... \<le> cost_of_path ?h ( xs\<^sub>1 @ x# xs\<^sub>2 )"
212258 by ( intro cost_of_path_append_geq_0 ) auto
213- also have "... \<le> cost_of_path ?c xs\<^sub>1 + cost_of_path ?c (x#xs\<^sub>2 @ y#xs\<^sub>3)"
259+ finally show "cost_of_path ?h xs > 0"
260+ by auto
261+ next
262+ fix xs \<^sub >1 xs \<^sub >2
263+ assume [ simp ]: "xs = xs\<^sub>1 @ y#xs\<^sub>2" and "x \<in> set xs\<^sub>2"
264+ moreover have "\<not> f y x"
265+ using assms by blast
266+ ultimately have "0 < cost_of_path ?h (y#xs\<^sub>2)"
267+ using assms by ( intro rotate_tour_invariant )
268+ also have "... \<le> cost_of_path ?h xs\<^sub>1 + cost_of_path ?h (y#xs\<^sub>2)"
214269 using cost_of_path_geq_0 by auto
215- also have "... \<le> cost_of_path ?c (xs\<^sub>1 @ x#xs\<^sub>2 @ y#xs\<^sub>3 )"
270+ also have "... \<le> cost_of_path ?h (xs\<^sub>1 @ y#xs\<^sub>2 )"
216271 by ( intro cost_of_path_append_geq_0 ) auto
217- also have "... = cost_of_path ?c xs"
218- using assms by auto
219- finally show ?thesis
272+ finally show "cost_of_path ?h xs > 0"
273+ by auto
274+ qed
275+
276+ lemma rearrange_tour :
277+ fixes c :: "'a \<Rightarrow> 'a \<Rightarrow> ('b::ordered_semiring_0)" \<comment> \<open>Needed for commutativity.\<close>
278+ assumes "\<And>u v. c u v = c v u"
279+ and "xs \<noteq> []" "ys \<noteq> []"
280+ shows "cost_of_path c (last xs#ys @ xs) = cost_of_path c (last ys#xs @ ys)"
281+ using assms
282+ proof ( induction ys arbitrary : xs rule : list012_induct )
283+ case Nil
284+ then show ?case by auto
285+ next
286+ case ( Singleton y )
287+ have "cost_of_path c (last xs#[y] @ xs) = cost_of_path c ([y] @ xs) + c (last xs) y"
288+ by ( auto simp add : add.commute )
289+ also have "... = cost_of_path c ([y] @ xs @ [y])"
290+ using Singleton cost_of_path_append_last [ of "[y] @ xs" c "[y]" ] by auto
291+ also have "... = cost_of_path c (last [y]#xs @ [y])"
292+ by auto
293+ finally show ?case
294+ by auto
295+ next
296+ case ( CCons y z ys )
297+ have "cost_of_path c (last xs#y#z#ys @ xs) = cost_of_path c (y#z#ys @ xs) + c (last xs) y"
298+ by ( auto simp add : add.commute add.left_commute )
299+ also have "... = cost_of_path c (y#z#ys @ xs @ [y])"
300+ using CCons cost_of_path_append_last [ of "y#z#ys @ xs" c "[y]" ] by auto
301+ also have "... = cost_of_path c (last (xs @ [y])#z#ys @ xs @ [y])"
302+ by auto
303+ also have "... = cost_of_path c (last (z#ys)#xs @ [y] @ z#ys)"
304+ using CCons CCons.IH [ of "xs @ [y]" ] by auto
305+ also have "... = cost_of_path c (last (y#z#ys)#xs @ y#z#ys)"
306+ by auto
307+ finally show ?case
220308 by auto
221309qed
222310
267355 assume "f x \<noteq> []" and "?fyxs \<noteq> []"
268356 hence "cost_of_path c (concat (map f (x#y#xs)))
269357 = cost_of_path c (f x) + c (last (f x)) (hd ?fyxs) + cost_of_path c ?fyxs"
270- by ( auto simp add : cost_of_path_append2 )
358+ by ( auto simp add : cost_of_path_append )
271359 also have "... \<le> cost_of_path c (f x) + k + cost_of_path c ?fyxs"
272360 using 3 \<open>f x \<noteq> []\<close> \<open>?fyxs \<noteq> []\<close> cost_hd_concat_map [ of "y#xs" f c "last (f x)" k ] by auto
273361 also have "... \<le> (\<Sum>x\<leftarrow>(x#y#xs). cost_of_path c (f x)) + (length (tl (x#y#xs))) * k"
0 commit comments