src/HOL/UNITY/Constrains.thy
author paulson
Fri Jan 31 20:12:44 2003 +0100 (2003-01-31)
changeset 13798 4c1a53627500
parent 13797 baefae13ad37
child 13805 3786b2fd6808
permissions -rw-r--r--
conversion to new-style theories and tidying
paulson@5313
     1
(*  Title:      HOL/UNITY/Constrains
paulson@5313
     2
    ID:         $Id$
paulson@5313
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
paulson@5313
     4
    Copyright   1998  University of Cambridge
paulson@5313
     5
paulson@13797
     6
Weak safety relations: restricted to the set of reachable states.
paulson@5313
     7
*)
paulson@5313
     8
paulson@13798
     9
header{*Weak Safety*}
paulson@13798
    10
paulson@13797
    11
theory Constrains = UNITY:
paulson@6535
    12
paulson@6535
    13
consts traces :: "['a set, ('a * 'a)set set] => ('a * 'a list) set"
paulson@6535
    14
paulson@6535
    15
  (*Initial states and program => (final state, reversed trace to it)...
paulson@6535
    16
    Arguments MUST be curried in an inductive definition*)
paulson@6535
    17
paulson@6535
    18
inductive "traces init acts"  
paulson@13797
    19
  intros 
paulson@6535
    20
         (*Initial trace is empty*)
paulson@13797
    21
    Init:  "s: init ==> (s,[]) : traces init acts"
paulson@6535
    22
paulson@13797
    23
    Acts:  "[| act: acts;  (s,evs) : traces init acts;  (s,s'): act |]
paulson@13797
    24
	    ==> (s', s#evs) : traces init acts"
paulson@6535
    25
paulson@6535
    26
paulson@6535
    27
consts reachable :: "'a program => 'a set"
paulson@6535
    28
paulson@6535
    29
inductive "reachable F"
paulson@13797
    30
  intros 
paulson@13797
    31
    Init:  "s: Init F ==> s : reachable F"
paulson@5313
    32
paulson@13797
    33
    Acts:  "[| act: Acts F;  s : reachable F;  (s,s'): act |]
paulson@13797
    34
	    ==> s' : reachable F"
paulson@6536
    35
paulson@13797
    36
constdefs
paulson@13797
    37
  Constrains :: "['a set, 'a set] => 'a program set"  (infixl "Co" 60)
paulson@6575
    38
    "A Co B == {F. F : (reachable F Int A)  co  B}"
paulson@6536
    39
paulson@13797
    40
  Unless  :: "['a set, 'a set] => 'a program set"     (infixl "Unless" 60)
paulson@6536
    41
    "A Unless B == (A-B) Co (A Un B)"
paulson@6536
    42
paulson@5648
    43
  Stable     :: "'a set => 'a program set"
paulson@6536
    44
    "Stable A == A Co A"
paulson@5313
    45
paulson@6570
    46
  (*Always is the weak form of "invariant"*)
paulson@6570
    47
  Always :: "'a set => 'a program set"
paulson@6570
    48
    "Always A == {F. Init F <= A} Int Stable A"
paulson@5313
    49
paulson@5784
    50
  (*Polymorphic in both states and the meaning of <= *)
paulson@6705
    51
  Increasing :: "['a => 'b::{order}] => 'a program set"
paulson@5784
    52
    "Increasing f == INT z. Stable {s. z <= f s}"
paulson@5784
    53
paulson@13797
    54
paulson@13798
    55
subsection{*traces and reachable*}
paulson@13797
    56
paulson@13797
    57
lemma reachable_equiv_traces:
paulson@13797
    58
     "reachable F = {s. EX evs. (s,evs): traces (Init F) (Acts F)}"
paulson@13797
    59
apply safe
paulson@13797
    60
apply (erule_tac [2] traces.induct)
paulson@13797
    61
apply (erule reachable.induct)
paulson@13797
    62
apply (blast intro: reachable.intros traces.intros)+
paulson@13797
    63
done
paulson@13797
    64
paulson@13797
    65
lemma Init_subset_reachable: "Init F <= reachable F"
paulson@13797
    66
by (blast intro: reachable.intros)
paulson@13797
    67
paulson@13797
    68
lemma stable_reachable [intro!,simp]:
paulson@13797
    69
     "Acts G <= Acts F ==> G : stable (reachable F)"
paulson@13797
    70
by (blast intro: stableI constrainsI reachable.intros)
paulson@13797
    71
paulson@13797
    72
(*The set of all reachable states is an invariant...*)
paulson@13797
    73
lemma invariant_reachable: "F : invariant (reachable F)"
paulson@13797
    74
apply (simp add: invariant_def)
paulson@13797
    75
apply (blast intro: reachable.intros)
paulson@13797
    76
done
paulson@13797
    77
paulson@13797
    78
(*...in fact the strongest invariant!*)
paulson@13797
    79
lemma invariant_includes_reachable: "F : invariant A ==> reachable F <= A"
paulson@13797
    80
apply (simp add: stable_def constrains_def invariant_def)
paulson@13797
    81
apply (rule subsetI)
paulson@13797
    82
apply (erule reachable.induct)
paulson@13797
    83
apply (blast intro: reachable.intros)+
paulson@13797
    84
done
paulson@13797
    85
paulson@13797
    86
paulson@13798
    87
subsection{*Co*}
paulson@13797
    88
paulson@13797
    89
(*F : B co B' ==> F : (reachable F Int B) co (reachable F Int B')*)
paulson@13797
    90
