type integer = int 64; type real = float 64; union STATE = ON | OFF; type PUMPSTATE = (STATE,STATE); WATERMIN = 0.5; WATERMAX = 1.5; WATERSTEP = 0.1; WATERINIT = 0.0; waterstate wl = if wl>WATERMAX then (ON,OFF) else if wl let level = sin wl+1.0 in (wl+WATERSTEP,waterstate level,waterstate level,level); wire water (water.wl' initially WATERINIT) (water.wl,pump.highlow,logger.log_highlow,logger.log_level); union PSTATE = PON | POFF | POFFWAITM | PHIGHWAITM; union PLOGSTATE = PLSUPON | PLSUPOFF | PLOPON | PLOPOFF | PLMAOFF | PLHIGHON | PLLOWOFF | PLON | PLOFF; union METHREQ = OPERATOR | PUMP; union METHVAL = O real | P real; box pump in (pump_state::PSTATE,supervisor::STATE,operator::STATE, meth_reply::METHVAL,meth_alarm::STATE,highlow::PUMPSTATE) out (pump_state'::PSTATE,meth_request::METHREQ,pump_action::PLOGSTATE) match (_,*,*,*,ON,*) -> (POFF,*,PLMAOFF) | (PON,OFF,_*,*,*,_*) -> (POFF,*,PLSUPOFF) | (PON,ON,_*,*,*,_*) -> (PON,*,*) | (POFF,ON,_*,*,*,_*) -> (PON,*,PLSUPON) | (POFF,OFF,_*,*,*,_*) -> (POFF,*,*) | (PON,*,ON,*,*,*) -> (PON,*,*) | (POFF,*,ON,*,*,*) -> (POFFWAITM,OPERATOR,*) | (POFFWAITM,OFF,_*,*,*,_*) -> (POFF,*,PLSUPOFF) | (POFFWAITM,ON,_*,*,*,_*) -> (PON,*,PLSUPON) | (POFFWAITM,*,ON,*,*,*) -> (POFFWAITM,*,*) | (POFFWAITM,*,OFF,*,*,*) -> (POFF,*,PLOPOFF) | (POFFWAITM,*,*,O ml,*,(_,low)) -> if low==ON || ml>=METHCRITICAL then (POFF,*,PLOFF) else (PON,*,PLOPON) | (s,*,*,ml,*,*) -> (s,*,*) | (PON,*,OFF,*,*,(high,_)) -> if high==ON then (PON,*,PLON) else (POFF,*,PLOPOFF) | (POFF,*,OFF,*,*,*) -> (POFF,*,*) | (POFF,*,*,*,*,(high,_)) -> if high==ON then (PHIGHWAITM,PUMP,*) else(POFF,*,*) | (PHIGHWAITM,OFF,_*,*,*,_*) -> (POFF,*,PLSUPOFF) | (PHIGHWAITM,ON,_*,*,*,_*) -> (PON,*,PLSUPON) | (PHIGHWAITM,*,ON,*,*,*) -> (POFFWAITM,*,*) | (PHIGHWAITM,*,OFF,*,*,*) -> (POFF,*,PLOPOFF) | (PHIGHWAITM,*,*,P ml,*,(_,low)) -> if low==ON || ml>=METHCRITICAL then (POFF,*,PLOFF) else (PON,*,PLHIGHON) | (PON,*,*,*,*,(_,ON)) -> (POFF,*,PLLOWOFF) | (s,*,*,*,*,(_,_)) -> (s,*,*) | (s,*,*,*,*,*) -> (s,*,*); wire pump (pump.pump_state' initially POFF trace,supervisor.control trace,operator.control trace, environ.meth_reply,environ.meth_alarm,water.highlow) (pump.pump_state,environ.meth_request,logger.pump_action); METHCRITICAL = 1.75; METHSTEP = 0.1; METHINIT = 1.0; box methane in (r::real) out (r'::real,next::real) match r -> (r+METHSTEP,cos r+1.0); wire methane (methane.r' initially METHINIT) (methane.r,environ.meth_level); CMCRITICAL = 1.9; CMSTEP = 0.15; CMINIT = 1.5; box carbonmonoxide in (r::real) out (r'::real,next::real) match r -> (r+CMSTEP,cos r+1.0); wire carbonmonoxide (carbonmonoxide.r' initially CMINIT) (carbonmonoxide.r,environ.carbmon_level); AFCRITICAL = 0.2; AFSTEP = 0.1; AFINIT = 1.75; box airflow in (r::real) out (r'::real,next::real) match r -> (r+AFSTEP,cos r+1.0); wire airflow (airflow.r' initially AFINIT) (airflow.r,environ.airflow_level); checkml ml = if ml>METHCRITICAL then ON else *; checkcml cml = if cml>CMCRITICAL then ON else *; checkafl afl = if afl (O ml,*,*,*,*,ml,*,*,*,*,*) | (ml,*,*,PUMP) -> (P ml,*,*,*,*,ml,*,*,*,*,*) | (ml,*,*,*) -> (*,checkml ml,checkml ml,*,*,ml,*,*,checkml ml,*,*) | (*,cml,*,*) -> (*,*,*,checkcml cml,*,*,cml,*,*,checkcml cml,*) | (*,*,afl,*) -> (*,*,*,*,checkafl afl,*,*,afl,*,*,checkafl afl) ; wire environ (methane.next,carbonmonoxide.next,airflow.next,pump.meth_request) (pump.meth_reply,pump.meth_alarm, operator.meth_op_alarm,operator.carbmon_op_alarm,operator.airflow_op_alarm, logger.log_meth,logger.log_carbmon,logger.log_airflow, logger.meth_alarm,logger.carbmon_alarm,logger.airflow_alarm); COEFF = 11; CONST = 13; MAX = 10000; rand r = (r*COEFF+CONST) mod MAX; SUPSEED = 7; SUPPROB = 15; box supervisor in (s::integer) out (s'::integer,control::STATE,action::STATE) match s -> let s' = rand s in case s' mod SUPPROB of 0 -> (s',ON,ON) | 1 -> (s',OFF,OFF) | _ -> (s',*,*); wire supervisor (supervisor.s' initially SUPSEED) (supervisor.s,pump.supervisor,logger.super_action); OPSEED = 5; OPPROB = 20; box operator in (s::integer, meth_op_alarm::STATE,carbmon_op_alarm::STATE,airflow_op_alarm::STATE) out (s'::integer,control::STATE,action::STATE) match (*,*,*,ON) -> (*,OFF,OFF) | (*,*,ON,*) -> (*,OFF,OFF) | (*,ON,*,*) -> (*,OFF,OFF) | (s,*,*,*) -> let s' = rand s in case s' mod OPPROB of 0 -> (s',ON,ON) | 1 -> (s',OFF,OFF) | _ -> (s',*,*); wire operator (operator.s' initially OPSEED, environ.meth_op_alarm,environ.carbmon_op_alarm, environ.airflow_op_alarm) (operator.s,pump.operator,logger.oper_action); plstate PLMAOFF = "OFF - METHANE ALARM"; plstate PLSUPON = "ON - SUPERVISOR"; plstate PLSUPOFF = "OFF - SUPERVISOR"; plstate PLOPON = "ON - OPERATOR"; plstate PLOPOFF = "OFF - OPERATOR"; plstate PLLOWOFF = "OFF - LOW WATER"; plstate PLHIGHON = "ON - HIGH WATER"; plstate PLON = "ON"; plstate PLOFF = "OFF"; state ON = "ON"; state OFF = "OFF"; box logger in (pump_action::PLOGSTATE, log_meth::real,log_carbmon::real,log_airflow::real, meth_alarm::STATE,carbmon_alarm::STATE,airflow_alarm::STATE, super_action::STATE,oper_action::STATE, log_highlow::(STATE,STATE),log_level::real) out (log::string) fair --(pa,*,*,*,*,*,*,*,*,*,*) -> * | --(*,md,*,*,*,*,*,*,*,*,*) -> * | --(*,*,cmd,*,*,*,*,*,*,*,*) -> * | --(*,*,*,afd,*,*,*,*,*,*,*) -> * | --(*,*,*,*,ON,*,*,*,*,*,*) -> * | --(*,*,*,*,*,ON,*,*,*,*,*) -> * | --(*,*,*,*,*,*,ON,*,*,*,*) -> * | --(*,*,*,*,*,*,*,sa,*,*,*) -> * | --(*,*,*,*,*,*,*,*,oa,*,*) -> * | --(*,*,*,*,*,*,*,*,*,(h,l),level) -> * ; -- The use of as in this way may be illegal? KH (pa,*,*,*,*,*,*,*,*,*,*) -> "pump: "++plstate pa++"\n" | (*,md,*,*,*,*,*,*,*,*,*) -> "methane: "++md as string++"\n" | (*,*,cmd,*,*,*,*,*,*,*,*) -> "carbon monoxide: "++cmd as string++"\n" | (*,*,*,afd,*,*,*,*,*,*,*) -> "airflow: "++afd as string++"\n" | (*,*,*,*,ON,*,*,*,*,*,*) -> "***METHANE ALARM ON***\n" | (*,*,*,*,*,ON,*,*,*,*,*) -> "***CARBON MONOXIDE ALARM ON***\n" | (*,*,*,*,*,*,ON,*,*,*,*) -> "***AIR FLOW ALARM ON***\n" | (*,*,*,*,*,*,*,sa,*,*,*) -> "***SUPERVISOR: "++state sa++"***\n" | (*,*,*,*,*,*,*,*,oa,*,*) -> "***OPERATOR: "++state oa++"***\n" | (*,*,*,*,*,*,*,*,*,(h,l),level) -> "water level: "++level as string++"\n"++ "***HIGH: "++state h++" LOW: "++state l++"***\n"; stream output to "std_out"; wire logger (pump.pump_action, environ.log_meth,environ.log_carbmon,environ.log_airflow, environ.log_meth_alarm,environ.log_carbmon_alarm,environ.log_airflow_alarm, supervisor.action,operator.action,water.log_highlow,water.log_level) (output);