src/HOL/Hoare/Pointers0.thy
author krauss
Mon, 01 Mar 2010 17:05:57 +0100
changeset 35419 d78659d1723e
parent 35416 d8d7d1b785af
child 38353 d98baa2cf589
permissions -rw-r--r--
more recdef (and old primrec) hunting
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     1
(*  Title:      HOL/Hoare/Pointers.thy
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     2
    Author:     Tobias Nipkow
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     3
    Copyright   2002 TUM
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     4
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     5
This is like Pointers.thy, but instead of a type constructor 'a ref
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     6
that adjoins Null to a type, Null is simply a distinguished element of
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     7
the address type. This avoids the Ref constructor and thus simplifies
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     8
specifications (a bit). However, the proofs don't seem to get simpler
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
     9
- in fact in some case they appear to get (a bit) more complicated.
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    10
*)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    11
35316
870dfea4f9c0 dropped axclass; dropped Id; session theory Hoare.thy
haftmann
parents: 35101
diff changeset
    12
theory Pointers0 imports Hoare_Logic begin
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    13
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    14
subsection "References"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    15
35316
870dfea4f9c0 dropped axclass; dropped Id; session theory Hoare.thy
haftmann
parents: 35101
diff changeset
    16
class ref =
870dfea4f9c0 dropped axclass; dropped Id; session theory Hoare.thy
haftmann
parents: 35101
diff changeset
    17
  fixes Null :: 'a
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    18
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    19
subsection "Field access and update"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    20
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    21
syntax
35101
6ce9177d6b38 modernized translations;
wenzelm
parents: 17778
diff changeset
    22
  "_fassign"  :: "'a::ref => id => 'v => 's com"
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    23
   ("(2_^._ :=/ _)" [70,1000,65] 61)
35101
6ce9177d6b38 modernized translations;
wenzelm
parents: 17778
diff changeset
    24
  "_faccess"  :: "'a::ref => ('a::ref \<Rightarrow> 'v) => 'v"
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    25
   ("_^._" [65,1000] 65)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    26
translations
35101
6ce9177d6b38 modernized translations;
wenzelm
parents: 17778
diff changeset
    27
  "p^.f := e"  =>  "f := CONST fun_upd f p e"
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    28
  "p^.f"       =>  "f p"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    29
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    30
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    31
text "An example due to Suzuki:"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    32
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    33
lemma "VARS v n
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    34
  {distinct[w,x,y,z]}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    35
  w^.v := (1::int); w^.n := x;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    36
  x^.v := 2; x^.n := y;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    37
  y^.v := 3; y^.n := z;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    38
  z^.v := 4; x^.n := z
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    39
  {w^.n^.n^.v = 4}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    40
by vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    41
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    42
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    43
section "The heap"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    44
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    45
subsection "Paths in the heap"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    46
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    47
consts
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    48
 Path :: "('a::ref \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    49
