src/HOL/IMP/Hoare.thy
author nipkow
Thu, 11 Mar 2010 19:05:46 +0100
changeset 35735 f139a9bb6501
parent 27362 a6dc1769fdda
child 35754 8e7dba5f00f5
permissions -rw-r--r--
converted proofs to Isar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1476
608483c2122a expanded tabs; incorporated Konrad's changes
clasohm
parents: 1447
diff changeset
     1
(*  Title:      HOL/IMP/Hoare.thy
938
621be7ec81d7 *** empty log message ***
nipkow
parents: 937
diff changeset
     2
    ID:         $Id$
1476
608483c2122a expanded tabs; incorporated Konrad's changes
clasohm
parents: 1447
diff changeset
     3
    Author:     Tobias Nipkow
936
a6d7b4084761 Hoare logic
nipkow
parents:
diff changeset
     4
    Copyright   1995 TUM
a6d7b4084761 Hoare logic
nipkow
parents:
diff changeset
     5
*)
a6d7b4084761 Hoare logic
nipkow
parents:
diff changeset
     6
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
     7
header "Inductive Definition of Hoare Logic"
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
     8
16417
9bc16273c2d4 migrated theory headers to new format
haftmann
parents: 13630
diff changeset
     9
theory Hoare imports Denotation begin
1447
bc2c0acbbf29 Added a verified verification-condition generator.
nipkow
parents: 1374
diff changeset
    10
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    11
types assn = "state => bool"
1447
bc2c0acbbf29 Added a verified verification-condition generator.
nipkow
parents: 1374
diff changeset
    12
27362
a6dc1769fdda modernized specifications;
wenzelm
parents: 23746
diff changeset
    13
definition
a6dc1769fdda modernized specifications;
wenzelm
parents: 23746
diff changeset
    14
  hoare_valid :: "[assn,com,assn] => bool" ("|= {(1_)}/ (_)/ {(1_)}" 50) where
a6dc1769fdda modernized specifications;
wenzelm
parents: 23746
diff changeset
    15
  "|= {P}c{Q} = (!s t. (s,t) : C(c) --> P s --> Q t)"
939
534955033ed2 Added pretty-printing coments
nipkow
parents: 938
diff changeset
    16
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    17
inductive
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    18
  hoare :: "assn => com => assn => bool" ("|- ({(1_)}/ (_)/ {(1_)})" 50)
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    19
where
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    20
  skip: "|- {P}\<SKIP>{P}"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    21
| ass:  "|- {%s. P(s[x\<mapsto>a s])} x:==a {P}"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    22
| semi: "[| |- {P}c{Q}; |- {Q}d{R} |] ==> |- {P} c;d {R}"
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    23
| If: "[| |- {%s. P s & b s}c{Q}; |- {%s. P s & ~b s}d{Q} |] ==>
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    24
      |- {P} \<IF> b \<THEN> c \<ELSE> d {Q}"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    25
| While: "|- {%s. P s & b s} c {P} ==>
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    26
         |- {P} \<WHILE> b \<DO> c {%s. P s & ~b s}"
23746
a455e69c31cc Adapted to new inductive definition package.
berghofe
parents: 20503
diff changeset
    27
| conseq: "[| !s. P' s --> P s; |- {P}c{Q}; !s. Q s --> Q' s |] ==>
1486
7b95d7b49f7a Introduced qed_spec_mp.
nipkow
parents: 1481
diff changeset
    28
          |- {P'}c{Q'}"
1481
03f096efa26d Modified datatype com.
nipkow
parents: 1476
diff changeset
    29
27362
a6dc1769fdda modernized specifications;
wenzelm
parents: 23746
diff changeset
    30
definition
a6dc1769fdda modernized specifications;
wenzelm
parents: 23746
diff changeset
    31
  wp :: "com => assn => assn" where
a6dc1769fdda modernized specifications;
wenzelm
parents: 23746
diff changeset
    32
  "wp c Q = (%s. !t. (s,t) : C(c) --> Q t)"
