src/HOL/Bali/Table.thy
author kuncar
Fri Dec 09 18:07:04 2011 +0100 (2011-12-09)
changeset 45802 b16f976db515
parent 45605 a89b4bc311a5
child 46212 d86ef6b96097
permissions -rw-r--r--
Quotient_Info stores only relation maps
wenzelm@12857
     1
(*  Title:      HOL/Bali/Table.thy
schirmer@12854
     2
    Author:     David von Oheimb
schirmer@12854
     3
*)
schirmer@12854
     4
header {* Abstract tables and their implementation as lists *}
schirmer@12854
     5
haftmann@16417
     6
theory Table imports Basis begin
schirmer@12854
     7
schirmer@12854
     8
text {*
schirmer@12854
     9
design issues:
schirmer@12854
    10
\begin{itemize}
schirmer@12854
    11
\item definition of table: infinite map vs. list vs. finite set
schirmer@12854
    12
      list chosen, because:
schirmer@12854
    13
  \begin{itemize} 
schirmer@12854
    14
  \item[+]  a priori finite
schirmer@12854
    15
  \item[+]  lookup is more operational than for finite set
schirmer@12854
    16
  \item[-]  not very abstract, but function table converts it to abstract 
schirmer@12854
    17
            mapping
schirmer@12854
    18
  \end{itemize}
schirmer@12854
    19
\item coding of lookup result: Some/None vs. value/arbitrary
schirmer@12854
    20
   Some/None chosen, because:
schirmer@12854
    21
  \begin{itemize}
schirmer@12854
    22
  \item[++] makes definedness check possible (applies also to finite set),
schirmer@12854
    23
     which is important for the type standard, hiding/overriding, etc.
schirmer@12854
    24
     (though it may perhaps be possible at least for the operational semantics
schirmer@12854
    25
      to treat programs as infinite, i.e. where classes, fields, methods etc.
schirmer@12854
    26
      of any name are considered to be defined)
schirmer@12854
    27
  \item[-]  sometimes awkward case distinctions, alleviated by operator 'the'
schirmer@12854
    28
  \end{itemize}
schirmer@12854
    29
\end{itemize}
schirmer@12854
    30
*}
schirmer@12854
    31
wenzelm@41778
    32
type_synonym ('a, 'b) table    --{* table with key type 'a and contents type 'b *}
nipkow@14134
    33
      = "'a \<rightharpoonup> 'b"
wenzelm@41778
    34
type_synonym ('a, 'b) tables   --{* non-unique table with key 'a and contents 'b *}
schirmer@12854
    35
      = "'a \<Rightarrow> 'b set"
schirmer@12854
    36
schirmer@12854
    37
schirmer@12854
    38
section "map of / table of"
schirmer@12854
    39
haftmann@34939
    40
abbreviation
wenzelm@35355
    41
  table_of :: "('a \<times> 'b) list \<Rightarrow> ('a, 'b) table"   --{* concrete table *}
wenzelm@35355
    42
  where "table_of \<equiv> map_of"
haftmann@34939
    43
schirmer@12854
    44
translations
wenzelm@35431
    45
  (type) "('a, 'b) table" <= (type) "'a \<rightharpoonup> 'b"
schirmer@12854
    46
schirmer@12854
    47