lemmas constrains_reachable_Int =  
paulson@13797
    91
    subset_refl [THEN stable_reachable [unfolded stable_def], 
paulson@13797
    92
                 THEN constrains_Int, standard]
paulson@13797
    93
paulson@13797
    94
(*Resembles the previous definition of Constrains*)
paulson@13797
    95
lemma Constrains_eq_constrains: 
paulson@13797
    96
     "A Co B = {F. F : (reachable F  Int  A) co (reachable F  Int  B)}"
paulson@13797
    97
apply (unfold Constrains_def)
paulson@13797
    98
apply (blast dest: constrains_reachable_Int intro: constrains_weaken)
paulson@13797
    99
done
paulson@13797
   100
paulson@13797
   101
lemma constrains_imp_Constrains: "F : A co A' ==> F : A Co A'"
paulson@13797
   102
apply (unfold Constrains_def)
paulson@13797
   103
apply (blast intro: constrains_weaken_L)
paulson@13797
   104
done
paulson@13797
   105
paulson@13797
   106
lemma stable_imp_Stable: "F : stable A ==> F : Stable A"
paulson@13797
   107
apply (unfold stable_def Stable_def)
paulson@13797
   108
apply (erule constrains_imp_Constrains)
paulson@13797
   109
done
paulson@13797
   110
paulson@13797
   111
lemma ConstrainsI: 
paulson@13797
   112
    "(!!act s s'. [| act: Acts F;  (s,s') : act;  s: A |] ==> s': A')  
paulson@13797
   113
     ==> F : A Co A'"
paulson@13797
   114
apply (rule constrains_imp_Constrains)
paulson@13797
   115
apply (blast intro: constrainsI)
paulson@13797
   116
done
paulson@13797
   117
paulson@13797
   118
lemma Constrains_empty [iff]: "F : {} Co B"
paulson@13797
   119
by (unfold Constrains_def constrains_def, blast)
paulson@13797
   120
paulson@13797
   121
lemma Constrains_UNIV [iff]: "F : A Co UNIV"
paulson@13797
   122
by (blast intro: ConstrainsI)
paulson@13797
   123
paulson@13797
   124
lemma Constrains_weaken_R: 
paulson@13797
   125
    "[| F : A Co A'; A'<=B' |] ==> F : A Co B'"
paulson@13797
   126
apply (unfold Constrains_def)
paulson@13797
   127
apply (blast intro: constrains_weaken_R)
paulson@13797
   128
done
paulson@13797
   129
paulson@13797
   130
lemma Constrains_weaken_L: 
paulson@13797
   131
    "[| F : A Co A'; B<=A |] ==> F : B Co A'"
paulson@13797
   132
apply (unfold Constrains_def)
paulson@13797
   133
apply (blast intro: constrains_weaken_L)
paulson@13797
   134
done
paulson@13797
   135
paulson@13797
   136
