src/HOL/IMP/HoareT.thy
changeset 52281 780b3870319f
parent 52228 ee8e3eaad24c
equal deleted inserted replaced
52280:c3f837d92537 52281:780b3870319f
     7 text{* Note that this definition of total validity @{text"\<Turnstile>\<^sub>t"} only
     7 text{* Note that this definition of total validity @{text"\<Turnstile>\<^sub>t"} only
     8 works if execution is deterministic (which it is in our case). *}
     8 works if execution is deterministic (which it is in our case). *}
     9 
     9 
    10 definition hoare_tvalid :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool"
    10 definition hoare_tvalid :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool"
    11   ("\<Turnstile>\<^sub>t {(1_)}/ (_)/ {(1_)}" 50) where
    11   ("\<Turnstile>\<^sub>t {(1_)}/ (_)/ {(1_)}" 50) where
    12 "\<Turnstile>\<^sub>t {P}c{Q}  \<equiv>  \<forall>s. P s \<longrightarrow> (\<exists>t. (c,s) \<Rightarrow> t \<and> Q t)"
    12 "\<Turnstile>\<^sub>t {P}c{Q}  \<longleftrightarrow>  (\<forall>s. P s \<longrightarrow> (\<exists>t. (c,s) \<Rightarrow> t \<and> Q t))"
    13 
    13 
    14 text{* Provability of Hoare triples in the proof system for total
    14 text{* Provability of Hoare triples in the proof system for total
    15 correctness is written @{text"\<turnstile>\<^sub>t {P}c{Q}"} and defined
    15 correctness is written @{text"\<turnstile>\<^sub>t {P}c{Q}"} and defined
    16 inductively. The rules for @{text"\<turnstile>\<^sub>t"} differ from those for
    16 inductively. The rules for @{text"\<turnstile>\<^sub>t"} differ from those for
    17 @{text"\<turnstile>"} only in the one place where nontermination can arise: the
    17 @{text"\<turnstile>"} only in the one place where nontermination can arise: the
    18 @{term While}-rule. *}
    18 @{term While}-rule. *}
    19 
    19 
    20 inductive
    20 inductive
    21   hoaret :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" ("\<turnstile>\<^sub>t ({(1_)}/ (_)/ {(1_)})" 50)
    21   hoaret :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" ("\<turnstile>\<^sub>t ({(1_)}/ (_)/ {(1_)})" 50)
    22 where
    22 where
    23 Skip:  "\<turnstile>\<^sub>t {P} SKIP {P}" |
    23 
    24 Assign:  "\<turnstile>\<^sub>t {\<lambda>s. P(s[a/x])} x::=a {P}" |
    24 Skip:  "\<turnstile>\<^sub>t {P} SKIP {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 
       
    26 Assign:  "\<turnstile>\<^sub>t {\<lambda>s. P(s[a/x])} x::=a {P}"  |
       
    27 
       
    28 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}"  |
       
    29 
    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>
    30 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}" |
    31   \<Longrightarrow> \<turnstile>\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}"  |
       
    32 
    28 While:
    33 While:
    29   "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T s n} c {\<lambda>s. P s \<and> (\<exists>n'. T s n' \<and> n' < n)} \<rbrakk>
    34   "(\<And>n::nat.
    30    \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T s n)} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" |
    35     \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T s n} c {\<lambda>s. P s \<and> (\<exists>n'. T s n' \<and> n' < n)})
       
    36    \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T s n)} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}"  |
       
    37 
    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>
    38 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'}"
    39            \<turnstile>\<^sub>t {P'}c{Q'}"
    33 
    40 
    34 text{* The @{term While}-rule is like the one for partial correctness but it
    41 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
    42 requires additionally that with every execution of the loop body some measure
    36 function @{term[source]"f :: state \<Rightarrow> nat"} decreases. *}
    43 relation @{term[source]"T :: state \<Rightarrow> nat \<Rightarrow> bool"} decreases.
       
    44 The following functional version is more intuitive: *}
       
    45 
       
    46 lemma While_fun:
       
    47   "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> n = f s} c {\<lambda>s. P s \<and> f s < n}\<rbrakk>
       
    48    \<Longrightarrow> \<turnstile>\<^sub>t {P} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}"
       
    49   by (rule While [where T="\<lambda>s n. n = f s", simplified])
       
    50 
       
    51 text{* Building in the consequence rule: *}
    37 
    52 
    38 lemma strengthen_pre:
    53 lemma strengthen_pre:
    39   "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s;  \<turnstile>\<^sub>t {P} c {Q} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P'} c {Q}"
    54   "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s;  \<turnstile>\<^sub>t {P} c {Q} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P'} c {Q}"
    40 by (metis conseq)
    55 by (metis conseq)
    41 
    56 
    44 by (metis conseq)
    59 by (metis conseq)
    45 
    60 
    46 lemma Assign': "\<forall>s. P s \<longrightarrow> Q(s[a/x]) \<Longrightarrow> \<turnstile>\<^sub>t {P} x ::= a {Q}"
    61 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])
    62 by (simp add: strengthen_pre[OF _ Assign])
    48 
    63 
    49 lemma While':
    64 lemma While_fun':
    50 assumes "\<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T s n} c {\<lambda>s. P s \<and> (\<exists>n'. T s n' \<and> n' < n)}"
    65 assumes "\<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> n = f s} c {\<lambda>s. P s \<and> f s < n}"
    51     and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s"
    66     and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s"
    52 shows "\<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T s n)} WHILE b DO c {Q}"
    67 shows "\<turnstile>\<^sub>t {P} WHILE b DO c {Q}"
    53 by(blast intro: assms(1) weaken_post[OF While assms(2)])
    68 by(blast intro: assms(1) weaken_post[OF While_fun assms(2)])
    54 
    69 
    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>s n. f s = n", simplified])
       
    59 
    70 
    60 text{* Our standard example: *}
    71 text{* Our standard example: *}
    61 
    72 
    62 lemma "\<turnstile>\<^sub>t {\<lambda>s. s ''x'' = i} ''y'' ::= N 0;; wsum {\<lambda>s. s ''y'' = sum i}"
    73 lemma "\<turnstile>\<^sub>t {\<lambda>s. s ''x'' = i} ''y'' ::= N 0;; wsum {\<lambda>s. s ''y'' = sum i}"
    63 apply(rule Seq)
    74 apply(rule Seq)
    64  prefer 2
    75  prefer 2
    65  apply(rule While' [where P = "\<lambda>s. (s ''y'' = sum i - sum(s ''x''))"
    76  apply(rule While_fun' [where P = "\<lambda>s. (s ''y'' = sum i - sum(s ''x''))"
    66     and T = "\<lambda>s n. n = nat(s ''x'')"])
    77     and f = "\<lambda>s. nat(s ''x'')"])
    67    apply(rule Seq)
    78    apply(rule Seq)
    68    prefer 2
    79    prefer 2
    69    apply(rule Assign)
    80    apply(rule Assign)
    70   apply(rule Assign')
    81   apply(rule Assign')
    71   apply simp
    82   apply simp