src/HOL/IMP/Hoare.thy
author haftmann
Fri, 01 Nov 2013 18:51:14 +0100
changeset 54230 b1d955791529
parent 53015 a1119cf551e8
child 58889 5b7a9633cfa8
permissions -rw-r--r--
more simplification rules on unary and binary minus
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43158
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     1
(* Author: Tobias Nipkow *)
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     2
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     3
header "Hoare Logic"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     4
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     5
theory Hoare imports Big_Step begin
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     6
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     7
subsection "Hoare Logic for Partial Correctness"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     8
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
     9
type_synonym assn = "state \<Rightarrow> bool"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    10
52165
nipkow
parents: 52046
diff changeset
    11
definition
nipkow
parents: 52046
diff changeset
    12
hoare_valid :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" ("\<Turnstile> {(1_)}/ (_)/ {(1_)}" 50) where
52167
nipkow
parents: 52165
diff changeset
    13
"\<Turnstile> {P}c{Q} = (\<forall>s t. P s \<and> (c,s) \<Rightarrow> t  \<longrightarrow>  Q t)"
52165
nipkow
parents: 52046
diff changeset
    14
45212
e87feee00a4c renamed name -> vname
nipkow
parents: 43158
diff changeset
    15
abbreviation state_subst :: "state \<Rightarrow> aexp \<Rightarrow> vname \<Rightarrow> state"
43158
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    16
  ("_[_'/_]" [1000,0,0] 999)
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    17
where "s[a/x] == s(x := aval a s)"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    18
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    19
inductive
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    20
  hoare :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" ("\<turnstile> ({(1_)}/ (_)/ {(1_)})" 50)
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    21
where
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    22
Skip: "\<turnstile> {P} SKIP {P}"  |
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    23
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    24
Assign:  "\<turnstile> {\<lambda>s. P(s[a/x])} x::=a {P}"  |
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    25
53015
a1119cf551e8 standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
wenzelm
parents: 52167
diff changeset
    26
Seq: "\<lbrakk> \<turnstile> {P} c\<^sub>1 {Q};  \<turnstile> {Q} c\<^sub>2 {R} \<rbrakk>
a1119cf551e8 standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
wenzelm
parents: 52167
diff changeset
    27
      \<Longrightarrow> \<turnstile> {P} c\<^sub>1;;c\<^sub>2 {R}"  |
43158
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    28
53015
a1119cf551e8 standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
wenzelm
parents: 52167
diff changeset
    29
If: "\<lbrakk> \<turnstile> {\<lambda>s. P s \<and> bval b s} c\<^sub>1 {Q};  \<turnstile> {\<lambda>s. P s \<and> \<not> bval b s} c\<^sub>2 {Q} \<rbrakk>
a1119cf551e8 standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
wenzelm
parents: 52167
diff changeset
    30
     \<Longrightarrow> \<turnstile> {P} IF b THEN c\<^sub>1 ELSE c\<^sub>2 {Q}"  |
43158
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    31
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    32
While: "\<turnstile> {\<lambda>s. P s \<and> bval b s} c {P} \<Longrightarrow>
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    33
        \<turnstile> {P} WHILE b DO c {\<lambda>s. P s \<and> \<not> bval b s}"  |
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    34
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    35
conseq: "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s;  \<turnstile> {P} c {Q};  \<forall>s. Q s \<longrightarrow> Q' s \<rbrakk>
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    36
        \<Longrightarrow> \<turnstile> {P'} c {Q'}"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    37
47818
151d137f1095 renamed Semi to Seq
nipkow
parents: 45212
diff changeset
    38
lemmas [simp] = hoare.Skip hoare.Assign hoare.Seq If
43158
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    39
47818
151d137f1095 renamed Semi to Seq
nipkow
parents: 45212
diff changeset
    40
lemmas [intro!] = hoare.Skip hoare.Assign hoare.Seq hoare.If
43158
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    41
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    42
lemma strengthen_pre:
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    43
  "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s;  \<turnstile> {P} c {Q} \<rbrakk> \<Longrightarrow> \<turnstile> {P'} c {Q}"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    44
by (blast intro: conseq)
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    45
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    46
lemma weaken_post:
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    47
  "\<lbrakk> \<turnstile> {P} c {Q};  \<forall>s. Q s \<longrightarrow> Q' s \<rbrakk> \<Longrightarrow>  \<turnstile> {P} c {Q'}"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    48
by (blast intro: conseq)
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    49
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    50
text{* The assignment and While rule are awkward to use in actual proofs
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    51
because their pre and postcondition are of a very special form and the actual
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    52
goal would have to match this form exactly. Therefore we derive two variants
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    53
with arbitrary pre and postconditions. *}
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    54
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    55
lemma Assign': "\<forall>s. P s \<longrightarrow> Q(s[a/x]) \<Longrightarrow> \<turnstile> {P} x ::= a {Q}"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    56
by (simp add: strengthen_pre[OF _ Assign])
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    57
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    58
lemma While':
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    59
assumes "\<turnstile> {\<lambda>s. P s \<and> bval b s} c {P}" and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    60
shows "\<turnstile> {P} WHILE b DO c {Q}"
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    61
by(rule weaken_post[OF While[OF assms(1)] assms(2)])
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    62
686fa0a0696e imported rest of new IMP
kleing
parents:
diff changeset
    63
end