src/HOL/IMP/Abs_Int1.thy
changeset 51711 df3426139651
parent 51390 1dff81cf425b
child 51712 30624dab6054
equal deleted inserted replaced
51710:f692657e0f71 51711:df3426139651
     1 (* Author: Tobias Nipkow *)
     1 (* Author: Tobias Nipkow *)
     2 
     2 
     3 theory Abs_Int1
     3 theory Abs_Int1
     4 imports Abs_State
     4 imports Abs_State
     5 begin
     5 begin
       
     6 
       
     7 (* FIXME mv *)
       
     8 instantiation acom :: (type) vars
       
     9 begin
       
    10 
       
    11 definition "vars_acom = vars o strip"
       
    12 
       
    13 instance ..
       
    14 
       
    15 end
       
    16 
       
    17 lemma finite_Cvars: "finite(vars(C::'a acom))"
       
    18 by(simp add: vars_acom_def)
       
    19 
     6 
    20 
     7 lemma le_iff_le_annos_zip: "C1 \<le> C2 \<longleftrightarrow>
    21 lemma le_iff_le_annos_zip: "C1 \<le> C2 \<longleftrightarrow>
     8  (\<forall> (a1,a2) \<in> set(zip (annos C1) (annos C2)). a1 \<le> a2) \<and> strip C1 = strip C2"
    22  (\<forall> (a1,a2) \<in> set(zip (annos C1) (annos C2)). a1 \<le> a2) \<and> strip C1 = strip C2"
     9 by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: size_annos_same2)
    23 by(induct C1 C2 rule: less_eq_acom.induct) (auto simp: size_annos_same2)
    10 
    24 
    11 lemma le_iff_le_annos: "C1 \<le> C2 \<longleftrightarrow>
    25 lemma le_iff_le_annos: "C1 \<le> C2 \<longleftrightarrow>
    12   strip C1 = strip C2 \<and> (\<forall> i<size(annos C1). annos C1 ! i \<le> annos C2 ! i)"
    26   strip C1 = strip C2 \<and> (\<forall> i<size(annos C1). annos C1 ! i \<le> annos C2 ! i)"
    13 by(auto simp add: le_iff_le_annos_zip set_zip) (metis size_annos_same2)
    27 by(auto simp add: le_iff_le_annos_zip set_zip) (metis size_annos_same2)
    14 
    28 
    15 
    29 (* FIXME mv *)
    16 lemma mono_fun_L[simp]: "F \<in> L X \<Longrightarrow> F \<le> G \<Longrightarrow> x : X \<Longrightarrow> fun F x \<le> fun G x"
    30 lemma post_in_annos: "post C \<in> set(annos C)"
    17 by(simp add: mono_fun L_st_def)
       
    18 
       
    19 lemma bot_in_L[simp]: "bot c \<in> L(vars c)"
       
    20 by(simp add: L_acom_def bot_def)
       
    21 
       
    22 lemma L_acom_simps[simp]: "SKIP {P} \<in> L X \<longleftrightarrow> P \<in> L X"
       
    23   "(x ::= e {P}) \<in> L X \<longleftrightarrow> x : X \<and> vars e \<subseteq> X \<and> P \<in> L X"
       
    24   "(C1;C2) \<in> L X \<longleftrightarrow> C1 \<in> L X \<and> C2 \<in> L X"
       
    25   "(IF b THEN {P1} C1 ELSE {P2} C2 {Q}) \<in> L X \<longleftrightarrow>
       
    26    vars b \<subseteq> X \<and> C1 \<in> L X \<and> C2 \<in> L X \<and> P1 \<in> L X \<and> P2 \<in> L X \<and> Q \<in> L X"
       
    27   "({I} WHILE b DO {P} C {Q}) \<in> L X \<longleftrightarrow>
       
    28    I \<in> L X \<and> vars b \<subseteq> X \<and> P \<in> L X \<and> C \<in> L X \<and> Q \<in> L X"
       
    29 by(auto simp add: L_acom_def)
       
    30 
       
    31 lemma post_in_annos: "post C : set(annos C)"
       
    32 by(induction C) auto
    31 by(induction C) auto
    33 
       
    34 lemma post_in_L[simp]: "C \<in> L X \<Longrightarrow> post C \<in> L X"
       
    35 by(simp add: L_acom_def post_in_annos)
       
    36 
    32 
    37 
    33 
    38 subsection "Computable Abstract Interpretation"
    34 subsection "Computable Abstract Interpretation"
    39 
    35 
    40 text{* Abstract interpretation over type @{text st} instead of functions. *}
    36 text{* Abstract interpretation over type @{text st} instead of functions. *}
    45 fun aval' :: "aexp \<Rightarrow> 'av st \<Rightarrow> 'av" where
    41 fun aval' :: "aexp \<Rightarrow> 'av st \<Rightarrow> 'av" where
    46 "aval' (N i) S = num' i" |
    42 "aval' (N i) S = num' i" |
    47 "aval' (V x) S = fun S x" |
    43 "aval' (V x) S = fun S x" |
    48 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)"
    44 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)"
    49 
    45 
    50 lemma aval'_sound: "s : \<gamma>\<^isub>s S \<Longrightarrow> vars a \<subseteq> dom S \<Longrightarrow> aval a s : \<gamma>(aval' a S)"
    46 lemma aval'_sound: "s : \<gamma>\<^isub>s S \<Longrightarrow> aval a s : \<gamma>(aval' a S)"
    51 by (induction a) (auto simp: gamma_num' gamma_plus' \<gamma>_st_def)
    47 by (induction a) (auto simp: gamma_num' gamma_plus' \<gamma>_st_def)
    52 
    48 
    53 lemma gamma_Step_subcomm: fixes C1 C2 :: "'a::semilattice_sup acom"
    49 lemma gamma_Step_subcomm: fixes C1 C2 :: "'a::semilattice_sup acom"
    54   assumes "!!x e S. x : X \<Longrightarrow> vars e \<subseteq> X \<Longrightarrow> S \<in> L X \<Longrightarrow> f1 x e (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (f2 x e S)"
    50   assumes "!!x e S. f1 x e (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (f2 x e S)"
    55           "!!b S. S \<in> L X \<Longrightarrow> vars b \<subseteq> X \<Longrightarrow> g1 b (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (g2 b S)"
    51           "!!b S. g1 b (\<gamma>\<^isub>o S) \<subseteq> \<gamma>\<^isub>o (g2 b S)"
    56   shows "C \<in> L X \<Longrightarrow> S \<in> L X \<Longrightarrow> Step f1 g1 (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (Step f2 g2 S C)"
    52   shows "Step f1 g1 (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (Step f2 g2 S C)"
    57 proof(induction C arbitrary: S)
    53 proof(induction C arbitrary: S)
    58 qed (auto simp: assms intro!: mono_gamma_o post_in_L sup_ge1 sup_ge2)
    54 qed (auto simp: assms intro!: mono_gamma_o sup_ge1 sup_ge2)
    59 
    55 
    60 lemma in_gamma_update: "\<lbrakk> s : \<gamma>\<^isub>s S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>s(update S x a)"
    56 lemma in_gamma_update: "\<lbrakk> s : \<gamma>\<^isub>s S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>s(update S x a)"
    61 by(simp add: \<gamma>_st_def)
    57 by(simp add: \<gamma>_st_def)
    62 
    58 
    63 end
    59 end
    64 
       
    65 
       
    66 lemma Step_in_L: fixes C :: "'a::semilatticeL acom"
       
    67 assumes "!!x e S. \<lbrakk>S \<in> L X; x \<in> X; vars e \<subseteq> X\<rbrakk> \<Longrightarrow> f x e S \<in> L X"
       
    68         "!!b S. S \<in> L X \<Longrightarrow> vars b \<subseteq> X \<Longrightarrow> g b S \<in> L X"
       
    69 shows"\<lbrakk> C \<in> L X; S \<in> L X \<rbrakk> \<Longrightarrow> Step f g S C \<in> L X"
       
    70 proof(induction C arbitrary: S)
       
    71   case Assign thus ?case
       
    72     by(auto simp: L_st_def assms split: option.splits)
       
    73 qed (auto simp: assms)
       
    74 
    60 
    75 
    61 
    76 text{* The for-clause (here and elsewhere) only serves the purpose of fixing
    62 text{* The for-clause (here and elsewhere) only serves the purpose of fixing
    77 the name of the type parameter @{typ 'av} which would otherwise be renamed to
    63 the name of the type parameter @{typ 'av} which would otherwise be renamed to
    78 @{typ 'a}. *}
    64 @{typ 'a}. *}
    83 definition "step' = Step
    69 definition "step' = Step
    84   (\<lambda>x e S. case S of None \<Rightarrow> None | Some S \<Rightarrow> Some(update S x (aval' e S)))
    70   (\<lambda>x e S. case S of None \<Rightarrow> None | Some S \<Rightarrow> Some(update S x (aval' e S)))
    85   (\<lambda>b S. S)"
    71   (\<lambda>b S. S)"
    86 
    72 
    87 definition AI :: "com \<Rightarrow> 'av st option acom option" where
    73 definition AI :: "com \<Rightarrow> 'av st option acom option" where
    88 "AI c = pfp (step' (Top(vars c))) (bot c)"
    74 "AI c = pfp (step' \<top>) (bot c)"
    89 
    75 
    90 
    76 
    91 lemma strip_step'[simp]: "strip(step' S C) = strip C"
    77 lemma strip_step'[simp]: "strip(step' S C) = strip C"
    92 by(simp add: step'_def)
    78 by(simp add: step'_def)
    93 
    79 
    94 
    80 
    95 text{* Soundness: *}
    81 text{* Soundness: *}
    96 
    82 
    97 lemma step_step': "C \<in> L X \<Longrightarrow> S \<in> L X \<Longrightarrow> step (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' S C)"
    83 lemma step_step': "step (\<gamma>\<^isub>o S) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' S C)"
    98 unfolding step_def step'_def
    84 unfolding step_def step'_def
    99 by(rule gamma_Step_subcomm)
    85 by(rule gamma_Step_subcomm)
   100   (auto simp: L_st_def intro!: aval'_sound in_gamma_update split: option.splits)
    86   (auto simp: intro!: aval'_sound in_gamma_update split: option.splits)
   101 
       
   102 lemma step'_in_L[simp]: "\<lbrakk> C \<in> L X; S \<in> L X \<rbrakk> \<Longrightarrow> step' S C \<in> L X"
       
   103 unfolding step'_def
       
   104 by(rule Step_in_L)(auto simp: L_st_def step'_def split: option.splits)
       
   105 
    87 
   106 lemma AI_sound: "AI c = Some C \<Longrightarrow> CS c \<le> \<gamma>\<^isub>c C"
    88 lemma AI_sound: "AI c = Some C \<Longrightarrow> CS c \<le> \<gamma>\<^isub>c C"
   107 proof(simp add: CS_def AI_def)
    89 proof(simp add: CS_def AI_def)
   108   assume 1: "pfp (step' (Top(vars c))) (bot c) = Some C"
    90   assume 1: "pfp (step' \<top>) (bot c) = Some C"
   109   have "C \<in> L(vars c)"
    91   have pfp': "step' \<top> C \<le> C" by(rule pfp_pfp[OF 1])
   110     by(rule pfp_inv[where P = "%C. C \<in> L(vars c)", OF 1 _ bot_in_L])
    92   have 2: "step (\<gamma>\<^isub>o \<top>) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c C"  --"transfer the pfp'"
   111       (erule step'_in_L[OF _ Top_in_L])
       
   112   have pfp': "step' (Top(vars c)) C \<le> C" by(rule pfp_pfp[OF 1])
       
   113   have 2: "step (\<gamma>\<^isub>o(Top(vars c))) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c C"
       
   114   proof(rule order_trans)
    93   proof(rule order_trans)
   115     show "step (\<gamma>\<^isub>o (Top(vars c))) (\<gamma>\<^isub>c C) \<le>  \<gamma>\<^isub>c (step' (Top(vars c)) C)"
    94     show "step (\<gamma>\<^isub>o \<top>) (\<gamma>\<^isub>c C) \<le> \<gamma>\<^isub>c (step' \<top> C)" by(rule step_step')
   116       by(rule step_step'[OF `C \<in> L(vars c)` Top_in_L])
    95     show "... \<le> \<gamma>\<^isub>c C" by (metis mono_gamma_c[OF pfp'])
   117     show "\<gamma>\<^isub>c (step' (Top(vars c)) C) \<le> \<gamma>\<^isub>c C"
       
   118       by(rule mono_gamma_c[OF pfp'])
       
   119   qed
    96   qed
   120   have 3: "strip (\<gamma>\<^isub>c C) = c" by(simp add: strip_pfp[OF _ 1] step'_def)
    97   have 3: "strip (\<gamma>\<^isub>c C) = c" by(simp add: strip_pfp[OF _ 1] step'_def)
   121   have "lfp c (step (\<gamma>\<^isub>o(Top(vars c)))) \<le> \<gamma>\<^isub>c C"
    98   have "lfp c (step (\<gamma>\<^isub>o \<top>)) \<le> \<gamma>\<^isub>c C"
   122     by(rule lfp_lowerbound[simplified,where f="step (\<gamma>\<^isub>o(Top(vars c)))", OF 3 2])
    99     by(rule lfp_lowerbound[simplified,where f="step (\<gamma>\<^isub>o \<top>)", OF 3 2])
   123   thus "lfp c (step UNIV) \<le> \<gamma>\<^isub>c C" by simp
   100   thus "lfp c (step UNIV) \<le> \<gamma>\<^isub>c C" by simp
   124 qed
   101 qed
   125 
   102 
   126 end
   103 end
   127 
   104 
   128 
   105 
   129 subsubsection "Monotonicity"
   106 subsubsection "Monotonicity"
   130 
   107 
   131 lemma le_sup_disj: "y \<in> L X \<Longrightarrow> (z::_::semilatticeL) \<in> L X \<Longrightarrow>
   108 lemma le_sup_disj: "x \<le> y \<or> x \<le> z \<Longrightarrow> x \<le> y \<squnion> (z::_::semilattice_sup)"
   132   x \<le> y \<or> x \<le> z \<Longrightarrow> x \<le> y \<squnion> z"
       
   133 by (metis sup_ge1 sup_ge2 order_trans)
   109 by (metis sup_ge1 sup_ge2 order_trans)
   134 
   110 
   135 theorem mono2_Step: fixes C1 :: "'a::semilatticeL acom"
   111 theorem mono2_Step: fixes C1 :: "'a::semilattice acom"
   136   assumes "!!x e S1 S2. \<lbrakk>S1 \<in> L X; S2 \<in> L X; x \<in> X; vars e \<subseteq> X; S1 \<le> S2\<rbrakk> \<Longrightarrow> f x e S1 \<le> f x e S2"
   112   assumes "!!x e S1 S2. S1 \<le> S2 \<Longrightarrow> f x e S1 \<le> f x e S2"
   137           "!!b S1 S2. S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> vars b \<subseteq> X \<Longrightarrow> S1 \<le> S2 \<Longrightarrow> g b S1 \<le> g b S2"
   113           "!!b S1 S2. S1 \<le> S2 \<Longrightarrow> g b S1 \<le> g b S2"
   138   shows "S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> C1 \<in> L X \<Longrightarrow> C2 \<in> L X \<Longrightarrow>
   114   shows "S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> Step f g S1 C1 \<le> Step f g S2 C2"
   139   S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> Step f g S1 C1 \<le> Step f g S2 C2"
       
   140 by(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct)
   115 by(induction C1 C2 arbitrary: S1 S2 rule: less_eq_acom.induct)
   141   (auto simp: mono_post assms le_sup_disj le_sup_disj[OF  post_in_L post_in_L])
   116   (auto simp: mono_post assms le_sup_disj)
   142 
   117 
   143 
   118 
   144 locale Abs_Int_mono = Abs_Int +
   119 locale Abs_Int_mono = Abs_Int +
   145 assumes mono_plus': "a1 \<le> b1 \<Longrightarrow> a2 \<le> b2 \<Longrightarrow> plus' a1 a2 \<le> plus' b1 b2"
   120 assumes mono_plus': "a1 \<le> b1 \<Longrightarrow> a2 \<le> b2 \<Longrightarrow> plus' a1 a2 \<le> plus' b1 b2"
   146 begin
   121 begin
   147 
   122 
   148 lemma mono_aval':
   123 lemma mono_aval': "S1 \<le> S2 \<Longrightarrow> aval' e S1 \<le> aval' e S2"
   149   "S1 \<le> S2 \<Longrightarrow> S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> vars e \<subseteq> X \<Longrightarrow> aval' e S1 \<le> aval' e S2"
   124 by(induction e) (auto simp: mono_plus' mono_fun)
   150 by(induction e) (auto simp: less_eq_st_def mono_plus' L_st_def)
   125 
   151 
   126 theorem mono_step': "S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> step' S1 C1 \<le> step' S2 C2"
   152 theorem mono_step': "S1 \<in> L X \<Longrightarrow> S2 \<in> L X \<Longrightarrow> C1 \<in> L X \<Longrightarrow> C2 \<in> L X \<Longrightarrow>
       
   153   S1 \<le> S2 \<Longrightarrow> C1 \<le> C2 \<Longrightarrow> step' S1 C1 \<le> step' S2 C2"
       
   154 unfolding step'_def
   127 unfolding step'_def
   155 by(rule mono2_Step) (auto simp: mono_aval' split: option.split)
   128 by(rule mono2_Step) (auto simp: mono_aval' split: option.split)
   156 
   129 
   157 lemma mono_step'_top: "C \<in> L X \<Longrightarrow> C' \<in> L X \<Longrightarrow>
   130 lemma mono_step'_top: "C \<le> C' \<Longrightarrow> step' \<top> C \<le> step' \<top> C'"
   158   C \<le> C' \<Longrightarrow> step' (Top X) C \<le> step' (Top X) C'"
   131 by (metis mono_step' order_refl)
   159 by (metis Top_in_L mono_step' order_refl)
   132 
   160 
   133 lemma AI_least_pfp: assumes "AI c = Some C" "step' \<top> C' \<le> C'" "strip C' = c"
   161 lemma pfp_bot_least:
       
   162 assumes "\<forall>x\<in>L(vars c)\<inter>{C. strip C = c}.\<forall>y\<in>L(vars c)\<inter>{C. strip C = c}.
       
   163   x \<le> y \<longrightarrow> f x \<le> f y"
       
   164 and "\<forall>C. C \<in> L(vars c)\<inter>{C. strip C = c} \<longrightarrow> f C \<in> L(vars c)\<inter>{C. strip C = c}"
       
   165 and "f C' \<le> C'" "strip C' = c" "C' \<in> L(vars c)" "pfp f (bot c) = Some C"
       
   166 shows "C \<le> C'"
   134 shows "C \<le> C'"
   167 by(rule while_least[OF assms(1,2) _ _ assms(3) _ assms(6)[unfolded pfp_def]])
   135 by(rule pfp_bot_least[OF _ _ assms(2,3) assms(1)[unfolded AI_def]])
   168   (simp_all add: assms(4,5) bot_least)
       
   169 
       
   170 lemma AI_least_pfp: assumes "AI c = Some C"
       
   171 and "step' (Top(vars c)) C' \<le> C'" "strip C' = c" "C' \<in> L(vars c)"
       
   172 shows "C \<le> C'"
       
   173 by(rule pfp_bot_least[OF _ _ assms(2-4) assms(1)[unfolded AI_def]])
       
   174   (simp_all add: mono_step'_top)
   136   (simp_all add: mono_step'_top)
   175 
   137 
   176 end
   138 end
   177 
   139 
   178 
   140 
   194     by (blast intro: I mono)
   156     by (blast intro: I mono)
   195 qed
   157 qed
   196 
   158 
   197 
   159 
   198 locale Measure1 =
   160 locale Measure1 =
   199 fixes m :: "'av::order \<Rightarrow> nat"
   161 fixes m :: "'av::{order,top} \<Rightarrow> nat"
   200 fixes h :: "nat"
   162 fixes h :: "nat"
   201 assumes h: "m x \<le> h"
   163 assumes h: "m x \<le> h"
   202 begin
   164 begin
   203 
   165 
   204 definition m_s :: "'av st \<Rightarrow> nat" ("m\<^isub>s") where
   166 definition m_s :: "vname set \<Rightarrow> 'av st \<Rightarrow> nat" ("m\<^isub>s") where
   205 "m_s S = (\<Sum> x \<in> dom S. m(fun S x))"
   167 "m_s X S = (\<Sum> x \<in> X. m(fun S x))"
   206 
   168 
   207 lemma m_s_h: "x \<in> L X \<Longrightarrow> finite X \<Longrightarrow> m_s x \<le> h * card X"
   169 lemma m_s_h: "finite X \<Longrightarrow> m_s X S \<le> h * card X"
   208 by(simp add: L_st_def m_s_def)
   170 by(simp add: m_s_def) (metis nat_mult_commute of_nat_id setsum_bounded[OF h])
   209   (metis nat_mult_commute of_nat_id setsum_bounded[OF h])
   171 
   210 
   172 definition m_o :: "vname set \<Rightarrow> 'av st option \<Rightarrow> nat" ("m\<^isub>o") where
   211 definition m_o :: "nat \<Rightarrow> 'av st option \<Rightarrow> nat" ("m\<^isub>o") where
   173 "m_o X opt = (case opt of None \<Rightarrow> h * card X + 1 | Some S \<Rightarrow> m_s X S)"
   212 "m_o d opt = (case opt of None \<Rightarrow> h*d+1 | Some S \<Rightarrow> m_s S)"
   174 
   213 
   175 lemma m_o_h: "finite X \<Longrightarrow> m_o X opt \<le> (h*card X + 1)"
   214 lemma m_o_h: "ost \<in> L X \<Longrightarrow> finite X \<Longrightarrow> m_o (card X) ost \<le> (h*card X + 1)"
   176 by(auto simp add: m_o_def m_s_h le_SucI split: option.split dest:m_s_h)
   215 by(auto simp add: m_o_def m_s_h split: option.split dest!:m_s_h)
       
   216 
   177 
   217 definition m_c :: "'av st option acom \<Rightarrow> nat" ("m\<^isub>c") where
   178 definition m_c :: "'av st option acom \<Rightarrow> nat" ("m\<^isub>c") where
   218 "m_c C = (\<Sum>i<size(annos C). m_o (card(vars(strip C))) (annos C ! i))"
   179 "m_c C = (\<Sum>i<size(annos C). m_o (vars C) (annos C ! i))"
   219 
   180 
   220 lemma m_c_h: assumes "C \<in> L(vars(strip C))"
   181 text{* Upper complexity bound: *}
   221 shows "m_c C \<le> size(annos C) * (h * card(vars(strip C)) + 1)"
   182 lemma m_c_h: "m_c C \<le> size(annos C) * (h * card(vars C) + 1)"
   222 proof-
   183 proof-
   223   let ?X = "vars(strip C)" let ?n = "card ?X" let ?a = "size(annos C)"
   184   let ?X = "vars C" let ?n = "card ?X" let ?a = "size(annos C)"
   224   { fix i assume "i < ?a"
   185   have "m_c C = (\<Sum>i<?a. m_o ?X (annos C ! i))" by(simp add: m_c_def)
   225     hence "annos C ! i \<in> L ?X" using assms by(simp add: L_acom_def)
       
   226     note m_o_h[OF this finite_cvars]
       
   227   } note 1 = this
       
   228   have "m_c C = (\<Sum>i<?a. m_o ?n (annos C ! i))" by(simp add: m_c_def)
       
   229   also have "\<dots> \<le> (\<Sum>i<?a. h * ?n + 1)"
   186   also have "\<dots> \<le> (\<Sum>i<?a. h * ?n + 1)"
   230     apply(rule setsum_mono) using 1 by simp
   187     apply(rule setsum_mono) using m_o_h[OF finite_Cvars] by simp
   231   also have "\<dots> = ?a * (h * ?n + 1)" by simp
   188   also have "\<dots> = ?a * (h * ?n + 1)" by simp
   232   finally show ?thesis .
   189   finally show ?thesis .
   233 qed
   190 qed
   234 
   191 
   235 end
   192 end
   236 
   193 
       
   194 text{* The predicates @{text "top_on X a"} that follow describe that @{text a} is some object
       
   195 that maps all variables in @{text X} to @{term \<top>}.
       
   196 This is an important invariant for the termination proof where we argue that only
       
   197 the finitely many variables in the program change. That the others do not change
       
   198 follows because they remain @{term \<top>}. *}
       
   199 
       
   200 class top_on =
       
   201 fixes top_on :: "vname set \<Rightarrow> 'a \<Rightarrow> bool"
       
   202 
       
   203 instantiation st :: (top)top_on
       
   204 begin
       
   205 
       
   206 fun top_on_st :: "vname set \<Rightarrow> 'a st \<Rightarrow> bool" where
       
   207 "top_on_st X F = (\<forall>x\<in>X. fun F x = \<top>)"
       
   208 
       
   209 instance ..
       
   210 
       
   211 end
       
   212 
       
   213 instantiation option :: (top_on)top_on
       
   214 begin
       
   215 
       
   216 fun top_on_option :: "vname set \<Rightarrow> 'a option \<Rightarrow> bool" where
       
   217 "top_on_option X (Some F) = top_on X F" |
       
   218 "top_on_option X None = True"
       
   219 
       
   220 instance ..
       
   221 
       
   222 end
       
   223 
       
   224 instantiation acom :: (top_on)top_on
       
   225 begin
       
   226 
       
   227 definition top_on_acom :: "vname set \<Rightarrow> 'a acom \<Rightarrow> bool" where
       
   228 "top_on_acom X C = (\<forall>a \<in> set(annos C). top_on X a)"
       
   229 
       
   230 instance ..
       
   231 
       
   232 end
       
   233 
       
   234 lemma top_on_top: "top_on X (\<top>::_ st option)"
       
   235 by(auto simp: top_option_def fun_top)
       
   236 
       
   237 lemma top_on_bot: "top_on X (bot c)"
       
   238 by(auto simp add: top_on_acom_def bot_def)
       
   239 
       
   240 lemma top_on_post: "top_on X C \<Longrightarrow> top_on X (post C)"
       
   241 by(simp add: top_on_acom_def post_in_annos)
       
   242 
       
   243 lemma top_on_acom_simps:
       
   244   "top_on X (SKIP {Q}) = top_on X Q"
       
   245   "top_on X (x ::= e {Q}) = top_on X Q"
       
   246   "top_on X (C1;C2) = (top_on X C1 \<and> top_on X C2)"
       
   247   "top_on X (IF b THEN {P1} C1 ELSE {P2} C2 {Q}) =
       
   248    (top_on X P1 \<and> top_on X C1 \<and> top_on X P2 \<and> top_on X C2 \<and> top_on X Q)"
       
   249   "top_on X ({I} WHILE b DO {P} C {Q}) =
       
   250    (top_on X I \<and> top_on X C \<and> top_on X P \<and> top_on X Q)"
       
   251 by(auto simp add: top_on_acom_def)
       
   252 
       
   253 lemma top_on_sup:
       
   254   "top_on X o1 \<Longrightarrow> top_on X o2 \<Longrightarrow> top_on X (o1 \<squnion> o2 :: _ st option)"
       
   255 apply(induction o1 o2 rule: sup_option.induct)
       
   256 apply(auto)
       
   257 by transfer simp
       
   258 
       
   259 lemma top_on_Step: fixes C :: "('a::semilattice)st option acom"
       
   260 assumes "!!x e S. \<lbrakk>top_on X S; x \<notin> X; vars e \<subseteq> -X\<rbrakk> \<Longrightarrow> top_on X (f x e S)"
       
   261         "!!b S. top_on X S \<Longrightarrow> vars b \<subseteq> -X \<Longrightarrow> top_on X (g b S)"
       
   262 shows "\<lbrakk> vars C \<subseteq> -X; top_on X S; top_on X C \<rbrakk> \<Longrightarrow> top_on X (Step f g S C)"
       
   263 proof(induction C arbitrary: S)
       
   264 qed (auto simp: top_on_acom_simps vars_acom_def top_on_post top_on_sup assms)
       
   265 
       
   266 
   237 locale Measure = Measure1 +
   267 locale Measure = Measure1 +
   238 assumes m2: "x < y \<Longrightarrow> m x > m y"
   268 assumes m2: "x < y \<Longrightarrow> m x > m y"
   239 begin
   269 begin
   240 
   270 
   241 lemma m1: "x \<le> y \<Longrightarrow> m x \<ge> m y"
   271 lemma m1: "x \<le> y \<Longrightarrow> m x \<ge> m y"
   242 by(auto simp: le_less m2)
   272 by(auto simp: le_less m2)
   243 
   273 
   244 lemma m_s2: "finite(dom S1) \<Longrightarrow> S1 < S2 \<Longrightarrow> m_s S1 > m_s S2"
   274 lemma m_s2_rep: assumes "finite(X)" and "S1 = S2 on -X" and "\<forall>x. S1 x \<le> S2 x" and "S1 \<noteq> S2"
   245 proof(auto simp add: less_st_def less_eq_st_def m_s_def)
   275 shows "(\<Sum>x\<in>X. m (S2 x)) < (\<Sum>x\<in>X. m (S1 x))"
   246   assume "finite(dom S2)" and 0: "\<forall>x\<in>dom S2. fun S1 x \<le> fun S2 x"
   276 proof-
   247   hence 1: "\<forall>x\<in>dom S2. m(fun S1 x) \<ge> m(fun S2 x)" by (metis m1)
   277   from assms(3) have 1: "\<forall>x\<in>X. m(S1 x) \<ge> m(S2 x)" by (simp add: m1)
   248   fix x assume "x \<in> dom S2" "\<not> fun S2 x \<le> fun S1 x"
   278   from assms(2,3,4) have "EX x:X. S1 x < S2 x"
   249   hence 2: "\<exists>x\<in>dom S2. m(fun S1 x) > m(fun S2 x)" by (metis 0 m2 less_le_not_le)
   279     by(simp add: fun_eq_iff) (metis Compl_iff le_neq_trans)
   250   from setsum_strict_mono_ex1[OF `finite(dom S2)` 1 2]
   280   hence 2: "\<exists>x\<in>X. m(S1 x) > m(S2 x)" by (metis m2)
   251   show "(\<Sum>x\<in>dom S2. m (fun S2 x)) < (\<Sum>x\<in>dom S2. m (fun S1 x))" .
   281   from setsum_strict_mono_ex1[OF `finite X` 1 2]
   252 qed
   282   show "(\<Sum>x\<in>X. m (S2 x)) < (\<Sum>x\<in>X. m (S1 x))" .
   253 
   283 qed
   254 lemma m_o2: "finite X \<Longrightarrow> o1 \<in> L X \<Longrightarrow> o2 \<in> L X \<Longrightarrow>
   284 
   255   o1 < o2 \<Longrightarrow> m_o (card X) o1 > m_o (card X) o2"
   285 lemma m_s2: "finite(X) \<Longrightarrow> fun S1 = fun S2 on -X \<Longrightarrow> S1 < S2 \<Longrightarrow> m_s X S1 > m_s X S2"
       
   286 apply(auto simp add: less_st_def m_s_def)
       
   287 apply (transfer fixing: m)
       
   288 apply(simp add: less_eq_st_rep_iff eq_st_def m_s2_rep)
       
   289 done
       
   290 
       
   291 lemma m_o2: "finite X \<Longrightarrow> top_on (-X) o1 \<Longrightarrow> top_on (-X) o2 \<Longrightarrow>
       
   292   o1 < o2 \<Longrightarrow> m_o X o1 > m_o X o2"
   256 proof(induction o1 o2 rule: less_eq_option.induct)
   293 proof(induction o1 o2 rule: less_eq_option.induct)
   257   case 1 thus ?case by (auto simp: m_o_def L_st_def m_s2 less_option_def)
   294   case 1 thus ?case by (auto simp: m_o_def m_s2 less_option_def)
   258 next
   295 next
   259   case 2 thus ?case by(auto simp: m_o_def less_option_def le_imp_less_Suc m_s_h)
   296   case 2 thus ?case by(auto simp: m_o_def less_option_def le_imp_less_Suc m_s_h)
   260 next
   297 next
   261   case 3 thus ?case by (auto simp: less_option_def)
   298   case 3 thus ?case by (auto simp: less_option_def)
   262 qed
   299 qed
   263 
   300 
   264 lemma m_o1: "finite X \<Longrightarrow> o1 \<in> L X \<Longrightarrow> o2 \<in> L X \<Longrightarrow>
   301 lemma m_o1: "finite X \<Longrightarrow> top_on (-X) o1 \<Longrightarrow> top_on (-X) o2 \<Longrightarrow>
   265   o1 \<le> o2 \<Longrightarrow> m_o (card X) o1 \<ge> m_o (card X) o2"
   302   o1 \<le> o2 \<Longrightarrow> m_o X o1 \<ge> m_o X o2"
   266 by(auto simp: le_less m_o2)
   303 by(auto simp: le_less m_o2)
   267 
   304 
   268 lemma m_c2: "C1 \<in> L(vars(strip C1)) \<Longrightarrow> C2 \<in> L(vars(strip C2)) \<Longrightarrow>
   305 
       
   306 lemma m_c2: "top_on (-vars C1) C1 \<Longrightarrow> top_on (-vars C2) C2 \<Longrightarrow>
   269   C1 < C2 \<Longrightarrow> m_c C1 > m_c C2"
   307   C1 < C2 \<Longrightarrow> m_c C1 > m_c C2"
   270 proof(auto simp add: le_iff_le_annos m_c_def size_annos_same[of C1 C2] less_acom_def L_acom_def)
   308 proof(auto simp add: le_iff_le_annos m_c_def size_annos_same[of C1 C2] vars_acom_def less_acom_def)
   271   let ?X = "vars(strip C2)"
   309   let ?X = "vars(strip C2)"
   272   let ?n = "card ?X"
   310   assume top: "top_on (- vars(strip C2)) C1"  "top_on (- vars(strip C2)) C2"
   273   assume V1: "\<forall>a\<in>set(annos C1). a \<in> L ?X"
   311   and strip_eq: "strip C1 = strip C2"
   274     and V2: "\<forall>a\<in>set(annos C2). a \<in> L ?X"
   312   and 0: "\<forall>i<size(annos C2). annos C1 ! i \<le> annos C2 ! i"
   275     and strip_eq: "strip C1 = strip C2"
   313   hence 1: "\<forall>i<size(annos C2). m_o ?X (annos C1 ! i) \<ge> m_o ?X (annos C2 ! i)"
   276     and 0: "\<forall>i<size(annos C2). annos C1 ! i \<le> annos C2 ! i"
   314     apply (auto simp: all_set_conv_all_nth vars_acom_def top_on_acom_def)
   277   hence 1: "\<forall>i<size(annos C2). m_o ?n (annos C1 ! i) \<ge> m_o ?n (annos C2 ! i)"
   315     by (metis finite_cvars m_o1 size_annos_same2)
   278     by (auto simp: all_set_conv_all_nth)
   316   fix i assume i: "i < size(annos C2)" "\<not> annos C2 ! i \<le> annos C1 ! i"
   279        (metis finite_cvars m_o1 size_annos_same2)
   317   have topo1: "top_on (- ?X) (annos C1 ! i)"
   280   fix i assume "i < size(annos C2)" "\<not> annos C2 ! i \<le> annos C1 ! i"
   318     using i(1) top(1) by(simp add: top_on_acom_def size_annos_same[OF strip_eq])
   281   hence "m_o ?n (annos C1 ! i) > m_o ?n (annos C2 ! i)" (is "?P i")
   319   have topo2: "top_on (- ?X) (annos C2 ! i)"
   282     by(metis m_o2[OF finite_cvars] V1 V2 nth_mem size_annos_same[OF strip_eq] 0 less_option_def)
   320     using i(1) top(2) by(simp add: top_on_acom_def size_annos_same[OF strip_eq])
       
   321   from i have "m_o ?X (annos C1 ! i) > m_o ?X (annos C2 ! i)" (is "?P i")
       
   322     by (metis 0 less_option_def m_o2[OF finite_cvars topo1] topo2)
   283   hence 2: "\<exists>i < size(annos C2). ?P i" using `i < size(annos C2)` by blast
   323   hence 2: "\<exists>i < size(annos C2). ?P i" using `i < size(annos C2)` by blast
   284   show "(\<Sum>i<size(annos C2). m_o ?n (annos C2 ! i))
   324   show "(\<Sum>i<size(annos C2). m_o ?X (annos C2 ! i))
   285          < (\<Sum>i<size(annos C2). m_o ?n (annos C1 ! i))"
   325          < (\<Sum>i<size(annos C2). m_o ?X (annos C1 ! i))"
   286     apply(rule setsum_strict_mono_ex1) using 1 2 by (auto)
   326     apply(rule setsum_strict_mono_ex1) using 1 2 by (auto)
   287 qed
   327 qed
   288 
   328 
   289 end
   329 end
       
   330 
   290 
   331 
   291 locale Abs_Int_measure =
   332 locale Abs_Int_measure =
   292   Abs_Int_mono where \<gamma>=\<gamma> + Measure where m=m
   333   Abs_Int_mono where \<gamma>=\<gamma> + Measure where m=m
   293   for \<gamma> :: "'av::semilattice \<Rightarrow> val set" and m :: "'av \<Rightarrow> nat"
   334   for \<gamma> :: "'av::semilattice \<Rightarrow> val set" and m :: "'av \<Rightarrow> nat"
   294 begin
   335 begin
   295 
   336 
       
   337 lemma top_on_step': "\<lbrakk> vars C \<subseteq> -X; top_on X C \<rbrakk> \<Longrightarrow> top_on X (step' \<top> C)"
       
   338 unfolding step'_def
       
   339 by(rule top_on_Step)
       
   340   (auto simp add: top_option_def fun_top split: option.splits)
       
   341 
   296 lemma AI_Some_measure: "\<exists>C. AI c = Some C"
   342 lemma AI_Some_measure: "\<exists>C. AI c = Some C"
   297 unfolding AI_def
   343 unfolding AI_def
   298 apply(rule pfp_termination[where I = "\<lambda>C. strip C = c \<and> C \<in> L(vars c)" and m="m_c"])
   344 apply(rule pfp_termination[where I = "\<lambda>C. strip C = c \<and> top_on (- vars C) C" and m="m_c"])
   299 apply(simp_all add: m_c2 mono_step'_top bot_least)
   345 apply(simp_all add: m_c2 mono_step'_top bot_least top_on_bot)
       
   346 apply(auto simp add: top_on_step' vars_acom_def)
   300 done
   347 done
   301 
   348 
   302 end
   349 end
   303 
   350 
   304 end
   351 end