(* ### To map *)
nipkow@14025
    48
lemma map_add_find_left[simp]:
schirmer@12854
    49
"n k = None \<Longrightarrow> (m ++ n) k = m k"
nipkow@14025
    50
by (simp add: map_add_def)
schirmer@12854
    51
schirmer@12854
    52
section {* Conditional Override *}
haftmann@35416
    53
definition cond_override :: "('b \<Rightarrow>'b \<Rightarrow> bool) \<Rightarrow> ('a, 'b)table \<Rightarrow> ('a, 'b)table \<Rightarrow> ('a, 'b) table" where
schirmer@12854
    54
schirmer@13688
    55
--{* when merging tables old and new, only override an entry of table old when  
schirmer@13688
    56
   the condition cond holds *}
wenzelm@37956
    57
"cond_override cond old new =
wenzelm@37956
    58
 (\<lambda>k.
schirmer@12854
    59
  (case new k of
schirmer@12854
    60
     None         \<Rightarrow> old k                       
schirmer@12854
    61
   | Some new_val \<Rightarrow> (case old k of
schirmer@12854
    62
                        None         \<Rightarrow> Some new_val          
schirmer@12854
    63
                      | Some old_val \<Rightarrow> (if cond new_val old_val
schirmer@12854
    64
                                         then Some new_val     
wenzelm@37956
    65
                                         else Some old_val))))"
schirmer@12854
    66
schirmer@12854
    67
lemma cond_override_empty1[simp]: "cond_override c empty t = t"
nipkow@39302
    68
by (simp add: cond_override_def fun_eq_iff)
schirmer@12854
    69
schirmer@12854
    70
lemma cond_override_empty2[simp]: "cond_override c t empty = t"
nipkow@39302
    71
by (simp add: cond_override_def fun_eq_iff)
schirmer@12854
    72
schirmer@12854
    73
lemma cond_override_None[simp]:
schirmer@12854
    74
 "old k = None \<Longrightarrow> (cond_override c old new) k = new k"
schirmer@12854
    75
by (simp add: cond_override_def)
schirmer@12854
    76
schirmer@12854
    77
lemma cond_override_override:
schirmer@12854
    78
 "\<lbrakk>old k = Some ov;new k = Some nv; C nv ov\<rbrakk> 
schirmer@12854
    79
  \<Longrightarrow> (cond_override C old new) k = Some nv"
schirmer@12854
    80
by (auto simp add: cond_override_def)
schirmer@12854
    81
schirmer@12854
    82
lemma cond_override_noOverride:
schirmer@12854
    83
 "\<lbrakk>old k = Some ov;new k = Some nv; \<not> (C nv ov)\<rbrakk> 
schirmer@12854
    84
  \<Longrightarrow> (cond_override C old new) k = Some ov"
schirmer@12854
    85
by (auto simp add: cond_override_def)
schirmer@12854
    86
schirmer@12854
    87
lemma dom_cond_override: "dom (cond_override C s t) \<subseteq> dom s \<union> dom t"
schirmer@12854
    88
by (auto simp add: cond_override_def dom_def)
schirmer@12854
    89
schirmer@12854
    90
lemma finite_dom_cond_override:
schirmer@12854
    91
 "\<lbrakk> finite (dom s); finite (dom t) \<rbrakk> \<Longrightarrow> finite (dom (cond_override C s t))"
schirmer@12854
    92
apply (rule_tac B="dom s \<union> dom t" in finite_subset)
schirmer@12854
    93
apply (rule dom_cond_override)
schirmer@12854
    94
by (rule finite_UnI)
schirmer@12854
    95
schirmer@12854
    96
section {* Filter on Tables *}
schirmer@12854
    97
wenzelm@37956
    98
definition
wenzelm@37956
    99
  filter_tab :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> ('a, 'b) table \<Rightarrow> ('a, 'b) table" where
wenzelm@37956
   100
  "filter_tab c t = (\<lambda>k. (case t k of 
schirmer@12854
   101
                           None   \<Rightarrow> None
wenzelm@37956
   102
                         | Some x \<Rightarrow> if c k x then Some x else None))"
schirmer@12854
   103
schirmer@12854
   104
lemma filter_tab_empty[simp]: "filter_tab c empty = empty"
schirmer@12854
   105
by (simp add: filter_tab_def empty_def)
schirmer@12854
   106
schirmer@12854
   107
lemma filter_tab_True[simp]: "filter_tab (\<lambda>x y. True) t = t"
nipkow@39302
   108
by (simp add: fun_eq_iff filter_tab_def)
schirmer@12854
   109
schirmer@12854
   110
lemma filter_tab_False[simp]: "filter_tab (\<lambda>x y. False) t = empty"
nipkow@39302
   111
by (simp add: fun_eq_iff filter_tab_def empty_def)
schirmer@12854
   112
schirmer@12854
   113