lemma Constrains_weaken: 
paulson@13797
   137
   "[| F : A Co A'; B<=A; A'<=B' |] ==> F : B Co B'"
paulson@13797
   138
apply (unfold Constrains_def)
paulson@13797
   139
apply (blast intro: constrains_weaken)
paulson@13797
   140
done
paulson@13797
   141
paulson@13797
   142
(** Union **)
paulson@13797
   143
paulson@13797
   144
lemma Constrains_Un: 
paulson@13797
   145
    "[| F : A Co A'; F : B Co B' |] ==> F : (A Un B) Co (A' Un B')"
paulson@13797
   146
apply (unfold Constrains_def)
paulson@13797
   147
apply (blast intro: constrains_Un [THEN constrains_weaken])
paulson@13797
   148
done
paulson@13797
   149
paulson@13797
   150
lemma Constrains_UN: 
paulson@13797
   151
  assumes Co: "!!i. i:I ==> F : (A i) Co (A' i)"
paulson@13797
   152
  shows "F : (UN i:I. A i) Co (UN i:I. A' i)"
paulson@13797
   153
apply (unfold Constrains_def)
paulson@13797
   154
apply (rule CollectI)
paulson@13797
   155
apply (rule Co [unfolded Constrains_def, THEN CollectD, THEN constrains_UN, 
paulson@13797
   156
                THEN constrains_weaken],   auto)
paulson@13797
   157
done
paulson@13797
   158
paulson@13797
   159
(** Intersection **)
paulson@13797
   160
paulson@13797
   161
lemma Constrains_Int: 
paulson@13797
   162
    "[| F : A Co A'; F : B Co B' |] ==> F : (A Int B) Co (A' Int B')"
paulson@13797
   163
apply (unfold Constrains_def)
paulson@13797
   164
apply (blast intro: constrains_Int [THEN constrains_weaken])
paulson@13797
   165
done
paulson@13797
   166
paulson@13797
   167
lemma Constrains_INT: 
paulson@13797
   168
  assumes Co: "!!i. i:I ==> F : (A i) Co (A' i)"
paulson@13797
   169
  shows "F : (INT i:I. A i) Co (INT i:I. A' i)"
paulson@13797
   170
apply (unfold Constrains_def)
paulson@13797
   171
apply (rule CollectI)
paulson@13797
   172
apply (rule Co [unfolded Constrains_def, THEN CollectD, THEN constrains_INT, 
paulson@13797
   173
                THEN constrains_weaken],   auto)
paulson@13797
   174
done
paulson@13797
   175
paulson@13797
   176
lemma Constrains_imp_subset: "F : A Co A' ==> reachable F Int A <= A'"
paulson@13797
   177
by (simp add: constrains_imp_subset Constrains_def)
paulson@13797
   178
paulson@13797
   179
lemma Constrains_trans: "[| F : A Co B; F : B Co C |] ==> F : A Co C"
paulson@13797
   180
apply (simp add: Constrains_eq_constrains)
paulson@13797
   181
apply (blast intro: constrains_trans constrains_weaken)
paulson@13797
   182
done
paulson@13797
   183
paulson@13797
   184
lemma Constrains_cancel:
paulson@13797
   185
     "[| F : A Co (A' Un B); F : B Co B' |] ==> F : A Co (A' Un B')"
paulson@13797
   186
by (simp add: Constrains_eq_constrains constrains_def, blast)
paulson@13797
   187
paulson@13797
   188
paulson@13798
   189
subsection{*Stable*}
paulson@13797
   190
paulson@13797
   191
