💊 Drug1 💊 Drug2 💊 Drug3 Medical Pillbox Time

Nr Name Value Previous Value
1 drawerLed ? ?
2 drug ? ?
3 drugIndex ? ?
4 isPillTaken ? ?
5 isPillTobeTaken ? ?
6 mCurrTimeSecs ? ?
7 start ? ?
8 time_consumption ? ?
Nr Name Value
1 Drawer {drawer1,drawer2,drawer3}
2 Timer {tenMinutes,Timer2}
3 LedLights {OFF,ON}
4 Drugs {TYLENOL,ASPIRINE,MOMENT}
5 INT (-1 .. 3)
Nr Name Enabled
1 ENV_toggle_isPillTaken ?
2 r_Main ?
3 IncTimeByMinutes ?
MACHINE pillbox_final
SETS /* deferred */
  Drawer;
  Timer
 ; /* enumerated */
  LedLights={OFF,ON};
  Drugs={TYLENOL,ASPIRINE,MOMENT}
CONCRETE_CONSTANTS
  drawer1,
  drawer2,
  drawer3,
  tenMinutes
ABSTRACT_VARIABLES
  isPillTaken,
  drawerLed,
  time_consumption,
  drug,
  drugIndex,
  isPillTobeTaken,
  mCurrTimeSecs,
  start
/* PROMOTED OPERATIONS
  ENV_toggle_isPillTaken,
  r_Main,
  IncTimeByMinutes */
/* NOT PROMOTED OPERATIONS
  r_choosePillToTake,
  r_reset_timer,
  r_pillToBeTaken,
  r_setOtherDrawers,
  r_reset,
  r_take */
PROPERTIES
    Drawer = {drawer1,drawer2,drawer3}
  & card({drawer1,drawer2,drawer3}) = 3