lemma filter_tab_ran_subset: "ran (filter_tab c t) \<subseteq> ran t"
schirmer@12854
   114
by (auto simp add: filter_tab_def ran_def)
schirmer@12854
   115
schirmer@12854
   116
lemma filter_tab_range_subset: "range (filter_tab c t) \<subseteq> range t \<union> {None}"
schirmer@12854
   117
apply (auto simp add: filter_tab_def)
schirmer@12854
   118
apply (drule sym, blast)
schirmer@12854
   119
done
schirmer@12854
   120
schirmer@12854
   121
lemma finite_range_filter_tab:
schirmer@12854
   122
  "finite (range t) \<Longrightarrow> finite (range (filter_tab c t))"
schirmer@12854
   123
apply (rule_tac B="range t \<union> {None} " in finite_subset)
schirmer@12854
   124
apply (rule filter_tab_range_subset)
schirmer@12854
   125
apply (auto intro: finite_UnI)
schirmer@12854
   126
done
schirmer@12854
   127
schirmer@12854
   128
lemma filter_tab_SomeD[dest!]: 
schirmer@12854
   129
"filter_tab c t k = Some x \<Longrightarrow> (t k = Some x) \<and> c k x"
schirmer@12854
   130
by (auto simp add: filter_tab_def)
schirmer@12854
   131
schirmer@12854
   132
lemma filter_tab_SomeI: "\<lbrakk>t k = Some x;C k x\<rbrakk> \<Longrightarrow>filter_tab C t k = Some x"
schirmer@12854
   133
by (simp add: filter_tab_def)
schirmer@12854
   134
schirmer@12854
   135
lemma filter_tab_all_True: 
schirmer@12854
   136
 "\<forall> k y. t k = Some y \<longrightarrow> p k y \<Longrightarrow>filter_tab p t = t"
nipkow@39302
   137
apply (auto simp add: filter_tab_def fun_eq_iff)
schirmer@12854
   138
done
schirmer@12854
   139
schirmer@12854
   140
lemma filter_tab_all_True_Some:
schirmer@12854
   141
 "\<lbrakk>\<forall> k y. t k = Some y \<longrightarrow> p k y; t k = Some v\<rbrakk> \<Longrightarrow> filter_tab p t k = Some v"
nipkow@39302
   142
by (auto simp add: filter_tab_def fun_eq_iff)
schirmer@12854
   143
schirmer@12925
   144
lemma filter_tab_all_False: 
schirmer@12925
   145
 "\<forall> k y. t k = Some y \<longrightarrow> \<not> p k y \<Longrightarrow>filter_tab p t = empty"
nipkow@39302
   146
by (auto simp add: filter_tab_def fun_eq_iff)
schirmer@12925
   147
schirmer@12854
   148
lemma filter_tab_None: "t k = None \<Longrightarrow> filter_tab p t k = None"
nipkow@39302
   149
apply (simp add: filter_tab_def fun_eq_iff)
schirmer@12854
   150
done
schirmer@12854
   151
schirmer@12854
   152
lemma filter_tab_dom_subset: "dom (filter_tab C t) \<subseteq> dom t"
schirmer@12854
   153
by (auto simp add: filter_tab_def dom_def)
schirmer@12854
   154
schirmer@12854
   155
lemma filter_tab_eq: "\<lbrakk>a=b\<rbrakk> \<Longrightarrow> filter_tab C a = filter_tab C b"
nipkow@39302
   156
by (auto simp add: fun_eq_iff filter_tab_def)
schirmer@12854
   157
schirmer@12854
   158
lemma finite_dom_filter_tab:
schirmer@12854
   159
"finite (dom t) \<Longrightarrow> finite (dom (filter_tab C t))"
schirmer@12854
   160
apply (rule_tac B="dom t" in finite_subset)
schirmer@12854
   161
by (rule filter_tab_dom_subset)
schirmer@12854
   162
schirmer@12854
   163
schirmer@12854
   164
lemma filter_tab_weaken:
schirmer@12854
   165
