src/HOL/IMP/Collecting1.thy
changeset 45623 f682f3f7b726
child 45655 a49f9428aba4
equal deleted inserted replaced
45622:4334c91b7405 45623:f682f3f7b726
       
     1 theory Collecting1
       
     2 imports Collecting
       
     3 begin
       
     4 
       
     5 subsection "A small step semantics on annotated commands"
       
     6 
       
     7 text{* The idea: the state is propagated through the annotated command as an
       
     8 annotation @{term "Some s"}, all other annotations are @{const None}. *}
       
     9 
       
    10 fun join :: "'a option \<Rightarrow> 'a option \<Rightarrow> 'a option" where
       
    11 "join None x = x" |
       
    12 "join x None = x"
       
    13 
       
    14 definition bfilter :: "bexp \<Rightarrow> bool \<Rightarrow> state option \<Rightarrow> state option" where
       
    15 "bfilter b r so =
       
    16   (case so of None \<Rightarrow> None | Some s \<Rightarrow> if bval b s = r then Some s else None)"
       
    17 
       
    18 lemma bfilter_None[simp]: "bfilter b r None = None"
       
    19 by(simp add: bfilter_def split: option.split)
       
    20 
       
    21 fun step1 :: "state option \<Rightarrow> state option acom \<Rightarrow> state option acom" where
       
    22 "step1 so (SKIP {P}) = SKIP {so}" |
       
    23 "step1 so (x::=e {P}) =
       
    24   x ::= e {case so of None \<Rightarrow> None | Some s \<Rightarrow> Some(s(x := aval e s))}" |
       
    25 "step1 so (c1;c2) = step1 so c1; step1 (post c1) c2" |
       
    26 "step1 so (IF b THEN c1 ELSE c2 {P}) =
       
    27   IF b THEN step1 (bfilter b True so) c1
       
    28   ELSE step1 (bfilter b False so) c2
       
    29   {join (post c1) (post c2)}" |
       
    30 "step1 so ({I} WHILE b DO c {P}) =
       
    31   {join so (post c)}
       
    32   WHILE b DO step1 (bfilter b True I) c
       
    33   {bfilter b False I}"
       
    34 
       
    35 definition "show_acom xs = map_acom (Option.map (show_state xs))"
       
    36 
       
    37 definition
       
    38  "p1 = ''x'' ::= N 2; IF Less (V ''x'') (N 3) THEN ''x'' ::= N 1 ELSE com.SKIP"
       
    39 
       
    40 definition "p2 =
       
    41  ''x'' ::= N 0; WHILE Less (V ''x'') (N 2) DO ''x'' ::= Plus (V ''x'') (N 1)"
       
    42 
       
    43 value "show_acom [''x'']
       
    44  (((step1 None)^^6) (step1 (Some <>) (anno None p2)))"
       
    45 
       
    46 subsubsection "Relating the small step and the collecting semantics"
       
    47 
       
    48 hide_const (open) set
       
    49 
       
    50 abbreviation set :: "'a option acom \<Rightarrow> 'a set acom" where
       
    51 "set == map_acom Option.set"
       
    52 
       
    53 definition some :: "'a option \<Rightarrow> nat" where
       
    54 "some opt = (case opt of Some x \<Rightarrow> 1 | None \<Rightarrow> 0)"
       
    55 
       
    56 lemma some[simp]: "some None = 0 \<and> some (Some x) = 1"
       
    57 by(simp add: some_def split:option.split)
       
    58 
       
    59 fun somes :: "'a option acom \<Rightarrow> nat" where
       
    60 "somes(SKIP {p}) = some p" |
       
    61 "somes(x::=e {p}) = some p" |
       
    62 "somes(c1;c2) = somes c1 + somes c2" |
       
    63 "somes(IF b THEN c1 ELSE c2 {p}) = somes c1 + somes c2 + some p" |
       
    64 "somes({i} WHILE b DO c {p}) = some i + somes c + some p"
       
    65 
       
    66 lemma some_anno_None: "somes(anno None c) = 0"
       
    67 by(induction c) auto
       
    68 
       
    69 lemma some_post: "some(post co) \<le> somes co"
       
    70 by(induction co) auto
       
    71 
       
    72 lemma some_join:
       
    73   "some so1 + some so2 \<le> 1 \<Longrightarrow> some(join so1 so2) = some so1 + some so2"
       
    74 by(simp add: some_def split: option.splits)
       
    75 
       
    76 lemma somes_step1: "some so + somes co \<le> 1 \<Longrightarrow>
       
    77  somes(step1 so co) + some(post co) = some so + somes co"
       
    78 proof(induction co arbitrary: so)
       
    79   case SKIP thus ?case by simp
       
    80 next
       
    81   case Assign thus ?case by (simp split:option.split)
       
    82 next
       
    83   case (Semi co1 _)
       
    84   from Semi.prems Semi.IH(1)[of so] Semi.IH(2)[of "post co1"]
       
    85   show ?case by simp
       
    86 next
       
    87   case (If b)
       
    88   from If.prems If.IH(1)[of "bfilter b True so"]
       
    89        If.prems If.IH(2)[of "bfilter b False so"]
       
    90   show ?case
       
    91     by (auto simp: bfilter_def some_join split:option.split)
       
    92 next
       
    93   case (While i b c p)
       
    94   from While.prems While.IH[of "bfilter b True i"]
       
    95   show ?case
       
    96     by(auto simp: bfilter_def some_join split:option.split)
       
    97 qed
       
    98 
       
    99 lemma post_map_acom[simp]: "post(map_acom f c) = f(post c)"
       
   100 by(induction c) auto
       
   101 
       
   102 lemma join_eq_Some: "some so1 + some so2 \<le> 1 \<Longrightarrow>
       
   103   join so1 so2 = Some s =
       
   104  (so1 = Some s & so2 = None | so1 = None & so2 = Some s)"
       
   105 apply(cases so1) apply simp
       
   106 apply(cases so2) apply auto
       
   107 done
       
   108 
       
   109 lemma set_bfilter:
       
   110   "Option.set (bfilter b r so) = {s : Option.set so. bval b s = r}"
       
   111 by(auto simp: bfilter_def split: option.splits)
       
   112 
       
   113 lemma set_join:  "some so1 + some so2 \<le> 1 \<Longrightarrow>
       
   114   Option.set (join so1 so2) = Option.set so1 \<union> Option.set so2"
       
   115 apply(cases so1) apply simp
       
   116 apply(cases so2) apply auto
       
   117 done
       
   118 
       
   119 lemma add_le1_iff: "m + n \<le> (Suc 0) \<longleftrightarrow> (m=0 \<and> n\<le>1 | m\<le>1 & n=0)"
       
   120 by arith
       
   121 
       
   122 lemma some_0_iff: "some opt = 0 \<longleftrightarrow> opt = None"
       
   123 by(auto simp add: some_def split: option.splits)
       
   124 
       
   125 lemma some_le1[simp]: "some x \<le> Suc 0"
       
   126 by(auto simp add: some_def split: option.splits)
       
   127 
       
   128 lemma step1_preserves_le:
       
   129   "\<lbrakk> step_cs S cs = cs; Option.set so \<subseteq> S; set co \<le> cs;
       
   130     somes co + some so \<le> 1 \<rbrakk> \<Longrightarrow>
       
   131   set(step1 so co) \<le> cs"
       
   132 proof(induction co arbitrary: S cs so)
       
   133   case SKIP thus ?case by (clarsimp simp: SKIP_le)
       
   134 next
       
   135   case Assign thus ?case by (fastforce simp: Assign_le split: option.splits)
       
   136 next
       
   137   case (Semi co1 co2)
       
   138   from Semi.prems show ?case using some_post[of co1]
       
   139     by (fastforce simp add: Semi_le add_le1_iff Semi.IH dest: le_post)
       
   140 next
       
   141   case (If _ co1 co2)
       
   142   from If.prems show ?case
       
   143     using some_post[of co1] some_post[of co2]
       
   144     by (fastforce simp: If_le add_le1_iff some_0_iff set_bfilter subset_iff
       
   145       join_eq_Some If.IH dest: le_post)
       
   146 next
       
   147   case (While _ _ co)
       
   148   from While.prems show ?case
       
   149     using some_post[of co]
       
   150     by (fastforce simp: While_le set_bfilter subset_iff join_eq_Some
       
   151       add_le1_iff some_0_iff While.IH dest: le_post)
       
   152 qed
       
   153 
       
   154 lemma step1_None_preserves_le:
       
   155   "\<lbrakk> step_cs S cs = cs; set co \<le> cs; somes co \<le> 1 \<rbrakk> \<Longrightarrow>
       
   156   set(step1 None co) \<le> cs"
       
   157 by(auto dest: step1_preserves_le[of _ _ None])
       
   158 
       
   159 lemma step1_Some_preserves_le:
       
   160   "\<lbrakk> step_cs S cs = cs; s : S; set co \<le> cs; somes co = 0 \<rbrakk> \<Longrightarrow>
       
   161   set(step1 (Some s) co) \<le> cs"
       
   162 by(auto dest: step1_preserves_le[of _ _ "Some s"])
       
   163 
       
   164 lemma steps_None_preserves_le: assumes "step_cs S cs = cs"
       
   165 shows "set co \<le> cs \<Longrightarrow> somes co \<le> 1 \<Longrightarrow> set ((step1 None ^^ n) co) \<le> cs"
       
   166 proof(induction n arbitrary: co)
       
   167   case 0 thus ?case by simp
       
   168 next
       
   169   case (Suc n) thus ?case
       
   170     using somes_step1[of None co] step1_None_preserves_le[OF assms Suc.prems]
       
   171     by(simp add:funpow_swap1 Suc.IH)
       
   172 qed
       
   173 
       
   174 
       
   175 definition steps :: "state \<Rightarrow> com \<Rightarrow> nat \<Rightarrow> state option acom" where
       
   176 "steps s c n = ((step1 None)^^n) (step1 (Some s) (anno None c))"
       
   177 
       
   178 lemma steps_approx_fix_step_cs: assumes "step_cs S cs = cs" and "s:S"
       
   179 shows "set (steps s (strip cs) n) \<le> cs"
       
   180 proof-
       
   181   { fix c have "somes (anno None c) = 0" by(induction c) auto }
       
   182   note somes_None = this
       
   183   let ?cNone = "anno None (strip cs)"
       
   184   have "set ?cNone \<le> cs" by(induction cs) auto
       
   185   from step1_Some_preserves_le[OF assms this somes_None]
       
   186   have 1: "set(step1 (Some s) ?cNone) \<le> cs" .
       
   187   have 2: "somes (step1 (Some s) ?cNone) \<le> 1"
       
   188     using some_post somes_step1[of "Some s" ?cNone]
       
   189     by (simp add:some_anno_None[of "strip cs"])
       
   190   from steps_None_preserves_le[OF assms(1) 1 2]
       
   191   show ?thesis by(simp add: steps_def)
       
   192 qed
       
   193 
       
   194 theorem steps_approx_CS: "s:S \<Longrightarrow> set (steps s c n) \<le> CS S c"
       
   195 by (metis CS_unfold steps_approx_fix_step_cs strip_CS)
       
   196 
       
   197 lemma While_final_False: "(WHILE b DO c, s) \<Rightarrow> t \<Longrightarrow> \<not> bval b t"
       
   198 by(induct "WHILE b DO c" s t rule: big_step_induct) simp_all
       
   199 
       
   200 lemma step_cs_complete:
       
   201   "\<lbrakk> step_cs S c = c; (strip c,s) \<Rightarrow> t; s:S \<rbrakk> \<Longrightarrow> t : post c"
       
   202 proof(induction c arbitrary: S s t)
       
   203   case (While Inv b c P)
       
   204   from While.prems have inv: "step_cs {s:Inv. bval b s} c = c"
       
   205     and "post c \<subseteq> Inv" and "S \<subseteq> Inv" and "{s:Inv. \<not> bval b s} \<subseteq> P"  by(auto)
       
   206   { fix s t have "(WHILE b DO strip c,s) \<Rightarrow> t \<Longrightarrow> s : Inv \<Longrightarrow> t : Inv"
       
   207     proof(induction "WHILE b DO strip c" s t rule: big_step_induct)
       
   208       case WhileFalse thus ?case by simp
       
   209     next
       
   210       case (WhileTrue s1 s2 s3)
       
   211       from WhileTrue.hyps(5) While.IH[OF inv `(strip c, s1) \<Rightarrow> s2`]
       
   212         `s1 : Inv` `post c \<subseteq> Inv` `bval b s1`
       
   213       show ?case by auto
       
   214     qed
       
   215   } note Inv = this
       
   216   from  While.prems(2) have "(WHILE b DO strip c, s) \<Rightarrow> t" and "\<not> bval b t"
       
   217     by(auto dest: While_final_False)
       
   218   from Inv[OF this(1)] `s : S` `S \<subseteq> Inv` have "t : Inv" by blast
       
   219   with `{s:Inv. \<not> bval b s} \<subseteq> P` show ?case using `\<not> bval b t` by auto
       
   220 qed auto
       
   221 
       
   222 theorem CS_complete: "\<lbrakk> (c,s) \<Rightarrow> t; s:S \<rbrakk> \<Longrightarrow> t : post(CS S c)"
       
   223 by (metis CS_unfold step_cs_complete strip_CS)
       
   224 
       
   225 end