src/HOL/IMP/HoareT.thy
changeset 52227 f9e68ba3f004
parent 52046 bc01725d7918
child 52228 ee8e3eaad24c
equal deleted inserted replaced
52226:0d3165844048 52227:f9e68ba3f004
    24 Assign:  "\<turnstile>\<^sub>t {\<lambda>s. P(s[a/x])} x::=a {P}" |
    24 Assign:  "\<turnstile>\<^sub>t {\<lambda>s. P(s[a/x])} x::=a {P}" |
    25 Seq: "\<lbrakk> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1 {P\<^isub>2}; \<turnstile>\<^sub>t {P\<^isub>2} c\<^isub>2 {P\<^isub>3} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1;;c\<^isub>2 {P\<^isub>3}" |
    25 Seq: "\<lbrakk> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1 {P\<^isub>2}; \<turnstile>\<^sub>t {P\<^isub>2} c\<^isub>2 {P\<^isub>3} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1;;c\<^isub>2 {P\<^isub>3}" |
    26 If: "\<lbrakk> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s} c\<^isub>1 {Q}; \<turnstile>\<^sub>t {\<lambda>s. P s \<and> \<not> bval b s} c\<^isub>2 {Q} \<rbrakk>
    26 If: "\<lbrakk> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s} c\<^isub>1 {Q}; \<turnstile>\<^sub>t {\<lambda>s. P s \<and> \<not> bval b s} c\<^isub>2 {Q} \<rbrakk>
    27   \<Longrightarrow> \<turnstile>\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}" |
    27   \<Longrightarrow> \<turnstile>\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}" |
    28 While:
    28 While:
    29   "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> f s = n} c {\<lambda>s. P s \<and> f s < n}\<rbrakk>
    29   "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T n s} c {\<lambda>s. P s \<and> (\<exists>n'. T n' s \<and> n' < n)} \<rbrakk>
    30    \<Longrightarrow> \<turnstile>\<^sub>t {P} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" |
    30    \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T n s)} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" |
    31 conseq: "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s; \<turnstile>\<^sub>t {P}c{Q}; \<forall>s. Q s \<longrightarrow> Q' s  \<rbrakk> \<Longrightarrow>
    31 conseq: "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s; \<turnstile>\<^sub>t {P}c{Q}; \<forall>s. Q s \<longrightarrow> Q' s  \<rbrakk> \<Longrightarrow>
    32            \<turnstile>\<^sub>t {P'}c{Q'}"
    32            \<turnstile>\<^sub>t {P'}c{Q'}"
    33 
    33 
    34 text{* The @{term While}-rule is like the one for partial correctness but it
    34 text{* The @{term While}-rule is like the one for partial correctness but it
    35 requires additionally that with every execution of the loop body some measure
    35 requires additionally that with every execution of the loop body some measure
    45 
    45 
    46 lemma Assign': "\<forall>s. P s \<longrightarrow> Q(s[a/x]) \<Longrightarrow> \<turnstile>\<^sub>t {P} x ::= a {Q}"
    46 lemma Assign': "\<forall>s. P s \<longrightarrow> Q(s[a/x]) \<Longrightarrow> \<turnstile>\<^sub>t {P} x ::= a {Q}"
    47 by (simp add: strengthen_pre[OF _ Assign])
    47 by (simp add: strengthen_pre[OF _ Assign])
    48 
    48 
    49 lemma While':
    49 lemma While':
    50 assumes "\<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> f s = n} c {\<lambda>s. P s \<and> f s < n}"
    50 assumes "\<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T n s} c {\<lambda>s. P s \<and> (\<exists>n'. T n' s \<and> n' < n)}"
    51     and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s"
    51     and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s"
    52 shows "\<turnstile>\<^sub>t {P} WHILE b DO c {Q}"
    52 shows "\<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T n s)} WHILE b DO c {Q}"
    53 by(blast intro: assms(1) weaken_post[OF While assms(2)])
    53 by(blast intro: assms(1) weaken_post[OF While assms(2)])
       
    54 
       
    55 lemma While_fun:
       
    56   "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> f s = n} c {\<lambda>s. P s \<and> f s < n}\<rbrakk>
       
    57    \<Longrightarrow> \<turnstile>\<^sub>t {P} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}"
       
    58   by (rule While [where T="\<lambda>n s. f s = n", simplified])
    54 
    59 
    55 text{* Our standard example: *}
    60 text{* Our standard example: *}
    56 
    61 
    57 abbreviation "w n ==
    62 abbreviation "w n ==
    58   WHILE Less (V ''y'') (N n)
    63   WHILE Less (V ''y'') (N n)
    61 lemma "\<turnstile>\<^sub>t {\<lambda>s. 0 \<le> n} ''x'' ::= N 0;; ''y'' ::= N 0;; w n {\<lambda>s. s ''x'' = \<Sum>{1..n}}"
    66 lemma "\<turnstile>\<^sub>t {\<lambda>s. 0 \<le> n} ''x'' ::= N 0;; ''y'' ::= N 0;; w n {\<lambda>s. s ''x'' = \<Sum>{1..n}}"
    62 apply(rule Seq)
    67 apply(rule Seq)
    63 prefer 2
    68 prefer 2
    64 apply(rule While'
    69 apply(rule While'
    65   [where P = "\<lambda>s. s ''x'' = \<Sum> {1..s ''y''} \<and> 0 \<le> s ''y'' \<and> s ''y'' \<le> n"
    70   [where P = "\<lambda>s. s ''x'' = \<Sum> {1..s ''y''} \<and> 0 \<le> s ''y'' \<and> s ''y'' \<le> n"
    66    and f = "\<lambda>s. nat (n - s ''y'')"])
    71    and T = "\<lambda>n' s. n' = nat (n - s ''y'')"])
    67 apply(rule Seq)
    72 apply(rule Seq)
    68 prefer 2
    73 prefer 2
    69 apply(rule Assign)
    74 apply(rule Assign)
    70 apply(rule Assign')
    75 apply(rule Assign')
    71 apply (simp add: atLeastAtMostPlus1_int_conv algebra_simps)
    76 apply (simp add: atLeastAtMostPlus1_int_conv algebra_simps)
    72 apply clarsimp
    77 apply clarsimp
    73 apply fastforce
       
    74 apply(rule Seq)
    78 apply(rule Seq)
    75 prefer 2
    79 prefer 2
    76 apply(rule Assign)
    80 apply(rule Assign)
    77 apply(rule Assign')
    81 apply(rule Assign')
    78 apply simp
    82 apply simp
    81 
    85 
    82 text{* The soundness theorem: *}
    86 text{* The soundness theorem: *}
    83 
    87 
    84 theorem hoaret_sound: "\<turnstile>\<^sub>t {P}c{Q}  \<Longrightarrow>  \<Turnstile>\<^sub>t {P}c{Q}"
    88 theorem hoaret_sound: "\<turnstile>\<^sub>t {P}c{Q}  \<Longrightarrow>  \<Turnstile>\<^sub>t {P}c{Q}"
    85 proof(unfold hoare_tvalid_def, induct rule: hoaret.induct)
    89 proof(unfold hoare_tvalid_def, induct rule: hoaret.induct)
    86   case (While P b f c)
    90   case (While P b T c)
    87   show ?case
    91   {
    88   proof
    92     fix s n
    89     fix s
    93     have "\<lbrakk> P s; T n s \<rbrakk> \<Longrightarrow> \<exists>t. (WHILE b DO c, s) \<Rightarrow> t \<and> P t \<and> \<not> bval b t"
    90     show "P s \<longrightarrow> (\<exists>t. (WHILE b DO c, s) \<Rightarrow> t \<and> P t \<and> \<not> bval b t)"
    94     proof(induction "n" arbitrary: s rule: less_induct)
    91     proof(induction "f s" arbitrary: s rule: less_induct)
       
    92       case (less n)
    95       case (less n)
    93       thus ?case by (metis While(2) WhileFalse WhileTrue)
    96       thus ?case by (metis While(2) WhileFalse WhileTrue)
    94     qed
    97     qed
    95   qed
    98   }
       
    99   thus ?case by auto
    96 next
   100 next
    97   case If thus ?case by auto blast
   101   case If thus ?case by auto blast
    98 qed fastforce+
   102 qed fastforce+
    99 
   103 
   100 
   104 
   136 
   140 
   137 text{* The relation is in fact a function: *}
   141 text{* The relation is in fact a function: *}
   138 
   142 
   139 lemma Its_fun: "Its b c s n \<Longrightarrow> Its b c s n' \<Longrightarrow> n=n'"
   143 lemma Its_fun: "Its b c s n \<Longrightarrow> Its b c s n' \<Longrightarrow> n=n'"
   140 proof(induction arbitrary: n' rule:Its.induct)
   144 proof(induction arbitrary: n' rule:Its.induct)
   141 (* new release:
       
   142   case Its_0 thus ?case by(metis Its.cases)
   145   case Its_0 thus ?case by(metis Its.cases)
   143 next
   146 next
   144   case Its_Suc thus ?case by(metis Its.cases big_step_determ)
   147   case Its_Suc thus ?case by(metis Its.cases big_step_determ)
   145 qed
       
   146 *)
       
   147   case Its_0
       
   148   from this(1) Its.cases[OF this(2)] show ?case by metis
       
   149 next
       
   150   case (Its_Suc b s c s' n n')
       
   151   note C = this
       
   152   from this(5) show ?case
       
   153   proof cases
       
   154     case Its_0 with Its_Suc(1) show ?thesis by blast
       
   155   next
       
   156     case Its_Suc with C show ?thesis by(metis big_step_determ)
       
   157   qed
       
   158 qed
   148 qed
   159 
   149 
   160 text{* For all terminating loops, @{const Its} yields a result: *}
   150 text{* For all terminating loops, @{const Its} yields a result: *}
   161 
   151 
   162 lemma WHILE_Its: "(WHILE b DO c,s) \<Rightarrow> t \<Longrightarrow> \<exists>n. Its b c s n"
   152 lemma WHILE_Its: "(WHILE b DO c,s) \<Rightarrow> t \<Longrightarrow> \<exists>n. Its b c s n"
   164   case WhileFalse thus ?case by (metis Its_0)
   154   case WhileFalse thus ?case by (metis Its_0)
   165 next
   155 next
   166   case WhileTrue thus ?case by (metis Its_Suc)
   156   case WhileTrue thus ?case by (metis Its_Suc)
   167 qed
   157 qed
   168 
   158 
   169 text{* Now the relation is turned into a function with the help of
       
   170 the description operator @{text THE}: *}
       
   171 
       
   172 definition its :: "bexp \<Rightarrow> com \<Rightarrow> state \<Rightarrow> nat" where
       
   173 "its b c s = (THE n. Its b c s n)"
       
   174 
       
   175 text{* The key property: every loop iteration increases @{const its} by 1. *}
       
   176 
       
   177 lemma its_Suc: "\<lbrakk> bval b s; (c, s) \<Rightarrow> s'; (WHILE b DO c, s') \<Rightarrow> t\<rbrakk>
       
   178        \<Longrightarrow> its b c s = Suc(its b c s')"
       
   179 by (metis its_def WHILE_Its Its.intros(2) Its_fun the_equality)
       
   180 
       
   181 lemma wpt_is_pre: "\<turnstile>\<^sub>t {wp\<^sub>t c Q} c {Q}"
   159 lemma wpt_is_pre: "\<turnstile>\<^sub>t {wp\<^sub>t c Q} c {Q}"
   182 proof (induction c arbitrary: Q)
   160 proof (induction c arbitrary: Q)
   183   case SKIP show ?case by simp (blast intro:hoaret.Skip)
   161   case SKIP show ?case by simp (blast intro:hoaret.Skip)
   184 next
   162 next
   185   case Assign show ?case by simp (blast intro:hoaret.Assign)
   163   case Assign show ?case by simp (blast intro:hoaret.Assign)
   188 next
   166 next
   189   case If thus ?case by simp (blast intro:hoaret.If hoaret.conseq)
   167   case If thus ?case by simp (blast intro:hoaret.If hoaret.conseq)
   190 next
   168 next
   191   case (While b c)
   169   case (While b c)
   192   let ?w = "WHILE b DO c"
   170   let ?w = "WHILE b DO c"
       
   171   let ?T = "\<lambda>n s. Its b c s n"
       
   172   have "\<forall>s. wp\<^sub>t (WHILE b DO c) Q s \<longrightarrow> wp\<^sub>t (WHILE b DO c) Q s \<and> (\<exists>n. Its b c s n)"
       
   173     unfolding wpt_def by (metis WHILE_Its)
       
   174   moreover
   193   { fix n
   175   { fix n
   194     have "\<forall>s. wp\<^sub>t ?w Q s \<and> bval b s \<and> its b c s = n \<longrightarrow>
   176     { fix s t
   195               wp\<^sub>t c (\<lambda>s'. wp\<^sub>t ?w Q s' \<and> its b c s' < n) s"
   177       assume "bval b s" "?T n s" "(?w, s) \<Rightarrow> t" "Q t"
   196       unfolding wpt_def by (metis WhileE its_Suc lessI)
   178       from `bval b s` `(?w, s) \<Rightarrow> t` obtain s' where
       
   179         "(c,s) \<Rightarrow> s'" "(?w,s') \<Rightarrow> t" by auto      
       
   180       from `(?w, s') \<Rightarrow> t` obtain n'' where "?T n'' s'" by (blast dest: WHILE_Its)
       
   181       with `bval b s` `(c, s) \<Rightarrow> s'`
       
   182       have "?T (Suc n'') s" by (rule Its_Suc)
       
   183       with `?T n s` have "n = Suc n''" by (rule Its_fun)
       
   184       with `(c,s) \<Rightarrow> s'` `(?w,s') \<Rightarrow> t` `Q t` `?T n'' s'`
       
   185       have "wp\<^sub>t c (\<lambda>s'. wp\<^sub>t ?w Q s' \<and> (\<exists>n'. ?T n' s' \<and> n' < n)) s"
       
   186         by (auto simp: wpt_def)
       
   187     } 
       
   188     hence "\<forall>s. wp\<^sub>t ?w Q s \<and> bval b s \<and> ?T n s \<longrightarrow>
       
   189               wp\<^sub>t c (\<lambda>s'. wp\<^sub>t ?w Q s' \<and> (\<exists>n'. ?T n' s' \<and> n' < n)) s"
       
   190       unfolding wpt_def by auto
       
   191       (* by (metis WhileE Its_Suc Its_fun WHILE_Its lessI) *) 
   197     note strengthen_pre[OF this While]
   192     note strengthen_pre[OF this While]
   198   } note hoaret.While[OF this]
   193   } note hoaret.While[OF this]
   199   moreover have "\<forall>s. wp\<^sub>t ?w Q s \<and> \<not> bval b s \<longrightarrow> Q s" by (auto simp add:wpt_def)
   194   moreover have "\<forall>s. wp\<^sub>t ?w Q s \<and> \<not> bval b s \<longrightarrow> Q s" by (auto simp add:wpt_def)
   200   ultimately show ?case by(rule weaken_post)
   195   ultimately show ?case by (rule conseq) 
   201 qed
   196 qed
   202 
   197 
   203 
   198 
   204 text{*\noindent In the @{term While}-case, @{const its} provides the obvious
   199 text{*\noindent In the @{term While}-case, @{const Its} provides the obvious
   205 termination argument.
   200 termination argument.
   206 
   201 
   207 The actual completeness theorem follows directly, in the same manner
   202 The actual completeness theorem follows directly, in the same manner
   208 as for partial correctness: *}
   203 as for partial correctness: *}
   209 
   204