src/HOL/UNITY/Simple/Lift.thy
author paulson
Wed Feb 05 13:35:32 2003 +0100 (2003-02-05)
changeset 13806 fd40c9d9076b
parent 13785 e2fcd88be55d
child 13812 91713a1915ee
permissions -rw-r--r--
more tidying
paulson@11195
     1
(*  Title:      HOL/UNITY/Lift.thy
paulson@11195
     2
    ID:         $Id$
paulson@11195
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
paulson@11195
     4
    Copyright   1998  University of Cambridge
paulson@11195
     5
paulson@11195
     6
The Lift-Control Example
paulson@11195
     7
*)
paulson@11195
     8
paulson@13785
     9
theory Lift = UNITY_Main:
paulson@11195
    10
paulson@11195
    11
record state =
paulson@13785
    12
  floor :: "int"	    (*current position of the lift*)
paulson@13785
    13
  "open" :: "bool"	    (*whether the door is opened at floor*)
paulson@13785
    14
  stop  :: "bool"	    (*whether the lift is stopped at floor*)
paulson@13785
    15
  req   :: "int set"	    (*for each floor, whether the lift is requested*)
paulson@13785
    16
  up    :: "bool"	    (*current direction of movement*)
paulson@13785
    17
  move  :: "bool"	    (*whether moving takes precedence over opening*)
paulson@11195
    18
paulson@11195
    19
consts
paulson@13785
    20
  Min :: "int"       (*least and greatest floors*)
paulson@13785
    21
  Max :: "int"       (*least and greatest floors*)
paulson@11195
    22
paulson@13785
    23
axioms
paulson@13806
    24
  Min_le_Max [iff]: "Min \<le> Max"
paulson@11195
    25
  
paulson@11195
    26
constdefs
paulson@11195
    27
  
paulson@11195
    28
  (** Abbreviations: the "always" part **)
paulson@11195
    29
  
paulson@13785
    30
  above :: "state set"
paulson@13806
    31
    "above == {s. \<exists>i. floor s < i & i \<le> Max & i \<in> req s}"
paulson@11195
    32
paulson@13785
    33
  below :: "state set"
paulson@13806
    34
    "below == {s. \<exists>i. Min \<le> i & i < floor s & i \<in> req s}"
paulson@11195
    35
paulson@13785
    36
  queueing :: "state set"
paulson@13806
    37
    "queueing == above \<union> below"
paulson@11195
    38
paulson@13785
    39
  goingup :: "state set"
paulson@13806
    40
    "goingup   == above \<inter> ({s. up s}  \<union> -below)"
paulson@11195
    41
paulson@13785
    42
  goingdown :: "state set"
paulson@13806
    43
    "goingdown == below \<inter> ({s. ~ up s} \<union> -above)"
paulson@11195
    44
paulson@13785
    45
  ready :: "state set"
paulson@11195
    46
    "ready == {s. stop s & ~ open s & move s}"
paulson@11195
    47
 
paulson@11195
    48
  (** Further abbreviations **)
paulson@11195
    49
paulson@13785
    50
  moving :: "state set"
paulson@11195
    51
    "moving ==  {s. ~ stop s & ~ open s}"
paulson@11195
    52
paulson@13785
    53
  stopped :: "state set"
paulson@11195
    54
    "stopped == {s. stop s  & ~ open s & ~ move s}"
paulson@11195
    55
paulson@13785
    56
  opened :: "state set"
paulson@11195
    57
    "opened ==  {s. stop s  &  open s  &  move s}"
paulson@11195
    58
paulson@13785
    59
  closed :: "state set"  (*but this is the same as ready!!*)
paulson@11195
    60
    "closed ==  {s. stop s  & ~ open s &  move s}"
paulson@11195
    61
paulson@13785
    62
  atFloor :: "int => state set"
paulson@11195
    63
    "atFloor n ==  {s. floor s = n}"
paulson@11195
    64
paulson@13785
    65
  Req :: "int => state set"
paulson@13806
    66
    "Req n ==  {s. n \<in> req s}"
paulson@11195
    67
paulson@11195
    68
paulson@11195
    69
  
paulson@11195
    70
  (** The program **)
paulson@11195
    71
  
paulson@11195
    72
  request_act :: "(state*state) set"
paulson@11195
    73
    "request_act == {(s,s'). s' = s (|stop:=True, move:=False|)