939
534955033ed2 Added pretty-printing coments
nipkow
parents: 938
diff changeset
    33
18372
2bffdf62fe7f tuned proofs;
wenzelm
parents: 16417
diff changeset
    34
(*
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    35
Soundness (and part of) relative completeness of Hoare rules
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    36
wrt denotational semantics
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    37
*)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    38
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    39
lemma strengthen_pre: "[| !s. P' s --> P s; |- {P}c{Q} |] ==> |- {P'}c{Q}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    40
by (blast intro: conseq)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    41
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    42
lemma weaken_post: "[| |- {P}c{Q}; !s. Q s --> Q' s |] ==> |- {P}c{Q'}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    43
by (blast intro: conseq)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    44
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    45
lemma hoare_sound: "|- {P}c{Q} ==> |= {P}c{Q}"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    46
proof(induct rule: hoare.induct)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    47
  case (While P b c)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    48
  { fix s t
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    49
    let ?G = "Gamma b (C c)"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    50
    assume "(s,t) \<in> lfp ?G"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    51
    hence "P s \<longrightarrow> P t \<and> \<not> b t"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    52
    proof(rule lfp_induct2)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    53
      show "mono ?G" by(rule Gamma_mono)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    54
    next
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    55
      fix s t assume "(s,t) \<in> ?G (lfp ?G \<inter> {(s,t). P s \<longrightarrow> P t \<and> \<not> b t})"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    56
      thus "P s \<longrightarrow> P t \<and> \<not> b t" using While.hyps
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    57
        by(auto simp: hoare_valid_def Gamma_def)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    58
    qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    59
  }
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    60
  thus ?case by(simp add:hoare_valid_def)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    61
qed (auto simp: hoare_valid_def)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    62
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    63
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    64
lemma wp_SKIP: "wp \<SKIP> Q = Q"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    65
by (simp add: wp_def)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    66
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    67
lemma wp_Ass: "wp (x:==a) Q = (%s. Q(s[x\<mapsto>a s]))"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    68
by (simp add: wp_def)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    69
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    70
lemma wp_Semi: "wp (c;d) Q = wp c (wp d Q)"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    71
by (rule ext) (auto simp: wp_def)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    72
18372
2bffdf62fe7f tuned proofs;
wenzelm
parents: 16417
diff changeset
    73
lemma wp_If:
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    74
 "wp (\<IF> b \<THEN> c \<ELSE> d) Q = (%s. (b s --> wp c Q s) &  (~b s --> wp d Q s))"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    75
by (rule ext) (auto simp: wp_def)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    76
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    77
lemma wp_While_If:
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    78
 "wp (\<WHILE> b \<DO> c) Q s =
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    79
  wp (IF b THEN c;\<WHILE> b \<DO> c ELSE SKIP) Q s"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    80
by(simp only: wp_def C_While_If)
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    81
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    82
(*Not suitable for rewriting: LOOPS!*)
18372
2bffdf62fe7f tuned proofs;
wenzelm
parents: 16417
diff changeset
    83
lemma wp_While_if:
12434
kleing
parents: 12431
diff changeset
    84
  "wp (\<WHILE> b \<DO> c) Q s = (if b s then wp (c;\<WHILE> b \<DO> c) Q s else Q s)"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    85
by(simp add:wp_While_If wp_If wp_SKIP)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    86
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    87
lemma wp_While_True: "b s ==>
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    88
  wp (\<WHILE> b \<DO> c) Q s = wp (c;\<WHILE> b \<DO> c) Q s"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    89
by(simp add: wp_While_if)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    90
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    91
lemma wp_While_False: "~b s ==> wp (\<WHILE> b \<DO> c) Q s = Q s"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    92
by(simp add: wp_While_if)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    93
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
    94
lemmas [simp] = wp_SKIP wp_Ass wp_Semi wp_If wp_While_True wp_While_False
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    95
18372
2bffdf62fe7f tuned proofs;
wenzelm
parents: 16417
diff changeset
    96
