Select Git revision
CarlaTravelAgencyErr.mch
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CarlaTravelAgencyErr.mch 9.45 KiB
MACHINE CarlaTravelAgencyErr
/* contains an error that can be found by model checking */
/* machine developed by Carla Ferreira (the final machine contains no errors) */
SETS
USER = {user1,user2};
SESSION = {sess1,sess2, sess3};
SESSION_REQUEST = {bc, br, uc, ur, none};
SESSION_STATE = {s0, s1, s2, s3, s4, s5, s6, s7};
HOTEL = {h1, h2, noHotel};
CAR_RENT = {c1, c2, noCarRent};
CARD = {valid, wrong, unknown};
ROOM = {h1a, h1b, h2a, h2b};
CAR = {c1a, c1b, c2a, c2b};
RESP = {done, impossible, undef}
CONSTANTS
AGENCY_USER
PROPERTIES
AGENCY_USER <: USER & AGENCY_USER /= {}
VARIABLES
session,
session_response,
session_card,
session_state,
session_request,
user_hotel_bookings,
user_rental_bookings,
rooms_hotel,
cars_rental,
global_room_bookings,
global_car_bookings
DEFINITIONS
rooms_available(h) == (dom(global_room_bookings)/\rooms_hotel~[{h}]) /= rooms_hotel~[{h}];
cars_available(r) == (dom(global_car_bookings)/\cars_rental~[{r}]) /= cars_rental~[{r}]
INVARIANT
session: SESSION +-> USER & /*AGENCY_USER & */
session_response: SESSION +-> RESP &
session_card: SESSION +-> CARD &
session_state: SESSION +-> SESSION_STATE &
session_request: SESSION +-> SESSION_REQUEST &
user_hotel_bookings: USER +-> HOTEL & /* AGENCY_USER +-> HOTEL & */
user_rental_bookings: USER +-> CAR_RENT & /* AGENCY_USER +-> CAR_RENT & */
rooms_hotel: ROOM --> HOTEL &
cars_rental: CAR --> CAR_RENT &
global_room_bookings: ROOM >+> USER &
global_car_bookings: CAR >+> USER &
dom(session)=dom(session_response) & dom(session)=dom(session_card) &
dom(session)=dom(session_state) & dom(session)=dom(session_request) &
dom(user_hotel_bookings)=dom(user_rental_bookings) &
ran(session) <: dom(user_hotel_bookings)
&
( sess1:dom(session) & session_card(sess1) /= valid =>
session_response(sess1) = undef )
INITIALISATION
session := {} ||
session_response := {} ||
session_card := {} ||
session_state := {} ||
session_request := {} ||
user_hotel_bookings := {} ||
user_rental_bookings := {} ||
rooms_hotel := {h1a |-> h1, h1b |-> h1, h2a |-> h2, h2b |-> h2} ||
cars_rental := {c1a |-> c1, c1b |-> c1, c2a |-> c2, c2b |-> c2} ||
/* global_room_bookings : ( global_room_bookings : ROOM >+>USER ) ||
global_car_bookings : ( global_car_bookings : CAR >+> USER ) */
global_room_bookings := {} ||
global_car_bookings := {}
OPERATIONS
sid_ <-- login(uu) =
PRE uu : USER /* AGENCY_USER */
THEN
SELECT uu : dom(user_hotel_bookings) /* New session for a known user */
THEN
skip
WHEN uu /: dom(user_hotel_bookings) /* A new user - information needs to be created */
THEN
user_hotel_bookings(uu) := noHotel ||
user_rental_bookings(uu) := noCarRent
END
||
ANY sid WHERE sid : SESSION & sid /: dom(session) /* Creating a new session for the user */
THEN
session(sid) := uu ||
session_response(sid) := undef ||
session_card(sid) := unknown ||
session_state(sid) := s1 ||
session_request(sid) := none ||
sid_ := sid
END
END;
bookRoom(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s1 & session_request(sid) = none
THEN
session_state(sid) := s3 ||
session_request(sid) := br
END
END;
bookCar(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s1 & session_request(sid) = none
THEN
session_state(sid) := s5 ||
session_request(sid) := bc
END
END;
unbookRoom(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s1 & session_request(sid) = none
THEN
session_state(sid) := s2 ||
session_request(sid) := ur
END
END;
unbookCar(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s1 & session_request(sid) = none
THEN
session_state(sid) := s4 ||
session_request(sid) := uc
END
END;
enterCard(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) : {s2,s3,s4,s5}
THEN
session_state(sid) := s6 ||
ANY cc WHERE cc: (CARD-{unknown})
THEN
session_card(sid) := cc
END
END
END;
retryCard(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s6 & session_card(sid) = wrong
THEN
ANY cc WHERE cc: (CARD-{unknown})
THEN
session_card(sid) := cc
END
END
END;
response(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s6
THEN
session_state(sid) := s7
END
||
SELECT session_request(sid) = br & user_hotel_bookings(session(sid)) = noHotel
THEN
IF dom(global_room_bookings) <<: ROOM
THEN
ANY rr, hh WHERE rr:ROOM-dom(global_room_bookings) & hh:HOTEL & rooms_hotel(rr) = hh
THEN
global_room_bookings(rr) := session(sid) ||
user_hotel_bookings(session(sid)) := hh ||
session_response(sid) := done
END
ELSE session_response(sid) := impossible
END
WHEN session_request(sid) = br & user_hotel_bookings(session(sid)) /= noHotel
THEN
IF (dom(global_room_bookings)/\
rooms_hotel~[{user_hotel_bookings(session(sid))}]) /=
rooms_hotel~[{user_hotel_bookings(session(sid))}]
THEN
ANY rr WHERE rr:ROOM-dom(global_room_bookings) & rooms_hotel(rr) = user_hotel_bookings(session(sid))
THEN
global_room_bookings := global_room_bookings \/ { rr |-> session(sid)} ||
session_response(sid) := done
END
ELSE
session_response(sid) := impossible
END
WHEN session_request(sid) = bc & user_rental_bookings(session(sid)) = noCarRent
THEN
IF dom(global_car_bookings) <<: CAR
THEN
ANY cc, re WHERE cc:CAR-dom(global_car_bookings) & re:CAR_RENT & cars_rental(cc) = re
THEN
global_car_bookings(cc) := session(sid) ||
user_rental_bookings(session(sid)) := re ||
session_response(sid) := done
END
ELSE session_response(sid) := impossible
END
WHEN session_request(sid) = bc & user_rental_bookings(session(sid)) /= noCarRent
THEN
IF (dom(global_car_bookings) /\ cars_rental~[{user_rental_bookings(session(sid))}])
/= cars_rental~[{user_rental_bookings(session(sid))}]
THEN
ANY cc WHERE cc:CAR-dom(global_car_bookings) & cars_rental(cc) = user_rental_bookings(session(sid))
THEN
global_car_bookings(cc) := session(sid) ||
session_response(sid) := done
END
ELSE
session_response(sid) := impossible
END
WHEN session_request(sid) = ur
THEN
IF session(sid) : ran(global_room_bookings)
THEN
ANY rr WHERE rr:dom(global_room_bookings) & global_room_bookings(rr) = session(sid)
THEN
global_room_bookings := {rr} <<| global_room_bookings ||
session_response(sid) := done ||
IF {xx | xx:dom(global_room_bookings) & global_room_bookings(xx) = session(sid)} = {rr}
THEN user_hotel_bookings(session(sid)) := noHotel END
END
ELSE
session_response(sid) := impossible
END
WHEN session_request(sid) = uc
THEN
IF session(sid) : ran(global_car_bookings)
THEN
ANY cc WHERE cc:dom(global_car_bookings) & global_car_bookings(cc) = session(sid)
THEN
global_car_bookings := {cc} <<| global_car_bookings ||
session_response(sid) := done ||
IF {xx | xx:dom(global_car_bookings) & global_car_bookings(xx) = session(sid)} = {cc}
THEN user_rental_bookings(session(sid)) := noCarRent END
END
ELSE
session_response(sid) := impossible
END
END
END;
again(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) = s7
THEN
session_state(sid) := s1 ||
session_request(sid) := none ||
session_response(sid) := undef ||
session_card(sid) := unknown
END
END;
logout(sid)=
PRE sid : SESSION
THEN
SELECT sid:dom(session) & session_state(sid) : {s6,s7}
THEN
session := {sid} <<| session ||
session_response := {sid} <<| session_response ||
session_card := {sid} <<| session_card ||
session_state := {sid} <<| session_state ||
session_request := {sid} <<| session_request
END
END
END