paulson@13806
    74
		                  & ~ stop s & floor s \<in> req s}"
paulson@11195
    75
paulson@11195
    76
  open_act :: "(state*state) set"
paulson@11195
    77
    "open_act ==
paulson@11195
    78
         {(s,s'). s' = s (|open :=True,
paulson@11195
    79
			   req  := req s - {floor s},
paulson@11195
    80
			   move := True|)
paulson@13806
    81
		       & stop s & ~ open s & floor s \<in> req s
paulson@13806
    82
	               & ~(move s & s \<in> queueing)}"
paulson@11195
    83
paulson@11195
    84
  close_act :: "(state*state) set"
paulson@11195
    85
    "close_act == {(s,s'). s' = s (|open := False|) & open s}"
paulson@11195
    86
paulson@11195
    87
  req_up :: "(state*state) set"
paulson@11195
    88
    "req_up ==
paulson@11195
    89
         {(s,s'). s' = s (|stop  :=False,
paulson@11868
    90
			   floor := floor s + 1,
paulson@11195
    91
			   up    := True|)
paulson@13806
    92
		       & s \<in> (ready \<inter> goingup)}"
paulson@11195
    93
paulson@11195
    94
  req_down :: "(state*state) set"
paulson@11195
    95
    "req_down ==
paulson@11195
    96
         {(s,s'). s' = s (|stop  :=False,
paulson@11868
    97
			   floor := floor s - 1,
paulson@11195
    98
			   up    := False|)
paulson@13806
    99
		       & s \<in> (ready \<inter> goingdown)}"
paulson@11195
   100
paulson@11195
   101
  move_up :: "(state*state) set"
paulson@11195
   102
    "move_up ==
paulson@11868
   103
         {(s,s'). s' = s (|floor := floor s + 1|)
paulson@13806
   104
		       & ~ stop s & up s & floor s \<notin> req s}"
paulson@11195
   105
paulson@11195
   106
  move_down :: "(state*state) set"
paulson@11195
   107
    "move_down ==
paulson@11868
   108
         {(s,s'). s' = s (|floor := floor s - 1|)
paulson@13806
   109
		       & ~ stop s & ~ up s & floor s \<notin> req s}"
paulson@11195
   110
paulson@11195
   111
  (*This action is omitted from prior treatments, which therefore are
paulson@11195
   112
    unrealistic: nobody asks the lift to do anything!  But adding this
paulson@11195
   113
    action invalidates many of the existing progress arguments: various
paulson@11195
   114
    "ensures" properties fail.*)
paulson@11195
   115
  button_press  :: "(state*state) set"
paulson@11195
   116
    "button_press ==
paulson@13806
   117
         {(s,s'). \<exists>n. s' = s (|req := insert n (req s)|)
paulson@13806
   118
		        & Min \<le> n & n \<le> Max}"
paulson@11195
   119
paulson@11195
   120
paulson@13785
   121
  Lift :: "state program"
paulson@11195
   122
    (*for the moment, we OMIT button_press*)
paulson@11195
   123
    "Lift == mk_program ({s. floor s = Min & ~ up s & move s & stop s &
paulson@11195
   124
		          ~ open s & req s = {}},
paulson@11195
   125
			 {request_act, open_act, close_act,
paulson@11195
   126
			  req_up, req_down, move_up, move_down},
paulson@11195
   127
			 UNIV)"
paulson@11195
   128
paulson@11195
   129
paulson@11195
   130
  (** Invariants **)
paulson@11195
   131
paulson@13785
   132
  bounded :: "state set"
paulson@13806
   133
    "bounded == {s. Min \<le> floor s & floor s \<le> Max}"
paulson@11195
   134
paulson@13785
   135
  open_stop :: "state set"
paulson@11195
   136
    "open_stop == {s. open s --> stop s}"
paulson@11195
   137
  
paulson@13785
   138
  open_move :: "state set"
paulson@11195
   139
    "open_move == {s. open s --> move s}"
paulson@11195
   140
  
paulson@13785
   141
  stop_floor :: "state set"
paulson@13806
   142
    "stop_floor == {s. stop s & ~ move s --> floor s \<in> req s}"
paulson@11195
   143
  
paulson@13785
   144
  moving_up :: "state set"
paulson@11195
   145
    "moving_up == {s. ~ stop s & up s -->
paulson@13806
   146
                   (\<exists>f. floor s \<le> f & f \<le> Max & f \<in> req s)}"
paulson@11195
   147
  
paulson@13785
   148
  moving_down :: "state set"
paulson@11195
   149
    "moving_down == {s. ~ stop s & ~ up s -->
paulson@13806
   150
                     (\<exists>f. Min \<le> f & f \<le> floor s & f \<in> req s)}"
paulson@11195
   151
  
paulson@13785
   152
  metric :: "[int,state] => int"
paulson@11195
   153
    "metric ==
paulson@11195
   154
       %n s. if floor s < n then (if up s then n - floor s
paulson@11195
   155
			          else (floor s - Min) + (n-Min))
paulson@11195
   156
             else
paulson@11195
   157
             if n < floor s then (if up s then (Max - floor s) + (Max-n)
paulson@11195
   158
		                  else floor s - n)
paulson@11868
   159
             else 0"
paulson@11195
   160
paulson@13785
   161
locale Floor =
paulson@13785
   162
  fixes n
paulson@13806
   163
  assumes Min_le_n [iff]: "Min \<le> n"
paulson@13806
   164
      and n_le_Max [iff]: "n \<le> Max"
paulson@13785
   165
paulson@13806
   166
lemma not_mem_distinct: "[| x \<notin> A;  y \<in> A |] ==> x \<noteq> y"
paulson@13785
   167
by blast
paulson@13785
   168
paulson@13785
   169
paulson@13785
   170
declare Lift_def [THEN def_prg_Init, simp]
paulson@13785
   171
paulson@13785
   172
declare request_act_def [THEN def_act_simp, simp]
paulson@13785
   173
declare open_act_def [THEN def_act_simp, simp]
paulson@13785
   174
declare close_act_def [THEN def_act_simp, simp]
paulson@13785
   175
declare req_up_def [THEN def_act_simp, simp]
paulson@13785
   176
declare req_down_def [THEN def_act_simp, simp]
paulson@13785
   177
declare move_up_def [THEN def_act_simp, simp]
paulson@13785
   178
declare move_down_def [THEN def_act_simp, simp]
paulson@13785
   179
declare button_press_def [THEN def_act_simp, simp]
paulson@13785
   180
paulson@13785
   181
(*The ALWAYS properties*)
paulson@13785
   182
declare above_def [THEN def_set_simp, simp]
paulson@13785
   183
declare below_def [THEN def_set_simp, simp]
paulson@13785
   184
declare queueing_def [THEN def_set_simp, simp]
paulson@13785
   185
declare goingup_def [THEN def_set_simp, simp]
paulson@13785
   186
declare goingdown_def [THEN def_set_simp, simp]
paulson@13785
   187
declare ready_def [THEN def_set_simp, simp]
paulson@13785
   188
paulson@13785
   189
(*Basic definitions*)
paulson@13785
   190
declare bounded_def [simp] 
paulson@13785
   191
        open_stop_def [simp] 
paulson@13785
   192
        open_move_def [simp] 
paulson@13785
   193
        stop_floor_def [simp]
paulson@13785
   194
        moving_up_def [simp]
paulson@13785
   195
        moving_down_def [simp]
paulson@13785
   196
paulson@13806
   197
lemma open_stop: "Lift \<in> Always open_stop"
paulson@13785
   198
apply (rule AlwaysI, force) 
paulson@13785
   199
apply (unfold Lift_def, constrains) 
paulson@13785
   200
done
paulson@13785
   201
paulson@13806
   202
lemma stop_floor: "Lift \<in> Always stop_floor"
paulson@13785
   203
apply (rule AlwaysI, force) 
paulson@13785
   204
apply (unfold Lift_def, constrains)
paulson@13785
   205
done
paulson@13785
   206
paulson@13785
   207
(*This one needs open_stop, which was proved above*)
paulson@13806
   208
lemma open_move: "Lift \<in> Always open_move"
paulson@13785
   209
apply (cut_tac open_stop)
paulson@13785
   210
apply (rule AlwaysI, force) 
paulson@13785
   211
apply (unfold Lift_def, constrains)
paulson@13785
   212
done
paulson@13785
   213
paulson@13806
   214
lemma moving_up: "Lift \<in> Always moving_up"
paulson@13785
   215
apply (rule AlwaysI, force) 
paulson@13785
   216
apply (unfold Lift_def, constrains)
paulson@13785
   217
apply (auto dest: zle_imp_zless_or_eq simp add: add1_zle_eq)
paulson@13785
   218
done
paulson@13785
   219
paulson@13806
   220
lemma moving_down: "Lift \<in> Always moving_down"
paulson@13785
   221
apply (rule AlwaysI, force) 
paulson@13785
   222
apply (unfold Lift_def, constrains)
paulson@13785
   223
apply (blast dest: zle_imp_zless_or_eq)
paulson@13785
   224
done
paulson@13785
   225
paulson@13806
   226
lemma bounded: "Lift \<in> Always bounded"
paulson@13785
   227
apply (cut_tac moving_up moving_down)
paulson@13785
   228
apply (rule AlwaysI, force) 
paulson@13785
   229
apply (unfold Lift_def, constrains, auto)
paulson@13785
   230
apply (drule not_mem_distinct, assumption, arith)+
paulson@13785
   231
done
paulson@13785
   232
paulson@13785
   233
paulson@13785
   234
subsection{*Progress*}
paulson@13785
   235
paulson@13785
   236
declare moving_def [THEN def_set_simp, simp]
paulson@13785
   237
declare stopped_def [THEN def_set_simp, simp]
paulson@13785
   238
declare opened_def [THEN def_set_simp, simp]
paulson@13785
   239
declare closed_def [THEN def_set_simp, simp]
paulson@13785
   240
declare atFloor_def [THEN def_set_simp, simp]
paulson@13785
   241
declare Req_def [THEN def_set_simp, simp]
paulson@13785
   242
paulson@13785
   243
paulson@13785
   244
(** The HUG'93 paper mistakenly omits the Req n from these! **)
paulson@13785
   245
paulson@13785
   246
(** Lift_1 **)
paulson@13806
   247
lemma E_thm01: "Lift \<in> (stopped \<inter> atFloor n) LeadsTo (opened \<inter> atFloor n)"
paulson@13785
   248
apply (cut_tac stop_floor)
paulson@13785
   249
apply (unfold Lift_def, ensures_tac "open_act")
paulson@13785
   250
done  (*lem_lift_1_5*)
paulson@13785
   251
paulson@13806
   252
lemma E_thm02: "Lift \<in> (Req n \<inter> stopped - atFloor n) LeadsTo  
paulson@13806
   253
                     (Req n \<inter> opened - atFloor n)"
paulson@13785
   254
apply (cut_tac stop_floor)
paulson@13785
   255
apply (unfold Lift_def, ensures_tac "open_act")
paulson@13785
   256
done  (*lem_lift_1_1*)
paulson@13785
   257
paulson@13806
   258
lemma E_thm03: "Lift \<in> (Req n \<inter> opened - atFloor n) LeadsTo  
paulson@13806
   259
                     (Req n \<inter> closed - (atFloor n - queueing))"
paulson@13785
   260
apply (unfold Lift_def, ensures_tac "close_act")
paulson@13785
   261
done  (*lem_lift_1_2*)
paulson@13785
   262
paulson@13806
   263
lemma E_thm04: "Lift \<in> (Req n \<inter> closed \<inter> (atFloor n - queueing))   
paulson@13806
   264
             LeadsTo (opened \<inter> atFloor n)"
paulson@13785
   265
apply (unfold Lift_def, ensures_tac "open_act")
paulson@13785
   266
done  (*lem_lift_1_7*)
paulson@13785
   267
paulson@13785
   268
paulson@13785
   269
(** Lift 2.  Statements of thm05a and thm05b were wrong! **)
paulson@13785
   270
paulson@13785
   271
lemmas linorder_leI = linorder_not_less [THEN iffD1]
paulson@13785
   272
paulson@13785
   273
lemmas (in Floor) le_MinD = Min_le_n [THEN order_antisym]
paulson@13785
   274
              and Max_leD = n_le_Max [THEN [2] order_antisym]
paulson@13785
   275
paulson@13785
   276
declare (in Floor) le_MinD [dest!]
paulson@13785
   277
               and linorder_leI [THEN le_MinD, dest!]
paulson@13785
   278
               and Max_leD [dest!]
paulson@13785
   279
               and linorder_leI [THEN Max_leD, dest!]
paulson@13785
   280
paulson@13785
   281
paulson@13785
   282
(*lem_lift_2_0 
paulson@13785
   283
  NOT an ensures_tac property, but a mere inclusion
paulson@13785
   284
  don't know why script lift_2.uni says ENSURES*)
paulson@13785
   285
lemma (in Floor) E_thm05c: 
paulson@13806
   286
    "Lift \<in> (Req n \<inter> closed - (atFloor n - queueing))    
paulson@13806
   287
             LeadsTo ((closed \<inter> goingup \<inter> Req n)  \<union> 
paulson@13806
   288
                      (closed \<inter> goingdown \<inter> Req n))"
paulson@13785
   289
by (auto intro!: subset_imp_LeadsTo elim!: int_neqE)
paulson@13785
   290
paulson@13785
   291
(*lift_2*)
paulson@13806
   292
lemma (in Floor) lift_2: "Lift \<in> (Req n \<inter> closed - (atFloor n - queueing))    
paulson@13806
   293
             LeadsTo (moving \<inter> Req n)"
paulson@13785
   294
apply (rule LeadsTo_Trans [OF E_thm05c LeadsTo_Un])
paulson@13785
   295
apply (unfold Lift_def) 
paulson@13785
   296
apply (ensures_tac [2] "req_down")
paulson@13785
   297
apply (ensures_tac "req_up", auto)
paulson@13785
   298
done
paulson@13785
   299
paulson@13785
   300
paulson@13785
   301
(** Towards lift_4 ***)
paulson@13785
   302
 
paulson@13785
   303
declare split_if_asm [split]
paulson@13785
   304
paulson@13785
   305
paulson@13785
   306
(*lem_lift_4_1 *)
paulson@13785
   307
lemma (in Floor) E_thm12a:
paulson@13785
   308
     "0 < N ==>  
paulson@13806
   309
      Lift \<in> (moving \<inter> Req n \<inter> {s. metric n s = N} \<inter> 
paulson@13806
   310
              {s. floor s \<notin> req s} \<inter> {s. up s})    
paulson@13785
   311
             LeadsTo  
paulson@13806
   312
               (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   313
apply (cut_tac moving_up)
paulson@13785
   314
apply (unfold Lift_def, ensures_tac "move_up", safe)
paulson@13806
   315
(*this step consolidates two formulae to the goal  metric n s' \<le> metric n s*)
paulson@13785
   316
apply (erule linorder_leI [THEN order_antisym, symmetric])
paulson@13785
   317
apply (auto simp add: metric_def)
paulson@13785
   318
done
paulson@13785
   319
paulson@13785
   320
paulson@13785
   321
(*lem_lift_4_3 *)
paulson@13785
   322
lemma (in Floor) E_thm12b: "0 < N ==>  
paulson@13806
   323
      Lift \<in> (moving \<inter> Req n \<inter> {s. metric n s = N} \<inter> 
paulson@13806
   324
              {s. floor s \<notin> req s} - {s. up s})    
paulson@13806
   325
             LeadsTo (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   326
apply (cut_tac moving_down)
paulson@13785
   327
apply (unfold Lift_def, ensures_tac "move_down", safe)
paulson@13806
   328
(*this step consolidates two formulae to the goal  metric n s' \<le> metric n s*)
paulson@13785
   329
apply (erule linorder_leI [THEN order_antisym, symmetric])
paulson@13785
   330
apply (auto simp add: metric_def)
paulson@13785
   331
done
paulson@13785
   332
paulson@13785
   333
(*lift_4*)
paulson@13785
   334
lemma (in Floor) lift_4:
paulson@13806
   335
     "0<N ==> Lift \<in> (moving \<inter> Req n \<inter> {s. metric n s = N} \<inter> 
paulson@13806
   336
                            {s. floor s \<notin> req s}) LeadsTo      
paulson@13806
   337
                           (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   338
apply (rule LeadsTo_Trans [OF subset_imp_LeadsTo
paulson@13785
   339
                              LeadsTo_Un [OF E_thm12a E_thm12b]], auto)
paulson@13785
   340
done
paulson@13785
   341
paulson@13785
   342
paulson@13785
   343
(** towards lift_5 **)
paulson@13785
   344
paulson@13785
   345
(*lem_lift_5_3*)
paulson@13785
   346
lemma (in Floor) E_thm16a: "0<N    
paulson@13806
   347
  ==> Lift \<in> (closed \<inter> Req n \<inter> {s. metric n s = N} \<inter> goingup) LeadsTo  
paulson@13806
   348
             (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   349
apply (cut_tac bounded)
paulson@13785
   350
apply (unfold Lift_def, ensures_tac "req_up")
paulson@13785
   351
apply (auto simp add: metric_def)
paulson@13785
   352
done
paulson@13785
   353
paulson@13785
   354
paulson@13785
   355
(*lem_lift_5_1 has ~goingup instead of goingdown*)
paulson@13785
   356
lemma (in Floor) E_thm16b: "0<N ==>    
paulson@13806
   357
      Lift \<in> (closed \<inter> Req n \<inter> {s. metric n s = N} \<inter> goingdown) LeadsTo  
paulson@13806
   358
                   (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   359
apply (cut_tac bounded)
paulson@13785
   360
apply (unfold Lift_def, ensures_tac "req_down")
paulson@13785
   361
apply (auto simp add: metric_def)
paulson@13785
   362
done
paulson@13785
   363
paulson@13785
   364
paulson@13785
   365
(*lem_lift_5_0 proves an intersection involving ~goingup and goingup,
paulson@13785
   366
  i.e. the trivial disjunction, leading to an asymmetrical proof.*)
paulson@13785
   367
lemma (in Floor) E_thm16c:
paulson@13806
   368
     "0<N ==> Req n \<inter> {s. metric n s = N} \<subseteq> goingup \<union> goingdown"
paulson@13785
   369
by (force simp add: metric_def)
paulson@13785
   370
paulson@13785
   371
paulson@13785
   372
(*lift_5*)
paulson@13785
   373
lemma (in Floor) lift_5:
paulson@13806
   374
     "0<N ==> Lift \<in> (closed \<inter> Req n \<inter> {s. metric n s = N}) LeadsTo    
paulson@13806
   375
                     (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   376
apply (rule LeadsTo_Trans [OF subset_imp_LeadsTo
paulson@13785
   377
                              LeadsTo_Un [OF E_thm16a E_thm16b]])
paulson@13785
   378
apply (drule E_thm16c, auto)
paulson@13785
   379
done
paulson@13785
   380
paulson@13785
   381
paulson@13785
   382
(** towards lift_3 **)
paulson@13785
   383
paulson@13785
   384
(*lemma used to prove lem_lift_3_1*)
paulson@13785
   385
lemma (in Floor) metric_eq_0D [dest]:
paulson@13806
   386
     "[| metric n s = 0;  Min \<le> floor s;  floor s \<le> Max |] ==> floor s = n"
paulson@13785
   387
by (force simp add: metric_def)
paulson@13785
   388
paulson@13785
   389
paulson@13785
   390
(*lem_lift_3_1*)
paulson@13806
   391
lemma (in Floor) E_thm11: "Lift \<in> (moving \<inter> Req n \<inter> {s. metric n s = 0}) LeadsTo    
paulson@13806
   392
                       (stopped \<inter> atFloor n)"
paulson@13785
   393
apply (cut_tac bounded)
paulson@13785
   394
apply (unfold Lift_def, ensures_tac "request_act", auto)
paulson@13785
   395
done
paulson@13785
   396
paulson@13785
   397
(*lem_lift_3_5*)
paulson@13785
   398
lemma (in Floor) E_thm13: 
paulson@13806
   399
  "Lift \<in> (moving \<inter> Req n \<inter> {s. metric n s = N} \<inter> {s. floor s \<in> req s})  
paulson@13806
   400
  LeadsTo (stopped \<inter> Req n \<inter> {s. metric n s = N} \<inter> {s. floor s \<in> req s})"
paulson@13785
   401
apply (unfold Lift_def, ensures_tac "request_act")
paulson@13785
   402
apply (auto simp add: metric_def)
paulson@13785
   403
done
paulson@13785
   404
paulson@13785
   405
(*lem_lift_3_6*)
paulson@13785
   406
lemma (in Floor) E_thm14: "0 < N ==>  
paulson@13806
   407
      Lift \<in>  
paulson@13806
   408
        (stopped \<inter> Req n \<inter> {s. metric n s = N} \<inter> {s. floor s \<in> req s})  
paulson@13806
   409
        LeadsTo (opened \<inter> Req n \<inter> {s. metric n s = N})"
paulson@13785
   410
apply (unfold Lift_def, ensures_tac "open_act")
paulson@13785
   411
apply (auto simp add: metric_def)
paulson@13785
   412
done
paulson@13785
   413
paulson@13785
   414
(*lem_lift_3_7*)
paulson@13806
   415
lemma (in Floor) E_thm15: "Lift \<in> (opened \<inter> Req n \<inter> {s. metric n s = N})   
paulson@13806
   416
             LeadsTo (closed \<inter> Req n \<inter> {s. metric n s = N})"
paulson@13785
   417
apply (unfold Lift_def, ensures_tac "close_act")
paulson@13785
   418
apply (auto simp add: metric_def)
paulson@13785
   419
done
paulson@13785
   420
paulson@13785
   421
paulson@13785
   422
(** the final steps **)
paulson@13785
   423
paulson@13785
   424
lemma (in Floor) lift_3_Req: "0 < N ==>  
paulson@13806
   425
      Lift \<in>  
paulson@13806
   426
        (moving \<inter> Req n \<inter> {s. metric n s = N} \<inter> {s. floor s \<in> req s})    
paulson@13806
   427
        LeadsTo (moving \<inter> Req n \<inter> {s. metric n s < N})"
paulson@13785
   428
apply (blast intro!: E_thm13 E_thm14 E_thm15 lift_5 intro: LeadsTo_Trans)
paulson@13785
   429
done
paulson@13785
   430
paulson@13785
   431
paulson@13785
   432
(*Now we observe that our integer metric is really a natural number*)
paulson@13806
   433
lemma (in Floor) Always_nonneg: "Lift \<in> Always {s. 0 \<le> metric n s}"
paulson@13785
   434
apply (rule bounded [THEN Always_weaken])
paulson@13785
   435
apply (auto simp add: metric_def)
paulson@13785
   436
done
paulson@13785
   437
paulson@13785
   438
lemmas (in Floor) R_thm11 = Always_LeadsTo_weaken [OF Always_nonneg E_thm11]
paulson@13785
   439
paulson@13785
   440
lemma (in Floor) lift_3:
paulson@13806
   441
     "Lift \<in> (moving \<inter> Req n) LeadsTo (stopped \<inter> atFloor n)"
paulson@13785
   442
apply (rule Always_nonneg [THEN integ_0_le_induct])
paulson@13785
   443
apply (case_tac "0 < z")
paulson@13806
   444
(*If z \<le> 0 then actually z = 0*)
paulson@13785
   445
prefer 2 apply (force intro: R_thm11 order_antisym simp add: linorder_not_less)
paulson@13785
   446
apply (rule LeadsTo_weaken_R [OF asm_rl Un_upper1])
paulson@13785
   447
apply (rule LeadsTo_Trans [OF subset_imp_LeadsTo
paulson@13785
   448
                              LeadsTo_Un [OF lift_4 lift_3_Req]], auto)
paulson@13785
   449
done
paulson@13785
   450
paulson@13785
   451
paulson@13806
   452
lemma (in Floor) lift_1: "Lift \<in> (Req n) LeadsTo (opened \<inter> atFloor n)"
paulson@13785
   453
apply (rule LeadsTo_Trans)
paulson@13785
   454
 prefer 2
paulson@13785
   455
 apply (rule LeadsTo_Un [OF E_thm04 LeadsTo_Un_post])
paulson@13785
   456
 apply (rule E_thm01 [THEN [2] LeadsTo_Trans_Un])
paulson@13785
   457
 apply (rule lift_3 [THEN [2] LeadsTo_Trans_Un])
paulson@13785
   458
 apply (rule lift_2 [THEN [2] LeadsTo_Trans_Un])
paulson@13785
   459
 apply (rule LeadsTo_Trans_Un [OF E_thm02 E_thm03])
paulson@13785
   460
apply (rule open_move [THEN Always_LeadsToI])
paulson@13785
   461
apply (rule Always_LeadsToI [OF open_stop subset_imp_LeadsTo], clarify)
paulson@13785
   462
(*The case split is not essential but makes the proof much faster.*)
paulson@13785
   463
apply (case_tac "open x", auto)
paulson@13785
   464
done
paulson@13785
   465
paulson@11195
   466
paulson@11195
   467
end