src/HOL/Hoare/Separation.thy
author nipkow
Sun, 23 Mar 2003 11:57:07 +0100
changeset 13875 12997e3ddd8d
parent 13867 1fdecd15437f
child 13903 ad1c28671a93
permissions -rw-r--r--
*** empty log message ***
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     1
theory Separation = HoareAbort:
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     2
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     3
types heap = "(nat \<Rightarrow> nat option)"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     4
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     5
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     6
text{* The semantic definition of a few connectives: *}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     7
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
     8
constdefs
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
     9
 ortho:: "heap \<Rightarrow> heap \<Rightarrow> bool" (infix "\<bottom>" 55)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    10
"h1 \<bottom> h2 == dom h1 \<inter> dom h2 = {}"
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    11
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    12
 is_empty :: "heap \<Rightarrow> bool"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    13
"is_empty h == h = empty"
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    14
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    15
 singl:: "heap \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    16
"singl h x y == dom h = {x} & h x = Some y"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    17
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    18
 star:: "(heap \<Rightarrow> bool) \<Rightarrow> (heap \<Rightarrow> bool) \<Rightarrow> (heap \<Rightarrow> bool)"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    19
"star P Q == \<lambda>h. \<exists>h1 h2. h = h1++h2 \<and> h1 \<bottom> h2 \<and> P h1 \<and> Q h2"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    20
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    21
 wand:: "(heap \<Rightarrow> bool) \<Rightarrow> (heap \<Rightarrow> bool) \<Rightarrow> (heap \<Rightarrow> bool)"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    22
"wand P Q == \<lambda>h. \<forall>h'. h' \<bottom> h \<and> P h' \<longrightarrow> Q(h++h')"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    23
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    24
lemma "VARS x y z w h
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    25
 {star (%h. singl h x y) (%h. singl h z w) h}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    26
 SKIP
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    27
 {x \<noteq> z}"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    28
apply vcg
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    29
apply(auto simp:star_def ortho_def singl_def)
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    30
done
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    31
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    32
text{* To suppress the heap parameter of the connectives, we assume it
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    33
is always called H and add/remove it upon parsing/printing. Thus
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    34
every pointer program needs to have a program variable H, and
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    35
assertions should not contain any locally bound Hs - otherwise they
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    36
may bind the implicit H. *}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    37
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    38
text{* Nice input syntax: *}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    39
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    40
syntax
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    41
 "@emp" :: "bool" ("emp")
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    42
 "@singl" :: "nat \<Rightarrow> nat \<Rightarrow> bool" ("[_ \<mapsto> _]")
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    43
 "@star" :: "bool \<Rightarrow> bool \<Rightarrow> bool" (infixl "**" 60)
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    44
 "@wand" :: "bool \<Rightarrow> bool \<Rightarrow> bool" (infixl "-o" 60)
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    45
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    46
ML{*
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    47
(* free_tr takes care of free vars in the scope of sep. logic connectives:
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    48
   they are implicitly applied to the heap *)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    49
fun free_tr(t as Free _) = t $ Syntax.free "H"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    50
  | free_tr t = t
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    51
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    52
fun emp_tr [] = Syntax.const "is_empty" $ Syntax.free "H"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    53
  | emp_tr ts = raise TERM ("emp_tr", ts);
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    54
fun singl_tr [p,q] = Syntax.const "singl" $ Syntax.free "H" $ p $ q
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    55
  | singl_tr ts = raise TERM ("singl_tr", ts);
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    56
fun star_tr [P,Q] = Syntax.const "star" $
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    57
      absfree("H",dummyT,free_tr P) $ absfree("H",dummyT,free_tr Q) $
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    58
      Syntax.free "H"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    59
  | star_tr ts = raise TERM ("star_tr", ts);
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    60
fun wand_tr [P,Q] = Syntax.const "wand" $
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    61
      absfree("H",dummyT,P) $ absfree("H",dummyT,Q) $ Syntax.free "H"
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    62
  | wand_tr ts = raise TERM ("wand_tr", ts);
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    63
*}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    64
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    65
parse_translation
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    66
 {* [("@emp", emp_tr), ("@singl", singl_tr),
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    67
     ("@star", star_tr), ("@wand", wand_tr)] *}
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    68
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    69
lemma "VARS H x y z w
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    70
 {[x\<mapsto>y] ** [z\<mapsto>w]}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    71
 SKIP
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    72
 {x \<noteq> z}"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    73