"\<lbrakk>\<forall> a \<in> t k: \<exists> b \<in> s k: P a b; 
schirmer@12854
   166
  \<And> k x y. \<lbrakk>t k = Some x;s k = Some y\<rbrakk> \<Longrightarrow> cond k x \<longrightarrow> cond k y
schirmer@12854
   167
 \<rbrakk> \<Longrightarrow> \<forall> a \<in> filter_tab cond t k: \<exists> b \<in> filter_tab cond s k: P a b"
berghofe@13601
   168
apply (force simp add: filter_tab_def)
schirmer@12854
   169
done
schirmer@12854
   170
schirmer@12854
   171
lemma cond_override_filter: 
schirmer@12854
   172
  "\<lbrakk>\<And> k old new. \<lbrakk>s k = Some new; t k = Some old\<rbrakk> 
schirmer@12854
   173
    \<Longrightarrow> (\<not> overC new old \<longrightarrow>  \<not> filterC k new) \<and> 
schirmer@12854
   174
        (overC new old \<longrightarrow> filterC k old \<longrightarrow> filterC k new)
schirmer@12854
   175
   \<rbrakk> \<Longrightarrow>
schirmer@12854
   176
    cond_override overC (filter_tab filterC t) (filter_tab filterC s) 
schirmer@12854
   177
    = filter_tab filterC (cond_override overC t s)"
nipkow@39302
   178
by (auto simp add: fun_eq_iff cond_override_def filter_tab_def )
schirmer@12854
   179
schirmer@12925
   180
schirmer@12854
   181
section {* Misc. *}
schirmer@12854
   182
schirmer@12854
   183
lemma Ball_set_table: "(\<forall> (x,y)\<in> set l. P x y) \<Longrightarrow> \<forall> x. \<forall> y\<in> map_of l x: P x y"
wenzelm@24038
   184
apply (erule rev_mp)
schirmer@12854
   185
apply (induct l)
schirmer@12854
   186
apply simp
schirmer@12854
   187
apply (simp (no_asm))
schirmer@12854
   188
apply auto
schirmer@12854
   189
done
schirmer@12854
   190
schirmer@12854
   191
lemma Ball_set_tableD: 
nipkow@30235
   192
  "\<lbrakk>(\<forall> (x,y)\<in> set l. P x y); x \<in> Option.set (table_of l xa)\<rbrakk> \<Longrightarrow> P xa x"
schirmer@12854
   193
apply (frule Ball_set_table)
schirmer@12854
   194
by auto
schirmer@12854
   195
schirmer@12854
   196
declare map_of_SomeD [elim]
schirmer@12854
   197
schirmer@12854
   198
lemma table_of_Some_in_set:
schirmer@12854
   199
"table_of l k = Some x \<Longrightarrow> (k,x) \<in> set l"
schirmer@12854
   200
by auto
schirmer@12854
   201
schirmer@12854
   202
lemma set_get_eq: 
schirmer@12854
   203
  "unique l \<Longrightarrow> (k, the (table_of l k)) \<in> set l = (table_of l k \<noteq> None)"
paulson@18447
   204
by (auto dest!: weak_map_of_SomeI)
schirmer@12854
   205
schirmer@12854
   206
lemma inj_Pair_const2: "inj (\<lambda>k. (k, C))"
paulson@13585
   207
apply (rule inj_onI)
schirmer@12854
   208
apply auto
schirmer@12854
   209
done
schirmer@12854
   210
schirmer@12854
   211
lemma table_of_mapconst_SomeI:
schirmer@12854
   212
  "\<lbrakk>table_of t k = Some y'; snd y=y'; fst y=c\<rbrakk> \<Longrightarrow>
schirmer@12854
   213
   table_of (map (\<lambda>(k,x). (k,c,x)) t) k = Some y"
schirmer@12854
   214
apply (induct t)
schirmer@12854
   215
apply auto
schirmer@12854
   216
done
schirmer@12854
   217
schirmer@12854
   218
lemma table_of_mapconst_NoneI:
schirmer@12854
   219
  "\<lbrakk>table_of t k = None\<rbrakk> \<Longrightarrow>
schirmer@12854
   220
   table_of (map (\<lambda>(k,x). (k,c,x)) t) k = None"
