paulson@5277: (* Title: HOL/UNITY/Lift.thy paulson@5277: ID: $Id$ paulson@5277: Author: Lawrence C Paulson, Cambridge University Computer Laboratory paulson@5277: Copyright 1998 University of Cambridge paulson@5277: paulson@5277: The Lift-Control Example paulson@5277: *) paulson@5277: paulson@5277: Lift = SubstAx + paulson@5277: paulson@5277: record state = paulson@5277: floor :: nat (*current position of the lift*) paulson@5277: open :: bool (*whether the door is open at floor*) paulson@5277: stop :: bool (*whether the lift is stopped at floor*) paulson@5277: req :: nat set (*for each floor, whether the lift is requested*) paulson@5277: up :: bool (*current direction of movement*) paulson@5277: move :: bool (*whether moving takes precedence over opening*) paulson@5277: paulson@5277: consts paulson@5277: min, max :: nat (*least and greatest floors*) paulson@5277: paulson@5277: rules paulson@5277: min_le_max "min <= max" paulson@5277: paulson@5277: paulson@5277: constdefs paulson@5277: paulson@5277: (** Abbreviations: the "always" part **) paulson@5277: paulson@5277: above :: "state set" paulson@5277: "above == {s. EX i. floor s < i & i <= max & i : req s}" paulson@5277: paulson@5277: below :: "state set" paulson@5277: "below == {s. EX i. min <= i & i < floor s & i : req s}" paulson@5277: paulson@5277: queueing :: "state set" paulson@5277: "queueing == above Un below" paulson@5277: paulson@5277: goingup :: "state set" paulson@5277: "goingup == above Int ({s. up s} Un Compl below)" paulson@5277: paulson@5277: goingdown :: "state set" paulson@5277: "goingdown == below Int ({s. ~ up s} Un Compl above)" paulson@5277: paulson@5277: ready :: "state set" paulson@5277: "ready == {s. stop s & ~ open s & move s}" paulson@5277: paulson@5277: paulson@5277: (** The program **) paulson@5277: paulson@5277: request_act :: "(state*state) set" paulson@5277: "request_act == {(s,s'). s' = s (|stop:=True, move:=False|) paulson@5277: & ~ stop s & floor s : req s}" paulson@5277: paulson@5277: open_act :: "(state*state) set" paulson@5277: "open_act == paulson@5277: {(s,s'). s' = s (|open :=True, paulson@5277: req := req s - {floor s}, paulson@5277: move := True|) paulson@5277: & stop s & ~ open s & floor s : req s paulson@5277: & ~(move s & s: queueing)}" paulson@5277: paulson@5277: close_act :: "(state*state) set" paulson@5277: "close_act == {(s,s'). s' = s (|open := False|) & open s}" paulson@5277: paulson@5277: req_up_act :: "(state*state) set" paulson@5277: "req_up_act == paulson@5277: {(s,s'). s' = s (|stop :=False, paulson@5277: floor := Suc (floor s), paulson@5277: up := True|) paulson@5277: & s : (ready Int goingup)}" paulson@5277: paulson@5277: req_down_act :: "(state*state) set" paulson@5277: "req_down_act == paulson@5277: {(s,s'). s' = s (|stop :=False, paulson@5277: floor := floor s - 1, paulson@5277: up := False|) paulson@5277: & s : (ready Int goingdown)}" paulson@5277: paulson@5277: move_up :: "(state*state) set" paulson@5277: "move_up == paulson@5277: {(s,s'). s' = s (|floor := Suc (floor s)|) paulson@5277: & ~ stop s & up s & floor s ~: req s}" paulson@5277: paulson@5277: move_down :: "(state*state) set" paulson@5277: "move_down == paulson@5277: {(s,s'). s' = s (|floor := floor s - 1|) paulson@5277: & ~ stop s & ~ up s & floor s ~: req s}" paulson@5277: paulson@5277: Lprg :: state program paulson@5277: "Lprg == (|Init = {s. floor s = min & ~ up s & move s & stop s & paulson@5277: ~ open s & req s = {}}, paulson@5277: Acts = {id, request_act, open_act, close_act, paulson@5277: req_up_act, req_down_act, move_up, move_down}|)" paulson@5277: paulson@5277: paulson@5277: (** Invariants **) paulson@5277: paulson@5277: bounded :: state set paulson@5277: "bounded == {s. min <= floor s & floor s <= max}" paulson@5277: paulson@5277: (** ??? paulson@5277: (~ stop s & up s --> floor s < max) & paulson@5277: (~ stop s & ~ up s --> min < floor s)}" paulson@5277: **) paulson@5277: paulson@5277: open_stop :: state set paulson@5277: "open_stop == {s. open s --> stop s}" paulson@5277: paulson@5277: open_move :: state set paulson@5277: "open_move == {s. open s --> move s}" paulson@5277: paulson@5277: stop_floor :: state set paulson@5277: "stop_floor == {s. open s & ~ move s --> floor s : req s}" paulson@5277: paulson@5277: moving_up :: state set paulson@5277: "moving_up == {s. ~ stop s & up s --> paulson@5277: (EX f. floor s <= f & f <= max & f : req s)}" paulson@5277: paulson@5277: moving_down :: state set paulson@5277: "moving_down == {s. ~ stop s & ~ up s --> paulson@5277: (EX f. min <= f & f <= floor s & f : req s)}" paulson@5277: paulson@5277: valid :: "state set" paulson@5277: "valid == bounded Int open_stop Int open_move" paulson@5277: paulson@5277: end