lemma wp_While: "wp (\<WHILE> b \<DO> c) Q s =
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    97
   (s : gfp(%S.{s. if b s then wp c (%s. s:S) s else Q s}))"
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    98
apply (simp (no_asm))
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
    99
apply (rule iffI)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   100
 apply (rule weak_coinduct)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   101
  apply (erule CollectI)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   102
 apply safe
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   103
  apply simp
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   104
 apply simp
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   105
apply (simp add: wp_def Gamma_def)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   106
apply (intro strip)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   107
apply (rule mp)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   108
 prefer 2 apply (assumption)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   109
apply (erule lfp_induct2)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   110
apply (fast intro!: monoI)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   111
apply (subst gfp_unfold)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   112
 apply (fast intro!: monoI)
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   113
apply fast
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   114
done
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   115
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   116
declare C_while [simp del]
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   117
18372
2bffdf62fe7f tuned proofs;
wenzelm
parents: 16417
diff changeset
   118
lemmas [intro!] = hoare.skip hoare.ass hoare.semi hoare.If
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   119
18372
2bffdf62fe7f tuned proofs;
wenzelm
parents: 16417
diff changeset
   120
lemma wp_is_pre: "|- {wp c Q} c {Q}"
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   121
proof(induct c arbitrary: Q)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   122
  case SKIP show ?case by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   123
next
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   124
  case Assign show ?case by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   125
next
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   126
  case Semi thus ?case by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   127
next
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   128
  case (Cond b c1 c2)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   129
  let ?If = "IF b THEN c1 ELSE c2"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   130
  show ?case
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   131
  proof(rule If)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   132
    show "|- {\<lambda>s. wp ?If Q s \<and> b s} c1 {Q}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   133
    proof(rule strengthen_pre[OF _ Cond(1)])
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   134
      show "\<forall>s. wp ?If Q s \<and> b s \<longrightarrow> wp c1 Q s" by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   135
    qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   136
    show "|- {\<lambda>s. wp ?If Q s \<and> \<not> b s} c2 {Q}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   137
    proof(rule strengthen_pre[OF _ Cond(2)])
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   138
      show "\<forall>s. wp ?If Q s \<and> \<not> b s \<longrightarrow> wp c2 Q s" by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   139
    qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   140
  qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   141
next
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   142
  case (While b c)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   143
  let ?w = "WHILE b DO c"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   144
  have "|- {wp ?w Q} ?w {\<lambda>s. wp ?w Q s \<and> \<not> b s}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   145
  proof(rule hoare.While)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   146
    show "|- {\<lambda>s. wp ?w Q s \<and> b s} c {wp ?w Q}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   147
    proof(rule strengthen_pre[OF _ While(1)])
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   148
      show "\<forall>s. wp ?w Q s \<and> b s \<longrightarrow> wp c (wp ?w Q) s" by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   149
    qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   150
  qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   151
  thus ?case
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   152
  proof(rule weaken_post)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   153
    show "\<forall>s. wp ?w Q s \<and> \<not> b s \<longrightarrow> Q s" by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   154
  qed
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   155
qed
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   156
35735
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   157
lemma hoare_relative_complete: assumes "|= {P}c{Q}" shows "|- {P}c{Q}"
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   158
proof(rule conseq)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   159
  show "\<forall>s. P s \<longrightarrow> wp c Q s" using assms
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   160
    by (auto simp: hoare_valid_def wp_def)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   161
  show "|- {wp c Q} c {Q}" by(rule wp_is_pre)
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   162
  show "\<forall>s. Q s \<longrightarrow> Q s" by auto
f139a9bb6501 converted proofs to Isar
nipkow
parents: 27362
diff changeset
   163
qed
12431
07ec657249e5 converted to Isar
kleing
parents: 9241
diff changeset
   164
939
534955033ed2 Added pretty-printing coments
nipkow
parents: 938
diff changeset
   165
end