src/HOL/IMP/Abs_Int0.thy
changeset 45623 f682f3f7b726
parent 45127 d2eb07a1e01b
child 45655 a49f9428aba4
equal deleted inserted replaced
45622:4334c91b7405 45623:f682f3f7b726
     4 imports Abs_State
     4 imports Abs_State
     5 begin
     5 begin
     6 
     6 
     7 subsection "Computable Abstract Interpretation"
     7 subsection "Computable Abstract Interpretation"
     8 
     8 
     9 text{* Abstract interpretation over type @{text astate} instead of
     9 text{* Abstract interpretation over type @{text st} instead of
    10 functions. *}
    10 functions. *}
    11 
    11 
    12 locale Abs_Int = Val_abs
    12 context Val_abs
    13 begin
    13 begin
    14 
    14 
    15 fun aval' :: "aexp \<Rightarrow> 'a st \<Rightarrow> 'a" where
    15 fun aval' :: "aexp \<Rightarrow> 'a st \<Rightarrow> 'a" where
    16 "aval' (N n) _ = num' n" |
    16 "aval' (N n) _ = num' n" |
    17 "aval' (V x) S = lookup S x" |
    17 "aval' (V x) S = lookup S x" |
    18 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)"
    18 "aval' (Plus a1 a2) S = plus' (aval' a1 S) (aval' a2 S)"
    19 
    19 
    20 fun step :: "'a st up \<Rightarrow> 'a st up acom \<Rightarrow> 'a st up acom" where
    20 lemma aval'_sound: "s : \<gamma>\<^isub>f S \<Longrightarrow> aval a s : \<gamma>(aval' a S)"
       
    21 by (induct a) (auto simp: rep_num' rep_plus' rep_st_def lookup_def)
       
    22 
       
    23 end
       
    24 
       
    25 locale Abs_Int = Val_abs
       
    26 begin
       
    27 
       
    28 fun step :: "'a st option \<Rightarrow> 'a st option acom \<Rightarrow> 'a st option acom" where
    21 "step S (SKIP {P}) = (SKIP {S})" |
    29 "step S (SKIP {P}) = (SKIP {S})" |
    22 "step S (x ::= e {P}) =
    30 "step S (x ::= e {P}) =
    23   x ::= e {case S of Bot \<Rightarrow> Bot | Up S \<Rightarrow> Up(update S x (aval' e S))}" |
    31   x ::= e {case S of None \<Rightarrow> None | Some S \<Rightarrow> Some(update S x (aval' e S))}" |
    24 "step S (c1; c2) = step S c1; step (post c1) c2" |
    32 "step S (c1; c2) = step S c1; step (post c1) c2" |
    25 "step S (IF b THEN c1 ELSE c2 {P}) =
    33 "step S (IF b THEN c1 ELSE c2 {P}) =
    26   (let c1' = step S c1; c2' = step S c2
    34   (let c1' = step S c1; c2' = step S c2
    27    in IF b THEN c1' ELSE c2' {post c1 \<squnion> post c2})" |
    35    in IF b THEN c1' ELSE c2' {post c1 \<squnion> post c2})" |
    28 "step S ({Inv} WHILE b DO c {P}) =
    36 "step S ({Inv} WHILE b DO c {P}) =
    29    {S \<squnion> post c} WHILE b DO step Inv c {Inv}"
    37    {S \<squnion> post c} WHILE b DO step Inv c {Inv}"
    30 
    38 
    31 definition AI :: "com \<Rightarrow> 'a st up acom option" where
    39 definition AI :: "com \<Rightarrow> 'a st option acom option" where
    32 "AI = lpfp\<^isub>c (step \<top>)"
    40 "AI = lpfp\<^isub>c (step \<top>)"
    33 
    41 
    34 
    42 
    35 lemma strip_step[simp]: "strip(step S c) = strip c"
    43 lemma strip_step[simp]: "strip(step S c) = strip c"
    36 by(induct c arbitrary: S) (simp_all add: Let_def)
    44 by(induct c arbitrary: S) (simp_all add: Let_def)
    37 
    45 
    38 
    46 
    39 text{* Soundness: *}
    47 text{* Soundness: *}
    40 
    48 
    41 lemma aval'_sound: "s <:f S \<Longrightarrow> aval a s <: aval' a S"
    49 lemma in_rep_update:
    42 by (induct a) (auto simp: rep_num' rep_plus' rep_st_def lookup_def)
    50   "\<lbrakk> s : \<gamma>\<^isub>f S; i : \<gamma> a \<rbrakk> \<Longrightarrow> s(x := i) : \<gamma>\<^isub>f(update S x a)"
    43 
       
    44 lemma in_rep_update: "\<lbrakk> s <:f S; i <: a \<rbrakk> \<Longrightarrow> s(x := i) <:f update S x a"
       
    45 by(simp add: rep_st_def lookup_update)
    51 by(simp add: rep_st_def lookup_update)
    46 
    52 
    47 lemma step_sound:
    53 text{* The soundness proofs are textually identical to the ones for the step
    48   "step S c \<sqsubseteq> c \<Longrightarrow> (strip c,s) \<Rightarrow> t \<Longrightarrow> s <:up S \<Longrightarrow> t <:up post c"
    54 function operating on states as functions. *}
    49 proof(induction c arbitrary: S s t)
    55 
       
    56 lemma step_preserves_le2:
       
    57   "\<lbrakk> S \<subseteq> \<gamma>\<^isub>u sa; cs \<le> \<gamma>\<^isub>c ca; strip cs = c; strip ca = c \<rbrakk>
       
    58    \<Longrightarrow> step_cs S cs \<le> \<gamma>\<^isub>c (step sa ca)"
       
    59 proof(induction c arbitrary: cs ca S sa)
    50   case SKIP thus ?case
    60   case SKIP thus ?case
    51     by simp (metis skipE up_fun_in_rep_le)
    61     by(auto simp:strip_eq_SKIP)
    52 next
    62 next
    53   case Assign thus ?case
    63   case Assign thus ?case
    54     apply (auto simp del: fun_upd_apply simp: split: up.splits)
    64     by (fastforce simp: strip_eq_Assign intro: aval'_sound in_rep_update
    55     by (metis aval'_sound fun_in_rep_le in_rep_update)
    65       split: option.splits del:subsetD)
    56 next
    66 next
    57   case Semi thus ?case by simp blast
    67   case Semi thus ?case apply (auto simp: strip_eq_Semi)
       
    68     by (metis le_post post_map_acom)
    58 next
    69 next
    59   case (If b c1 c2 S0) thus ?case
    70   case (If b c1 c2)
    60     apply(auto simp: Let_def)
    71   then obtain cs1 cs2 ca1 ca2 P Pa where
    61     apply (metis up_fun_in_rep_le)+
    72       "cs = IF b THEN cs1 ELSE cs2 {P}" "ca = IF b THEN ca1 ELSE ca2 {Pa}"
    62     done
    73       "P \<subseteq> \<gamma>\<^isub>u Pa" "cs1 \<le> \<gamma>\<^isub>c ca1" "cs2 \<le> \<gamma>\<^isub>c ca2"
       
    74       "strip cs1 = c1" "strip ca1 = c1" "strip cs2 = c2" "strip ca2 = c2"
       
    75     by (fastforce simp: strip_eq_If)
       
    76   moreover have "post cs1 \<subseteq> \<gamma>\<^isub>u(post ca1 \<squnion> post ca2)"
       
    77     by (metis (no_types) `cs1 \<le> \<gamma>\<^isub>c ca1` join_ge1 le_post mono_rep_u order_trans post_map_acom)
       
    78   moreover have "post cs2 \<subseteq> \<gamma>\<^isub>u(post ca1 \<squnion> post ca2)"
       
    79     by (metis (no_types) `cs2 \<le> \<gamma>\<^isub>c ca2` join_ge2 le_post mono_rep_u order_trans post_map_acom)
       
    80   ultimately show ?case using If.prems(1) by (simp add: If.IH subset_iff)
    63 next
    81 next
    64   case (While Inv b c P)
    82   case (While b c1)
    65   from While.prems have inv: "step Inv c \<sqsubseteq> c"
    83   then obtain cs1 ca1 I P Ia Pa where
    66     and "post c \<sqsubseteq> Inv" and "S \<sqsubseteq> Inv" and "Inv \<sqsubseteq> P" by(auto simp: Let_def)
    84     "cs = {I} WHILE b DO cs1 {P}" "ca = {Ia} WHILE b DO ca1 {Pa}"
    67   { fix s t have "(WHILE b DO strip c,s) \<Rightarrow> t \<Longrightarrow> s <:up Inv \<Longrightarrow> t <:up Inv"
    85     "I \<subseteq> \<gamma>\<^isub>u Ia" "P \<subseteq> \<gamma>\<^isub>u Pa" "cs1 \<le> \<gamma>\<^isub>c ca1"
    68     proof(induction "WHILE b DO strip c" s t rule: big_step_induct)
    86     "strip cs1 = c1" "strip ca1 = c1"
    69       case WhileFalse thus ?case by simp
    87     by (fastforce simp: strip_eq_While)
    70     next
    88   moreover have "S \<union> post cs1 \<subseteq> \<gamma>\<^isub>u (sa \<squnion> post ca1)"
    71       case (WhileTrue s1 s2 s3)
    89     using `S \<subseteq> \<gamma>\<^isub>u sa` le_post[OF `cs1 \<le> \<gamma>\<^isub>c ca1`, simplified]
    72       from WhileTrue.hyps(5)[OF up_fun_in_rep_le[OF While.IH[OF inv `(strip c, s1) \<Rightarrow> s2` `s1 <:up Inv`] `post c \<sqsubseteq> Inv`]]
    90     by (metis (no_types) join_ge1 join_ge2 le_sup_iff mono_rep_u order_trans)
    73       show ?case .
    91   ultimately show ?case by (simp add: While.IH subset_iff)
    74     qed
       
    75   }
       
    76   thus ?case using While.prems(2)
       
    77     by simp (metis `s <:up S` `S \<sqsubseteq> Inv` `Inv \<sqsubseteq> P` up_fun_in_rep_le)
       
    78 qed
    92 qed
    79 
    93 
    80 lemma AI_sound: "\<lbrakk> AI c = Some c';  (c,s) \<Rightarrow> t \<rbrakk> \<Longrightarrow> t <:up post c'"
    94 lemma step_preserves_le:
    81 by (metis AI_def in_rep_Top_up lpfpc_pfp step_sound strip_lpfpc strip_step)
    95   "\<lbrakk> S \<subseteq> \<gamma>\<^isub>u sa; cs \<le> \<gamma>\<^isub>c ca; strip cs = c \<rbrakk>
       
    96    \<Longrightarrow> step_cs S cs \<le> \<gamma>\<^isub>c(step sa ca)"
       
    97 by (metis le_strip step_preserves_le2 strip_acom)
       
    98 
       
    99 lemma AI_sound: "AI c = Some c' \<Longrightarrow> CS UNIV c \<le> \<gamma>\<^isub>c c'"
       
   100 proof(simp add: CS_def AI_def)
       
   101   assume 1: "lpfp\<^isub>c (step \<top>) c = Some c'"
       
   102   have 2: "step \<top> c' \<sqsubseteq> c'" by(rule lpfpc_pfp[OF 1])
       
   103   have 3: "strip (\<gamma>\<^isub>c (step \<top> c')) = c"
       
   104     by(simp add: strip_lpfpc[OF _ 1])
       
   105   have "lfp c (step_cs UNIV) \<le> \<gamma>\<^isub>c (step \<top> c')"
       
   106   proof(rule lfp_lowerbound[OF 3])
       
   107     show "step_cs UNIV (\<gamma>\<^isub>c (step \<top> c')) \<le> \<gamma>\<^isub>c (step \<top> c')"
       
   108     proof(rule step_preserves_le[OF _ _ 3])
       
   109       show "UNIV \<subseteq> \<gamma>\<^isub>u \<top>" by simp
       
   110       show "\<gamma>\<^isub>c (step \<top> c') \<le> \<gamma>\<^isub>c c'" by(rule mono_rep_c[OF 2])
       
   111     qed
       
   112   qed
       
   113   from this 2 show "lfp c (step_cs UNIV) \<le> \<gamma>\<^isub>c c'"
       
   114     by (blast intro: mono_rep_c order_trans)
       
   115 qed
    82 
   116 
    83 end
   117 end
    84 
   118 
    85 
   119 
    86 subsubsection "Monotonicity"
   120 subsubsection "Monotonicity"
    95 lemma mono_update: "a \<sqsubseteq> a' \<Longrightarrow> S \<sqsubseteq> S' \<Longrightarrow> update S x a \<sqsubseteq> update S' x a'"
   129 lemma mono_update: "a \<sqsubseteq> a' \<Longrightarrow> S \<sqsubseteq> S' \<Longrightarrow> update S x a \<sqsubseteq> update S' x a'"
    96 by(auto simp add: le_st_def lookup_def update_def)
   130 by(auto simp add: le_st_def lookup_def update_def)
    97 
   131 
    98 lemma step_mono: "S \<sqsubseteq> S' \<Longrightarrow> step S c \<sqsubseteq> step S' c"
   132 lemma step_mono: "S \<sqsubseteq> S' \<Longrightarrow> step S c \<sqsubseteq> step S' c"
    99 apply(induction c arbitrary: S S')
   133 apply(induction c arbitrary: S S')
   100 apply (auto simp: Let_def mono_update mono_aval' le_join_disj split: up.split)
   134 apply (auto simp: Let_def mono_update mono_aval' le_join_disj split: option.split)
   101 done
   135 done
   102 
   136 
   103 end
   137 end
   104 
   138 
   105 end
   139 end