blob: 0e1952586a2e4a321f826d5a5446403759bd3309 [file] [log] [blame]
--#define HMON(h_mon, var) VAR h_mon : boolean; INIT h_mon <-> var; TRANS next(h_mon) <-> (h_mon | next(var));
--------------------------------------------------------------------------------
MODULE forge_environment
VAR workload : {low, mid, high};
VAR heat : {low, high};
--------------------------------------------------------------------------------
MODULE forge_robot (env_workload, env_heat, time_delta, do_timed, done_timed)
-- hack!
TRANS non_crit_overheating != next(non_crit_overheating) -> position = next(position);
TRANS crit_overheating != next(crit_overheating) -> position = next(position);
-- discretization constraints
TRANS heat_level < 10 -> !next(heat_level > 10);
TRANS heat_level < 13 -> !next(heat_level > 13);
TRANS heat_level < 15 -> !next(heat_level > 15);
TRANS work_done < 6 -> !next(work_done > 6);
VAR non_crit_overheating : boolean;
ASSIGN init(non_crit_overheating) := FALSE;
ASSIGN next(non_crit_overheating) := case
heat_level >= 10 : TRUE;
TRUE : FALSE;
esac;
--INVARSPEC (non_crit_overheating != next(non_crit_overheating)) -> !do_timed;
VAR crit_overheating : boolean;
ASSIGN init(crit_overheating) := FALSE;
ASSIGN next(crit_overheating) := case
heat_level >= 15 : TRUE;
TRUE : FALSE;
esac;
--INVARSPEC (crit_overheating != next(crit_overheating)) -> !do_timed;
-- robot position
DEFINE can_move := !f_locomotion & heat_level < 13;
VAR position : {critical_zone, safe_zone};
ASSIGN init(position) := safe_zone;
ASSIGN next(position) := case
do_timed : position;
!can_move : position;
-- stay in critical zone until work is done
position=critical_zone & work_done < 6 : critical_zone;
-- leave critical zone once work is done
position=critical_zone & work_done = 6 : safe_zone;
-- do not enter critical zone with positive heat level
position=safe_zone & heat_level > 0 : safe_zone;
-- random choice
TRUE : {critical_zone, safe_zone};
esac;
-- robot heat level
VAR heat_level : real;
ASSIGN init(heat_level) := 0;
ASSIGN next(heat_level) := case
!do_timed : heat_level;
-- heat development in safe zone
position=safe_zone : max(0, heat_level - time_delta);
-- heat development leaving critical zone
position=critical_zone & next(position=safe_zone) : heat_level;
-- heat development in critical zone
f_cooling & env_heat = high : heat_level + time_delta * 2;
TRUE : heat_level + time_delta;
esac;
--LTLSPEC G ((position=safe_zone & X (position=critical_zone)) -> heat_level=0);
-- status of work in critical zone
VAR work_done : real;
ASSIGN init(work_done) := 6;
ASSIGN next(work_done) := case
-- no work
next(position=safe_zone) : 6;
-- start work
position=safe_zone & next(position=critical_zone) : 0;
-- doing work
env_workload=low : work_done + time_delta * 3;
env_workload=mid : work_done + time_delta * 2;
TRUE : work_done + time_delta;
esac;
-- failure of robot cooling system (permanent)
VAR f_cooling : boolean;
TRANS f_cooling -> next(f_cooling);
TRANS do_timed -> f_cooling=next(f_cooling);
-- failure of robot locomotion (permanent)
VAR f_locomotion : boolean;
TRANS f_locomotion -> next(f_locomotion);
TRANS do_timed -> f_locomotion=next(f_locomotion);
--LTLSPEC G (f_cooling -> G f_cooling);
--LTLSPEC G (f_locomotion -> G f_locomotion);
--------------------------------------------------------------------------------
MODULE main
-- environment modeling amount of heat and workload in critical zone
VAR environment : forge_environment;
-- assume environment is stable when robot enters critical zone,
-- but can be different each time the robot enters the zone.
TRANS robot.position=critical_zone -> environment.workload = next(environment.workload);
TRANS robot.position=critical_zone -> environment.heat = next(environment.heat);
VAR robot : forge_robot(environment.workload, environment.heat, time_delta,
do_timed, done_timed);
IVAR time_delta : real;
FAIRNESS time_delta > 0;
TRANS time_delta >= 0;
-- guard to prevent discrete updates during timed transitions
VAR do_timed : boolean;
TRANS do_timed <-> time_delta > 0;
TRANS do_timed -> !next(do_timed);
-- guard to enable discrete updates after each timed transition
VAR done_timed : boolean;
INIT !done_timed;
TRANS do_timed <-> next(done_timed);
--INVARSPEC do_timed -> !done_timed;
--INVARSPEC done_timed -> !do_timed;
--LTLSPEC G F do_timed;
-- HMON(h_F_LOCOMOTION, robot.f_locomotion)
-- INVARSPEC time_delta=1 -> (h_F_LOCOMOTION = next(h_F_LOCOMOTION));
--
-- HMON(h_F_COOLING, robot.f_cooling)
-- INVARSPEC time_delta=1 -> (h_F_COOLING = next(h_F_COOLING));
--
-- DEFINE def_NON_CRITICAL_OVERHEATING:= robot.heat_level >= 10;
-- HMON(h_NON_CRITICAL_OVERHEATING, def_NON_CRITICAL_OVERHEATING)
-- INVARSPEC time_delta=1 -> (h_NON_CRITICAL_OVERHEATING = next(h_NON_CRITICAL_OVERHEATING));
--
-- DEFINE def_CRITICAL_OVERHEATING:= robot.heat_level = 15;
-- HMON(h_CRITICAL_OVERHEATING, def_CRITICAL_OVERHEATING)
-- INVARSPEC time_delta=1 -> (h_CRITICAL_OVERHEATING = next(h_CRITICAL_OVERHEATING));
--
-- DEFINE def_UNIT_STUCK:= !robot.can_move;
-- HMON(h_UNIT_STUCK, def_UNIT_STUCK)
-- INVARSPEC time_delta=1 -> (h_UNIT_STUCK = next(h_UNIT_STUCK));