primrec
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    50
"Path h x [] y = (x = y)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    51
"Path h x (a#as) y = (x \<noteq> Null \<and> x = a \<and> Path h (h a) as y)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    52
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    53
lemma [iff]: "Path h Null xs y = (xs = [] \<and> y = Null)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    54
apply(case_tac xs)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    55
apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    56
apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    57
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    58
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    59
lemma [simp]: "a \<noteq> Null \<Longrightarrow> Path h a as z =
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    60
 (as = [] \<and> z = a  \<or>  (\<exists>bs. as = a#bs \<and> Path h (h a) bs z))"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    61
apply(case_tac as)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    62
apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    63
apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    64
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    65
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    66
lemma [simp]: "\<And>x. Path f x (as@bs) z = (\<exists>y. Path f x as y \<and> Path f y bs z)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    67
by(induct as, simp+)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    68
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    69
lemma [simp]: "\<And>x. u \<notin> set as \<Longrightarrow> Path (f(u := v)) x as y = Path f x as y"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    70
by(induct as, simp, simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    71
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    72
subsection "Lists on the heap"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    73
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    74
subsubsection "Relational abstraction"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    75
35416
d8d7d1b785af replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents: 35316
diff changeset
    76
definition List :: "('a::ref \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> bool" where
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    77
"List h x as == Path h x as Null"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    78
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    79
lemma [simp]: "List h x [] = (x = Null)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    80
by(simp add:List_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    81
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    82
lemma [simp]: "List h x (a#as) = (x \<noteq> Null \<and> x = a \<and> List h (h a) as)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    83
by(simp add:List_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    84
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    85
lemma [simp]: "List h Null as = (as = [])"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    86
by(case_tac as, simp_all)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    87
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    88
lemma List_Ref[simp]:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    89
 "a \<noteq> Null \<Longrightarrow> List h a as = (\<exists>bs. as = a#bs \<and> List h (h a) bs)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    90
by(case_tac as, simp_all, fast)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    91
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    92
theorem notin_List_update[simp]:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    93
 "\<And>x. a \<notin> set as \<Longrightarrow> List (h(a := y)) x as = List h x as"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    94
apply(induct as)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    95
apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    96
apply(clarsimp simp add:fun_upd_apply)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    97
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    98
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
    99
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   100
declare fun_upd_apply[simp del]fun_upd_same[simp] fun_upd_other[simp]
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   101
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   102
lemma List_unique: "\<And>x bs. List h x as \<Longrightarrow> List h x bs \<Longrightarrow> as = bs"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   103
by(induct as, simp, clarsimp)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   104
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   105
lemma List_unique1: "List h p as \<Longrightarrow> \<exists>!as. List h p as"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   106
by(blast intro:List_unique)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   107
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   108
lemma List_app: "\<And>x. List h x (as@bs) = (\<exists>y. Path h x as y \<and> List h y bs)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   109
by(induct as, simp, clarsimp)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   110
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   111
lemma List_hd_not_in_tl[simp]: "List h (h a) as \<Longrightarrow> a \<notin> set as"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   112
apply (clarsimp simp add:in_set_conv_decomp)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   113
apply(frule List_app[THEN iffD1])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   114
apply(fastsimp dest: List_unique)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   115
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   116
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   117
lemma List_distinct[simp]: "\<And>x. List h x as \<Longrightarrow> distinct as"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   118
apply(induct as, simp)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   119
apply(fastsimp dest:List_hd_not_in_tl)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   120
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   121
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   122
subsection "Functional abstraction"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   123
35416
d8d7d1b785af replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents: 35316
diff changeset
   124
definition islist :: "('a::ref \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> bool" where
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   125
"islist h p == \<exists>as. List h p as"
35416
d8d7d1b785af replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents: 35316
diff changeset
   126
d8d7d1b785af replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents: 35316
diff changeset
   127
definition list :: "('a::ref \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a list" where
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   128
"list h p == SOME as. List h p as"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   129
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   130
lemma List_conv_islist_list: "List h p as = (islist h p \<and> as = list h p)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   131
apply(simp add:islist_def list_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   132
apply(rule iffI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   133
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   134
apply blast
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   135
apply(subst some1_equality)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   136
  apply(erule List_unique1)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   137
 apply assumption
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   138
apply(rule refl)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   139
apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   140
apply(rule someI_ex)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   141
apply fast
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   142
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   143
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   144
lemma [simp]: "islist h Null"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   145
by(simp add:islist_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   146
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   147
lemma [simp]: "a \<noteq> Null \<Longrightarrow> islist h a = islist h (h a)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   148
by(simp add:islist_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   149
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   150
lemma [simp]: "list h Null = []"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   151
by(simp add:list_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   152
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   153
lemma list_Ref_conv[simp]:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   154
 "\<lbrakk> a \<noteq> Null; islist h (h a) \<rbrakk> \<Longrightarrow> list h a = a # list h (h a)"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   155
apply(insert List_Ref[of _ h])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   156
apply(fastsimp simp:List_conv_islist_list)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   157
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   158
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   159
lemma [simp]: "islist h (h a) \<Longrightarrow> a \<notin> set(list h (h a))"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   160
apply(insert List_hd_not_in_tl[of h])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   161
apply(simp add:List_conv_islist_list)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   162
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   163
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   164
lemma list_upd_conv[simp]:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   165
 "islist h p \<Longrightarrow> y \<notin> set(list h p) \<Longrightarrow> list (h(y := q)) p = list h p"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   166
apply(drule notin_List_update[of _ _ h q p])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   167
apply(simp add:List_conv_islist_list)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   168
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   169
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   170
lemma islist_upd[simp]:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   171
 "islist h p \<Longrightarrow> y \<notin> set(list h p) \<Longrightarrow> islist (h(y := q)) p"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   172
apply(frule notin_List_update[of _ _ h q p])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   173
apply(simp add:List_conv_islist_list)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   174
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   175
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   176
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   177
section "Verifications"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   178
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   179
subsection "List reversal"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   180
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   181
text "A short but unreadable proof:"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   182
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   183
lemma "VARS tl p q r
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   184
  {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {}}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   185
  WHILE p \<noteq> Null
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   186
  INV {\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   187
                 rev ps @ qs = rev Ps @ Qs}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   188
  DO r := p; p := p^.tl; r^.tl := q; q := r OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   189
  {List tl q (rev Ps @ Qs)}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   190
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   191
  apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   192
 apply(fastsimp intro:notin_List_update[THEN iffD2])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   193
(* explicily:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   194
 apply clarify
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   195
 apply(rename_tac ps qs)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   196
 apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   197
 apply(rename_tac ps')
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   198
 apply(rule_tac x = ps' in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   199
 apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   200
 apply(rule_tac x = "p#qs" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   201
 apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   202
*)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   203
apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   204
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   205
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   206
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   207
text "A longer readable version:"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   208
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   209
lemma "VARS tl p q r
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   210
  {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {}}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   211
  WHILE p \<noteq> Null
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   212
  INV {\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   213
               rev ps @ qs = rev Ps @ Qs}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   214
  DO r := p; p := p^.tl; r^.tl := q; q := r OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   215
  {List tl q (rev Ps @ Qs)}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   216
proof vcg
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   217
  fix tl p q r
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   218
  assume "List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   219
  thus "\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   220
                rev ps @ qs = rev Ps @ Qs" by fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   221
next
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   222
  fix tl p q r
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   223
  assume "(\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   224
                   rev ps @ qs = rev Ps @ Qs) \<and> p \<noteq> Null"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   225
         (is "(\<exists>ps qs. ?I ps qs) \<and> _")
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   226
  then obtain ps qs where I: "?I ps qs \<and> p \<noteq> Null" by fast
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   227
  then obtain ps' where "ps = p # ps'" by fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   228
  hence "List (tl(p := q)) (p^.tl) ps' \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   229
         List (tl(p := q)) p       (p#qs) \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   230
         set ps' \<inter> set (p#qs) = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   231
         rev ps' @ (p#qs) = rev Ps @ Qs"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   232
    using I by fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   233
  thus "\<exists>ps' qs'. List (tl(p := q)) (p^.tl) ps' \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   234
                  List (tl(p := q)) p       qs' \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   235
                  set ps' \<inter> set qs' = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   236
                  rev ps' @ qs' = rev Ps @ Qs" by fast
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   237
next
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   238
  fix tl p q r
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   239
  assume "(\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   240
                   rev ps @ qs = rev Ps @ Qs) \<and> \<not> p \<noteq> Null"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   241
  thus "List tl q (rev Ps @ Qs)" by fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   242
qed
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   243
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   244
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   245
text{* Finaly, the functional version. A bit more verbose, but automatic! *}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   246
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   247
lemma "VARS tl p q r
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   248
  {islist tl p \<and> islist tl q \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   249
   Ps = list tl p \<and> Qs = list tl q \<and> set Ps \<inter> set Qs = {}}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   250
  WHILE p \<noteq> Null
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   251
  INV {islist tl p \<and> islist tl q \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   252
       set(list tl p) \<inter> set(list tl q) = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   253
       rev(list tl p) @ (list tl q) = rev Ps @ Qs}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   254
  DO r := p; p := p^.tl; r^.tl := q; q := r OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   255
  {islist tl q \<and> list tl q = rev Ps @ Qs}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   256
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   257
  apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   258
 apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   259
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   260
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   261
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   262
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   263
subsection "Searching in a list"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   264
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   265
text{*What follows is a sequence of successively more intelligent proofs that
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   266
a simple loop finds an element in a linked list.
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   267
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   268
We start with a proof based on the @{term List} predicate. This means it only
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   269
works for acyclic lists. *}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   270
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   271
lemma "VARS tl p
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   272
  {List tl p Ps \<and> X \<in> set Ps}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   273
  WHILE p \<noteq> Null \<and> p \<noteq> X
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   274
  INV {p \<noteq> Null \<and> (\<exists>ps. List tl p ps \<and> X \<in> set ps)}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   275
  DO p := p^.tl OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   276
  {p = X}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   277
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   278
  apply(case_tac "p = Null")
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   279
   apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   280
  apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   281
 apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   282
 apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   283
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   284
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   285
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   286
text{*Using @{term Path} instead of @{term List} generalizes the correctness
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   287
statement to cyclic lists as well: *}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   288
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   289
lemma "VARS tl p
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   290
  {Path tl p Ps X}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   291
  WHILE p \<noteq> Null \<and> p \<noteq> X
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   292
  INV {\<exists>ps. Path tl p ps X}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   293
  DO p := p^.tl OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   294
  {p = X}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   295
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   296
  apply blast
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   297
 apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   298
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   299
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   300
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   301
text{*Now it dawns on us that we do not need the list witness at all --- it
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   302
suffices to talk about reachability, i.e.\ we can use relations directly. *}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   303
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   304
lemma "VARS tl p
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   305
  {(p,X) \<in> {(x,y). y = tl x & x \<noteq> Null}^*}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   306
  WHILE p \<noteq> Null \<and> p \<noteq> X
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   307
  INV {(p,X) \<in> {(x,y). y = tl x & x \<noteq> Null}^*}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   308
  DO p := p^.tl OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   309
  {p = X}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   310
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   311
 apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   312
 apply(erule converse_rtranclE)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   313
  apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   314
 apply(simp)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   315
apply(fastsimp elim:converse_rtranclE)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   316
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   317
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   318
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   319
subsection "Merging two lists"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   320
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   321
text"This is still a bit rough, especially the proof."
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   322
35419
d78659d1723e more recdef (and old primrec) hunting
krauss
parents: 35416
diff changeset
   323
fun merge :: "'a list * 'a list * ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list" where
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   324
"merge(x#xs,y#ys,f) = (if f x y then x # merge(xs,y#ys,f)
35419
d78659d1723e more recdef (and old primrec) hunting
krauss
parents: 35416
diff changeset
   325
                                else y # merge(x#xs,ys,f))" |
d78659d1723e more recdef (and old primrec) hunting
krauss
parents: 35416
diff changeset
   326
"merge(x#xs,[],f) = x # merge(xs,[],f)" |
d78659d1723e more recdef (and old primrec) hunting
krauss
parents: 35416
diff changeset
   327
"merge([],y#ys,f) = y # merge([],ys,f)" |
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   328
"merge([],[],f) = []"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   329
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   330
lemma imp_disjCL: "(P|Q \<longrightarrow> R) = ((P \<longrightarrow> R) \<and> (~P \<longrightarrow> Q \<longrightarrow> R))"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   331
by blast
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   332
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   333
declare disj_not1[simp del] imp_disjL[simp del] imp_disjCL[simp]
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   334
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   335
lemma "VARS hd tl p q r s
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   336
 {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {} \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   337
  (p \<noteq> Null \<or> q \<noteq> Null)}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   338
 IF if q = Null then True else p ~= Null & p^.hd \<le> q^.hd
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   339
 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   340
 s := r;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   341
 WHILE p \<noteq> Null \<or> q \<noteq> Null
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   342
 INV {EX rs ps qs. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   343
      distinct(s # ps @ qs @ rs) \<and> s \<noteq> Null \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   344
      merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) =
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   345
      rs @ s # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   346
      (tl s = p \<or> tl s = q)}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   347
 DO IF if q = Null then True else p \<noteq> Null \<and> p^.hd \<le> q^.hd
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   348
    THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   349
    s := s^.tl
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   350
 OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   351
 {List tl r (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   352
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   353
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   354
apply (fastsimp)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   355
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   356
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   357
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   358
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   359
apply(simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   360
apply(rule_tac x = "rs @ [s]" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   361
apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   362
apply(rule_tac x = "bs" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   363
apply (fastsimp simp:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   364
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   365
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   366
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   367
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   368
apply(rule_tac x = "rs @ [s]" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   369
apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   370
apply(rule_tac x = "bsa" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   371
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   372
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   373
apply(rule exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   374
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   375
apply(rule_tac x = bs in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   376
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   377
apply(rule refl)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   378
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   379
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   380
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   381
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   382
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   383
apply(rule_tac x = "rs @ [s]" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   384
apply simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   385
apply(rule_tac x = bs in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   386
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   387
apply clarsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   388
apply(rule_tac x = "rs @ [s]" in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   389
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   390
apply(rule exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   391
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   392
apply(rule_tac x = bsa in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   393
apply(rule conjI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   394
apply(rule refl)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   395
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   396
apply(rule_tac x = bs in exI)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   397
apply (simp add:eq_sym_conv)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   398
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   399
apply(clarsimp simp add:List_app)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   400
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   401
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   402
(* TODO: merging with islist/list instead of List: an improvement?
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   403
   needs (is)path, which is not so easy to prove either. *)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   404
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   405
subsection "Storage allocation"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   406
35416
d8d7d1b785af replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents: 35316
diff changeset
   407
definition new :: "'a set \<Rightarrow> 'a::ref" where
13771
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   408
"new A == SOME a. a \<notin> A & a \<noteq> Null"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   409
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   410
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   411
lemma new_notin:
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   412
 "\<lbrakk> ~finite(UNIV::('a::ref)set); finite(A::'a set); B \<subseteq> A \<rbrakk> \<Longrightarrow>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   413
  new (A) \<notin> B & new A \<noteq> Null"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   414
apply(unfold new_def)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   415
apply(rule someI2_ex)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   416
 apply (fast dest:ex_new_if_finite[of "insert Null A"])
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   417
apply (fast)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   418
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   419
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   420
lemma "~finite(UNIV::('a::ref)set) \<Longrightarrow>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   421
  VARS xs elem next alloc p q
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   422
  {Xs = xs \<and> p = (Null::'a)}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   423
  WHILE xs \<noteq> []
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   424
  INV {islist next p \<and> set(list next p) \<subseteq> set alloc \<and>
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   425
       map elem (rev(list next p)) @ xs = Xs}
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   426
  DO q := new(set alloc); alloc := q#alloc;
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   427
     q^.next := p; q^.elem := hd xs; xs := tl xs; p := q
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   428
  OD
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   429
  {islist next p \<and> map elem (rev(list next p)) = Xs}"
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   430
apply vcg_simp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   431
 apply (clarsimp simp: subset_insert_iff neq_Nil_conv fun_upd_apply new_notin)
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   432
apply fastsimp
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   433
done
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   434
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   435
6cd59cc885a1 *** empty log message ***
nipkow
parents:
diff changeset
   436
end