(*Useful because there's no Stable_weaken.  [Tanja Vos]*)
paulson@13797
   192
lemma Stable_eq: "[| F: Stable A; A = B |] ==> F : Stable B"
paulson@13797
   193
by blast
paulson@13797
   194
paulson@13797
   195
lemma Stable_eq_stable: "(F : Stable A) = (F : stable (reachable F Int A))"
paulson@13797
   196
by (simp add: Stable_def Constrains_eq_constrains stable_def)
paulson@13797
   197
paulson@13797
   198
lemma StableI: "F : A Co A ==> F : Stable A"
paulson@13797
   199
by (unfold Stable_def, assumption)
paulson@13797
   200
paulson@13797
   201
lemma StableD: "F : Stable A ==> F : A Co A"
paulson@13797
   202
by (unfold Stable_def, assumption)
paulson@13797
   203
paulson@13797
   204
lemma Stable_Un: 
paulson@13797
   205
    "[| F : Stable A; F : Stable A' |] ==> F : Stable (A Un A')"
paulson@13797
   206
apply (unfold Stable_def)
paulson@13797
   207
apply (blast intro: Constrains_Un)
paulson@13797
   208
done
paulson@13797
   209
paulson@13797
   210
lemma Stable_Int: 
paulson@13797
   211
    "[| F : Stable A; F : Stable A' |] ==> F : Stable (A Int A')"
paulson@13797
   212
apply (unfold Stable_def)
paulson@13797
   213
apply (blast intro: Constrains_Int)
paulson@13797
   214
done
paulson@13797
   215
paulson@13797
   216
lemma Stable_Constrains_Un: 
paulson@13797
   217
    "[| F : Stable C; F : A Co (C Un A') |]    
paulson@13797
   218
     ==> F : (C Un A) Co (C Un A')"
paulson@13797
   219
apply (unfold Stable_def)
paulson@13797
   220
apply (blast intro: Constrains_Un [THEN Constrains_weaken])
paulson@13797
   221
done
paulson@13797
   222
paulson@13797
   223
lemma Stable_Constrains_Int: 
paulson@13797
   224
    "[| F : Stable C; F : (C Int A) Co A' |]    
paulson@13797
   225
     ==> F : (C Int A) Co (C Int A')"
paulson@13797
   226
apply (unfold Stable_def)
paulson@13797
   227
apply (blast intro: Constrains_Int [THEN Constrains_weaken])
paulson@13797
   228
done
paulson@13797
   229
paulson@13797
   230
lemma Stable_UN: 
paulson@13797
   231
    "(!!i. i:I ==> F : Stable (A i)) ==> F : Stable (UN i:I. A i)"
paulson@13797
   232
by (simp add: Stable_def Constrains_UN) 
paulson@13797
   233
paulson@13797
   234
lemma Stable_INT: 
paulson@13797
   235
    "(!!i. i:I ==> F : Stable (A i)) ==> F : Stable (INT i:I. A i)"
paulson@13797
   236
by (simp add: Stable_def Constrains_INT) 
paulson@13797
   237
paulson@13797
   238
lemma Stable_reachable: "F : Stable (reachable F)"
paulson@13797
   239
by (simp add: Stable_eq_stable)
paulson@13797
   240
paulson@13797
   241
paulson@13797
   242
paulson@13798
   243
subsection{*Increasing*}
paulson@13797
   244
paulson@13797
   245
lemma IncreasingD: 
paulson@13797
   246
     "F : Increasing f ==> F : Stable {s. x <= f s}"
paulson@13797
   247
by (unfold Increasing_def, blast)
paulson@13797
   248
paulson@13797
   249
lemma mono_Increasing_o: 
paulson@13797
   250
     "mono g ==> Increasing f <= Increasing (g o f)"
paulson@13797
   251
apply (simp add: Increasing_def Stable_def Constrains_def stable_def 
paulson@13797
   252
                 constrains_def)
paulson@13797
   253
apply (blast intro: monoD order_trans)
paulson@13797
   254
done
paulson@13797
   255
paulson@13797
   256
lemma strict_IncreasingD: 
paulson@13797
   257
     "!!z::nat. F : Increasing f ==> F: Stable {s. z < f s}"
paulson@13797
   258
by (simp add: Increasing_def Suc_le_eq [symmetric])
paulson@13797
   259
paulson@13797
   260
lemma increasing_imp_Increasing: 
paulson@13797
   261
     "F : increasing f ==> F : Increasing f"
paulson@13797
   262
apply (unfold increasing_def Increasing_def)
paulson@13797
   263
apply (blast intro: stable_imp_Stable)
paulson@13797
   264
done
paulson@13797
   265
paulson@13797
   266
lemmas Increasing_constant =  
paulson@13797
   267
    increasing_constant [THEN increasing_imp_Increasing, standard, iff]
paulson@13797
   268
paulson@13797
   269
paulson@13798
   270
subsection{*The Elimination Theorem*}
paulson@13798
   271
paulson@13798
   272
(*The "free" m has become universally quantified! Should the premise be !!m
paulson@13798
   273
instead of ALL m ?  Would make it harder to use in forward proof.*)
paulson@13797
   274
paulson@13797
   275
lemma Elimination: 
paulson@13797
   276
    "[| ALL m. F : {s. s x = m} Co (B m) |]  
paulson@13797
   277
     ==> F : {s. s x : M} Co (UN m:M. B m)"
paulson@13797
   278
by (unfold Constrains_def constrains_def, blast)
paulson@13797
   279
paulson@13797
   280
(*As above, but for the trivial case of a one-variable state, in which the
paulson@13797
   281
  state is identified with its one variable.*)
paulson@13797
   282
lemma Elimination_sing: 
paulson@13797
   283
    "(ALL m. F : {m} Co (B m)) ==> F : M Co (UN m:M. B m)"
paulson@13797
   284
by (unfold Constrains_def constrains_def, blast)
paulson@13797
   285
paulson@13797
   286
paulson@13798
   287
subsection{*Specialized laws for handling Always*}
paulson@13797
   288
paulson@13797
   289
(** Natural deduction rules for "Always A" **)
paulson@13797
   290
paulson@13797
   291
lemma AlwaysI: "[| Init F<=A;  F : Stable A |] ==> F : Always A"
paulson@13797
   292
by (simp add: Always_def)
paulson@13797
   293
paulson@13797
   294
lemma AlwaysD: "F : Always A ==> Init F<=A & F : Stable A"
paulson@13797
   295
by (simp add: Always_def)
paulson@13797
   296
paulson@13797
   297
lemmas AlwaysE = AlwaysD [THEN conjE, standard]
paulson@13797
   298
lemmas Always_imp_Stable = AlwaysD [THEN conjunct2, standard]
paulson@13797
   299
paulson@13797
   300
paulson@13797
   301
(*The set of all reachable states is Always*)
paulson@13797
   302
lemma Always_includes_reachable: "F : Always A ==> reachable F <= A"
paulson@13797
   303
apply (simp add: Stable_def Constrains_def constrains_def Always_def)
paulson@13797
   304
apply (rule subsetI)
paulson@13797
   305
apply (erule reachable.induct)
paulson@13797
   306
apply (blast intro: reachable.intros)+
paulson@13797
   307
done
paulson@13797
   308
paulson@13797
   309
lemma invariant_imp_Always: 
paulson@13797
   310
     "F : invariant A ==> F : Always A"
paulson@13797
   311
apply (unfold Always_def invariant_def Stable_def stable_def)
paulson@13797
   312
apply (blast intro: constrains_imp_Constrains)
paulson@13797
   313
done
paulson@13797
   314
paulson@13797
   315
lemmas Always_reachable =
paulson@13797
   316
    invariant_reachable [THEN invariant_imp_Always, standard]
paulson@13797
   317
paulson@13797
   318
lemma Always_eq_invariant_reachable:
paulson@13797
   319
     "Always A = {F. F : invariant (reachable F Int A)}"
paulson@13797
   320
apply (simp add: Always_def invariant_def Stable_def Constrains_eq_constrains
paulson@13797
   321
                 stable_def)
paulson@13797
   322
apply (blast intro: reachable.intros)
paulson@13797
   323
done
paulson@13797
   324
paulson@13797
   325
(*the RHS is the traditional definition of the "always" operator*)
paulson@13797
   326
lemma Always_eq_includes_reachable: "Always A = {F. reachable F <= A}"
paulson@13797
   327
by (auto dest: invariant_includes_reachable simp add: Int_absorb2 invariant_reachable Always_eq_invariant_reachable)
paulson@13797
   328
paulson@13797
   329
lemma Always_UNIV_eq [simp]: "Always UNIV = UNIV"
paulson@13797
   330
by (auto simp add: Always_eq_includes_reachable)
paulson@13797
   331
paulson@13797
   332
lemma UNIV_AlwaysI: "UNIV <= A ==> F : Always A"
paulson@13797
   333
by (auto simp add: Always_eq_includes_reachable)
paulson@13797
   334
paulson@13797
   335
lemma Always_eq_UN_invariant: "Always A = (UN I: Pow A. invariant I)"
paulson@13797
   336
apply (simp add: Always_eq_includes_reachable)
paulson@13797
   337
apply (blast intro: invariantI Init_subset_reachable [THEN subsetD] 
paulson@13797
   338
                    invariant_includes_reachable [THEN subsetD])
paulson@13797
   339
done
paulson@13797
   340
paulson@13797
   341
lemma Always_weaken: "[| F : Always A; A <= B |] ==> F : Always B"
paulson@13797
   342
by (auto simp add: Always_eq_includes_reachable)
paulson@13797
   343
paulson@13797
   344
paulson@13798
   345
subsection{*"Co" rules involving Always*}
paulson@13797
   346
paulson@13797
   347
lemma Always_Constrains_pre:
paulson@13797
   348
     "F : Always INV ==> (F : (INV Int A) Co A') = (F : A Co A')"
paulson@13797
   349
by (simp add: Always_includes_reachable [THEN Int_absorb2] Constrains_def 
paulson@13797
   350
              Int_assoc [symmetric])
paulson@13797
   351
paulson@13797
   352
lemma Always_Constrains_post:
paulson@13797
   353
     "F : Always INV ==> (F : A Co (INV Int A')) = (F : A Co A')"
paulson@13797
   354
by (simp add: Always_includes_reachable [THEN Int_absorb2] 
paulson@13797
   355
              Constrains_eq_constrains Int_assoc [symmetric])
paulson@13797
   356
paulson@13797
   357
(* [| F : Always INV;  F : (INV Int A) Co A' |] ==> F : A Co A' *)
paulson@13797
   358
lemmas Always_ConstrainsI = Always_Constrains_pre [THEN iffD1, standard]
paulson@13797
   359
paulson@13797
   360
(* [| F : Always INV;  F : A Co A' |] ==> F : A Co (INV Int A') *)
paulson@13797
   361
lemmas Always_ConstrainsD = Always_Constrains_post [THEN iffD2, standard]
paulson@13797
   362
paulson@13797
   363
(*The analogous proof of Always_LeadsTo_weaken doesn't terminate*)
paulson@13797
   364
lemma Always_Constrains_weaken:
paulson@13797
   365
     "[| F : Always C;  F : A Co A';    
paulson@13797
   366
         C Int B <= A;   C Int A' <= B' |]  
paulson@13797
   367
      ==> F : B Co B'"
paulson@13797
   368
apply (rule Always_ConstrainsI, assumption)
paulson@13797
   369
apply (drule Always_ConstrainsD, assumption)
paulson@13797
   370
apply (blast intro: Constrains_weaken)
paulson@13797
   371
done
paulson@13797
   372
paulson@13797
   373
paulson@13797
   374
(** Conjoining Always properties **)
paulson@13797
   375
paulson@13797
   376
lemma Always_Int_distrib: "Always (A Int B) = Always A Int Always B"
paulson@13797
   377
by (auto simp add: Always_eq_includes_reachable)
paulson@13797
   378
paulson@13797
   379
lemma Always_INT_distrib: "Always (INTER I A) = (INT i:I. Always (A i))"
paulson@13797
   380
by (auto simp add: Always_eq_includes_reachable)
paulson@13797
   381
paulson@13797
   382
lemma Always_Int_I:
paulson@13797
   383
     "[| F : Always A;  F : Always B |] ==> F : Always (A Int B)"
paulson@13797
   384
by (simp add: Always_Int_distrib)
paulson@13797
   385
paulson@13797
   386
(*Allows a kind of "implication introduction"*)
paulson@13797
   387
lemma Always_Compl_Un_eq:
paulson@13797
   388
     "F : Always A ==> (F : Always (-A Un B)) = (F : Always B)"
paulson@13797
   389
by (auto simp add: Always_eq_includes_reachable)
paulson@13797
   390
paulson@13797
   391
(*Delete the nearest invariance assumption (which will be the second one
paulson@13797
   392
  used by Always_Int_I) *)
paulson@13797
   393
lemmas Always_thin = thin_rl [of "F : Always A", standard]
paulson@13797
   394
paulson@5313
   395
end