apply vcg
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    74
apply(auto simp:star_def ortho_def singl_def)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    75
done
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    76
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    77
lemma "VARS H x y z w
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    78
 {emp ** emp}
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    79
 SKIP
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    80
 {emp}"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    81
apply vcg
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    82
apply(auto simp:star_def ortho_def is_empty_def)
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    83
done
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    84
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    85
text{* Nice output syntax: *}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    86
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    87
ML{*
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    88
local
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    89
fun strip (Abs(_,_,(t as Free _) $ Bound 0)) = t
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    90
  | strip (Abs(_,_,(t as Var _) $ Bound 0)) = t
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    91
  | strip (Abs(_,_,P)) = P
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    92
  | strip (Const("is_empty",_)) = Syntax.const "@emp"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    93
  | strip t = t;
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    94
in
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    95
fun is_empty_tr' [_] = Syntax.const "@emp"
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
    96
fun singl_tr' [_,p,q] = Syntax.const "@singl" $ p $ q
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    97
fun star_tr' [P,Q,_] = Syntax.const "@star" $ strip P $ strip Q
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    98
fun wand_tr' [P,Q,_] = Syntax.const "@wand" $ strip P $ strip Q
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
    99
end
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   100
*}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   101
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   102
print_translation
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   103
 {* [("is_empty", is_empty_tr'),("singl", singl_tr'),("star", star_tr')] *}
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   104
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   105
lemma "VARS H x y z w
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   106
 {[x\<mapsto>y] ** [z\<mapsto>w]}
13867
1fdecd15437f just a few mods to a few thms
nipkow
parents: 13857
diff changeset
   107
 y := w
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   108
 {x \<noteq> z}"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   109
apply vcg
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   110
apply(auto simp:star_def ortho_def singl_def)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   111
done
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   112
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   113
lemma "VARS H x y z w
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   114
 {emp ** emp}
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   115
 SKIP
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   116
 {emp}"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   117
apply vcg
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   118
apply(auto simp:star_def ortho_def is_empty_def)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   119
done
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   120
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   121
(* move to Map.thy *)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   122
lemma override_comm: "dom m1 \<inter> dom m2 = {} \<Longrightarrow> m1++m2 = m2++m1"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   123
apply(rule ext)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   124
apply(fastsimp simp:override_def split:option.split)
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   125
done
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   126
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   127
(* a law of separation logic *)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   128
(* something is wrong with the pretty printer, but I cannot figure out what. *)
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   129
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   130
lemma star_comm: "P ** Q = Q ** P"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   131
apply(simp add:star_def ortho_def)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   132
apply(blast intro:override_comm)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   133
done
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   134
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   135
lemma "VARS H x y z w
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   136
 {P ** Q}
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   137
 SKIP
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   138
 {Q ** P}"
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   139
apply vcg
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   140
apply(simp add: star_comm)
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   141
done
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   142
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   143
end
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   144
(*
13857
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   145
consts llist :: "(heap * nat)set"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   146
inductive llist
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   147
intros
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   148
empty: "(%n. None, 0) : llist"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   149
cons: "\<lbrakk> R h h1 h2; pto h1 p q; (h2,q):llist \<rbrakk> \<Longrightarrow> (h,p):llist"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   150
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   151
lemma "VARS p q h
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   152
 {(h,p) : llist}
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   153
 h := h(q \<mapsto> p)
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   154
 {(h,q) : llist}"
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   155
apply vcg
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   156
apply(rule_tac "h1.0" = "%n. if n=q then Some p else None" in llist.cons)
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   157
prefer 3 apply assumption
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   158
prefer 2 apply(simp add:singl_def dom_def)
11d7c5a8dbb7 *** empty log message ***
nipkow
parents:
diff changeset
   159
apply(simp add:R_def dom_def)
13875
12997e3ddd8d *** empty log message ***
nipkow
parents: 13867
diff changeset
   160
*)