schirmer@12854
   221
apply (induct t)
schirmer@12854
   222
apply auto
schirmer@12854
   223
done
schirmer@12854
   224
wenzelm@45605
   225
lemmas table_of_map2_SomeI = inj_Pair_const2 [THEN map_of_mapk_SomeI]
schirmer@12854
   226
schirmer@12854
   227
lemma table_of_map_SomeI [rule_format (no_asm)]: "table_of t k = Some x \<longrightarrow>
schirmer@12854
   228
   table_of (map (\<lambda>(k,x). (k, f x)) t) k = Some (f x)"
schirmer@12854
   229
apply (induct_tac "t")
schirmer@12854
   230
apply auto
schirmer@12854
   231
done
schirmer@12854
   232
schirmer@12854
   233
lemma table_of_remap_SomeD [rule_format (no_asm)]: 
schirmer@12854
   234
  "table_of (map (\<lambda>((k,k'),x). (k,(k',x))) t) k = Some (k',x) \<longrightarrow>
schirmer@12854
   235
  table_of t (k, k') = Some x"
schirmer@12854
   236
apply (induct_tac "t")
schirmer@12854
   237
apply  auto
schirmer@12854
   238
done
schirmer@12854
   239
schirmer@12854
   240
lemma table_of_mapf_Some [rule_format (no_asm)]: "\<forall>x y. f x = f y \<longrightarrow> x = y \<Longrightarrow> 
schirmer@12854
   241
  table_of (map (\<lambda>(k,x). (k,f x)) t) k = Some (f x) \<longrightarrow> table_of t k = Some x"
schirmer@12854
   242
apply (induct_tac "t")
schirmer@12854
   243
apply  auto
schirmer@12854
   244
done
schirmer@12854
   245
schirmer@12854
   246
lemma table_of_mapf_SomeD [rule_format (no_asm), dest!]: 
schirmer@12854
   247
"table_of (map (\<lambda>(k,x). (k, f x)) t) k = Some z \<longrightarrow> (\<exists>y\<in>table_of t k: z=f y)"
schirmer@12854
   248
apply (induct_tac "t")
schirmer@12854
   249
apply  auto
schirmer@12854
   250
done
schirmer@12854
   251
schirmer@12854
   252
lemma table_of_mapf_NoneD [rule_format (no_asm), dest!]: 
schirmer@12854
   253
"table_of (map (\<lambda>(k,x). (k, f x)) t) k = None \<longrightarrow> (table_of t k = None)"
schirmer@12854
   254
apply (induct_tac "t")
schirmer@12854
   255
apply auto
schirmer@12854
   256
done
schirmer@12854
   257
schirmer@12854
   258
lemma table_of_mapkey_SomeD [rule_format (no_asm), dest!]: 
schirmer@12854
   259
  "table_of (map (\<lambda>(k,x). ((k,C),x)) t) (k,D) = Some x \<longrightarrow> C = D \<and> table_of t k = Some x"
schirmer@12854
   260
apply (induct_tac "t")
schirmer@12854
   261
apply  auto
schirmer@12854
   262
done
schirmer@12854
   263
lemma table_of_mapkey_SomeD2 [rule_format (no_asm), dest!]: 
schirmer@12854
   264
  "table_of (map (\<lambda>(k,x). ((k,C),x)) t) ek = Some x 
schirmer@12854
   265
   \<longrightarrow> C = snd ek \<and> table_of t (fst ek) = Some x"
schirmer@12854
   266
apply (induct_tac "t")
schirmer@12854
   267
apply  auto
schirmer@12854
   268
done
schirmer@12854
   269
schirmer@12854
   270
lemma table_append_Some_iff: "table_of (xs@ys) k = Some z = 
schirmer@12854
   271
 (table_of xs k = Some z \<or> (table_of xs k = None \<and> table_of ys k = Some z))"
nipkow@14025
   272
apply (simp)
nipkow@14025
   273
apply (rule map_add_Some_iff)
schirmer@12854
   274
done
schirmer@12854
   275
schirmer@12854
   276
lemma table_of_filter_unique_SomeD [rule_format (no_asm)]:
schirmer@12854
   277
  "table_of (filter P xs) k = Some z \<Longrightarrow> unique xs \<longrightarrow> table_of xs k = Some z"
schirmer@12854
   278
apply (induct xs)
schirmer@12854
   279
apply (auto del: map_of_SomeD intro!: map_of_SomeD)
schirmer@12854
   280
done
schirmer@12854
   281
schirmer@12854
   282
wenzelm@37956
   283
definition
wenzelm@37956
   284
  Un_tables :: "('a, 'b) tables set \<Rightarrow> ('a, 'b) tables"
wenzelm@37956
   285
  where "Un_tables ts\<spacespace>\<spacespace>= (\<lambda>k. \<Union>t\<in>ts. t k)"
wenzelm@37956
   286
wenzelm@37956
   287
definition
wenzelm@37956
   288
  overrides_t :: "('a, 'b) tables \<Rightarrow> ('a, 'b) tables \<Rightarrow> ('a, 'b) tables"  (infixl "\<oplus>\<oplus>" 100)
wenzelm@37956
   289
  where "s \<oplus>\<oplus> t = (\<lambda>k. if t k = {} then s k else t k)"
wenzelm@37956
   290
wenzelm@37956
   291
definition
wenzelm@37956
   292
  hidings_entails :: "('a, 'b) tables \<Rightarrow> ('a, 'c) tables \<Rightarrow> ('b \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> bool"
wenzelm@37956
   293
    ("_ hidings _ entails _" 20)
wenzelm@37956
   294
  where "(t hidings s entails R) = (\<forall>k. \<forall>x\<in>t k. \<forall>y\<in>s k. R x y)"
wenzelm@37956
   295
wenzelm@37956
   296
definition
schirmer@13688
   297
  --{* variant for unique table: *}
wenzelm@37956
   298
  hiding_entails :: "('a, 'b) table  \<Rightarrow> ('a, 'c) table  \<Rightarrow> ('b \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> bool"
wenzelm@37956
   299
    ("_ hiding _ entails _"  20)
wenzelm@37956
   300
  where "(t hiding  s entails R) = (\<forall>k. \<forall>x\<in>t k: \<forall>y\<in>s k: R x y)"
wenzelm@37956
   301
wenzelm@37956
   302
definition
schirmer@13688
   303
  --{* variant for a unique table and conditional overriding: *}
schirmer@12854
   304
  cond_hiding_entails :: "('a, 'b) table  \<Rightarrow> ('a, 'c) table  
schirmer@12854
   305
                          \<Rightarrow> ('b \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> ('b \<Rightarrow> 'c \<Rightarrow> bool) \<Rightarrow> bool"  
schirmer@12854
   306
                          ("_ hiding _ under _ entails _"  20)
wenzelm@37956
   307
  where "(t hiding  s under C entails R) = (\<forall>k. \<forall>x\<in>t k: \<forall>y\<in>s k: C x y \<longrightarrow> R x y)"
schirmer@12854
   308
schirmer@12854
   309
section "Untables"
schirmer@12854
   310
schirmer@12854
   311
lemma Un_tablesI [intro]:  "\<And>x. \<lbrakk>t \<in> ts; x \<in> t k\<rbrakk> \<Longrightarrow> x \<in> Un_tables ts k"
schirmer@12854
   312
apply (simp add: Un_tables_def)
schirmer@12854
   313
apply auto
schirmer@12854
   314
done
schirmer@12854
   315
schirmer@12854
   316
lemma Un_tablesD [dest!]: "\<And>x. x \<in> Un_tables ts k \<Longrightarrow> \<exists>t. t \<in> ts \<and> x \<in> t k"
schirmer@12854
   317
apply (simp add: Un_tables_def)
schirmer@12854
   318
apply auto
schirmer@12854
   319
done
schirmer@12854
   320
schirmer@12854
   321
lemma Un_tables_empty [simp]: "Un_tables {} = (\<lambda>k. {})"
schirmer@12854
   322
apply (unfold Un_tables_def)
schirmer@12854
   323
apply (simp (no_asm))
schirmer@12854
   324
done
schirmer@12854
   325
schirmer@12854
   326
schirmer@12854
   327
section "overrides"
schirmer@12854
   328
schirmer@12854
   329
lemma empty_overrides_t [simp]: "(\<lambda>k. {}) \<oplus>\<oplus> m = m"
schirmer@12854
   330
apply (unfold overrides_t_def)
schirmer@12854
   331
apply (simp (no_asm))
schirmer@12854
   332
done
schirmer@12854
   333
lemma overrides_empty_t [simp]: "m \<oplus>\<oplus> (\<lambda>k. {}) = m"
schirmer@12854
   334
apply (unfold overrides_t_def)
schirmer@12854
   335
apply (simp (no_asm))
schirmer@12854
   336
done
schirmer@12854
   337
schirmer@12854
   338
lemma overrides_t_Some_iff: 
schirmer@12854
   339
 "(x \<in> (s \<oplus>\<oplus> t) k) = (x \<in> t k \<or> t k = {} \<and> x \<in> s k)"
schirmer@12854
   340
by (simp add: overrides_t_def)
schirmer@12854
   341
schirmer@12854
   342
lemmas overrides_t_SomeD = overrides_t_Some_iff [THEN iffD1, dest!]
schirmer@12854
   343
schirmer@12854
   344
lemma overrides_t_right_empty [simp]: "n k = {} \<Longrightarrow> (m \<oplus>\<oplus> n) k = m k"  
schirmer@12854
   345
by (simp add: overrides_t_def)
schirmer@12854
   346
schirmer@12854
   347
lemma overrides_t_find_right [simp]: "n k \<noteq> {} \<Longrightarrow> (m \<oplus>\<oplus> n) k = n k"  
schirmer@12854
   348
by (simp add: overrides_t_def)
schirmer@12854
   349
schirmer@12854
   350
section "hiding entails"
schirmer@12854
   351
schirmer@12854
   352
lemma hiding_entailsD: 
schirmer@12854
   353
  "\<lbrakk>t hiding s entails R; t k = Some x; s k = Some y\<rbrakk> \<Longrightarrow> R x y"
schirmer@12854
   354
by (simp add: hiding_entails_def)
schirmer@12854
   355
schirmer@12854
   356
lemma empty_hiding_entails: "empty hiding s entails R"
schirmer@12854
   357
by (simp add: hiding_entails_def)
schirmer@12854
   358
schirmer@12854
   359
lemma hiding_empty_entails: "t hiding empty entails R"
schirmer@12854
   360
by (simp add: hiding_entails_def)
schirmer@12854
   361
declare empty_hiding_entails [simp] hiding_empty_entails [simp]
schirmer@12854
   362
schirmer@12854
   363
section "cond hiding entails"
schirmer@12854
   364
schirmer@12854
   365
lemma cond_hiding_entailsD: 
schirmer@12854
   366
"\<lbrakk>t hiding s under C entails R; t k = Some x; s k = Some y; C x y\<rbrakk> \<Longrightarrow> R x y"
schirmer@12854
   367
by (simp add: cond_hiding_entails_def)
schirmer@12854
   368
schirmer@12854
   369
lemma empty_cond_hiding_entails[simp]: "empty hiding s under C entails R"
schirmer@12854
   370
by (simp add: cond_hiding_entails_def)
schirmer@12854
   371
schirmer@12854
   372
lemma cond_hiding_empty_entails[simp]: "t hiding empty under C entails R"
schirmer@12854
   373
by (simp add: cond_hiding_entails_def)
schirmer@12854
   374
schirmer@12854
   375
lemma hidings_entailsD: "\<lbrakk>t hidings s entails R; x \<in> t k; y \<in> s k\<rbrakk> \<Longrightarrow> R x y"
schirmer@12854
   376
by (simp add: hidings_entails_def)
schirmer@12854
   377
schirmer@12854
   378
lemma hidings_empty_entails: "t hidings (\<lambda>k. {}) entails R"
schirmer@12854
   379
apply (unfold hidings_entails_def)
schirmer@12854
   380
apply (simp (no_asm))
schirmer@12854
   381
done
schirmer@12854
   382
schirmer@12854
   383
lemma empty_hidings_entails: 
schirmer@12854
   384
  "(\<lambda>k. {}) hidings s entails R"apply (unfold hidings_entails_def)
schirmer@12854
   385
by (simp (no_asm))
schirmer@12854
   386
declare empty_hidings_entails [intro!] hidings_empty_entails [intro!]
schirmer@12854
   387
schirmer@12854
   388
schirmer@12854
   389
schirmer@12854
   390
(*###TO Map?*)
wenzelm@37956
   391
primrec atleast_free :: "('a ~=> 'b) => nat => bool"
wenzelm@37956
   392
where
wenzelm@37956
   393
  "atleast_free m 0 = True"
wenzelm@37956
   394
| atleast_free_Suc: "atleast_free m (Suc n) = (\<exists>a. m a = None & (!b. atleast_free (m(a|->b)) n))"
schirmer@12854
   395
schirmer@12854
   396
lemma atleast_free_weaken [rule_format (no_asm)]: 
schirmer@12854
   397
  "!m. atleast_free m (Suc n) \<longrightarrow> atleast_free m n"
schirmer@12854
   398
apply (induct_tac "n")
schirmer@12854
   399
apply (simp (no_asm))
schirmer@12854
   400
apply clarify
schirmer@12854
   401
apply (simp (no_asm))
schirmer@12854
   402
apply (drule atleast_free_Suc [THEN iffD1])
schirmer@12854
   403
apply fast
schirmer@12854
   404
done
schirmer@12854
   405
schirmer@12854
   406
lemma atleast_free_SucI: 
schirmer@12854
   407
"[| h a = None; !obj. atleast_free (h(a|->obj)) n |] ==> atleast_free h (Suc n)"
schirmer@12854
   408
by force
schirmer@12854
   409
schirmer@12854
   410
declare fun_upd_apply [simp del]
schirmer@12854
   411
lemma atleast_free_SucD_lemma [rule_format (no_asm)]: 
schirmer@12854
   412
" !m a. m a = None --> (!c. atleast_free (m(a|->c)) n) -->  
schirmer@12854
   413
  (!b d. a ~= b --> atleast_free (m(b|->d)) n)"
schirmer@12854
   414
apply (induct_tac "n")
schirmer@12854
   415
apply  auto
schirmer@12854
   416
apply (rule_tac x = "a" in exI)
schirmer@12854
   417
apply  (rule conjI)
schirmer@12854
   418
apply  (force simp add: fun_upd_apply)
schirmer@12854
   419
apply (erule_tac V = "m a = None" in thin_rl)
schirmer@12854
   420
apply clarify
schirmer@12854
   421
apply (subst fun_upd_twist)
schirmer@12854
   422
apply  (erule not_sym)
schirmer@12854
   423
apply (rename_tac "ba")
schirmer@12854
   424
apply (drule_tac x = "ba" in spec)
schirmer@12854
   425
apply clarify
schirmer@12854
   426
apply (tactic "smp_tac 2 1")
schirmer@12854
   427
apply (erule (1) notE impE)
schirmer@12854
   428
apply (case_tac "aa = b")
schirmer@12854
   429
apply fast+
schirmer@12854
   430
done
schirmer@12854
   431
declare fun_upd_apply [simp]
schirmer@12854
   432
schirmer@12854
   433
lemma atleast_free_SucD [rule_format (no_asm)]: "atleast_free h (Suc n) ==> atleast_free (h(a|->b)) n"
schirmer@12854
   434
apply auto
schirmer@12854
   435
apply (case_tac "aa = a")
schirmer@12854
   436
apply auto
schirmer@12854
   437
apply (erule atleast_free_SucD_lemma)
schirmer@12854
   438
apply auto
schirmer@12854
   439
done
schirmer@12854
   440
schirmer@12854
   441
declare atleast_free_Suc [simp del]
schirmer@12854
   442
end