src/HOL/UNITY/Simple/Lift.thy
changeset 16184 80617b8d33c5
parent 14378 69c4d5997669
child 32960 69916a850301
equal deleted inserted replaced
16183:052d9aba392d 16184:80617b8d33c5
     4     Copyright   1998  University of Cambridge
     4     Copyright   1998  University of Cambridge
     5 
     5 
     6 The Lift-Control Example
     6 The Lift-Control Example
     7 *)
     7 *)
     8 
     8 
     9 theory Lift = UNITY_Main:
     9 theory Lift
       
    10 imports "../UNITY_Main"
       
    11 
       
    12 begin
    10 
    13 
    11 record state =
    14 record state =
    12   floor :: "int"	    (*current position of the lift*)
    15   floor :: "int"	    --{*current position of the lift*}
    13   "open" :: "bool"	    (*whether the door is opened at floor*)
    16   "open" :: "bool"	    --{*whether the door is opened at floor*}
    14   stop  :: "bool"	    (*whether the lift is stopped at floor*)
    17   stop  :: "bool"	    --{*whether the lift is stopped at floor*}
    15   req   :: "int set"	    (*for each floor, whether the lift is requested*)
    18   req   :: "int set"	    --{*for each floor, whether the lift is requested*}
    16   up    :: "bool"	    (*current direction of movement*)
    19   up    :: "bool"	    --{*current direction of movement*}
    17   move  :: "bool"	    (*whether moving takes precedence over opening*)
    20   move  :: "bool"	    --{*whether moving takes precedence over opening*}
    18 
    21 
    19 consts
    22 consts
    20   Min :: "int"       (*least and greatest floors*)
    23   Min :: "int"       --{*least and greatest floors*}
    21   Max :: "int"       (*least and greatest floors*)
    24   Max :: "int"       --{*least and greatest floors*}
    22 
    25 
    23 axioms
    26 axioms
    24   Min_le_Max [iff]: "Min \<le> Max"
    27   Min_le_Max [iff]: "Min \<le> Max"
    25   
    28   
    26 constdefs
    29 constdefs
    27   
    30   
    28   (** Abbreviations: the "always" part **)
    31   --{*Abbreviations: the "always" part*}
    29   
    32   
    30   above :: "state set"
    33   above :: "state set"
    31     "above == {s. \<exists>i. floor s < i & i \<le> Max & i \<in> req s}"
    34     "above == {s. \<exists>i. floor s < i & i \<le> Max & i \<in> req s}"
    32 
    35 
    33   below :: "state set"
    36   below :: "state set"
    43     "goingdown == below \<inter> ({s. ~ up s} \<union> -above)"
    46     "goingdown == below \<inter> ({s. ~ up s} \<union> -above)"
    44 
    47 
    45   ready :: "state set"
    48   ready :: "state set"
    46     "ready == {s. stop s & ~ open s & move s}"
    49     "ready == {s. stop s & ~ open s & move s}"
    47  
    50  
    48   (** Further abbreviations **)
    51   --{*Further abbreviations*}
    49 
    52 
    50   moving :: "state set"
    53   moving :: "state set"
    51     "moving ==  {s. ~ stop s & ~ open s}"
    54     "moving ==  {s. ~ stop s & ~ open s}"
    52 
    55 
    53   stopped :: "state set"
    56   stopped :: "state set"
    54     "stopped == {s. stop s  & ~ open s & ~ move s}"
    57     "stopped == {s. stop s  & ~ open s & ~ move s}"
    55 
    58 
    56   opened :: "state set"
    59   opened :: "state set"
    57     "opened ==  {s. stop s  &  open s  &  move s}"
    60     "opened ==  {s. stop s  &  open s  &  move s}"
    58 
    61 
    59   closed :: "state set"  (*but this is the same as ready!!*)
    62   closed :: "state set"  --{*but this is the same as ready!!*}
    60     "closed ==  {s. stop s  & ~ open s &  move s}"
    63     "closed ==  {s. stop s  & ~ open s &  move s}"
    61 
    64 
    62   atFloor :: "int => state set"
    65   atFloor :: "int => state set"
    63     "atFloor n ==  {s. floor s = n}"
    66     "atFloor n ==  {s. floor s = n}"
    64 
    67 
    65   Req :: "int => state set"
    68   Req :: "int => state set"
    66     "Req n ==  {s. n \<in> req s}"
    69     "Req n ==  {s. n \<in> req s}"
    67 
    70 
    68 
    71 
    69   
    72   
    70   (** The program **)
    73   --{*The program*}
    71   
    74   
    72   request_act :: "(state*state) set"
    75   request_act :: "(state*state) set"
    73     "request_act == {(s,s'). s' = s (|stop:=True, move:=False|)
    76     "request_act == {(s,s'). s' = s (|stop:=True, move:=False|)
    74 		                  & ~ stop s & floor s \<in> req s}"
    77 		                  & ~ stop s & floor s \<in> req s}"
    75 
    78 
   106   move_down :: "(state*state) set"
   109   move_down :: "(state*state) set"
   107     "move_down ==
   110     "move_down ==
   108          {(s,s'). s' = s (|floor := floor s - 1|)
   111          {(s,s'). s' = s (|floor := floor s - 1|)
   109 		       & ~ stop s & ~ up s & floor s \<notin> req s}"
   112 		       & ~ stop s & ~ up s & floor s \<notin> req s}"
   110 
   113 
   111   (*This action is omitted from prior treatments, which therefore are
       
   112     unrealistic: nobody asks the lift to do anything!  But adding this
       
   113     action invalidates many of the existing progress arguments: various
       
   114     "ensures" properties fail.*)
       
   115   button_press  :: "(state*state) set"
   114   button_press  :: "(state*state) set"
       
   115       --{*This action is omitted from prior treatments, which therefore are
       
   116 	unrealistic: nobody asks the lift to do anything!  But adding this
       
   117 	action invalidates many of the existing progress arguments: various
       
   118 	"ensures" properties fail. Maybe it should be constrained to only
       
   119         allow button presses in the current direction of travel, like in a
       
   120         real lift.*}
   116     "button_press ==
   121     "button_press ==
   117          {(s,s'). \<exists>n. s' = s (|req := insert n (req s)|)
   122          {(s,s'). \<exists>n. s' = s (|req := insert n (req s)|)
   118 		        & Min \<le> n & n \<le> Max}"
   123 		        & Min \<le> n & n \<le> Max}"
   119 
   124 
   120 
   125 
   121   Lift :: "state program"
   126   Lift :: "state program"
   122     (*for the moment, we OMIT button_press*)
   127     --{*for the moment, we OMIT @{text button_press}*}
   123     "Lift == mk_total_program
   128     "Lift == mk_total_program
   124                 ({s. floor s = Min & ~ up s & move s & stop s &
   129                 ({s. floor s = Min & ~ up s & move s & stop s &
   125 		          ~ open s & req s = {}},
   130 		          ~ open s & req s = {}},
   126 		 {request_act, open_act, close_act,
   131 		 {request_act, open_act, close_act,
   127  		  req_up, req_down, move_up, move_down},
   132  		  req_up, req_down, move_up, move_down},
   128 		 UNIV)"
   133 		 UNIV)"
   129 
   134 
   130 
   135 
   131   (** Invariants **)
   136   --{*Invariants*}
   132 
   137 
   133   bounded :: "state set"
   138   bounded :: "state set"
   134     "bounded == {s. Min \<le> floor s & floor s \<le> Max}"
   139     "bounded == {s. Min \<le> floor s & floor s \<le> Max}"
   135 
   140 
   136   open_stop :: "state set"
   141   open_stop :: "state set"
   195         moving_up_def [simp]
   200         moving_up_def [simp]
   196         moving_down_def [simp]
   201         moving_down_def [simp]
   197 
   202 
   198 lemma open_stop: "Lift \<in> Always open_stop"
   203 lemma open_stop: "Lift \<in> Always open_stop"
   199 apply (rule AlwaysI, force) 
   204 apply (rule AlwaysI, force) 
   200 apply (unfold Lift_def, constrains)
   205 apply (unfold Lift_def, safety)
   201 done
   206 done
   202 
   207 
   203 lemma stop_floor: "Lift \<in> Always stop_floor"
   208 lemma stop_floor: "Lift \<in> Always stop_floor"
   204 apply (rule AlwaysI, force) 
   209 apply (rule AlwaysI, force) 
   205 apply (unfold Lift_def, constrains)
   210 apply (unfold Lift_def, safety)
   206 done
   211 done
   207 
   212 
   208 (*This one needs open_stop, which was proved above*)
   213 (*This one needs open_stop, which was proved above*)
   209 lemma open_move: "Lift \<in> Always open_move"
   214 lemma open_move: "Lift \<in> Always open_move"
   210 apply (cut_tac open_stop)
   215 apply (cut_tac open_stop)
   211 apply (rule AlwaysI, force) 
   216 apply (rule AlwaysI, force) 
   212 apply (unfold Lift_def, constrains)
   217 apply (unfold Lift_def, safety)
   213 done
   218 done
   214 
   219 
   215 lemma moving_up: "Lift \<in> Always moving_up"
   220 lemma moving_up: "Lift \<in> Always moving_up"
   216 apply (rule AlwaysI, force) 
   221 apply (rule AlwaysI, force) 
   217 apply (unfold Lift_def, constrains)
   222 apply (unfold Lift_def, safety)
   218 apply (auto dest: order_le_imp_less_or_eq simp add: add1_zle_eq)
   223 apply (auto dest: order_le_imp_less_or_eq simp add: add1_zle_eq)
   219 done
   224 done
   220 
   225 
   221 lemma moving_down: "Lift \<in> Always moving_down"
   226 lemma moving_down: "Lift \<in> Always moving_down"
   222 apply (rule AlwaysI, force) 
   227 apply (rule AlwaysI, force) 
   223 apply (unfold Lift_def, constrains)
   228 apply (unfold Lift_def, safety)
   224 apply (blast dest: order_le_imp_less_or_eq)
   229 apply (blast dest: order_le_imp_less_or_eq)
   225 done
   230 done
   226 
   231 
   227 lemma bounded: "Lift \<in> Always bounded"
   232 lemma bounded: "Lift \<in> Always bounded"
   228 apply (cut_tac moving_up moving_down)
   233 apply (cut_tac moving_up moving_down)
   229 apply (rule AlwaysI, force) 
   234 apply (rule AlwaysI, force) 
   230 apply (unfold Lift_def, constrains, auto)
   235 apply (unfold Lift_def, safety, auto)
   231 apply (drule not_mem_distinct, assumption, arith)+
   236 apply (drule not_mem_distinct, assumption, arith)+
   232 done
   237 done
   233 
   238 
   234 
   239 
   235 subsection{*Progress*}
   240 subsection{*Progress*}
   240 declare closed_def [THEN def_set_simp, simp]
   245 declare closed_def [THEN def_set_simp, simp]
   241 declare atFloor_def [THEN def_set_simp, simp]
   246 declare atFloor_def [THEN def_set_simp, simp]
   242 declare Req_def [THEN def_set_simp, simp]
   247 declare Req_def [THEN def_set_simp, simp]
   243 
   248 
   244 
   249 
   245 (** The HUG'93 paper mistakenly omits the Req n from these! **)
   250 text{*The HUG'93 paper mistakenly omits the Req n from these!*}
   246 
   251 
   247 (** Lift_1 **)
   252 (** Lift_1 **)
   248 lemma E_thm01: "Lift \<in> (stopped \<inter> atFloor n) LeadsTo (opened \<inter> atFloor n)"
   253 lemma E_thm01: "Lift \<in> (stopped \<inter> atFloor n) LeadsTo (opened \<inter> atFloor n)"
   249 apply (cut_tac stop_floor)
   254 apply (cut_tac stop_floor)
   250 apply (unfold Lift_def, ensures_tac "open_act")
   255 apply (unfold Lift_def, ensures_tac "open_act")