theory TPP2011Minamide2 imports Main begin locale children = fixes S :: "'a set" (* S is the set of children *) fixes right::"'a \ 'a" assumes nonempty[intro,simp]: "S \ {}" assumes finite[intro,simp]: "finite S" assumes image: "right ` S \ S" lemma (in children) [simp]: assumes "X \ S" shows "finite X" by (rule finite_subset[where B = "S"], simp_all add: assms) primrec (in children) rightn :: "['a, nat] \ 'a" where "rightn x 0 = x" | "rightn x (Suc n) = rightn (right x) n" lemma (in children) image_rightn[rule_format]: "\x\S. rightn x n \ S" by (induct n, insert image, auto) locale circle_children = children + assumes circle: "\x\S. \y\S. \n. y = rightn x n" definition avg :: "[nat, nat] \ nat" (infix "\" 100) where "m1 \ m2 = (m1 + m2 + 1) div 2" lemma avg_sym :"m1 \ m2 = m2 \ m1" by (simp add: avg_def) lemma avg1: assumes "m1 \ m" "m2 \ m" shows "m1 \ m2 \ m" proof (unfold avg_def) have "(m1 + m2 + 1) div 2 \ (2*m+1) div 2" by (rule div_le_mono, insert assms, auto) thus "(m1 + m2 + 1) div 2 \ m" by simp qed lemma avg2: assumes "m \ m1 " "m \ m2" shows "m \ m1 \ m2" proof (unfold avg_def) have "(2*m+1) div 2 \ (m1 + m2 + 1) div 2" by (rule div_le_mono, insert assms, auto) thus " m \ (m1 + m2 + 1) div 2" by simp qed lemma avg3: assumes "m < m1 " "m \ m2" shows "m < m1 \ m2" proof (unfold avg_def) have "\m1'. m1 = m1' + 1" using assms by arith then obtain m1' where "m1 = m1' + 1" by blast have "(2*m+2) div 2 \ (m1' + m2 + 2) div 2" by (rule div_le_mono, insert prems, auto) thus "m < (m1 + m2 + 1) div 2" using prems by (simp) qed definition (in children) step :: "['a \ nat] \ 'a \ nat" where "step f x = f x \ f (right x)" definition (in children) wmin :: "['a \ nat] \ nat" where "wmin f = Min (f ` S)" definition (in children) wmax :: "['a \ nat] \ nat" where "wmax f = Max (f ` S)" lemma (in children) wmin[simp]: assumes "x \ S" shows "wmin f \ f x" by (unfold wmin_def, rule Min_le, insert assms, auto) lemma (in children) wmax[simp]: assumes "x \ S" shows "f x \ wmax f" by (unfold wmax_def, rule Max_ge, insert assms, auto) lemma (in children) L1: assumes "x \ S" shows "step f x \ wmax f" by (simp add: step_def, rule avg1, insert assms image, auto) lemma (in children) L2: assumes "x \ S" shows "wmin f \ step f x" by (simp add: step_def, rule avg2, insert assms image, auto) lemma (in children) L3: assumes "x \ S" "wmin f < f x" shows "wmin f < step f x" by (simp add: step_def, rule avg3, fact, insert assms image, auto) lemma (in children) L4: assumes "x \ S" "f x < f (right x)" shows "f x < step f x" by (simp add: step_def, simp add: avg_sym[of "f x"], rule avg3, fact, insert assms image, simp) lemma (in children) L5': "step f -` {wmin f} \ S \ f -` {wmin f} \ S" proof (auto) fix x assume x_in_S: "x \ S" assume "step f x = wmin f" show "f x = wmin f" proof (rule contrapos_pp) assume H: "f x \ wmin f" have "wmin f < step f x" proof (rule L3) show "wmin f < f x" by (rule neq_le_trans, insert H x_in_S, auto) qed (fact) thus "step f x \ wmin f" by simp qed (fact) qed lemma (in children) L5'': assumes H1: "f x = wmin f" and "x \ S" "wmin f < f (right x)" shows "step f -` {wmin f} \ S \ f -` {wmin f} \ S" proof (rule, rule L5') have "wmin f < step f x" by (simp add: H1[THEN sym], rule L4, fact, simp add: H1, fact) hence "step f x \ wmin f" by simp with H1 `x \ S` show "step f -` {wmin f} \ S \ f -` {wmin f} \ S" by (auto simp add: vimage_def) qed lemma (in children) right: shows "\x\S. (f x \ f (rightn x n)) \ (\y\S. f y = f x \ f y \ f (right y))" proof (induct n) case 0 show ?case using assms by auto next case (Suc n) show ?case proof fix x assume "x \ S" let ?x' = "right x" show "f x \ f (rightn x (Suc n)) \ (\y\S. f y = f x \ f y \ f (right y))" proof (cases "f x = f ?x'") case True have "(f ?x' \ f (rightn ?x' n)) \ (\y\S. f y = f ?x' \ f y \ f (right y))" by (rule Suc[THEN bspec], insert `x \ S` image, auto) with True show ?thesis by auto next case False show ?thesis by (rule impI, rule bexI[of _ x], insert False, auto, rule `x\S`) qed qed qed lemma (in circle_children) L5: assumes "wmin f < wmax f" shows "step f -` {wmin f} \ S \ f -` {wmin f} \ S" proof - have "wmin f \ f ` S" by (auto simp add: wmin_def) hence "\x\S. f x = wmin f" by (auto) then obtain x where "x \ S""f x = wmin f" by blast have "wmax f \ f ` S" by (auto simp add: wmax_def) hence "\y\S. f y = wmax f" by (auto) then obtain y where "y\S" "f y = wmax f" by blast have "\n. y = rightn x n" by (rule circle[rule_format], fact+) then obtain n where "y = rightn x n" by blast have "\y\S. f y = f x \ f y \ f (right y)" proof (rule right[rule_format], fact) show "f x \ f (rightn x n)" using prems by auto qed then obtain y where "y\S" "f y = f x" "f y \ f (right y)" by blast show ?thesis proof (rule L5''[of _ y]) show "f y = wmin f" using prems by auto next have "wmin f \ f (right y)" using prems by simp also have "wmin f \ f (right y)" using `y\S` image by auto finally show "wmin f < f (right y)" by simp qed (fact) qed lemma (in children) step_wmin: "wmin f \ wmin (step f)" by (subst (2) wmin_def, auto simp add: L2) lemma (in children) step_wmax: "wmax (step f) \ wmax f" by (subst (1) wmax_def, auto simp add: L1) lemma (in children) step_wmax_wmin: "wmax (step f) - wmin (step f) \ wmax f - wmin f" using step_wmin[of f] step_wmax[of f] by auto lemma (in children) wmin_wmax: "wmin f \ wmax f" by (auto simp add: wmin_def wmax_def) primrec (in circle_children) nstep :: "['a \ nat, nat] \ ('a \ nat)" where "nstep f 0 = f" | "nstep f (Suc n) = nstep (step f) n" theorem (in circle_children) terminating: (* abstract version *) "\n. wmin (nstep f n) = wmax (nstep f n)" (is "?P f") proof - let ?R = "inv_image (less_than <*lex*> finite_psubset) (%f. (wmax f - wmin f, f -` {wmin f} \ S))" show ?thesis proof (induct rule: wf_induct[where r = ?R]) show "wf ?R" by auto next fix f assume IH: "\y. (y, f) \ inv_image (less_than <*lex*> finite_psubset) (\f. (wmax f - wmin f, f -` {wmin f} \ S)) \ ?P y" show "\n. wmin (nstep f n) = wmax (nstep f n)" proof (cases "wmax f = wmin f") case True show ?thesis by (rule exI[of _ 0], simp add: True) next case False have "?P (step f)" proof (rule IH[rule_format]) show "(step f, f) \ inv_image (less_than <*lex*> finite_psubset) (\f. (wmax f - wmin f, f -` {wmin f} \ S))" proof (simp, cases "wmax (step f) - wmin (step f) < wmax f - wmin f") case True thus "wmax (step f) - wmin (step f) < wmax f - wmin f \ wmax (step f) - wmin (step f) = wmax f - wmin f \ step f -` {wmin (step f)} \ S \ f -` {wmin f} \ S" by auto next case False thus "wmax (step f) - wmin (step f) < wmax f - wmin f \ wmax (step f) - wmin (step f) = wmax f - wmin f \ step f -` {wmin (step f)} \ S \ f -` {wmin f} \ S" using step_wmax_wmin[of f] proof simp assume "wmax (step f) - wmin (step f) = wmax f - wmin f" hence "wmin (step f) = wmin f" using step_wmin[of f] step_wmax[of f] wmin_wmax[of f] wmin_wmax[of "step f"] by auto thus "step f -` {wmin (step f)} \ S \ f -` {wmin f} \ S" proof (simp) show "step f -` {wmin f} \ S \ f -` {wmin f} \ S" proof (rule L5) from `wmax f \ wmin f` wmin_wmax[of f] show "wmin f < wmax f" by auto qed qed qed qed qed then obtain n where n: "wmin (nstep (step f) n) = wmax (nstep (step f) n)" by blast show ?thesis by (rule exI[of _ "Suc n"], insert n, auto) qed qed qed locale N = fixes N::nat assumes [simp]:"0 < N" context N begin lemma circle: assumes H: "x < N" "y < N" shows "\n. y = (x + n) mod N" proof (cases "x \ y") case True show ?thesis by (rule exI[of _ "y - x"], insert True H, auto) next case False show ?thesis by (rule exI[of _ "y + (N - x)"], insert False H, auto) qed lemma children: "children {0..x. x < N \ children.rightn (\x. Suc x mod N) x n = (x + n) mod N" proof (induct n) case 0 show ?case by (simp add: children.rightn.simps[OF children]) next case (Suc n) thus ?case by (auto simp add: children.rightn.simps[OF children], arith) qed lemma circle_children: "circle_children {0..x\{0..y\{0..n. y = children.rightn (\x. Suc x mod N) x n" by (auto simp add: rightn, rule circle, auto) qed end theorem (* concrete version *) fixes N::nat assumes "0 < N" "S = {0..< N}" "right = (\x. Suc x mod N)" shows "\n. children.wmin S (circle_children.nstep right f n) = children.wmax S (circle_children.nstep right f n)" proof (simp add: assms, rule circle_children.terminating) show "circle_children {0..x. Suc x mod N)" by (rule N.circle_children, simp add: N_def, fact) qed end