# HG changeset patch # User nipkow # Date 1362582656 -3600 # Node ID 00b45c7e831f038b581cb0db0038418db7f767d0 # Parent 0c376ef98559a035a94cde93759c3445710d2cc9 major redesign: order instead of preorder, new definition of intervals as quotients diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int0.thy --- a/src/HOL/IMP/Abs_Int0.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int0.thy Wed Mar 06 16:10:56 2013 +0100 @@ -6,52 +6,26 @@ subsection "Orderings" -class preord = -fixes le :: "'a \ 'a \ bool" (infix "\" 50) -assumes le_refl[simp]: "x \ x" -and le_trans: "x \ y \ y \ z \ x \ z" -begin - -definition mono where "mono f = (\x y. x \ y \ f x \ f y)" - -declare le_trans[trans] +notation + Orderings.bot ("\") and + Orderings.top ("\") -end +declare order_trans[trans] -text{* Note: no antisymmetry. Allows implementations where some abstract -element is implemented by two different values @{prop "x \ y"} -such that @{prop"x \ y"} and @{prop"y \ x"}. Antisymmetry is not -needed because we never compare elements for equality but only for @{text"\"}. -*} - -class join = preord + +class join = order + fixes join :: "'a \ 'a \ 'a" (infixl "\" 65) -class semilattice = join + -fixes Top :: "'a" ("\") -assumes join_ge1 [simp]: "x \ x \ y" -and join_ge2 [simp]: "y \ x \ y" -and join_least: "x \ z \ y \ z \ x \ y \ z" -and top[simp]: "x \ \" +class semilattice = join + top + +assumes join_ge1 [simp]: "x \ x \ y" +and join_ge2 [simp]: "y \ x \ y" +and join_least: "x \ z \ y \ z \ x \ y \ z" begin -lemma join_le_iff[simp]: "x \ y \ z \ x \ z \ y \ z" -by (metis join_ge1 join_ge2 join_least le_trans) - -lemma le_join_disj: "x \ y \ x \ z \ x \ y \ z" -by (metis join_ge1 join_ge2 le_trans) - -end +lemma join_le_iff[simp]: "x \ y \ z \ x \ z \ y \ z" +by (metis join_ge1 join_ge2 join_least order_trans) -instantiation "fun" :: (type, preord) preord -begin - -definition "f \ g = (\x. f x \ g x)" - -instance -proof - case goal2 thus ?case by (metis le_fun_def preord_class.le_trans) -qed (simp_all add: le_fun_def) +lemma le_join_disj: "x \ y \ x \ z \ x \ y \ z" +by (metis join_ge1 join_ge2 order_trans) end @@ -60,81 +34,41 @@ begin definition "f \ g = (\x. f x \ g x)" -definition "\ = (\x. \)" lemma join_apply[simp]: "(f \ g) x = f x \ g x" by (simp add: join_fun_def) instance proof -qed (simp_all add: le_fun_def Top_fun_def) +qed (simp_all add: le_fun_def) end -instantiation acom :: (preord) preord +instantiation option :: (order)order begin -fun le_acom :: "('a::preord)acom \ 'a acom \ bool" where -"le_acom (SKIP {S}) (SKIP {S'}) = (S \ S')" | -"le_acom (x ::= e {S}) (x' ::= e' {S'}) = (x=x' \ e=e' \ S \ S')" | -"le_acom (C1;C2) (D1;D2) = (C1 \ D1 \ C2 \ D2)" | -"le_acom (IF b THEN {p1} C1 ELSE {p2} C2 {S}) (IF b' THEN {q1} D1 ELSE {q2} D2 {S'}) = - (b=b' \ p1 \ q1 \ C1 \ D1 \ p2 \ q2 \ C2 \ D2 \ S \ S')" | -"le_acom ({I} WHILE b DO {p} C {P}) ({I'} WHILE b' DO {p'} C' {P'}) = - (b=b' \ p \ p' \ C \ C' \ I \ I' \ P \ P')" | -"le_acom _ _ = False" - -lemma [simp]: "SKIP {S} \ C \ (\S'. C = SKIP {S'} \ S \ S')" -by (cases C) auto - -lemma [simp]: "x ::= e {S} \ C \ (\S'. C = x ::= e {S'} \ S \ S')" -by (cases C) auto - -lemma [simp]: "C1;C2 \ C \ (\D1 D2. C = D1;D2 \ C1 \ D1 \ C2 \ D2)" -by (cases C) auto - -lemma [simp]: "IF b THEN {p1} C1 ELSE {p2} C2 {S} \ C \ - (\q1 q2 D1 D2 S'. C = IF b THEN {q1} D1 ELSE {q2} D2 {S'} \ - p1 \ q1 \ C1 \ D1 \ p2 \ q2 \ C2 \ D2 \ S \ S')" -by (cases C) auto +fun less_eq_option where +"Some x \ Some y = (x \ y)" | +"None \ y = True" | +"Some _ \ None = False" -lemma [simp]: "{I} WHILE b DO {p} C {P} \ W \ - (\I' p' C' P'. W = {I'} WHILE b DO {p'} C' {P'} \ p \ p' \ C \ C' \ I \ I' \ P \ P')" -by (cases W) auto +definition less_option where "x < (y::'a option) = (x \ y \ \ y \ x)" -instance -proof - case goal1 thus ?case by (induct x) auto -next - case goal2 thus ?case - apply(induct x y arbitrary: z rule: le_acom.induct) - apply (auto intro: le_trans) - done -qed - -end - - -instantiation option :: (preord)preord -begin - -fun le_option where -"Some x \ Some y = (x \ y)" | -"None \ y = True" | -"Some _ \ None = False" - -lemma [simp]: "(x \ None) = (x = None)" +lemma [simp]: "(x \ None) = (x = None)" by (cases x) simp_all -lemma [simp]: "(Some x \ u) = (\y. u = Some y \ x \ y)" +lemma [simp]: "(Some x \ u) = (\y. u = Some y \ x \ y)" by (cases u) auto instance proof - case goal1 show ?case by(cases x, simp_all) + case goal1 show ?case by(rule less_option_def) +next + case goal2 show ?case by(cases x, simp_all) next - case goal2 thus ?case - by(cases z, simp, cases y, simp, cases x, auto intro: le_trans) + case goal3 thus ?case by(cases z, simp, cases y, simp, cases x, auto) +next + case goal4 thus ?case by(cases y, simp, cases x, auto) qed end @@ -157,25 +91,21 @@ instantiation option :: (semilattice)semilattice begin -definition "\ = Some \" +definition top_option where "\ = Some \" instance proof - case goal1 thus ?case by(cases x, simp, cases y, simp_all) + case goal1 show ?case by(cases a, simp_all add: top_option_def) next - case goal2 thus ?case by(cases y, simp, cases x, simp_all) + case goal2 thus ?case by(cases x, simp, cases y, simp_all) next - case goal3 thus ?case by(cases z, simp, cases y, simp, cases x, simp_all) + case goal3 thus ?case by(cases y, simp, cases x, simp_all) next - case goal4 thus ?case by(cases x, simp_all add: Top_option_def) + case goal4 thus ?case by(cases z, simp, cases y, simp, cases x, simp_all) qed end -class bot = preord + -fixes bot :: "'a" ("\") -assumes bot[simp]: "\ \ x" - -instantiation option :: (preord)bot +instantiation option :: (order)bot begin definition bot_option :: "'a option" where @@ -192,7 +122,7 @@ definition bot :: "com \ 'a option acom" where "bot c = anno None c" -lemma bot_least: "strip C = c \ bot c \ C" +lemma bot_least: "strip C = c \ bot c \ C" by(induct C arbitrary: c)(auto simp: bot_def) lemma strip_bot[simp]: "strip(bot c) = c" @@ -201,20 +131,21 @@ subsubsection "Post-fixed point iteration" -definition pfp :: "(('a::preord) \ 'a) \ 'a \ 'a option" where -"pfp f = while_option (\x. \ f x \ x) f" +definition pfp :: "(('a::order) \ 'a) \ 'a \ 'a option" where +"pfp f = while_option (\x. \ f x \ x) f" -lemma pfp_pfp: assumes "pfp f x0 = Some x" shows "f x \ x" +lemma pfp_pfp: assumes "pfp f x0 = Some x" shows "f x \ x" using while_option_stop[OF assms[simplified pfp_def]] by simp lemma while_least: -assumes "\x\L.\y\L. x \ y \ f x \ f y" and "\x. x \ L \ f x \ L" -and "\x \ L. b \ x" and "b \ L" and "f q \ q" and "q \ L" +fixes q :: "'a::order" +assumes "\x\L.\y\L. x \ y \ f x \ f y" and "\x. x \ L \ f x \ L" +and "\x \ L. b \ x" and "b \ L" and "f q \ q" and "q \ L" and "while_option P f b = Some p" -shows "p \ q" +shows "p \ q" using while_option_rule[OF _ assms(7)[unfolded pfp_def], - where P = "%x. x \ L \ x \ q"] -by (metis assms(1-6) le_trans) + where P = "%x. x \ L \ x \ q"] +by (metis assms(1-6) order_trans) lemma pfp_inv: "pfp f x = Some y \ (\x. P x \ P(f x)) \ P x \ P y" @@ -238,7 +169,7 @@ locale Val_abs = fixes \ :: "'av::semilattice \ val set" - assumes mono_gamma: "a \ b \ \ a \ \ b" + assumes mono_gamma: "a \ b \ \ a \ \ b" and gamma_Top[simp]: "\ \ = UNIV" fixes num' :: "val \ 'av" and plus' :: "'av \ 'av \ 'av" @@ -284,21 +215,21 @@ abbreviation \\<^isub>c :: "'av st option acom \ state set acom" where "\\<^isub>c == map_acom \\<^isub>o" -lemma gamma_s_Top[simp]: "\\<^isub>s Top = UNIV" -by(simp add: Top_fun_def \_fun_def) +lemma gamma_s_Top[simp]: "\\<^isub>s \ = UNIV" +by(simp add: top_fun_def \_fun_def) -lemma gamma_o_Top[simp]: "\\<^isub>o Top = UNIV" -by (simp add: Top_option_def) +lemma gamma_o_Top[simp]: "\\<^isub>o \ = UNIV" +by (simp add: top_option_def) -lemma mono_gamma_s: "f1 \ f2 \ \\<^isub>s f1 \ \\<^isub>s f2" +lemma mono_gamma_s: "f1 \ f2 \ \\<^isub>s f1 \ \\<^isub>s f2" by(auto simp: le_fun_def \_fun_def dest: mono_gamma) lemma mono_gamma_o: - "S1 \ S2 \ \\<^isub>o S1 \ \\<^isub>o S2" -by(induction S1 S2 rule: le_option.induct)(simp_all add: mono_gamma_s) + "S1 \ S2 \ \\<^isub>o S1 \ \\<^isub>o S2" +by(induction S1 S2 rule: less_eq_option.induct)(simp_all add: mono_gamma_s) -lemma mono_gamma_c: "C1 \ C2 \ \\<^isub>c C1 \ \\<^isub>c C2" -by (induction C1 C2 rule: le_acom.induct) (simp_all add:mono_gamma_o) +lemma mono_gamma_c: "C1 \ C2 \ \\<^isub>c C1 \ \\<^isub>c C2" +by (induction C1 C2 rule: less_eq_acom.induct) (simp_all add:mono_gamma_o) text{* Soundness: *} @@ -326,7 +257,7 @@ lemma AI_sound: "AI c = Some C \ CS c \ \\<^isub>c C" proof(simp add: CS_def AI_def) assume 1: "pfp (step' \) (bot c) = Some C" - have pfp': "step' \ C \ C" by(rule pfp_pfp[OF 1]) + have pfp': "step' \ C \ C" by(rule pfp_pfp[OF 1]) have 2: "step (\\<^isub>o \) (\\<^isub>c C) \ \\<^isub>c C" --"transfer the pfp'" proof(rule order_trans) show "step (\\<^isub>o \) (\\<^isub>c C) \ \\<^isub>c (step' \ C)" by(rule step_step') @@ -343,21 +274,21 @@ subsubsection "Monotonicity" -lemma mono_post: "C1 \ C2 \ post C1 \ post C2" -by(induction C1 C2 rule: le_acom.induct) (auto) +lemma mono_post: "C1 \ C2 \ post C1 \ post C2" +by(induction C1 C2 rule: less_eq_acom.induct) (auto) locale Abs_Int_Fun_mono = Abs_Int_Fun + -assumes mono_plus': "a1 \ b1 \ a2 \ b2 \ plus' a1 a2 \ plus' b1 b2" +assumes mono_plus': "a1 \ b1 \ a2 \ b2 \ plus' a1 a2 \ plus' b1 b2" begin -lemma mono_aval': "S \ S' \ aval' e S \ aval' e S'" +lemma mono_aval': "S \ S' \ aval' e S \ aval' e S'" by(induction e)(auto simp: le_fun_def mono_plus') -lemma mono_update: "a \ a' \ S \ S' \ S(x := a) \ S'(x := a')" +lemma mono_update: "a \ a' \ S \ S' \ S(x := a) \ S'(x := a')" by(simp add: le_fun_def) -lemma mono_step': "S1 \ S2 \ C1 \ C2 \ step' S1 C1 \ step' S2 C2" -apply(induction C1 C2 arbitrary: S1 S2 rule: le_acom.induct) +lemma mono_step': "S1 \ S2 \ C1 \ C2 \ step' S1 C1 \ step' S2 C2" +apply(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct) apply (auto simp: Let_def mono_update mono_aval' mono_post le_join_disj split: option.split) done diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int1.thy --- a/src/HOL/IMP/Abs_Int1.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int1.thy Wed Mar 06 16:10:56 2013 +0100 @@ -4,16 +4,16 @@ imports Abs_State begin -lemma le_iff_le_annos_zip: "C1 \ C2 \ - (\ (a1,a2) \ set(zip (annos C1) (annos C2)). a1 \ a2) \ strip C1 = strip C2" -by(induct C1 C2 rule: le_acom.induct) (auto simp: size_annos_same2) +lemma le_iff_le_annos_zip: "C1 \ C2 \ + (\ (a1,a2) \ set(zip (annos C1) (annos C2)). a1 \ a2) \ strip C1 = strip C2" +by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: size_annos_same2) -lemma le_iff_le_annos: "C1 \ C2 \ - strip C1 = strip C2 \ (\ i annos C2 ! i)" +lemma le_iff_le_annos: "C1 \ C2 \ + strip C1 = strip C2 \ (\ i annos C2 ! i)" by(auto simp add: le_iff_le_annos_zip set_zip) (metis size_annos_same2) -lemma mono_fun_L[simp]: "F \ L X \ F \ G \ x : X \ fun F x \ fun G x" +lemma mono_fun_L[simp]: "F \ L X \ F \ G \ x : X \ fun F x \ fun G x" by(simp add: mono_fun L_st_def) lemma bot_in_L[simp]: "bot c \ L(vars c)" @@ -71,7 +71,7 @@ {S \ post C} WHILE b DO {I} step' P C {I}" definition AI :: "com \ 'av st option acom option" where -"AI c = pfp (step' (top(vars c))) (bot c)" +"AI c = pfp (step' (Top(vars c))) (bot c)" lemma strip_step'[simp]: "strip(step' S C) = strip C" @@ -94,7 +94,7 @@ case Seq thus ?case by auto next case (If b p1 C1 p2 C2 P) - hence "post C1 \ post C1 \ post C2 \ post C2 \ post C1 \ post C2" + hence "post C1 \ post C1 \ post C2 \ post C2 \ post C1 \ post C2" by(simp, metis post_in_L join_ge1 join_ge2) thus ?case using If by (auto simp: mono_gamma_o) next @@ -105,26 +105,26 @@ "\ C \ L X; S \ L X \ \ (step' S C) \ L X" proof(induction C arbitrary: S) case Assign thus ?case - by(auto simp: L_st_def update_def split: option.splits) + by(auto simp: L_st_def split: option.splits) qed auto lemma AI_sound: "AI c = Some C \ CS c \ \\<^isub>c C" proof(simp add: CS_def AI_def) - assume 1: "pfp (step' (top(vars c))) (bot c) = Some C" + assume 1: "pfp (step' (Top(vars c))) (bot c) = Some C" have "C \ L(vars c)" by(rule pfp_inv[where P = "%C. C \ L(vars c)", OF 1 _ bot_in_L]) - (erule step'_in_L[OF _ top_in_L]) - have pfp': "step' (top(vars c)) C \ C" by(rule pfp_pfp[OF 1]) - have 2: "step (\\<^isub>o(top(vars c))) (\\<^isub>c C) \ \\<^isub>c C" + (erule step'_in_L[OF _ Top_in_L]) + have pfp': "step' (Top(vars c)) C \ C" by(rule pfp_pfp[OF 1]) + have 2: "step (\\<^isub>o(Top(vars c))) (\\<^isub>c C) \ \\<^isub>c C" proof(rule order_trans) - show "step (\\<^isub>o (top(vars c))) (\\<^isub>c C) \ \\<^isub>c (step' (top(vars c)) C)" - by(rule step_step'[OF `C \ L(vars c)` top_in_L]) - show "\\<^isub>c (step' (top(vars c)) C) \ \\<^isub>c C" + show "step (\\<^isub>o (Top(vars c))) (\\<^isub>c C) \ \\<^isub>c (step' (Top(vars c)) C)" + by(rule step_step'[OF `C \ L(vars c)` Top_in_L]) + show "\\<^isub>c (step' (Top(vars c)) C) \ \\<^isub>c C" by(rule mono_gamma_c[OF pfp']) qed have 3: "strip (\\<^isub>c C) = c" by(simp add: strip_pfp[OF _ 1]) - have "lfp c (step (\\<^isub>o(top(vars c)))) \ \\<^isub>c C" - by(rule lfp_lowerbound[simplified,where f="step (\\<^isub>o(top(vars c)))", OF 3 2]) + have "lfp c (step (\\<^isub>o(Top(vars c)))) \ \\<^isub>c C" + by(rule lfp_lowerbound[simplified,where f="step (\\<^isub>o(Top(vars c)))", OF 3 2]) thus "lfp c (step UNIV) \ \\<^isub>c C" by simp qed @@ -134,41 +134,41 @@ subsubsection "Monotonicity" lemma le_join_disj: "y \ L X \ (z::_::semilatticeL) \ L X \ - x \ y \ x \ z \ x \ y \ z" -by (metis join_ge1 join_ge2 preord_class.le_trans) + x \ y \ x \ z \ x \ y \ z" +by (metis join_ge1 join_ge2 order_trans) locale Abs_Int_mono = Abs_Int + -assumes mono_plus': "a1 \ b1 \ a2 \ b2 \ plus' a1 a2 \ plus' b1 b2" +assumes mono_plus': "a1 \ b1 \ a2 \ b2 \ plus' a1 a2 \ plus' b1 b2" begin lemma mono_aval': - "S1 \ S2 \ S1 \ L X \ S2 \ L X \ vars e \ X \ aval' e S1 \ aval' e S2" -by(induction e) (auto simp: le_st_def mono_plus' L_st_def) + "S1 \ S2 \ S1 \ L X \ S2 \ L X \ vars e \ X \ aval' e S1 \ aval' e S2" +by(induction e) (auto simp: less_eq_st_def mono_plus' L_st_def) theorem mono_step': "S1 \ L X \ S2 \ L X \ C1 \ L X \ C2 \ L X \ - S1 \ S2 \ C1 \ C2 \ step' S1 C1 \ step' S2 C2" -apply(induction C1 C2 arbitrary: S1 S2 rule: le_acom.induct) + S1 \ S2 \ C1 \ C2 \ step' S1 C1 \ step' S2 C2" +apply(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct) apply (auto simp: Let_def mono_aval' mono_post le_join_disj le_join_disj[OF post_in_L post_in_L] split: option.split) done lemma mono_step'_top: "C \ L X \ C' \ L X \ - C \ C' \ step' (top X) C \ step' (top X) C'" -by (metis top_in_L mono_step' preord_class.le_refl) + C \ C' \ step' (Top X) C \ step' (Top X) C'" +by (metis Top_in_L mono_step' order_refl) lemma pfp_bot_least: assumes "\x\L(vars c)\{C. strip C = c}.\y\L(vars c)\{C. strip C = c}. - x \ y \ f x \ f y" + x \ y \ f x \ f y" and "\C. C \ L(vars c)\{C. strip C = c} \ f C \ L(vars c)\{C. strip C = c}" -and "f C' \ C'" "strip C' = c" "C' \ L(vars c)" "pfp f (bot c) = Some C" -shows "C \ C'" +and "f C' \ C'" "strip C' = c" "C' \ L(vars c)" "pfp f (bot c) = Some C" +shows "C \ C'" apply(rule while_least[OF assms(1,2) _ _ assms(3) _ assms(6)[unfolded pfp_def]]) by (simp_all add: assms(4,5) bot_least) lemma AI_least_pfp: assumes "AI c = Some C" -and "step' (top(vars c)) C' \ C'" "strip C' = c" "C' \ L(vars c)" -shows "C \ C'" +and "step' (Top(vars c)) C' \ C'" "strip C' = c" "C' \ L(vars c)" +shows "C \ C'" apply(rule pfp_bot_least[OF _ _ assms(2-4) assms(1)[unfolded AI_def]]) by (simp_all add: mono_step'_top) @@ -177,30 +177,27 @@ subsubsection "Termination" -abbreviation sqless (infix "\" 50) where -"x \ y == x \ y \ \ y \ x" - lemma pfp_termination: -fixes x0 :: "'a::preord" and m :: "'a \ nat" -assumes mono: "\x y. I x \ I y \ x \ y \ f x \ f y" -and m: "\x y. I x \ I y \ x \ y \ m x > m y" -and I: "\x y. I x \ I(f x)" and "I x0" and "x0 \ f x0" +fixes x0 :: "'a::order" and m :: "'a \ nat" +assumes mono: "\x y. I x \ I y \ x \ y \ f x \ f y" +and m: "\x y. I x \ I y \ x < y \ m x > m y" +and I: "\x y. I x \ I(f x)" and "I x0" and "x0 \ f x0" shows "\x. pfp f x0 = Some x" -proof(simp add: pfp_def, rule wf_while_option_Some[where P = "%x. I x & x \ f x"]) - show "wf {(y,x). ((I x \ x \ f x) \ \ f x \ x) \ y = f x}" +proof(simp add: pfp_def, rule wf_while_option_Some[where P = "%x. I x & x \ f x"]) + show "wf {(y,x). ((I x \ x \ f x) \ \ f x \ x) \ y = f x}" by(rule wf_subset[OF wf_measure[of m]]) (auto simp: m I) next - show "I x0 \ x0 \ f x0" using `I x0` `x0 \ f x0` by blast + show "I x0 \ x0 \ f x0" using `I x0` `x0 \ f x0` by blast next - fix x assume "I x \ x \ f x" thus "I(f x) \ f x \ f(f x)" + fix x assume "I x \ x \ f x" thus "I(f x) \ f x \ f(f x)" by (blast intro: I mono) qed locale Measure1 = -fixes m :: "'av::preord \ nat" +fixes m :: "'av::order \ nat" fixes h :: "nat" -assumes m1: "x \ y \ m x \ m y" +assumes m1: "x \ y \ m x \ m y" assumes h: "m x \ h" begin @@ -211,9 +208,9 @@ by(simp add: L_st_def m_s_def) (metis nat_mult_commute of_nat_id setsum_bounded[OF h]) -lemma m_s1: "S1 \ S2 \ m_s S1 \ m_s S2" -proof(auto simp add: le_st_def m_s_def) - assume "\x\dom S2. fun S1 x \ fun S2 x" +lemma m_s1: "S1 \ S2 \ m_s S1 \ m_s S2" +proof(auto simp add: less_eq_st_def m_s_def) + assume "\x\dom S2. fun S1 x \ fun S2 x" hence "\x\dom S2. m(fun S1 x) \ m(fun S2 x)" by (metis m1) thus "(\x\dom S2. m (fun S2 x)) \ (\x\dom S2. m (fun S1 x))" by (metis setsum_mono) @@ -226,8 +223,8 @@ by(auto simp add: m_o_def m_s_h split: option.split dest!:m_s_h) lemma m_o1: "finite X \ o1 \ L X \ o2 \ L X \ - o1 \ o2 \ m_o (card X) o1 \ m_o (card X) o2" -proof(induction o1 o2 rule: le_option.induct) + o1 \ o2 \ m_o (card X) o1 \ m_o (card X) o2" +proof(induction o1 o2 rule: less_eq_option.induct) case 1 thus ?case by (simp add: m_o_def)(metis m_s1) next case 2 thus ?case @@ -257,46 +254,45 @@ end locale Measure = Measure1 + -assumes m2: "x \ y \ m x > m y" +assumes m2: "x < y \ m x > m y" begin -lemma m_s2: "finite(dom S1) \ S1 \ S2 \ m_s S1 > m_s S2" -proof(auto simp add: le_st_def m_s_def) - assume "finite(dom S2)" and 0: "\x\dom S2. fun S1 x \ fun S2 x" +lemma m_s2: "finite(dom S1) \ S1 < S2 \ m_s S1 > m_s S2" +proof(auto simp add: less_st_def less_eq_st_def m_s_def) + assume "finite(dom S2)" and 0: "\x\dom S2. fun S1 x \ fun S2 x" hence 1: "\x\dom S2. m(fun S1 x) \ m(fun S2 x)" by (metis m1) - fix x assume "x \ dom S2" "\ fun S2 x \ fun S1 x" - hence 2: "\x\dom S2. m(fun S1 x) > m(fun S2 x)" using 0 m2 by blast + fix x assume "x \ dom S2" "\ fun S2 x \ fun S1 x" + hence 2: "\x\dom S2. m(fun S1 x) > m(fun S2 x)" by (metis 0 m2 less_le_not_le) from setsum_strict_mono_ex1[OF `finite(dom S2)` 1 2] show "(\x\dom S2. m (fun S2 x)) < (\x\dom S2. m (fun S1 x))" . qed lemma m_o2: "finite X \ o1 \ L X \ o2 \ L X \ - o1 \ o2 \ m_o (card X) o1 > m_o (card X) o2" -proof(induction o1 o2 rule: le_option.induct) - case 1 thus ?case by (simp add: m_o_def L_st_def m_s2) + o1 < o2 \ m_o (card X) o1 > m_o (card X) o2" +proof(induction o1 o2 rule: less_eq_option.induct) + case 1 thus ?case by (auto simp: m_o_def L_st_def m_s2 less_option_def) next - case 2 thus ?case - by(auto simp add: m_o_def le_imp_less_Suc m_s_h) + case 2 thus ?case by(auto simp: m_o_def less_option_def le_imp_less_Suc m_s_h) next - case 3 thus ?case by simp + case 3 thus ?case by (auto simp: less_option_def) qed - +find_theorems "(_<_) = _" lemma m_c2: "C1 \ L(vars(strip C1)) \ C2 \ L(vars(strip C2)) \ - C1 \ C2 \ m_c C1 > m_c C2" -proof(auto simp add: le_iff_le_annos m_c_def size_annos_same[of C1 C2] L_acom_def) + C1 < C2 \ m_c C1 > m_c C2" +proof(auto simp add: le_iff_le_annos m_c_def size_annos_same[of C1 C2] less_acom_def L_acom_def) let ?X = "vars(strip C2)" let ?n = "card ?X" assume V1: "\a\set(annos C1). a \ L ?X" and V2: "\a\set(annos C2). a \ L ?X" and strip_eq: "strip C1 = strip C2" - and 0: "\i annos C2 ! i" + and 0: "\i annos C2 ! i" hence 1: "\i m_o ?n (annos C2 ! i)" by (auto simp: all_set_conv_all_nth) (metis finite_cvars m_o1 size_annos_same2) - fix i assume "i < size(annos C2)" "\ annos C2 ! i \ annos C1 ! i" + fix i assume "i < size(annos C2)" "\ annos C2 ! i \ annos C1 ! i" hence "m_o ?n (annos C1 ! i) > m_o ?n (annos C2 ! i)" (is "?P i") - by(metis m_o2[OF finite_cvars] V1 V2 nth_mem size_annos_same[OF strip_eq] 0) + by(metis m_o2[OF finite_cvars] V1 V2 nth_mem size_annos_same[OF strip_eq] 0 less_option_def) hence 2: "\i < size(annos C2). ?P i" using `i < size(annos C2)` by blast show "(\iiC. AI c = Some C" unfolding AI_def -apply(rule pfp_termination[where I = "%C. strip C = c \ C \ L(vars c)" - and m="m_c"]) +apply(rule pfp_termination[where I = "\C. strip C = c \ C \ L(vars c)" and m="m_c"]) apply(simp_all add: m_c2 mono_step'_top bot_least) done diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int1_const.thy --- a/src/HOL/IMP/Abs_Int1_const.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int1_const.thy Wed Mar 06 16:10:56 2013 +0100 @@ -23,10 +23,12 @@ instantiation const :: semilattice begin -fun le_const where -"_ \ Any = True" | -"Const n \ Const m = (n=m)" | -"Any \ Const _ = False" +fun less_eq_const where +"_ \ Any = True" | +"Const n \ Const m = (n=m)" | +"Any \ Const _ = False" + +definition "a < (b::const) = (a \ b & ~ b \ a)" fun join_const where "Const m \ Const n = (if n=m then Const m else Any)" | @@ -36,17 +38,21 @@ instance proof - case goal1 thus ?case by (cases x) simp_all + case goal1 thus ?case by (rule less_const_def) +next + case goal2 show ?case by (cases x) simp_all next - case goal2 thus ?case by(cases z, cases y, cases x, simp_all) + case goal3 thus ?case by(cases z, cases y, cases x, simp_all) next - case goal3 thus ?case by(cases x, cases y, simp_all) + case goal4 thus ?case by(cases x, cases y, simp_all, cases y, simp_all) next - case goal4 thus ?case by(cases y, cases x, simp_all) + case goal6 thus ?case by(cases x, cases y, simp_all) +next + case goal7 thus ?case by(cases y, cases x, simp_all) next - case goal5 thus ?case by(cases z, cases y, cases x, simp_all) + case goal8 thus ?case by(cases z, cases y, cases x, simp_all) next - case goal6 thus ?case by(simp add: Top_const_def) + case goal5 thus ?case by(simp add: top_const_def) qed end @@ -58,7 +64,7 @@ case goal1 thus ?case by(cases a, cases b, simp, simp, cases b, simp, simp) next - case goal2 show ?case by(simp add: Top_const_def) + case goal2 show ?case by(simp add: top_const_def) next case goal3 show ?case by simp next @@ -74,7 +80,7 @@ subsubsection "Tests" -definition "steps c i = (step_const(top(vars c)) ^^ i) (bot c)" +definition "steps c i = (step_const(Top(vars c)) ^^ i) (bot c)" value "show_acom (steps test1_const 0)" value "show_acom (steps test1_const 1)" @@ -139,7 +145,7 @@ next case goal2 thus ?case by(auto simp: m_const_def split: const.splits) next - case goal3 thus ?case by(auto simp: m_const_def split: const.splits) + case goal3 thus ?case by(auto simp: m_const_def less_const_def split: const.splits) qed thm AI_Some_measure diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int1_parity.thy --- a/src/HOL/IMP/Abs_Int1_parity.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int1_parity.thy Wed Mar 06 16:10:56 2013 +0100 @@ -1,3 +1,5 @@ +(* Author: Tobias Nipkow *) + theory Abs_Int1_parity imports Abs_Int1 begin @@ -6,29 +8,41 @@ datatype parity = Even | Odd | Either -text{* Instantiation of class @{class preord} with type @{typ parity}: *} +text{* Instantiation of class @{class order} with type @{typ parity}: *} -instantiation parity :: preord +instantiation parity :: order begin -text{* First the definition of the interface function @{text"\"}. Note that -the header of the definition must refer to the ascii name @{const le} of the -constants as @{text le_parity} and the definition is named @{text -le_parity_def}. Inside the definition the symbolic names can be used. *} +text{* First the definition of the interface function @{text"\"}. Note that +the header of the definition must refer to the ascii name @{const less_eq} of the +constants as @{text less_eq_parity} and the definition is named @{text +less_eq_parity_def}. Inside the definition the symbolic names can be used. *} + +definition less_eq_parity where +"x \ y = (y = Either \ x=y)" -definition le_parity where -"x \ y = (y = Either \ x=y)" +text{* We also need @{text"<"}, which is defined canonically: *} -text{* Now the instance proof, i.e.\ the proof that the definition fulfills +definition less_parity where +"x < y = (x \ y \ \ y \ (x::parity))" + +text{*\noindent (The type annotation is necessary to fix the type of the polymorphic predicates.) + +Now the instance proof, i.e.\ the proof that the definition fulfills the axioms (assumptions) of the class. The initial proof-step generates the necessary proof obligations. *} instance proof - fix x::parity show "x \ x" by(auto simp: le_parity_def) + fix x::parity show "x \ x" by(auto simp: less_eq_parity_def) +next + fix x y z :: parity assume "x \ y" "y \ z" thus "x \ z" + by(auto simp: less_eq_parity_def) next - fix x y z :: parity assume "x \ y" "y \ z" thus "x \ z" - by(auto simp: le_parity_def) + fix x y :: parity assume "x \ y" "y \ x" thus "x = y" + by(auto simp: less_eq_parity_def) +next + fix x y :: parity show "(x < y) = (x \ y \ \ y \ x)" by(rule less_parity_def) qed end @@ -39,9 +53,9 @@ begin definition join_parity where -"x \ y = (if x \ y then y else if y \ x then x else Either)" +"x \ y = (if x \ y then y else if y \ x then x else Either)" -definition Top_parity where +definition top_parity where "\ = Either" text{* Now the instance proof. This time we take a lazy shortcut: we do not @@ -52,13 +66,13 @@ instance proof - case goal1 (*join1*) show ?case by(auto simp: le_parity_def join_parity_def) + case goal1 (*top*) show ?case by(auto simp: less_eq_parity_def top_parity_def) next - case goal2 (*join2*) show ?case by(auto simp: le_parity_def join_parity_def) + case goal2 (*join1*) show ?case by(auto simp: less_eq_parity_def join_parity_def) next - case goal3 (*join least*) thus ?case by(auto simp: le_parity_def join_parity_def) + case goal3 (*join2*) show ?case by(auto simp: less_eq_parity_def join_parity_def) next - case goal4 (*Top*) show ?case by(auto simp: le_parity_def Top_parity_def) + case goal4 (*join least*) thus ?case by(auto simp: less_eq_parity_def join_parity_def) qed end @@ -92,10 +106,10 @@ where \ = \_parity and num' = num_parity and plus' = plus_parity proof txt{* of the locale axioms *} fix a b :: parity - assume "a \ b" thus "\_parity a \ \_parity b" - by(auto simp: le_parity_def) + assume "a \ b" thus "\_parity a \ \_parity b" + by(auto simp: less_eq_parity_def) next txt{* The rest in the lazy, implicit way *} - case goal2 show ?case by(auto simp: Top_parity_def) + case goal2 show ?case by(auto simp: top_parity_def) next case goal3 show ?case by auto next @@ -127,7 +141,7 @@ ''x'' ::= N 1; WHILE Less (V ''x'') (N 100) DO ''x'' ::= Plus (V ''x'') (N 3)" -definition "steps c i = (step_parity(top(vars c)) ^^ i) (bot c)" +definition "steps c i = (step_parity(Top(vars c)) ^^ i) (bot c)" value "show_acom (steps test2_parity 0)" value "show_acom (steps test2_parity 1)" @@ -147,7 +161,7 @@ case goal1 thus ?case proof(cases a1 a2 b1 b2 rule: parity.exhaust[case_product parity.exhaust[case_product parity.exhaust[case_product parity.exhaust]]]) (* FIXME - UGLY! *) - qed (auto simp add:le_parity_def) + qed (auto simp add:less_eq_parity_def) qed definition m_parity :: "parity \ nat" where @@ -157,11 +171,11 @@ where \ = \_parity and num' = num_parity and plus' = plus_parity and m = m_parity and h = "1" proof - case goal1 thus ?case by(auto simp add: m_parity_def le_parity_def) + case goal1 thus ?case by(auto simp add: m_parity_def less_eq_parity_def) next - case goal2 thus ?case by(auto simp add: m_parity_def le_parity_def) + case goal2 thus ?case by(auto simp add: m_parity_def less_eq_parity_def) next - case goal3 thus ?case by(auto simp add: m_parity_def le_parity_def) + case goal3 thus ?case by(auto simp add: m_parity_def less_eq_parity_def less_parity_def) qed thm AI_Some_measure diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int2.thy --- a/src/HOL/IMP/Abs_Int2.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int2.thy Wed Mar 06 16:10:56 2013 +0100 @@ -4,16 +4,21 @@ imports Abs_Int1 begin -instantiation prod :: (preord,preord) preord +instantiation prod :: (order,order) order begin -definition "le_prod p1 p2 = (fst p1 \ fst p2 \ snd p1 \ snd p2)" +definition "less_eq_prod p1 p2 = (fst p1 \ fst p2 \ snd p1 \ snd p2)" +definition "less_prod p1 p2 = (p1 \ p2 \ \ p2 \ (p1::'a*'b))" instance proof - case goal1 show ?case by(simp add: le_prod_def) + case goal1 show ?case by(rule less_prod_def) +next + case goal2 show ?case by(simp add: less_eq_prod_def) next - case goal2 thus ?case unfolding le_prod_def by(metis le_trans) + case goal3 thus ?case unfolding less_eq_prod_def by(metis order_trans) +next + case goal4 thus ?case by(simp add: less_eq_prod_def)(metis eq_iff surjective_pairing) qed end @@ -23,13 +28,13 @@ class lattice = semilattice + bot + fixes meet :: "'a \ 'a \ 'a" (infixl "\" 65) -assumes meet_le1 [simp]: "x \ y \ x" -and meet_le2 [simp]: "x \ y \ y" -and meet_greatest: "x \ y \ x \ z \ x \ y \ z" +assumes meet_le1 [simp]: "x \ y \ x" +and meet_le2 [simp]: "x \ y \ y" +and meet_greatest: "x \ y \ x \ z \ x \ y \ z" begin -lemma mono_meet: "x \ x' \ y \ y' \ x \ y \ x' \ y'" -by (metis meet_greatest meet_le1 meet_le2 le_trans) +lemma mono_meet: "x \ x' \ y \ y' \ x \ y \ x' \ y'" +by (metis meet_greatest meet_le1 meet_le2 order_trans) end @@ -83,7 +88,7 @@ "afilter (N n) a S = (if test_num' n a then S else None)" | "afilter (V x) a S = (case S of None \ None | Some S \ let a' = fun S x \ a in - if a' \ \ then None else Some(update S x a'))" | + if a' = \ then None else Some(update S x a'))" | "afilter (Plus e1 e2) a S = (let (a1,a2) = filter_plus' a (aval'' e1 S) (aval'' e2 S) in afilter e1 a1 (afilter e2 a2 S))" @@ -110,8 +115,7 @@ lemma afilter_in_L: "S \ L X \ vars e \ X \ afilter e a S \ L X" by(induction e arbitrary: a S) - (auto simp: Let_def update_def L_st_def - split: option.splits prod.split) + (auto simp: Let_def L_st_def split: option.splits prod.split) lemma afilter_sound: "S \ L X \ vars e \ X \ s : \\<^isub>o S \ aval e s : \ a \ s : \\<^isub>o (afilter e a S)" @@ -189,7 +193,7 @@ case Seq thus ?case by auto next case (If b _ C1 _ C2) - hence 0: "post C1 \ post C1 \ post C2 \ post C2 \ post C1 \ post C2" + hence 0: "post C1 \ post C1 \ post C2 \ post C2 \ post C1 \ post C2" by(simp, metis post_in_L join_ge1 join_ge2) have "vars b \ X" using If.prems by simp note vars = `S \ L X` `vars b \ X` @@ -204,26 +208,26 @@ lemma step'_in_L[simp]: "\ C \ L X; S \ L X \ \ step' S C \ L X" proof(induction C arbitrary: S) - case Assign thus ?case by(simp add: L_option_def L_st_def update_def split: option.splits) + case Assign thus ?case by(auto simp add: L_option_def L_st_def split: option.splits) qed (auto simp add: bfilter_in_L) lemma AI_sound: "AI c = Some C \ CS c \ \\<^isub>c C" proof(simp add: CS_def AI_def) - assume 1: "pfp (step' (top(vars c))) (bot c) = Some C" + assume 1: "pfp (step' (Top(vars c))) (bot c) = Some C" have "C \ L(vars c)" by(rule pfp_inv[where P = "%C. C \ L(vars c)", OF 1 _ bot_in_L]) - (erule step'_in_L[OF _ top_in_L]) - have pfp': "step' (top(vars c)) C \ C" by(rule pfp_pfp[OF 1]) - have 2: "step (\\<^isub>o(top(vars c))) (\\<^isub>c C) \ \\<^isub>c C" + (erule step'_in_L[OF _ Top_in_L]) + have pfp': "step' (Top(vars c)) C \ C" by(rule pfp_pfp[OF 1]) + have 2: "step (\\<^isub>o(Top(vars c))) (\\<^isub>c C) \ \\<^isub>c C" proof(rule order_trans) - show "step (\\<^isub>o (top(vars c))) (\\<^isub>c C) \ \\<^isub>c (step' (top(vars c)) C)" - by(rule step_step'[OF `C \ L(vars c)` top_in_L]) - show "\\<^isub>c (step' (top(vars c)) C) \ \\<^isub>c C" + show "step (\\<^isub>o (Top(vars c))) (\\<^isub>c C) \ \\<^isub>c (step' (Top(vars c)) C)" + by(rule step_step'[OF `C \ L(vars c)` Top_in_L]) + show "\\<^isub>c (step' (Top(vars c)) C) \ \\<^isub>c C" by(rule mono_gamma_c[OF pfp']) qed have 3: "strip (\\<^isub>c C) = c" by(simp add: strip_pfp[OF _ 1]) - have "lfp c (step (\\<^isub>o(top(vars c)))) \ \\<^isub>c C" - by(rule lfp_lowerbound[simplified,where f="step (\\<^isub>o(top(vars c)))", OF 3 2]) + have "lfp c (step (\\<^isub>o(Top(vars c)))) \ \\<^isub>c C" + by(rule lfp_lowerbound[simplified,where f="step (\\<^isub>o(Top(vars c)))", OF 3 2]) thus "lfp c (step UNIV) \ \\<^isub>c C" by simp qed @@ -233,19 +237,19 @@ subsubsection "Monotonicity" locale Abs_Int1_mono = Abs_Int1 + -assumes mono_plus': "a1 \ b1 \ a2 \ b2 \ plus' a1 a2 \ plus' b1 b2" -and mono_filter_plus': "a1 \ b1 \ a2 \ b2 \ r \ r' \ - filter_plus' r a1 a2 \ filter_plus' r' b1 b2" -and mono_filter_less': "a1 \ b1 \ a2 \ b2 \ - filter_less' bv a1 a2 \ filter_less' bv b1 b2" +assumes mono_plus': "a1 \ b1 \ a2 \ b2 \ plus' a1 a2 \ plus' b1 b2" +and mono_filter_plus': "a1 \ b1 \ a2 \ b2 \ r \ r' \ + filter_plus' r a1 a2 \ filter_plus' r' b1 b2" +and mono_filter_less': "a1 \ b1 \ a2 \ b2 \ + filter_less' bv a1 a2 \ filter_less' bv b1 b2" begin lemma mono_aval': - "S1 \ S2 \ S1 \ L X \ vars e \ X \ aval' e S1 \ aval' e S2" -by(induction e) (auto simp: le_st_def mono_plus' L_st_def) + "S1 \ S2 \ S1 \ L X \ vars e \ X \ aval' e S1 \ aval' e S2" +by(induction e) (auto simp: less_eq_st_def mono_plus' L_st_def) lemma mono_aval'': - "S1 \ S2 \ S1 \ L X \ vars e \ X \ aval'' e S1 \ aval'' e S2" + "S1 \ S2 \ S1 \ L X \ vars e \ X \ aval'' e S1 \ aval'' e S2" apply(cases S1) apply simp apply(cases S2) @@ -253,37 +257,37 @@ by (simp add: mono_aval') lemma mono_afilter: "S1 \ L X \ S2 \ L X \ vars e \ X \ - r1 \ r2 \ S1 \ S2 \ afilter e r1 S1 \ afilter e r2 S2" + r1 \ r2 \ S1 \ S2 \ afilter e r1 S1 \ afilter e r2 S2" apply(induction e arbitrary: r1 r2 S1 S2) apply(auto simp: test_num' Let_def mono_meet split: option.splits prod.splits) apply (metis mono_gamma subsetD) apply(drule (2) mono_fun_L) -apply (metis mono_meet le_trans) -apply(metis mono_aval'' mono_filter_plus'[simplified le_prod_def] fst_conv snd_conv afilter_in_L) +apply (metis mono_meet le_bot) +apply(metis mono_aval'' mono_filter_plus'[simplified less_eq_prod_def] fst_conv snd_conv afilter_in_L) done lemma mono_bfilter: "S1 \ L X \ S2 \ L X \ vars b \ X \ - S1 \ S2 \ bfilter b bv S1 \ bfilter b bv S2" + S1 \ S2 \ bfilter b bv S1 \ bfilter b bv S2" apply(induction b arbitrary: bv S1 S2) apply(simp) apply(simp) apply simp -apply(metis join_least le_trans[OF _ join_ge1] le_trans[OF _ join_ge2] bfilter_in_L) +apply(metis join_least order_trans[OF _ join_ge1] order_trans[OF _ join_ge2] bfilter_in_L) apply (simp split: prod.splits) -apply(metis mono_aval'' mono_afilter mono_filter_less'[simplified le_prod_def] fst_conv snd_conv afilter_in_L) +apply(metis mono_aval'' mono_afilter mono_filter_less'[simplified less_eq_prod_def] fst_conv snd_conv afilter_in_L) done theorem mono_step': "S1 \ L X \ S2 \ L X \ C1 \ L X \ C2 \ L X \ - S1 \ S2 \ C1 \ C2 \ step' S1 C1 \ step' S2 C2" -apply(induction C1 C2 arbitrary: S1 S2 rule: le_acom.induct) + S1 \ S2 \ C1 \ C2 \ step' S1 C1 \ step' S2 C2" +apply(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct) apply (auto simp: Let_def mono_bfilter mono_aval' mono_post le_join_disj le_join_disj[OF post_in_L post_in_L] bfilter_in_L split: option.split) done lemma mono_step'_top: "C1 \ L X \ C2 \ L X \ - C1 \ C2 \ step' (top X) C1 \ step' (top X) C2" -by (metis top_in_L mono_step' preord_class.le_refl) + C1 \ C2 \ step' (Top X) C1 \ step' (Top X) C2" +by (metis Top_in_L mono_step' order_refl) end diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int2_ivl.thy --- a/src/HOL/IMP/Abs_Int2_ivl.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int2_ivl.thy Wed Mar 06 16:10:56 2013 +0100 @@ -1,297 +1,341 @@ (* Author: Tobias Nipkow *) theory Abs_Int2_ivl -imports Abs_Int2 +imports "~~/src/HOL/Library/Quotient_List" + "~~/src/HOL/Library/Extended" + Abs_Int2 begin subsection "Interval Analysis" -datatype lb = Minf | Lb int -datatype ub = Pinf | Ub int +type_synonym eint = "int extended" +type_synonym eint2 = "eint * eint" -datatype ivl = Ivl lb ub +definition \_rep :: "eint2 \ int set" where +"\_rep p = (let (l,h) = p in {i. l \ Fin i \ Fin i \ h})" -definition "\_ivl i = (case i of - Ivl (Lb l) (Ub h) \ {l..h} | - Ivl (Lb l) Pinf \ {l..} | - Ivl Minf (Ub h) \ {..h} | - Ivl Minf Pinf \ UNIV)" +definition eq_ivl :: "eint2 \ eint2 \ bool" where +"eq_ivl p1 p2 = (\_rep p1 = \_rep p2)" -abbreviation Ivl_Lb_Ub :: "int \ int \ ivl" ("{_\_}") where -"{lo\hi} == Ivl (Lb lo) (Ub hi)" -abbreviation Ivl_Lb_Pinf :: "int \ ivl" ("{_\}") where -"{lo\} == Ivl (Lb lo) Pinf" -abbreviation Ivl_Minf_Ub :: "int \ ivl" ("{\_}") where -"{\hi} == Ivl Minf (Ub hi)" -abbreviation Ivl_Minf_Pinf :: "ivl" ("{\}") where -"{\} == Ivl Minf Pinf" +lemma refl_eq_ivl[simp]: "eq_ivl p p" +by(auto simp: eq_ivl_def) -lemmas lub_splits = lb.splits ub.splits - -definition "num_ivl n = {n\n}" +quotient_type ivl = eint2 / eq_ivl +by(rule equivpI)(auto simp: reflp_def symp_def transp_def eq_ivl_def) -fun in_ivl :: "int \ ivl \ bool" where -"in_ivl k (Ivl (Lb l) (Ub h)) \ l \ k \ k \ h" | -"in_ivl k (Ivl (Lb l) Pinf) \ l \ k" | -"in_ivl k (Ivl Minf (Ub h)) \ k \ h" | -"in_ivl k (Ivl Minf Pinf) \ True" +lift_definition \_ivl :: "ivl \ int set" is \_rep +by(simp add: eq_ivl_def) - -instantiation lb :: linorder -begin +abbreviation ivl_abbr :: "eint \ eint \ ivl" ("[_\_]") where +"[l\h] == abs_ivl(l,h)" -definition less_eq_lb where -"l1 \ l2 = (case l1 of Minf \ True | Lb i1 \ (case l2 of Minf \ False | Lb i2 \ i1 \ i2))" +lift_definition num_ivl :: "int \ ivl" is "\i. (Fin i, Fin i)" +by(auto simp: eq_ivl_def) -definition less_lb :: "lb \ lb \ bool" where -"((l1::lb) < l2) = (l1 \ l2 & ~ l1 \ l2)" +fun in_ivl_rep :: "int \ eint2 \ bool" where +"in_ivl_rep k (l,h) \ l \ Fin k \ Fin k \ h" -instance -proof - case goal1 show ?case by(rule less_lb_def) -next - case goal2 show ?case by(auto simp: less_eq_lb_def split:lub_splits) -next - case goal3 thus ?case by(auto simp: less_eq_lb_def split:lub_splits) -next - case goal4 thus ?case by(auto simp: less_eq_lb_def split:lub_splits) -next - case goal5 thus ?case by(auto simp: less_eq_lb_def split:lub_splits) -qed +lift_definition in_ivl :: "int \ ivl \ bool" is in_ivl_rep +by(auto simp: eq_ivl_def \_rep_def) + +definition is_empty_rep :: "eint2 \ bool" where +"is_empty_rep p = (let (l,h) = p in l>h | l=Pinf & h=Pinf | l=Minf & h=Minf)" -end - -instantiation ub :: linorder -begin +lemma \_rep_cases: "\_rep p = (case p of (Fin i,Fin j) => {i..j} | (Fin i,Pinf) => {i..} | + (Minf,Fin i) \ {..i} | (Minf,Pinf) \ UNIV | _ \ {})" +by(auto simp add: \_rep_def split: prod.splits extended.splits) -definition less_eq_ub where -"u1 \ u2 = (case u2 of Pinf \ True | Ub i2 \ (case u1 of Pinf \ False | Ub i1 \ i1 \ i2))" - -definition less_ub :: "ub \ ub \ bool" where -"((u1::ub) < u2) = (u1 \ u2 & ~ u1 \ u2)" +lift_definition is_empty_ivl :: "ivl \ bool" is is_empty_rep +apply(auto simp: eq_ivl_def \_rep_cases is_empty_rep_def) +apply(auto simp: not_less less_eq_extended_cases split: extended.splits) +done -instance -proof - case goal1 show ?case by(rule less_ub_def) -next - case goal2 show ?case by(auto simp: less_eq_ub_def split:lub_splits) -next - case goal3 thus ?case by(auto simp: less_eq_ub_def split:lub_splits) -next - case goal4 thus ?case by(auto simp: less_eq_ub_def split:lub_splits) -next - case goal5 thus ?case by(auto simp: less_eq_ub_def split:lub_splits) -qed +lemma eq_ivl_iff: "eq_ivl p1 p2 = (is_empty_rep p1 & is_empty_rep p2 | p1 = p2)" +by(auto simp: eq_ivl_def is_empty_rep_def \_rep_cases Icc_eq_Icc split: prod.splits extended.splits) -end +definition empty_rep :: eint2 where "empty_rep = (Pinf,Minf)" -lemmas le_lub_defs = less_eq_lb_def less_eq_ub_def +lift_definition empty_ivl :: ivl is empty_rep +by simp -lemma le_lub_simps[simp]: - "Minf \ l" "Lb i \ Lb j = (i \ j)" "~ Lb i \ Minf" - "h \ Pinf" "Ub i \ Ub j = (i \ j)" "~ Pinf \ Ub j" -by(auto simp: le_lub_defs split: lub_splits) - -definition empty where "empty = {1\0}" +lemma is_empty_empty_rep[simp]: "is_empty_rep empty_rep" +by(auto simp add: is_empty_rep_def empty_rep_def) -fun is_empty where -"is_empty {l\h} = (h_rep p = {})" +by(auto simp add: \_rep_cases is_empty_rep_def split: prod.splits extended.splits) -lemma [simp]: "is_empty(Ivl l h) = - (case l of Lb l \ (case h of Ub h \ h False) | Minf \ False)" -by(auto split: lub_splits) - -lemma [simp]: "is_empty i \ \_ivl i = {}" -by(auto simp add: \_ivl_def split: ivl.split lub_splits) +declare is_empty_rep_iff[THEN iffD1, simp] instantiation ivl :: semilattice begin -fun le_aux where -"le_aux (Ivl l1 h1) (Ivl l2 h2) = (l2 \ l1 & h1 \ h2)" +definition le_rep :: "eint2 \ eint2 \ bool" where +"le_rep p1 p2 = (let (l1,h1) = p1; (l2,h2) = p2 in + if is_empty_rep(l1,h1) then True else + if is_empty_rep(l2,h2) then False else l1 \ l2 & h1 \ h2)" + +lemma le_iff_subset: "le_rep p1 p2 \ \_rep p1 \ \_rep p2" +apply rule +apply(auto simp: is_empty_rep_def le_rep_def \_rep_def split: if_splits prod.splits)[1] +apply(auto simp: is_empty_rep_def \_rep_cases le_rep_def) +apply(auto simp: not_less split: extended.splits) +done + +lift_definition less_eq_ivl :: "ivl \ ivl \ bool" is le_rep +by(auto simp: eq_ivl_def le_iff_subset) -definition le_ivl where -"i1 \ i2 = - (if is_empty i1 then True else - if is_empty i2 then False else le_aux i1 i2)" +definition less_ivl where "i1 < i2 = (i1 \ i2 \ \ i2 \ (i1::ivl))" + +definition join_rep :: "eint2 \ eint2 \ eint2" where +"join_rep p1 p2 = (if is_empty_rep p1 then p2 else if is_empty_rep p2 then p1 + else let (l1,h1) = p1; (l2,h2) = p2 in (min l1 l2, max h1 h2))" -definition "i1 \ i2 = - (if is_empty i1 then i2 else if is_empty i2 then i1 - else case (i1,i2) of (Ivl l1 h1, Ivl l2 h2) \ Ivl (min l1 l2) (max h1 h2))" +lift_definition join_ivl :: "ivl \ ivl \ ivl" is join_rep +by(auto simp: eq_ivl_iff join_rep_def) -definition "\ = {\}" +lift_definition top_ivl :: ivl is "(Minf,Pinf)" +by(auto simp: eq_ivl_def) + +lemma is_empty_min_max: + "\ is_empty_rep (l1,h1) \ \ is_empty_rep (l2, h2) \ \ is_empty_rep (min l1 l2, max h1 h2)" +by(auto simp add: is_empty_rep_def max_def min_def split: if_splits) instance proof - case goal1 thus ?case - by(cases x, simp add: le_ivl_def) + case goal1 show ?case by (rule less_ivl_def) +next + case goal2 show ?case by transfer (simp add: le_rep_def split: prod.splits) next - case goal2 thus ?case - by(cases x, cases y, cases z, auto simp: le_ivl_def split: if_splits) + case goal3 thus ?case by transfer (auto simp: le_rep_def split: if_splits) next - case goal3 thus ?case - by(cases x, cases y, simp add: le_ivl_def join_ivl_def le_lub_defs min_def max_def split: lub_splits) + case goal4 thus ?case by transfer (auto simp: le_rep_def eq_ivl_iff split: if_splits) next - case goal4 thus ?case - by(cases x, cases y, simp add: le_ivl_def join_ivl_def le_lub_defs min_def max_def split: lub_splits) + case goal6 thus ?case by transfer (auto simp add: le_rep_def join_rep_def is_empty_min_max) +next + case goal7 thus ?case by transfer (auto simp add: le_rep_def join_rep_def is_empty_min_max) next - case goal5 thus ?case - by(cases x, cases y, cases z, auto simp add: le_ivl_def join_ivl_def le_lub_defs min_def max_def split: lub_splits if_splits) + case goal8 thus ?case by transfer (auto simp add: le_rep_def join_rep_def) next - case goal6 thus ?case - by(cases x, simp add: Top_ivl_def le_ivl_def le_lub_defs split: lub_splits) + case goal5 show ?case by transfer (simp add: le_rep_def is_empty_rep_def) qed end +text{* Implement (naive) executable equality: *} +instantiation ivl :: equal +begin + +definition equal_ivl where +"equal_ivl i1 (i2::ivl) = (i1\i2 \ i2 \ i1)" + +instance +proof + case goal1 show ?case by(simp add: equal_ivl_def eq_iff) +qed + +end + +lemma [simp]: fixes x :: "'a::linorder extended" shows "(\ x < Pinf) = (x = Pinf)" +by(simp add: not_less) +lemma [simp]: fixes x :: "'a::linorder extended" shows "(\ Minf < x) = (x = Minf)" +by(simp add: not_less) instantiation ivl :: lattice begin -definition "i1 \ i2 = (if is_empty i1 \ is_empty i2 then empty else - case (i1,i2) of (Ivl l1 h1, Ivl l2 h2) \ Ivl (max l1 l2) (min h1 h2))" +definition meet_rep :: "eint2 \ eint2 \ eint2" where +"meet_rep p1 p2 = (let (l1,h1) = p1; (l2,h2) = p2 in (max l1 l2, min h1 h2))" -definition "\ = empty" +lemma \_meet_rep: "\_rep(meet_rep p1 p2) = \_rep p1 \ \_rep p2" +by(auto simp:meet_rep_def \_rep_cases split: prod.splits extended.splits) + +lift_definition meet_ivl :: "ivl \ ivl \ ivl" is meet_rep +by(auto simp: \_meet_rep eq_ivl_def) + +definition "\ = empty_ivl" instance proof case goal2 thus ?case - by (simp add:meet_ivl_def empty_def le_ivl_def le_lub_defs max_def min_def split: ivl.splits lub_splits) + unfolding meet_rep_def by transfer (auto simp: le_iff_subset \_meet_rep) next case goal3 thus ?case - by (simp add: empty_def meet_ivl_def le_ivl_def le_lub_defs max_def min_def split: ivl.splits lub_splits) + unfolding meet_rep_def by transfer (auto simp: le_iff_subset \_meet_rep) next case goal4 thus ?case - by (cases x, cases y, cases z, auto simp add: le_ivl_def meet_ivl_def empty_def le_lub_defs max_def min_def split: lub_splits if_splits) + unfolding meet_rep_def by transfer (auto simp: le_iff_subset \_meet_rep) next - case goal1 show ?case by(cases x, simp add: bot_ivl_def empty_def le_ivl_def) + case goal1 show ?case unfolding bot_ivl_def by transfer (auto simp: le_iff_subset) qed end -instantiation lb :: plus +lemma eq_ivl_empty: "eq_ivl p empty_rep = is_empty_rep p" +by (metis eq_ivl_iff is_empty_empty_rep) + +lemma le_ivl_nice: "[l1\h1] \ [l2\h2] \ + (if [l1\h1] = \ then True else + if [l2\h2] = \ then False else l1 \ l2 & h1 \ h2)" +unfolding bot_ivl_def by transfer (simp add: le_rep_def eq_ivl_empty) + +lemma join_ivl_nice: "[l1\h1] \ [l2\h2] = + (if [l1\h1] = \ then [l2\h2] else + if [l2\h2] = \ then [l1\h1] else [min l1 l2\max h1 h2])" +unfolding bot_ivl_def by transfer (simp add: join_rep_def eq_ivl_empty) + +lemma meet_nice: "[l1\h1] \ [l2\h2] = [max l1 l2\min h1 h2]" +by transfer (simp add: meet_rep_def) + + +instantiation ivl :: plus begin -fun plus_lb where -"Lb x + Lb y = Lb(x+y)" | -"_ + _ = Minf" +definition plus_rep :: "eint2 \ eint2 \ eint2" where +"plus_rep p1 p2 = + (if is_empty_rep p1 \ is_empty_rep p2 then empty_rep else + let (l1,h1) = p1; (l2,h2) = p2 in (l1+l2, h1+h2))" + +lift_definition plus_ivl :: "ivl \ ivl \ ivl" is plus_rep +by(auto simp: plus_rep_def eq_ivl_iff) instance .. end -instantiation ub :: plus -begin - -fun plus_ub where -"Ub x + Ub y = Ub(x+y)" | -"_ + _ = Pinf" - -instance .. -end - -instantiation ivl :: plus -begin +lemma plus_ivl_nice: "[l1\h1] + [l2\h2] = + (if [l1\h1] = \ \ [l2\h2] = \ then \ else [l1+l2 \ h1+h2])" +unfolding bot_ivl_def by transfer (auto simp: plus_rep_def eq_ivl_empty) -definition "i1+i2 = (if is_empty i1 | is_empty i2 then empty else - case (i1,i2) of (Ivl l1 h1, Ivl l2 h2) \ Ivl (l1+l2) (h1+h2))" - -instance .. -end +lemma uminus_eq_Minf[simp]: "-x = Minf \ x = Pinf" +by(cases x) auto +lemma uminus_eq_Pinf[simp]: "-x = Pinf \ x = Minf" +by(cases x) auto -fun uminus_ub :: "ub \ lb" where -"uminus_ub(Ub( x)) = Lb(-x)" | -"uminus_ub Pinf = Minf" - -fun uminus_lb :: "lb \ ub" where -"uminus_lb(Lb( x)) = Ub(-x)" | -"uminus_lb Minf = Pinf" +lemma uminus_le_Fin_iff: "- x \ Fin(-y) \ Fin y \ (x::'a::ordered_ab_group_add extended)" +by(cases x) auto +lemma Fin_uminus_le_iff: "Fin(-y) \ -x \ x \ ((Fin y)::'a::ordered_ab_group_add extended)" +by(cases x) auto instantiation ivl :: uminus begin -fun uminus_ivl where -"-(Ivl l h) = Ivl (uminus_ub h) (uminus_lb l)" - -instance .. -end +definition uminus_rep :: "eint2 \ eint2" where +"uminus_rep p = (let (l,h) = p in (-h, -l))" -instantiation ivl :: minus -begin +lemma \_uminus_rep: "i : \_rep p \ -i \ \_rep(uminus_rep p)" +by(auto simp: uminus_rep_def \_rep_def image_def uminus_le_Fin_iff Fin_uminus_le_iff + split: prod.split) -definition minus_ivl :: "ivl \ ivl \ ivl" where -"(i1::ivl) - i2 = i1 + -i2" +lift_definition uminus_ivl :: "ivl \ ivl" is uminus_rep +by (auto simp: uminus_rep_def eq_ivl_def \_rep_cases) + (auto simp: Icc_eq_Icc split: extended.splits) instance .. end -lemma minus_ivl_cases: "i1 - i2 = (if is_empty i1 | is_empty i2 then empty else - case (i1,i2) of (Ivl l1 h1, Ivl l2 h2) \ Ivl (l1 + uminus_ub h2) (h1 + uminus_lb l2))" -by(auto simp: plus_ivl_def minus_ivl_def split: ivl.split lub_splits) +lemma uminus_nice: "-[l\h] = [-h\-l]" +by transfer (simp add: uminus_rep_def) + +instantiation ivl :: minus +begin +definition minus_ivl :: "ivl \ ivl \ ivl" where "(iv1::ivl) - iv2 = iv1 + -iv2" +instance .. +end + -lemma gamma_minus_ivl: - "n1 : \_ivl i1 \ n2 : \_ivl i2 \ n1-n2 : \_ivl(i1 - i2)" -by(auto simp add: minus_ivl_def plus_ivl_def \_ivl_def split: ivl.splits lub_splits) +definition filter_plus_ivl :: "ivl \ ivl \ ivl \ ivl*ivl" where +"filter_plus_ivl iv iv1 iv2 = (iv1 \ (iv - iv2), iv2 \ (iv - iv1))" + +definition filter_less_rep :: "bool \ eint2 \ eint2 \ eint2 * eint2" where +"filter_less_rep res p1 p2 = + (if is_empty_rep p1 \ is_empty_rep p2 then (empty_rep,empty_rep) else + let (l1,h1) = p1; (l2,h2) = p2 in + if res + then ((l1, min h1 (h2 + Fin -1)), (max (l1 + Fin 1) l2, h2)) + else ((max l1 l2, h1), (l2, min h1 h2)))" -definition "filter_plus_ivl i i1 i2 = ((*if is_empty i then empty else*) - i1 \ (i - i2), i2 \ (i - i1))" +lift_definition filter_less_ivl :: "bool \ ivl \ ivl \ ivl * ivl" is filter_less_rep +by(auto simp: prod_pred_def filter_less_rep_def eq_ivl_iff) +declare filter_less_ivl.abs_eq[code] (* bug in lifting *) + +lemma filter_less_ivl_nice: "filter_less_ivl b [l1\h1] [l2\h2] = + (if [l1\h1] = \ \ [l2\h2] = \ then (\,\) else + if b + then ([l1 \ min h1 (h2 + Fin -1)], [max (l1 + Fin 1) l2 \ h2]) + else ([max l1 l2 \ h1], [l2 \ min h1 h2]))" +unfolding prod_rel_eq[symmetric] bot_ivl_def +by transfer (auto simp: filter_less_rep_def eq_ivl_empty) -fun filter_less_ivl :: "bool \ ivl \ ivl \ ivl * ivl" where -"filter_less_ivl res (Ivl l1 h1) (Ivl l2 h2) = - (if is_empty(Ivl l1 h1) \ is_empty(Ivl l2 h2) then (empty, empty) else - if res - then (Ivl l1 (min h1 (h2 + Ub -1)), Ivl (max (l1 + Lb 1) l2) h2) - else (Ivl (max l1 l2) h1, Ivl l2 (min h1 h2)))" +lemma add_mono_le_Fin: + "\x1 \ Fin y1; x2 \ Fin y2\ \ x1 + x2 \ Fin (y1 + (y2::'a::ordered_ab_group_add))" +by(drule (1) add_mono) simp + +lemma add_mono_Fin_le: + "\Fin y1 \ x1; Fin y2 \ x2\ \ Fin(y1 + y2::'a::ordered_ab_group_add) \ x1 + x2" +by(drule (1) add_mono) simp + +lemma plus_rep_plus: + "\ i1 \ \_rep (l1,h1); i2 \ \_rep (l2, h2)\ \ i1 + i2 \ \_rep (l1 + l2, h1 + h2)" +by(simp add: \_rep_def add_mono_Fin_le add_mono_le_Fin) interpretation Val_abs where \ = \_ivl and num' = num_ivl and plus' = "op +" proof - case goal1 thus ?case - by(auto simp: \_ivl_def le_ivl_def le_lub_defs split: ivl.split lub_splits if_splits) + case goal1 thus ?case by transfer (simp add: le_iff_subset) next - case goal2 show ?case by(simp add: \_ivl_def Top_ivl_def) + case goal2 show ?case by transfer (simp add: \_rep_def) next - case goal3 thus ?case by(simp add: \_ivl_def num_ivl_def) + case goal3 show ?case by transfer (simp add: \_rep_def) next case goal4 thus ?case - by(auto simp add: \_ivl_def plus_ivl_def split: ivl.split lub_splits) + apply transfer + apply(auto simp: \_rep_def plus_rep_def add_mono_le_Fin add_mono_Fin_le) + by(auto simp: empty_rep_def is_empty_rep_def) qed + interpretation Val_abs1_gamma where \ = \_ivl and num' = num_ivl and plus' = "op +" defines aval_ivl is aval' proof - case goal1 thus ?case - by(auto simp add: \_ivl_def meet_ivl_def empty_def min_def max_def split: ivl.split lub_splits) + case goal1 show ?case + by transfer (auto simp add:meet_rep_def \_rep_cases split: prod.split extended.split) next - case goal2 show ?case by(auto simp add: bot_ivl_def \_ivl_def empty_def) + case goal2 show ?case unfolding bot_ivl_def by transfer simp qed -lemma mono_minus_ivl: fixes i1 :: ivl -shows "i1 \ i1' \ i2 \ i2' \ i1 - i2 \ i1' - i2'" -apply(auto simp add: minus_ivl_cases empty_def le_ivl_def le_lub_defs split: ivl.splits) - apply(simp split: lub_splits) - apply(simp split: lub_splits) -apply(simp split: lub_splits) -done +lemma \_plus_rep: "i1 : \_rep p1 \ i2 : \_rep p2 \ i1+i2 \ \_rep(plus_rep p1 p2)" +by(auto simp: plus_rep_def plus_rep_plus split: prod.splits) +lemma non_empty_meet: "\n1 \ \_rep a1; n2 \ \_rep a2; n1 + n2 \ \_rep a \ \ + \ is_empty_rep (meet_rep a1 (plus_rep a (uminus_rep a2)))" +by (auto simp add: \_meet_rep set_eq_iff is_empty_rep_iff simp del: all_not_in_conv) + (metis \_plus_rep \_uminus_rep add_diff_cancel diff_minus) + +lemma filter_plus: "\eq_ivl (meet_rep a1 (plus_rep a (uminus_rep a2))) b1 \ + eq_ivl (meet_rep a2 (plus_rep a (uminus_rep a1))) b2; + n1 \ \_rep a1; n2 \ \_rep a2; n1 + n2 \ \_rep a\ + \ n1 \ \_rep b1 \ n2 \ \_rep b2" +by (auto simp: eq_ivl_iff \_meet_rep non_empty_meet add_ac) + (metis \_plus_rep \_uminus_rep add_diff_cancel diff_def add_commute)+ interpretation Val_abs1 where \ = \_ivl and num' = num_ivl and plus' = "op +" and test_num' = in_ivl and filter_plus' = filter_plus_ivl and filter_less' = filter_less_ivl proof - case goal1 thus ?case - by (simp add: \_ivl_def split: ivl.split lub_splits) + case goal1 thus ?case by transfer (auto simp: \_rep_def) next - case goal2 thus ?case - by(auto simp add: filter_plus_ivl_def) - (metis gamma_minus_ivl add_diff_cancel add_commute)+ + case goal2 thus ?case unfolding filter_plus_ivl_def minus_ivl_def prod_rel_eq[symmetric] + by transfer (simp add: filter_plus) next case goal3 thus ?case - by(cases a1, cases a2, auto simp: \_ivl_def min_def max_def split: if_splits lub_splits) + unfolding prod_rel_eq[symmetric] + apply transfer + apply (auto simp add: filter_less_rep_def eq_ivl_iff max_def min_def split: if_splits) + apply(auto simp: \_rep_cases is_empty_rep_def split: extended.splits) + done qed interpretation Abs_Int1 @@ -308,25 +352,41 @@ text{* Monotonicity: *} +lemma mono_meet_rep: "le_rep p1 p2 \ le_rep q1 q2 \ le_rep (meet_rep p1 q1) (meet_rep p2 q2)" +by(auto simp add: le_iff_subset \_meet_rep) + +lemma mono_plus_rep: "le_rep p1 p2 \ le_rep q1 q2 \ le_rep (plus_rep p1 q1) (plus_rep p2 q2)" +apply(auto simp: plus_rep_def le_iff_subset split: if_splits) +by(auto simp: is_empty_rep_iff \_rep_cases split: extended.splits) + +lemma mono_minus_rep: "le_rep p1 p2 \ le_rep (uminus_rep p1) (uminus_rep p2)" +apply(auto simp: uminus_rep_def le_iff_subset split: if_splits prod.split) +by(auto simp: \_rep_cases split: extended.splits) + interpretation Abs_Int1_mono where \ = \_ivl and num' = num_ivl and plus' = "op +" and test_num' = in_ivl and filter_plus' = filter_plus_ivl and filter_less' = filter_less_ivl proof - case goal1 thus ?case - by(auto simp: plus_ivl_def le_ivl_def le_lub_defs empty_def split: if_splits ivl.splits lub_splits) + case goal1 thus ?case by transfer (rule mono_plus_rep) +next + case goal2 thus ?case unfolding filter_plus_ivl_def minus_ivl_def less_eq_prod_def + by transfer (auto simp: mono_meet_rep mono_plus_rep mono_minus_rep) next - case goal2 thus ?case - by(auto simp: filter_plus_ivl_def le_prod_def mono_meet mono_minus_ivl) -next - case goal3 thus ?case - apply(cases a1, cases b1, cases a2, cases b2, auto simp: le_prod_def) - by(auto simp add: empty_def le_ivl_def le_lub_defs min_def max_def split: lub_splits) + case goal3 thus ?case unfolding less_eq_prod_def + apply transfer + apply(auto simp:filter_less_rep_def le_iff_subset min_def max_def split: if_splits) + by(auto simp:is_empty_rep_iff \_rep_cases split: extended.splits) qed subsubsection "Tests" +(* Hide Fin in numerals on output *) +declare +Fin_numeral [code_post] Fin_neg_numeral [code_post] +zero_extended_def[symmetric, code_post] one_extended_def[symmetric, code_post] + value "show_acom_opt (AI_ivl test1_ivl)" text{* Better than @{text AI_const}: *} @@ -334,7 +394,7 @@ value "show_acom_opt (AI_ivl test4_const)" value "show_acom_opt (AI_ivl test6_const)" -definition "steps c i = (step_ivl(top(vars c)) ^^ i) (bot c)" +definition "steps c i = (step_ivl(Top(vars c)) ^^ i) (bot c)" value "show_acom_opt (AI_ivl test2_ivl)" value "show_acom (steps test2_ivl 0)" diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_Int3.thy --- a/src/HOL/IMP/Abs_Int3.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_Int3.thy Wed Mar 06 16:10:56 2013 +0100 @@ -65,17 +65,17 @@ class narrow = fixes narrow :: "'a \ 'a \ 'a" (infix "\" 65) -class WN = widen + narrow + preord + -assumes widen1: "x \ x \ y" -assumes widen2: "y \ x \ y" -assumes narrow1: "y \ x \ y \ x \ y" -assumes narrow2: "y \ x \ x \ y \ x" +class WN = widen + narrow + order + +assumes widen1: "x \ x \ y" +assumes widen2: "y \ x \ y" +assumes narrow1: "y \ x \ y \ x \ y" +assumes narrow2: "y \ x \ x \ y \ x" -class WN_Lc = widen + narrow + preord + Lc + -assumes widen1: "x \ Lc c \ y \ Lc c \ x \ x \ y" -assumes widen2: "x \ Lc c \ y \ Lc c \ y \ x \ y" -assumes narrow1: "y \ x \ y \ x \ y" -assumes narrow2: "y \ x \ x \ y \ x" +class WN_Lc = widen + narrow + order + Lc + +assumes widen1: "x \ Lc c \ y \ Lc c \ x \ x \ y" +assumes widen2: "x \ Lc c \ y \ Lc c \ y \ x \ y" +assumes narrow1: "y \ x \ y \ x \ y" +assumes narrow2: "y \ x \ x \ y \ x" assumes Lc_widen[simp]: "x \ Lc c \ y \ Lc c \ x \ y \ Lc c" assumes Lc_narrow[simp]: "x \ Lc c \ y \ Lc c \ x \ y \ Lc c" @@ -83,22 +83,25 @@ instantiation ivl :: WN begin -definition "widen_ivl ivl1 ivl2 = - ((*if is_empty ivl1 then ivl2 else - if is_empty ivl2 then ivl1 else*) - case (ivl1,ivl2) of (Ivl l1 h1, Ivl l2 h2) \ - Ivl (if l2 \ l1 \ l2 \ l1 then Minf else l1) - (if h1 \ h2 \ h1 \ h2 then Pinf else h1))" +definition "widen_rep p1 p2 = + (if is_empty_rep p1 then p2 else if is_empty_rep p2 then p1 else + let (l1,h1) = p1; (l2,h2) = p2 + in (if l2 < l1 then Minf else l1, if h1 < h2 then Pinf else h1))" + +lift_definition widen_ivl :: "ivl \ ivl \ ivl" is widen_rep +by(auto simp: widen_rep_def eq_ivl_iff) -definition "narrow_ivl ivl1 ivl2 = - ((*if is_empty ivl1 \ is_empty ivl2 then empty else*) - case (ivl1,ivl2) of (Ivl l1 h1, Ivl l2 h2) \ - Ivl (if l1 = Minf then l2 else l1) - (if h1 = Pinf then h2 else h1))" +definition "narrow_rep p1 p2 = + (if is_empty_rep p1 \ is_empty_rep p2 then empty_rep else + let (l1,h1) = p1; (l2,h2) = p2 + in (if l1 = Minf then l2 else l1, if h1 = Pinf then h2 else h1))" + +lift_definition narrow_ivl :: "ivl \ ivl \ ivl" is narrow_rep +by(auto simp: narrow_rep_def eq_ivl_iff) instance -proof qed - (auto simp add: widen_ivl_def narrow_ivl_def le_lub_defs le_ivl_def empty_def split: ivl.split lub_splits if_splits) +proof +qed (transfer, auto simp: widen_rep_def narrow_rep_def le_iff_subset \_rep_def subset_eq is_empty_rep_def empty_rep_def split: if_splits extended.splits)+ end @@ -106,23 +109,20 @@ instantiation st :: (WN)WN_Lc begin -definition "widen_st F1 F2 = FunDom (\x. fun F1 x \ fun F2 x) (dom F1)" +definition "widen_st F1 F2 = St (\x. fun F1 x \ fun F2 x) (dom F1)" -definition "narrow_st F1 F2 = FunDom (\x. fun F1 x \ fun F2 x) (dom F1)" +definition "narrow_st F1 F2 = St (\x. fun F1 x \ fun F2 x) (dom F1)" instance proof - case goal1 thus ?case - by(simp add: widen_st_def le_st_def WN_class.widen1) + case goal1 thus ?case by(simp add: widen_st_def less_eq_st_def WN_class.widen1) next case goal2 thus ?case - by(simp add: widen_st_def le_st_def WN_class.widen2 Lc_st_def L_st_def) + by(simp add: widen_st_def less_eq_st_def WN_class.widen2 Lc_st_def L_st_def) next - case goal3 thus ?case - by(auto simp: narrow_st_def le_st_def WN_class.narrow1) + case goal3 thus ?case by(auto simp: narrow_st_def less_eq_st_def WN_class.narrow1) next - case goal4 thus ?case - by(auto simp: narrow_st_def le_st_def WN_class.narrow2) + case goal4 thus ?case by(auto simp: narrow_st_def less_eq_st_def WN_class.narrow2) next case goal5 thus ?case by(auto simp: widen_st_def Lc_st_def L_st_def) next @@ -196,14 +196,14 @@ lemma widen_acom1: fixes C1 :: "'a acom" shows "\\a\set(annos C1). a \ Lc c; \a\set (annos C2). a \ Lc c; strip C1 = strip C2\ - \ C1 \ C1 \ C2" -by(induct C1 C2 rule: le_acom.induct) + \ C1 \ C1 \ C2" +by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: widen_acom_def widen1 Lc_acom_def) lemma widen_acom2: fixes C1 :: "'a acom" shows "\\a\set(annos C1). a \ Lc c; \a\set (annos C2). a \ Lc c; strip C1 = strip C2\ - \ C2 \ C1 \ C2" -by(induct C1 C2 rule: le_acom.induct) + \ C2 \ C1 \ C2" +by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: widen_acom_def widen2 Lc_acom_def) lemma strip_map2_acom[simp]: @@ -229,10 +229,10 @@ case goal2 thus ?case by(auto simp: Lc_acom_def widen_acom2) next case goal3 thus ?case - by(induct x y rule: le_acom.induct)(simp_all add: narrow_acom_def narrow1) + by(induct x y rule: less_eq_acom.induct)(simp_all add: narrow_acom_def narrow1) next case goal4 thus ?case - by(induct x y rule: le_acom.induct)(simp_all add: narrow_acom_def narrow2) + by(induct x y rule: less_eq_acom.induct)(simp_all add: narrow_acom_def narrow2) next case goal5 thus ?case by(auto simp: Lc_acom_def widen_acom_def split_conv elim!: in_set_zipE) @@ -255,12 +255,12 @@ lemma widen_c_in_L: fixes C1 C2 :: "_ st option acom" shows "strip C1 = strip C2 \ C1 \ L X \ C2 \ L X \ C1 \ C2 \ L X" -by(induction C1 C2 rule: le_acom.induct) +by(induction C1 C2 rule: less_eq_acom.induct) (auto simp: widen_acom_def) lemma narrow_c_in_L: fixes C1 C2 :: "_ st option acom" shows "strip C1 = strip C2 \ C1 \ L X \ C2 \ L X \ C1 \ C2 \ L X" -by(induction C1 C2 rule: le_acom.induct) +by(induction C1 C2 rule: less_eq_acom.induct) (auto simp: narrow_acom_def) lemma bot_in_Lc[simp]: "bot c \ Lc c" @@ -269,18 +269,18 @@ subsubsection "Post-fixed point computation" -definition iter_widen :: "('a \ 'a) \ 'a \ ('a::{preord,widen})option" -where "iter_widen f = while_option (\x. \ f x \ x) (\x. x \ f x)" +definition iter_widen :: "('a \ 'a) \ 'a \ ('a::{order,widen})option" +where "iter_widen f = while_option (\x. \ f x \ x) (\x. x \ f x)" -definition iter_narrow :: "('a \ 'a) \ 'a \ ('a::{preord,narrow})option" -where "iter_narrow f = while_option (\x. \ x \ x \ f x) (\x. x \ f x)" +definition iter_narrow :: "('a \ 'a) \ 'a \ ('a::{order,narrow})option" +where "iter_narrow f = while_option (\x. \ x \ x \ f x) (\x. x \ f x)" -definition pfp_wn :: "('a::{preord,widen,narrow} \ 'a) \ 'a \ 'a option" +definition pfp_wn :: "('a::{order,widen,narrow} \ 'a) \ 'a \ 'a option" where "pfp_wn f x = (case iter_widen f x of None \ None | Some p \ iter_narrow f p)" -lemma iter_widen_pfp: "iter_widen f x = Some p \ f p \ p" +lemma iter_widen_pfp: "iter_widen f x = Some p \ f p \ p" by(auto simp add: iter_widen_def dest: while_option_stop) lemma iter_widen_inv: @@ -295,7 +295,7 @@ using while_option_rule[where P = "\C'. strip C' = strip C", OF _ assms(2)] by (metis assms(1)) -lemma strip_iter_widen: fixes f :: "'a::{preord,widen} acom \ 'a acom" +lemma strip_iter_widen: fixes f :: "'a::{order,widen} acom \ 'a acom" assumes "\C. strip (f C) = strip C" and "iter_widen f C = Some C'" shows "strip C' = strip C" proof- @@ -305,12 +305,12 @@ qed lemma iter_narrow_pfp: -assumes mono: "!!x1 x2::_::WN_Lc. P x1 \ P x2 \ x1 \ x2 \ f x1 \ f x2" +assumes mono: "!!x1 x2::_::WN_Lc. P x1 \ P x2 \ x1 \ x2 \ f x1 \ f x2" and Pinv: "!!x. P x \ P(f x)" "!!x1 x2. P x1 \ P x2 \ P(x1 \ x2)" -and "P p0" and "f p0 \ p0" and "iter_narrow f p0 = Some p" -shows "P p \ f p \ p" +and "P p0" and "f p0 \ p0" and "iter_narrow f p0 = Some p" +shows "P p \ f p \ p" proof- - let ?Q = "%p. P p \ f p \ p \ p \ p0" + let ?Q = "%p. P p \ f p \ p \ p \ p0" { fix p assume "?Q p" note P = conjunct1[OF this] and 12 = conjunct2[OF this] note 1 = conjunct1[OF 12] and 2 = conjunct2[OF 12] @@ -318,12 +318,12 @@ have "?Q ?p'" proof auto show "P ?p'" by (blast intro: P Pinv) - have "f ?p' \ f p" by(rule mono[OF `P (p \ f p)` P narrow2[OF 1]]) - also have "\ \ ?p'" by(rule narrow1[OF 1]) - finally show "f ?p' \ ?p'" . - have "?p' \ p" by (rule narrow2[OF 1]) - also have "p \ p0" by(rule 2) - finally show "?p' \ p0" . + have "f ?p' \ f p" by(rule mono[OF `P (p \ f p)` P narrow2[OF 1]]) + also have "\ \ ?p'" by(rule narrow1[OF 1]) + finally show "f ?p' \ ?p'" . + have "?p' \ p" by (rule narrow2[OF 1]) + also have "p \ p0" by(rule 2) + finally show "?p' \ p0" . qed } thus ?thesis @@ -332,11 +332,11 @@ qed lemma pfp_wn_pfp: -assumes mono: "!!x1 x2::_::WN_Lc. P x1 \ P x2 \ x1 \ x2 \ f x1 \ f x2" +assumes mono: "!!x1 x2::_::WN_Lc. P x1 \ P x2 \ x1 \ x2 \ f x1 \ f x2" and Pinv: "P x" "!!x. P x \ P(f x)" "!!x1 x2. P x1 \ P x2 \ P(x1 \ x2)" "!!x1 x2. P x1 \ P x2 \ P(x1 \ x2)" -and pfp_wn: "pfp_wn f x = Some p" shows "P p \ f p \ p" +and pfp_wn: "pfp_wn f x = Some p" shows "P p \ f p \ p" proof- from pfp_wn obtain p0 where its: "iter_widen f x = Some p0" "iter_narrow f p0 = Some p" @@ -358,24 +358,24 @@ begin definition AI_wn :: "com \ 'av st option acom option" where -"AI_wn c = pfp_wn (step' (top(vars c))) (bot c)" +"AI_wn c = pfp_wn (step' (Top(vars c))) (bot c)" lemma AI_wn_sound: "AI_wn c = Some C \ CS c \ \\<^isub>c C" proof(simp add: CS_def AI_wn_def) - assume 1: "pfp_wn (step' (top(vars c))) (bot c) = Some C" - have 2: "(strip C = c & C \ L(vars c)) \ step' \\<^bsub>vars c\<^esub> C \ C" + assume 1: "pfp_wn (step' (Top(vars c))) (bot c) = Some C" + have 2: "(strip C = c & C \ L(vars c)) \ step' \\<^bsub>vars c\<^esub> C \ C" by(rule pfp_wn_pfp[where x="bot c"]) (simp_all add: 1 mono_step'_top widen_c_in_L narrow_c_in_L) - have pfp: "step (\\<^isub>o(top(vars c))) (\\<^isub>c C) \ \\<^isub>c C" + have pfp: "step (\\<^isub>o(Top(vars c))) (\\<^isub>c C) \ \\<^isub>c C" proof(rule order_trans) - show "step (\\<^isub>o (top(vars c))) (\\<^isub>c C) \ \\<^isub>c (step' (top(vars c)) C)" - by(rule step_step'[OF conjunct2[OF conjunct1[OF 2]] top_in_L]) + show "step (\\<^isub>o (Top(vars c))) (\\<^isub>c C) \ \\<^isub>c (step' (Top(vars c)) C)" + by(rule step_step'[OF conjunct2[OF conjunct1[OF 2]] Top_in_L]) show "... \ \\<^isub>c C" by(rule mono_gamma_c[OF conjunct2[OF 2]]) qed have 3: "strip (\\<^isub>c C) = c" by(simp add: strip_pfp_wn[OF _ 1]) - have "lfp c (step (\\<^isub>o (top(vars c)))) \ \\<^isub>c C" - by(rule lfp_lowerbound[simplified,where f="step (\\<^isub>o(top(vars c)))", OF 3 pfp]) + have "lfp c (step (\\<^isub>o (Top(vars c)))) \ \\<^isub>c C" + by(rule lfp_lowerbound[simplified,where f="step (\\<^isub>o(Top(vars c)))", OF 3 pfp]) thus "lfp c (step UNIV) \ \\<^isub>c C" by simp qed @@ -391,14 +391,10 @@ subsubsection "Tests" -(* Trick to make the code generator happy. *) -lemma [code]: "equal_class.equal (x::'a st) y = equal_class.equal x y" -by(rule refl) - definition "step_up_ivl n = - ((\C. C \ step_ivl (top(vars(strip C))) C)^^n)" + ((\C. C \ step_ivl (Top(vars(strip C))) C)^^n)" definition "step_down_ivl n = - ((\C. C \ step_ivl (top(vars(strip C))) C)^^n)" + ((\C. C \ step_ivl (Top(vars(strip C))) C)^^n)" text{* For @{const test3_ivl}, @{const AI_ivl} needed as many iterations as the loop took to execute. In contrast, @{const AI_ivl'} converges in a @@ -430,32 +426,31 @@ locale Measure_WN = Measure1 where m=m for m :: "'av::WN \ nat" + fixes n :: "'av \ nat" -assumes m_widen: "~ y \ x \ m(x \ y) < m x" -assumes n_mono: "x \ y \ n x \ n y" -assumes n_narrow: "y \ x \ ~ x \ x \ y \ n(x \ y) < n x" +assumes m_widen: "~ y \ x \ m(x \ y) < m x" +assumes n_mono: "x \ y \ n x \ n y" +assumes n_narrow: "y \ x \ ~ x \ x \ y \ n(x \ y) < n x" begin lemma m_s_widen: "S1 \ L X \ S2 \ L X \ finite X \ - ~ S2 \ S1 \ m_s(S1 \ S2) < m_s S1" -proof(auto simp add: le_st_def m_s_def L_st_def widen_st_def) + ~ S2 \ S1 \ m_s(S1 \ S2) < m_s S1" +proof(auto simp add: less_eq_st_def m_s_def L_st_def widen_st_def) assume "finite(dom S1)" have 1: "\x\dom S1. m(fun S1 x) \ m(fun S1 x \ fun S2 x)" by (metis m1 WN_class.widen1) - fix x assume "x \ dom S1" "\ fun S2 x \ fun S1 x" + fix x assume "x \ dom S1" "\ fun S2 x \ fun S1 x" hence 2: "EX x : dom S1. m(fun S1 x) > m(fun S1 x \ fun S2 x)" using m_widen by blast from setsum_strict_mono_ex1[OF `finite(dom S1)` 1 2] show "(\x\dom S1. m (fun S1 x \ fun S2 x)) < (\x\dom S1. m (fun S1 x))" . qed -lemma m_o_widen: "\ S1 \ L X; S2 \ L X; finite X; \ S2 \ S1 \ \ +lemma m_o_widen: "\ S1 \ L X; S2 \ L X; finite X; \ S2 \ S1 \ \ m_o (card X) (S1 \ S2) < m_o (card X) S1" -by(auto simp: m_o_def L_st_def m_s_h less_Suc_eq_le m_s_widen - split: option.split) +by(auto simp: m_o_def L_st_def m_s_h less_Suc_eq_le m_s_widen split: option.split) lemma m_c_widen: - "C1 \ Lc c \ C2 \ Lc c \ \ C2 \ C1 \ m_c (C1 \ C2) < m_c C1" + "C1 \ Lc c \ C2 \ Lc c \ \ C2 \ C1 \ m_c (C1 \ C2) < m_c C1" apply(auto simp: Lc_acom_def m_c_def Let_def widen_acom_def) apply(subgoal_tac "length(annos C2) = length(annos C1)") prefer 2 apply (simp add: size_annos_same2) @@ -475,25 +470,25 @@ definition n_s :: "'av st \ nat" ("n\<^isub>s") where "n\<^isub>s S = (\x\dom S. n(fun S x))" -lemma n_s_mono: assumes "S1 \ S2" shows "n\<^isub>s S1 \ n\<^isub>s S2" +lemma n_s_mono: assumes "S1 \ S2" shows "n\<^isub>s S1 \ n\<^isub>s S2" proof- - from assms have [simp]: "dom S1 = dom S2" "\x\dom S1. fun S1 x \ fun S2 x" - by(simp_all add: le_st_def) + from assms have [simp]: "dom S1 = dom S2" "\x\dom S1. fun S1 x \ fun S2 x" + by(simp_all add: less_eq_st_def) have "(\x\dom S1. n(fun S1 x)) \ (\x\dom S1. n(fun S2 x))" - by(rule setsum_mono)(simp add: le_st_def n_mono) + by(rule setsum_mono)(simp add: less_eq_st_def n_mono) thus ?thesis by(simp add: n_s_def) qed lemma n_s_narrow: -assumes "finite(dom S1)" and "S2 \ S1" "\ S1 \ S1 \ S2" +assumes "finite(dom S1)" and "S2 \ S1" "\ S1 \ S1 \ S2" shows "n\<^isub>s (S1 \ S2) < n\<^isub>s S1" proof- - from `S2\S1` have [simp]: "dom S1 = dom S2" "\x\dom S1. fun S2 x \ fun S1 x" - by(simp_all add: le_st_def) + from `S2\S1` have [simp]: "dom S1 = dom S2" "\x\dom S1. fun S2 x \ fun S1 x" + by(simp_all add: less_eq_st_def) have 1: "\x\dom S1. n(fun (S1 \ S2) x) \ n(fun S1 x)" - by(auto simp: le_st_def narrow_st_def n_mono WN_class.narrow2) - have 2: "\x\dom S1. n(fun (S1 \ S2) x) < n(fun S1 x)" using `\ S1 \ S1 \ S2` - by(force simp: le_st_def narrow_st_def intro: n_narrow) + by(auto simp: less_eq_st_def narrow_st_def n_mono WN_class.narrow2) + have 2: "\x\dom S1. n(fun (S1 \ S2) x) < n(fun S1 x)" using `\ S1 \ S1 \ S2` + by(force simp: less_eq_st_def narrow_st_def intro: n_narrow) have "(\x\dom S1. n(fun (S1 \ S2) x)) < (\x\dom S1. n(fun S1 x))" apply(rule setsum_strict_mono_ex1[OF `finite(dom S1)`]) using 1 2 by blast+ moreover have "dom (S1 \ S2) = dom S1" by(simp add: narrow_st_def) @@ -504,12 +499,12 @@ definition n_o :: "'av st option \ nat" ("n\<^isub>o") where "n\<^isub>o opt = (case opt of None \ 0 | Some S \ n\<^isub>s S + 1)" -lemma n_o_mono: "S1 \ S2 \ n\<^isub>o S1 \ n\<^isub>o S2" -by(induction S1 S2 rule: le_option.induct)(auto simp: n_o_def n_s_mono) +lemma n_o_mono: "S1 \ S2 \ n\<^isub>o S1 \ n\<^isub>o S2" +by(induction S1 S2 rule: less_eq_option.induct)(auto simp: n_o_def n_s_mono) lemma n_o_narrow: "S1 \ L X \ S2 \ L X \ finite X - \ S2 \ S1 \ \ S1 \ S1 \ S2 \ n\<^isub>o (S1 \ S2) < n\<^isub>o S1" + \ S2 \ S1 \ \ S1 \ S1 \ S2 \ n\<^isub>o (S1 \ S2) < n\<^isub>o S1" apply(induction S1 S2 rule: narrow_option.induct) apply(auto simp: n_o_def L_st_def n_s_narrow) done @@ -519,7 +514,7 @@ "n\<^isub>c C = (let as = annos C in \io (as!i))" lemma n_c_narrow: "C1 \ Lc c \ C2 \ Lc c \ - C2 \ C1 \ \ C1 \ C1 \ C2 \ n\<^isub>c (C1 \ C2) < n\<^isub>c C1" + C2 \ C1 \ \ C1 \ C1 \ C2 \ n\<^isub>c (C1 \ C2) < n\<^isub>c C1" apply(auto simp: n_c_def Let_def Lc_acom_def narrow_acom_def) apply(subgoal_tac "length(annos C2) = length(annos C1)") prefer 2 apply (simp add: size_annos_same2) @@ -544,13 +539,13 @@ fixes m :: "'a::WN_Lc \ nat" assumes P_f: "\C. P C \ P(f C)" and P_widen: "\C1 C2. P C1 \ P C2 \ P(C1 \ C2)" -and m_widen: "\C1 C2. P C1 \ P C2 \ ~ C2 \ C1 \ m(C1 \ C2) < m C1" +and m_widen: "\C1 C2. P C1 \ P C2 \ ~ C2 \ C1 \ m(C1 \ C2) < m C1" and "P C" shows "EX C'. iter_widen f C = Some C'" proof(simp add: iter_widen_def, rule measure_while_option_Some[where P = P and f=m]) show "P C" by(rule `P C`) next - fix C assume "P C" "\ f C \ C" thus "P (C \ f C) \ m (C \ f C) < m C" + fix C assume "P C" "\ f C \ C" thus "P (C \ f C) \ m (C \ f C) < m C" by(simp add: P_f P_widen m_widen) qed @@ -558,19 +553,19 @@ fixes n :: "'a::WN_Lc \ nat" assumes P_f: "\C. P C \ P(f C)" and P_narrow: "\C1 C2. P C1 \ P C2 \ P(C1 \ C2)" -and mono: "\C1 C2. P C1 \ P C2 \ C1 \ C2 \ f C1 \ f C2" -and n_narrow: "\C1 C2. P C1 \ P C2 \ C2 \ C1 \ ~ C1 \ C1 \ C2 \ n(C1 \ C2) < n C1" -and init: "P C" "f C \ C" shows "EX C'. iter_narrow f C = Some C'" +and mono: "\C1 C2. P C1 \ P C2 \ C1 \ C2 \ f C1 \ f C2" +and n_narrow: "\C1 C2. P C1 \ P C2 \ C2 \ C1 \ ~ C1 \ C1 \ C2 \ n(C1 \ C2) < n C1" +and init: "P C" "f C \ C" shows "EX C'. iter_narrow f C = Some C'" proof(simp add: iter_narrow_def, - rule measure_while_option_Some[where f=n and P = "%C. P C \ f C \ C"]) - show "P C \ f C \ C" using init by blast + rule measure_while_option_Some[where f=n and P = "%C. P C \ f C \ C"]) + show "P C \ f C \ C" using init by blast next - fix C assume 1: "P C \ f C \ C" and 2: "\ C \ C \ f C" + fix C assume 1: "P C \ f C \ C" and 2: "\ C \ C \ f C" hence "P (C \ f C)" by(simp add: P_f P_narrow) - moreover then have "f (C \ f C) \ C \ f C" - by (metis narrow1 narrow2 1 mono preord_class.le_trans) + moreover then have "f (C \ f C) \ C \ f C" + by (metis narrow1 narrow2 1 mono order_trans) moreover have "n (C \ f C) < n C" using 1 2 by(simp add: n_narrow P_f) - ultimately show "(P (C \ f C) \ f (C \ f C) \ C \ f C) \ n(C \ f C) < n C" + ultimately show "(P (C \ f C) \ f (C \ f C) \ C \ f C) \ n(C \ f C) < n C" by blast qed @@ -581,39 +576,51 @@ subsubsection "Termination: Intervals" -definition m_ivl :: "ivl \ nat" where -"m_ivl ivl = (case ivl of Ivl l h \ - (case l of Minf \ 0 | Lb _ \ 1) + (case h of Pinf \ 0 | Ub _ \ 1))" +definition m_rep :: "eint2 \ nat" where +"m_rep p = (if is_empty_rep p then 3 else + let (l,h) = p in (case l of Minf \ 0 | _ \ 1) + (case h of Pinf \ 0 | _ \ 1))" + +lift_definition m_ivl :: "ivl \ nat" is m_rep +by(auto simp: m_rep_def eq_ivl_iff) -lemma m_ivl_height: "m_ivl ivl \ 2" -by(simp add: m_ivl_def split: ivl.split lub_splits) +lemma m_ivl_nice: "m_ivl[l\h] = (if [l\h] = \ then 3 else + (if l = Minf then 0 else 1) + (if h = Pinf then 0 else 1))" +unfolding bot_ivl_def +by transfer (auto simp: m_rep_def eq_ivl_empty split: extended.split) -lemma m_ivl_anti_mono: "(y::ivl) \ x \ m_ivl x \ m_ivl y" -by(auto simp: m_ivl_def le_lub_defs le_ivl_def - split: ivl.split lub_splits if_splits) +lemma m_ivl_height: "m_ivl iv \ 3" +by transfer (simp add: m_rep_def split: prod.split extended.split) + +lemma m_ivl_anti_mono: "y \ x \ m_ivl x \ m_ivl y" +by transfer + (auto simp: m_rep_def is_empty_rep_def \_rep_cases le_iff_subset + split: prod.split extended.splits if_splits) lemma m_ivl_widen: - "~ y \ x \ m_ivl(x \ y) < m_ivl x" -by(auto simp: m_ivl_def widen_ivl_def le_lub_defs le_ivl_def - split: ivl.splits lub_splits if_splits) + "~ y \ x \ m_ivl(x \ y) < m_ivl x" +by transfer + (auto simp: m_rep_def widen_rep_def is_empty_rep_def \_rep_cases le_iff_subset + split: prod.split extended.splits if_splits) definition n_ivl :: "ivl \ nat" where -"n_ivl ivl = 2 - m_ivl ivl" +"n_ivl ivl = 3 - m_ivl ivl" -lemma n_ivl_mono: "(x::ivl) \ y \ n_ivl x \ n_ivl y" +lemma n_ivl_mono: "x \ y \ n_ivl x \ n_ivl y" unfolding n_ivl_def by (metis diff_le_mono2 m_ivl_anti_mono) lemma n_ivl_narrow: - "~ x \ x \ y \ n_ivl(x \ y) < n_ivl x" -by(auto simp: n_ivl_def m_ivl_def narrow_ivl_def le_lub_defs le_ivl_def - split: ivl.splits lub_splits if_splits) + "~ x \ x \ y \ n_ivl(x \ y) < n_ivl x" +unfolding n_ivl_def +by transfer + (auto simp add: m_rep_def narrow_rep_def is_empty_rep_def empty_rep_def \_rep_cases le_iff_subset + split: prod.splits if_splits extended.splits) interpretation Abs_Int2_measure where \ = \_ivl and num' = num_ivl and plus' = "op +" and test_num' = in_ivl and filter_plus' = filter_plus_ivl and filter_less' = filter_less_ivl -and m = m_ivl and n = n_ivl and h = 2 +and m = m_ivl and n = n_ivl and h = 3 proof case goal1 thus ?case by(rule m_ivl_anti_mono) next @@ -629,14 +636,14 @@ lemma iter_winden_step_ivl_termination: - "\C. iter_widen (step_ivl (top(vars c))) (bot c) = Some C" + "\C. iter_widen (step_ivl (Top(vars c))) (bot c) = Some C" apply(rule iter_widen_termination[where m = "m_c" and P = "%C. C \ Lc c"]) apply (simp_all add: step'_in_Lc m_c_widen) done lemma iter_narrow_step_ivl_termination: - "C0 \ Lc c \ step_ivl (top(vars c)) C0 \ C0 \ - \C. iter_narrow (step_ivl (top(vars c))) C0 = Some C" + "C0 \ Lc c \ step_ivl (Top(vars c)) C0 \ C0 \ + \C. iter_narrow (step_ivl (Top(vars c))) C0 = Some C" apply(rule iter_narrow_termination[where n = "n_c" and P = "%C. C \ Lc c"]) apply (simp add: step'_in_Lc) apply (simp) @@ -662,12 +669,11 @@ subsubsection "Counterexamples" -text{* Widening is increasing by assumption, -but @{prop"x \ f x"} is not an invariant of widening. It can already -be lost after the first step: *} +text{* Widening is increasing by assumption, but @{prop"x \ f x"} is not an invariant of widening. +It can already be lost after the first step: *} -lemma assumes "!!x y::'a::WN. x \ y \ f x \ f y" -and "x \ f x" and "\ f x \ x" shows "x \ f x \ f(x \ f x)" +lemma assumes "!!x y::'a::WN. x \ y \ f x \ f y" +and "x \ f x" and "\ f x \ x" shows "x \ f x \ f(x \ f x)" nitpick[card = 3, expect = genuine, show_consts] (* 1 < 2 < 3, @@ -682,9 +688,9 @@ text{* Widening terminates but may converge more slowly than Kleene iteration. In the following model, Kleene iteration goes from 0 to the least pfp in one step but widening takes 2 steps to reach a strictly larger pfp: *} -lemma assumes "!!x y::'a::WN. x \ y \ f x \ f y" -and "x \ f x" and "\ f x \ x" and "f(f x) \ f x" -shows "f(x \ f x) \ x \ f x" +lemma assumes "!!x y::'a::WN. x \ y \ f x \ f y" +and "x \ f x" and "\ f x \ x" and "f(f x) \ f x" +shows "f(x \ f x) \ x \ f x" nitpick[card = 4, expect = genuine, show_consts] (* diff -r 0c376ef98559 -r 00b45c7e831f src/HOL/IMP/Abs_State.thy --- a/src/HOL/IMP/Abs_State.thy Wed Mar 06 14:10:07 2013 +0100 +++ b/src/HOL/IMP/Abs_State.thy Wed Mar 06 16:10:56 2013 +0100 @@ -60,21 +60,21 @@ end class semilatticeL = join + L + -fixes top :: "vname set \ 'a" -assumes join_ge1 [simp]: "x \ L X \ y \ L X \ x \ x \ y" -and join_ge2 [simp]: "x \ L X \ y \ L X \ y \ x \ y" -and join_least[simp]: "x \ z \ y \ z \ x \ y \ z" -and top[simp]: "x \ L X \ x \ top X" -and top_in_L[simp]: "top X \ L X" +fixes Top :: "vname set \ 'a" +assumes join_ge1 [simp]: "x \ L X \ y \ L X \ x \ x \ y" +and join_ge2 [simp]: "x \ L X \ y \ L X \ y \ x \ y" +and join_least[simp]: "x \ z \ y \ z \ x \ y \ z" +and Top[simp]: "x \ L X \ x \ Top X" +and Top_in_L[simp]: "Top X \ L X" and join_in_L[simp]: "x \ L X \ y \ L X \ x \ y \ L X" -notation (input) top ("\\<^bsub>_\<^esub>") -notation (latex output) top ("\\<^bsub>\<^raw:\isa{>_\<^raw:}>\<^esub>") +notation (input) Top ("\\<^bsub>_\<^esub>") +notation (latex output) Top ("\\<^bsub>\<^raw:\isa{>_\<^raw:}>\<^esub>") instantiation option :: (semilatticeL)semilatticeL begin -definition top_option where "top c = Some(top c)" +definition Top_option where "Top c = Some(Top c)" instance proof case goal1 thus ?case by(cases x, simp, cases y, simp_all) @@ -83,9 +83,9 @@ next case goal3 thus ?case by(cases z, simp, cases y, simp, cases x, simp_all) next - case goal4 thus ?case by(cases x, simp_all add: top_option_def) + case goal4 thus ?case by(cases x, simp_all add: Top_option_def) next - case goal5 thus ?case by(simp add: top_option_def) + case goal5 thus ?case by(simp add: Top_option_def) next case goal6 thus ?case by(simp add: L_option_def split: option.splits) qed @@ -97,41 +97,77 @@ hide_type st --"to avoid long names" -text{* A concrete type of state with computable @{text"\"}: *} +text{* A concrete type of state with computable @{text"\"}: *} + +fun st :: "(vname \ 'a) * vname set \ bool" where +"st (f,X) = (\x. x \ X \ f x = undefined)" -datatype 'a st = FunDom "vname \ 'a" "vname set" +typedef 'a st = "{p :: (vname \ 'a) * vname set. st p}" +proof + show "(\x. undefined,{}) \ {p. st p}" by simp +qed + +setup_lifting type_definition_st + +lift_definition St :: "(vname \ 'a) \ vname set \ 'a st" is + "\f X. (\x. if x \ X then f x else undefined, X)" +by(simp) -fun "fun" where "fun (FunDom f X) = f" -fun dom where "dom (FunDom f X) = X" +lift_definition update :: "'a st \ vname \ 'a \ 'a st" is + "\(f,X) x a. (f(x := a), insert x X)" +by(auto) + +lift_definition "fun" :: "'a st \ vname \ 'a" is fst .. + +lift_definition dom :: "'a st \ vname set" is snd .. -definition "show_st S = (\x. (x, fun S x)) ` dom S" +lemma dom_St[simp]: "dom(St f X) = X" +by(simp add: St.rep_eq dom.rep_eq) -value [code] "show_st (FunDom (\x. 1::int) {''a'',''b''})" +lemma fun_St[simp]: "fun(St f X) = (\x. if x \ X then f x else undefined)" +by(simp add: St.rep_eq fun.rep_eq) + +definition show_st :: "'a st \ (vname * 'a)set" where +"show_st S = (\x. (x, fun S x)) ` dom S" definition "show_acom = map_acom (Option.map show_st)" definition "show_acom_opt = Option.map show_acom" -definition "update F x y = FunDom ((fun F)(x:=y)) (dom F)" +lemma fun_update[simp]: "fun (update S x y) = (fun S)(x:=y)" +by transfer auto -lemma fun_update[simp]: "fun (update S x y) = (fun S)(x:=y)" -by(rule ext)(auto simp: update_def) +lemma dom_update[simp]: "dom (update S x y) = insert x (dom S)" +by transfer auto + +definition \_st :: "('a \ 'b set) \ 'a st \ (vname \ 'b) set" where +"\_st \ F = {f. \x\dom F. f x \ \(fun F x)}" -lemma dom_update[simp]: "dom (update S x y) = dom S" -by(simp add: update_def) +lemma ext_st: "dom F = dom G \ \x \ dom G. fun F x = fun G x \ F=G" +apply(induct F rule:Abs_st_induct) +apply(induct G rule:Abs_st_induct) +apply (auto simp:Abs_st_inject fun_def dom_def Abs_st_inverse simp del: st.simps) +apply(rule ext) +apply auto +done -definition "\_st \ F = {f. \x\dom F. f x \ \(fun F x)}" - - -instantiation st :: (preord) preord +instantiation st :: (order) order begin -definition le_st :: "'a st \ 'a st \ bool" where -"F \ G = (dom F = dom G \ (\x \ dom F. fun F x \ fun G x))" +definition less_eq_st :: "'a st \ 'a st \ bool" where +"F \ (G::'a st) = (dom F = dom G \ (\x \ dom F. fun F x \ fun G x))" + +definition less_st where "F < (G::'a st) = (F \ G \ \ G \ F)" instance proof - case goal2 thus ?case by(auto simp: le_st_def)(metis preord_class.le_trans) -qed (auto simp: le_st_def) + case goal1 show ?case by(rule less_st_def) +next + case goal2 show ?case by(auto simp: less_eq_st_def) +next + case goal3 thus ?case by(fastforce simp: less_eq_st_def) +next + case goal4 thus ?case by (metis less_eq_st_def antisym ext_st) +qed end @@ -139,7 +175,7 @@ begin definition join_st :: "'a st \ 'a st \ 'a st" where -"F \ G = FunDom (\x. fun F x \ fun G x) (dom F)" +"F \ (G::'a st) = St (\x. fun F x \ fun G x) (dom F)" instance .. @@ -149,7 +185,7 @@ begin definition L_st :: "vname set \ 'a st set" where -"L X = {F. dom F = X}" +"L(X::vname set) = {F. dom F = X}" instance .. @@ -158,11 +194,10 @@ instantiation st :: (semilattice) semilatticeL begin -definition top_st where "top X = FunDom (\x. \) X" +definition Top_st :: "vname set \ 'a st" where "Top(X) = St (\x. \) X" instance -proof -qed (auto simp: le_st_def join_st_def top_st_def L_st_def) +proof qed(auto simp add: less_eq_st_def join_st_def Top_st_def L_st_def) end @@ -175,12 +210,12 @@ But L is not executable. This looping defn makes it look as if it were. *) -lemma mono_fun: "F \ G \ x : dom F \ fun F x \ fun G x" -by(auto simp: le_st_def) +lemma mono_fun: "F \ G \ x : dom F \ fun F x \ fun G x" +by(auto simp: less_eq_st_def) lemma mono_update[simp]: - "a1 \ a2 \ S1 \ S2 \ update S1 x a1 \ update S2 x a2" -by(auto simp add: le_st_def update_def) + "a1 \ a2 \ S1 \ S2 \ update S1 x a1 \ update S2 x a2" +by(auto simp add: less_eq_st_def) locale Gamma = Val_abs where \=\ for \ :: "'av::semilattice \ val set" @@ -195,22 +230,22 @@ abbreviation \\<^isub>c :: "'av st option acom \ state set acom" where "\\<^isub>c == map_acom \\<^isub>o" -lemma gamma_s_Top[simp]: "\\<^isub>s (top c) = UNIV" -by(auto simp: top_st_def \_st_def) +lemma gamma_s_Top[simp]: "\\<^isub>s (Top X) = UNIV" +by(auto simp: Top_st_def \_st_def) -lemma gamma_o_Top[simp]: "\\<^isub>o (top c) = UNIV" -by (simp add: top_option_def) +lemma gamma_o_Top[simp]: "\\<^isub>o (Top X) = UNIV" +by (simp add: Top_option_def) -lemma mono_gamma_s: "f \ g \ \\<^isub>s f \ \\<^isub>s g" -apply(simp add:\_st_def subset_iff le_st_def split: if_splits) +lemma mono_gamma_s: "f \ g \ \\<^isub>s f \ \\<^isub>s g" +apply(simp add:\_st_def subset_iff less_eq_st_def split: if_splits) by (metis mono_gamma subsetD) lemma mono_gamma_o: - "S1 \ S2 \ \\<^isub>o S1 \ \\<^isub>o S2" -by(induction S1 S2 rule: le_option.induct)(simp_all add: mono_gamma_s) + "S1 \ S2 \ \\<^isub>o S1 \ \\<^isub>o S2" +by(induction S1 S2 rule: less_eq_option.induct)(simp_all add: mono_gamma_s) -lemma mono_gamma_c: "C1 \ C2 \ \\<^isub>c C1 \ \\<^isub>c C2" -by (induction C1 C2 rule: le_acom.induct) (simp_all add:mono_gamma_o) +lemma mono_gamma_c: "C1 \ C2 \ \\<^isub>c C1 \ \\<^isub>c C2" +by (induction C1 C2 rule: less_eq_acom.induct) (simp_all add:mono_gamma_o) lemma in_gamma_option_iff: "x : \_option r u \ (\u'. u = Some u' \ x : r u')"