INVARIANT
    isPillTaken : Drawer --> BOOL
  & drawerLed : Drawer --> LedLights
  & time_consumption : Drawer --> seq(INTEGER)
  & drug : Drawer --> Drugs
  & drugIndex : Drawer --> NATURAL
  & isPillTobeTaken : Drawer --> BOOL
  & mCurrTimeSecs : NATURAL
  & start : Timer --> NATURAL
  & !d.(
     drawerLed(d) = ON
     =>
     not(#d2.(d2 /= d & drawerLed(d2) = ON))
    )
INITIALISATION
    BEGIN
         drawerLed := Drawer * {OFF}
      ||
         time_consumption := {drawer1 |-> [60,1200,1800],drawer2 |-> [2400,3000,3600],drawer3 |-> [180,1200,1800]}
      ||
         drug := {drawer1 |-> TYLENOL,drawer2 |-> ASPIRINE,drawer3 |-> MOMENT}
      ||
         isPillTobeTaken := Drawer * {FALSE}
      ||
         drugIndex := Drawer * {1}
      ||
         isPillTaken := Drawer * {FALSE}
      ||
         mCurrTimeSecs := 0
      ||
         start := Timer * {0}
    END
OPERATIONS
  ENV_toggle_isPillTaken(d,newval) = 
    SELECT 
        newval = 
        bool(
            isPillTaken(d) = FALSE
        )
    THEN 
      isPillTaken(d) := newval
    END;
  
  IncTimeByMinutes(mins) = 
    SELECT 
        mins : {1,10,60}
    THEN 
      mCurrTimeSecs := mCurrTimeSecs + mins * 60
    END;
  
  ΔdrawerLed,ΔisPillTobeTaken <-- r_reset(drawers) = 
    BEGIN
      ΔdrawerLed,drugIndex,ΔisPillTobeTaken := drawers * {OFF},drugIndex <+ %drawer.(drawer : drawers|drugIndex(drawer) + 1),drawers * {FALSE}
    END;
  
  ΔdrawerLed,ΔisPillTobeTaken <-- r_take(drawers) = 
    LET iftrue BE iftrue = {drawer|drawer : drawers & drawerLed(drawer) = ON & (mCurrTimeSecs >= start(tenMinutes) + 600 or isPillTaken(drawer) = TRUE)}
    IN
      ΔdrawerLed,ΔisPillTobeTaken <-- r_reset(iftrue)
    END;
  
  ΔdrawerLed,ΔisPillTobeTaken1,ΔisPillTobeTaken2 <-- r_setOtherDrawers = 
    BEGIN
         ΔisPillTobeTaken1 := %(drawer) . (
             drugIndex(drawer) : dom(time_consumption(drawer))
           & time_consumption(drawer)(drugIndex(drawer)) <= mCurrTimeSecs
           & drawerLed(drawer) = OFF
          | 
           TRUE
         )
      ||
         LET other BE other = {drawer|drugIndex(drawer) <= size(time_consumption(drawer))}
         IN
           ΔdrawerLed,ΔisPillTobeTaken2 <-- r_take(other)
         END
    END;
  
  r_reset_timer(t) = 
    BEGIN
      start(t) := mCurrTimeSecs
    END;
  
  ΔdrawerLed <-- r_pillToBeTaken(drawer) = 
    BEGIN
         IF drawerLed(drawer) = OFF THEN
           r_reset_timer(tenMinutes)
         END
      ||
         ΔdrawerLed := {drawer |-> ON}
    END;
  
  ΔdrawerLed <-- r_choosePillToTake = 
    LET cands BE cands = {drawer|isPillTobeTaken(drawer) = TRUE & drawerLed(drawer) = OFF & not(#d2.(d2 /= drawer & drawerLed(d2) = ON))}
    IN
      IF cands /= {} THEN
        ANY drawer
        WHERE 
            drawer : cands
        THEN
          ΔdrawerLed <-- r_pillToBeTaken(drawer)
        END
      ELSE
        ΔdrawerLed := {}
      END
    END;
  
  concurrent_updates <-- r_Main = 
    VAR ΔdrawerLed1,ΔdrawerLed2,ΔisPillTobeTaken1,ΔisPillTobeTaken2
    IN
           ΔdrawerLed1 <-- r_choosePillToTake
        ||
           ΔdrawerLed2,ΔisPillTobeTaken1,ΔisPillTobeTaken2 <-- r_setOtherDrawers
      ;
        drawerLed,isPillTobeTaken,concurrent_updates := drawerLed <+ (ΔdrawerLed1 \/ ΔdrawerLed2),isPillTobeTaken <+ (ΔisPillTobeTaken1 \/ ΔisPillTobeTaken2),(ΔdrawerLed1 \/ ΔdrawerLed2) |-> (ΔisPillTobeTaken1 \/ ΔisPillTobeTaken2)
    END
DEFINITIONS
 SET_PREF_STORE_DETAILED_TRANSITION_INFOS == TRUE;

/* DEFINITIONS
  EXPRESSION VISB_SVG_UPDATES3;
  EXPRESSION VISB_SVG_UPDATES2;
  EXPRESSION VISB_SVG_UPDATES5;
  EXPRESSION VISB_SVG_UPDATES4;
  EXPRESSION VISB_SVG_EVENTS3;
  EXPRESSION VISB_SVG_EVENTS1;
  EXPRESSION VISB_SVG_EVENTS2;
  EXPRESSION duration(t);
  EXPRESSION VISB_SVG_HOVERS3;
  PREDICATE expired(t);
  EXPRESSION VISB_SVG_HOVERS1;
  EXPRESSION VISB_SVG_HOVERS2;
  PREDICATE isOn(d);
  PREDICATE isOff(d);
  EXPRESSION ASSERT_CTL1;
  EXPRESSION isPillTaken_updates(d);
  EXPRESSION drawer_updates(d,col);
  EXPRESSION SET_PREF_STORE_DETAILED_TRANSITION_INFOS == 
  TRUE;
  PREDICATE drugIndexWD(d);
  PREDICATE isThereAnyOtherDeadline(d);
  EXPRESSION currentTime(t);
  EXPRESSION ASSERT_LTL1;
  EXPRESSION ASSERT_LTL2;
  PREDICATE pillDeadlineHit(d);
  EXPRESSION defaults;
  EXPRESSION VISB_SVG_FILE;
  EXPRESSION VISB_SVG_UPDATES1;
  PREDICATE areOthersOn(d);
  EXPRESSION ASSERT_LTL3; */
END
Nr Event Target State ID
1SETUP_CONSTANTS()State 0
2INITIALISATION(drawerLed={(drawer1↦OFF),(drawer2↦OFF),(drawer3↦OFF)},drug={(drawer1↦TYLENOL),(drawer2↦ASPIRINE),(drawer3...
3IncTimeByMinutes(1)
4r_Main-->(∅↦{(drawer1↦TRUE)})
5IncTimeByMinutes(1)
6r_Main-->({(drawer1↦ON)}↦{(drawer1↦TRUE)})
7IncTimeByMinutes(1)
8ENV_toggle_isPillTaken(drawer1,TRUE)
9r_Main-->({(drawer1↦OFF)}↦{(drawer1↦FALSE),(drawer3↦TRUE)})
10r_Main-->({(drawer3↦ON)}↦{(drawer3↦TRUE)})
11IncTimeByMinutes(1)
12ENV_toggle_isPillTaken(drawer1,FALSE)
13ENV_toggle_isPillTaken(drawer3,TRUE)
14r_Main-->({(drawer3↦OFF)}↦{(drawer3↦FALSE)})
15IncTimeByMinutes(10)
16IncTimeByMinutes(10)
17r_Main-->(∅↦{(drawer1↦TRUE),(drawer3↦TRUE)})
18r_Main-->({(drawer3↦ON)}↦{(drawer1↦TRUE),(drawer3↦TRUE)})
19ENV_toggle_isPillTaken(drawer2,TRUE)
20ENV_toggle_isPillTaken(drawer1,TRUE)
21r_Main-->({(drawer3↦OFF)}↦{(drawer1↦TRUE),(drawer3↦FALSE)})
22r_Main-->({(drawer1↦ON)}↦{(drawer1↦TRUE)})
23r_Main-->({(drawer1↦OFF)}↦{(drawer1↦FALSE)})
24ENV_toggle_isPillTaken(drawer1,FALSE)
25ENV_toggle_isPillTaken(drawer2,FALSE)
26ENV_toggle_isPillTaken(drawer3,FALSE)
27IncTimeByMinutes(1)
28IncTimeByMinutes(1)
29IncTimeByMinutes(1)
30IncTimeByMinutes(1)
31IncTimeByMinutes(1)
32IncTimeByMinutes(1)
33r_Main-->(∅↦{(drawer1↦TRUE),(drawer3↦TRUE)})
34r_Main-->({(drawer1↦ON)}↦{(drawer1↦TRUE),(drawer3↦TRUE)})
35ENV_toggle_isPillTaken(drawer1,TRUE)
36r_Main-->({(drawer1↦OFF)}↦{(drawer1↦FALSE),(drawer3↦TRUE)})
37r_Main-->({(drawer3↦ON)}↦{(drawer3↦TRUE)})
38ENV_toggle_isPillTaken(drawer3,TRUE)
39r_Main-->({(drawer3↦OFF)}↦{(drawer3↦FALSE)})
40IncTimeByMinutes(1)
41IncTimeByMinutes(1)
42IncTimeByMinutes(1)
43IncTimeByMinutes(1)
44IncTimeByMinutes(1)
45IncTimeByMinutes(1)
46r_Main-->(∅↦∅)
47IncTimeByMinutes(1)
48IncTimeByMinutes(1)
49IncTimeByMinutes(1)
50IncTimeByMinutes(1)
51r_Main-->(∅↦{(drawer2↦TRUE)})
52r_Main-->({(drawer2↦ON)}↦{(drawer2↦TRUE)})
53IncTimeByMinutes(1)
54ENV_toggle_isPillTaken(drawer1,FALSE)
55ENV_toggle_isPillTaken(drawer3,FALSE)
56ENV_toggle_isPillTaken(drawer2,TRUE)
57r_Main-->({(drawer2↦OFF)}↦{(drawer2↦FALSE)})
58IncTimeByMinutes(10)
59ENV_toggle_isPillTaken(drawer2,FALSE)
60r_Main-->(∅↦{(drawer2↦TRUE)})
61r_Main-->({(drawer2↦ON)}↦{(drawer2↦TRUE)})
62IncTimeByMinutes(1)
63ENV_toggle_isPillTaken(drawer2,TRUE)
64r_Main-->({(drawer2↦OFF)}↦{(drawer2↦FALSE)})
65IncTimeByMinutes(1)
66IncTimeByMinutes(10)
67r_Main-->(∅↦{(drawer2↦TRUE)})
68ENV_toggle_isPillTaken(drawer1,TRUE)
69ENV_toggle_isPillTaken(drawer1,FALSE)
Generated on 12/12/2025 at 12:08 using ProB version 1.15.1-nightly
Main specification file: ../../../../prob_examples/public_examples/ASM/PillBox/pillbox_final.mch (modified on 12/12/2025 at 9:30)
Main specification name: pillbox_final