MINEPUMP = STOPPED

STOPPED  =
    isStopped(?f).STOPPED
    + isNotRunning(?f).STOPPED
    + isNotReady(?f).STOPPED
    + setMethaneStop(?f).METHANESTOPPED 
    + setReady(?f).READY 
METHANESTOPPED  
    = setStop(?f).STOPPED
    + isMethaneStop(?f).METHANESTOPPED
    + setMethaneStop(?f).METHANESTOPPED 
    + isNotRunning(?f).METHANESTOPPED 
    + isNotReady(?f).METHANESTOPPED
    + setReady(?f).READY 
LOWSTOPPED  
    = setStop(?f).STOPPED
    + setMethaneStop(?f).METHANESTOPPED 
    + isLowStop(?f).LOWSTOPPED
    + isNotRunning(?f).LOWSTOPPED
    + isNotReady(?f).LOWSTOPPED
    + setReady(?f).READY 
READY  
    = setStop(?f).STOPPED
    + setMethaneStop(?f).METHANESTOPPED
    + isReady(?f).READY 
    + isNotRunning(?f).READY 
    + setReady(?f).READY
    + setRunning(?f).RUNNING 
RUNNING  
    = setStop(?f).STOPPED
    + setMethaneStop(?f).METHANESTOPPED 
    + setLowStop(?f).LOWSTOPPED
    + isRunning(?f).RUNNING 
    + isNotReady(?f).READY 

-- -------------------------------
CONTROLLER = START

START =  receiveMsg(True).MSG
MSG =  commandMsg(c).COMMAND +
       palarmMsg(m).PALARM +
       levelMsg(True).LEVEL   
COMMAND =  
      stopCmd(ct).STOPCOMMAND  +
      startCmd(cp).STARTCOMMAND
STOPCOMMAND = isRunning(True).S10 +
     isNotRunning(True).S11
S10 = pumpStop(True).S11
S11 = setStop(True).S12
S12 = i(True).START
STARTCOMMAND = 
      isNotRunning(True).S14 +
      isRunning(True).S15 +
      isReady(True).S15
S14 = setReady(True).S15
S15 = i(True).START
PALARM = isRunning(True).S17 +
      isNotRunning(True).S18
S17 = pumpStop(True).S18
S18 = setMethaneStop(True).S19
S19 = i(True).START
LEVEL = highLevel(lh).S21 +
      normalLevel(True).START +
      lowLevel(ll).S27 + 
      highLevel(notlh).START +
      lowLevel(notll).START
S21 = isReady(True).S22 +
     isLowStop(ll).S22 +
     isMethaneStop(m).S26 +
     isRunning(True).S26 +
     isStopped(True).S26
S22 = setReady(True).S23 +
      setMethaneStop(m).S23
S23 = isReady(True).S24 +
      isNotReady(True).S26
S24 = pumpStart(True).S25
S25 = setRunning(True).S26
S26 = i(True).START
S27 = isRunning(True).S28 +
      isNotRunning(True).S30
S28 = pumpStop(True).S29 
S29 = setLowStop(True).S30
S30 = i(True).START

-- ---------------------------------



-- ---------------------------------
-- METHANE LEVEL
-- ---------------------------------
METHANELEVEL = MS1

MS1 =  methaneRise(True).METHANE
METHANE =  methaneLower(True).MS1 
      + palarmMsg(?f).METHANE      
      + setMethaneStop(?f).METHANE  
    
-- ---------------------------------
-- WATER PUMP
-- ---------------------------------
PUMP = PUMPOFF

PUMPOFF = pumpStart(?f).PUMPON
PUMPON = pumpRunning(True).PUMPON       
      + pumpStop(?f).PUMPOFF

-- ---------------------------------
-- WATER LEVEL
-- ---------------------------------
WATERLEVEL = NORMALWATER

NORMALWATER = 
      pumpRunning(?f).LOWWATER       
      + normalLevel(?f).NORMALWATER     
      +  waterRise(True).HIGHWATER   
LOWWATER = 
     lowLevel(?f).LOWWATER 
      +  waterRise(True).NORMALWATER
      + pumpRunning(?f).LOWWATER
HIGHWATER = 
      pumpRunning(?f).NORMALWATER       
      + highLevel(?f).HIGHWATER    
      
-- ---------------------------------



-- ---------------------------------

net MinePumpSystem = 
          CONTROLLER 
          /setStop,isStopped,isMethaneStop,setLowStop,isLowStop,  
           setReady,isReady,isNotReady,setRunning,isRunning,isNotRunning,palarmMsg,
           pumpStart,pumpStop,lowLevel,normalLevel,highLevel,
           setMethaneStop/ 
           ( (MINEPUMP /setMethaneStop/ METHANELEVEL)
              // PUMP /pumpRunning/ WATERLEVEL)

--  LIVENESS OF FTS
Constraints { LIVE }



-------- PROPERTIES ------------
-- AG EX#{true} true    (methane can raise and lower freely !!)


-- There is never a situation in which the pump runs indefinitely 
--    even though there is methane.
--
-- AG AF (not METHANE or PUMPOFF)
--    FALSE :   loop(receiveMsg -> commandMsg -> startCmd -> IsRunning -> tau)
--    TRUE solo per paths per cui: 
--     assert:  (([]<> readCommand) && ([]<> readAlarm) && ([]<> readLevel)).
--

-- =========================================================
--  TRUE PROPERTIES FOR ALL PRODUCTS
-----------------------------------------------------------
-- The system behaviour includes a (mandatory) path that contains 
--   only methane variations
--
-- max X: (EX#{methaneRise or methaneLower} X)
-----------------------------------------------------------
-- we cannot have two palarmMsg without a set MethaneStop.
--
--  AG[palarmMsg] not E[ {not setMethaneStop} U palarmMsg]
-----------------------------------------------------------
-- water level cannot decrease if pump does not start
--
--  AG[highLevel] not E[ {not pumpStart} U lowLevel]
-----------------------------------------------------------
-- pumpStop signal cannot occur is pump is already OFF
--
--  AG not (PUMPOFF and EX {pumpStop} true)
--  AG not (not PUMPON and EX {pumpStop} true)
-----------------------------------------------------------
-- pumpStart signal cannot occur is system is not in READY state
--
-- AG not (not READY and EX {pumpStart} true)
-----------------------------------------------------------
-- after a stop command we cannot have a start command ifin the meanwhile the 
-- system does not actually move to the stopped status
--
-- AG [stopCmd] not E[ not STOPPED U {startCmd}]
-----------------------------------------------------------
-----------------------------------------------------------
-----------------------------------------------------------


