
-----------------------------------------------
-----------------------------------------------
Class SYSTEM is
Signals
  OnBoardReceive, LocationRequest, ReceiveMA, tick,
  LUreceive, LUsend, RBCreceive, RBCsend
  
Vars
   counter :=0;
   maxcycles := 3;

Behavior

--------------------------------------
--          Cycle_Wait             --
--------------------------------------
--
-- REQ: Every 5 seconds GR shall produce a location request for SR
-- 
--
SYSTEM.OBU.CYCLE_WAIT.Requiring_Position -> CYCLE_WAIT.Requiring_Position { tick / 
      self.LocationRequest;
  }


--------------------------------------
--           Send LU Request        --
--------------------------------------
--
-- REQ: When SR receives a location request, SR shall send the location request to LU
-- Note: The "send location request" operation can fail, and therefore the request could 
--        not reach the location unit
--
SYSTEM.OBU.OBU2LU.Empty -> OBU2LU.Choice  {LocationRequest}

SYSTEM.OBU.OBU2LU.Choice -> OBU2LU.Empty  {- /OBU2LU_comm_failure;}

SYSTEM.OBU.OBU2LU.Choice -> OBU2LU.Full   {- /Sending_request_to_LU}

SYSTEM.OBU.OBU2LU.Full -> OBU2LU.Empty    {- /self.LUreceive; }


--------------------------------------
--   Send Location to RBC (SLRBC)   --
--------------------------------------
--
-- REQ: When SLRBC receives a location, SLRBC shall send the location to RBC
-- Note: The "send location request" operation can fail, and therefore the request could 
--        not reach the location unit
--
SYSTEM.OBU.OBU2RBC.Empty -> OBU2RBC.Choice  {OnBoardReceive}

SYSTEM.OBU.OBU2RBC.Choice -> OBU2RBC.Empty  {- /OBU2RBC_comm_failure;}

SYSTEM.OBU.OBU2RBC.Choice -> OBU2RBC.Full   {- /Sending_location_to_RBC}

SYSTEM.OBU.OBU2RBC.Full -> OBU2RBC.Empty    {- /self.RBCreceive; }


-----------------------------------------------
-----------------------------------------------
--
-- REQ: If RMA does not receive a new MA after 15 seconds from the reception of the 
--         previous MA, RMA shall stop the train
--
SYSTEM.OBU.CONTROLLER.Counting -> CONTROLLER.Counting { tick [counter < maxcycles]/ 
      counter:=counter+1;
  }

SYSTEM.OBU.CONTROLLER.Counting -> CONTROLLER.STOPPED  {
    tick [counter >= maxcycles] /
    counter := counter+1;
    OBU_Stopping;
   }

SYSTEM.OBU.CONTROLLER.Counting -> CONTROLLER.Counting  {
    ReceiveMA /
    counter=0;
   }


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

SYSTEM.LU.CALC.Idle   -> CALC.choice { LUreceive}
  
SYSTEM.LU.CALC.choice -> CALC.Idle { - /CALC_failure; }
  
SYSTEM.LU.CALC.choice -> CALC.Busy { - /Calulate_location; }
  
SYSTEM.LU.CALC.Busy   -> CALC.Idle { - /self.LUsend; }
  
  ---
  
SYSTEM.LU.LU2OBU.Empty  -> LU2OBU.choice { LUsend}
  
SYSTEM.LU.LU2OBU.choice -> LU2OBU.Empty { - /LU2OBU_failure; }
  
SYSTEM.LU.LU2OBU.choice -> LU2OBU.Full { - /Sending_location_to_OBU }
  
SYSTEM.LU.LU2OBU.Full   -> LU2OBU.Empty { - /self.OnBoardReceive }

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

SYSTEM.RBC.MACALC.Idle   -> MACALC.choice { RBCreceive}
  
SYSTEM.RBC.MACALC.choice -> MACALC.Idle { - /MACALC_failure; }
  
SYSTEM.RBC.MACALC.choice -> MACALC.Busy { - /Calulate_MA; }
  
SYSTEM.RBC.MACALC.Busy   -> MACALC.Idle { - /self.RBCsend; }
  
  ---
  
SYSTEM.RBC.RBC2OBU.Empty  -> RBC2OBU.choice { RBCsend}
  
SYSTEM.RBC.RBC2OBU.choice -> RBC2OBU.Empty { - /RBC2OBU_failure; }
  
SYSTEM.RBC.RBC2OBU.choice -> RBC2OBU.Full { - /Sending_MA_to_OBU }
  
SYSTEM.RBC.RBC2OBU.Full   -> RBC2OBU.Empty { - /self.ReceiveMA }

end SYSTEM;
  
-----------------------------------------------
-----------------------------------------------
Class Timer is
 Signals stop, step
Vars
 Priority := -1;
Behaviour
  s0 -> s0 { -   / SYS.tick}
end Timer;
 
-----------------------------------------------
-----------------------------------------------
SYS:SYSTEM;
Timer: Timer;

Abstractions {
--  Action $1($*) -> $1($*)
  Action SYS:accept(tick) -> tick
  Action SYS:accept(ReceiveMA) -> ReceiveMA
  Action SYS:discard(tick) -> DEADLOCK
  State inState(SYS.OBU.CONTROLLER.STOPPED) -> STOPPED
  State inState(SYS.OBU.CONTROLLER.STOPPED) -> STOPPED
  State SYS.counter > SYS.maxcycles ->  TIMEOUT
  State SYS.counter=$1 ->  counter($1)
}


---- PROPERTIES ---------
--  AG (TIMEOUT implies STOPPED)
-- 
-- all paths from a non stopped train status lead either to a stop or to the handling of an MA
-- AG AF (STOPPED or (counter(0)))
--
-- It is possible to infinetely receive a sequence of MA 
--  EG EF (counter(0))
--
-- In absence of failures the train handle an infinite sequence of MA ???
-- 
-- In presence of less then N of failures between two MA the train handles an infinite sequence of MA ???
-- 
-- No deadlocks:   FINAL implies STOPPED
