1

I am working on a promela model that it fairly simple. Using two different modules, it acts as a crosswalk/Traffic light. The first module is the traffic light that outputs the current signal (green, red, yellow, pending). This module also receives as an input a signal called "pedestrian" which acts as an indicator that there are pedestrians wanting to cross. The second module acts as the crosswalk. It receives output signals from the traffic light module (green, yellow, green). It outputs the pedestrian signal to the traffic light module. This module simply defines whether the pedestrian(s) is crossing, waiting or not present. My issue is that upon running the model in Spin, it times out once the crosswalk begins toe execute its first few statements. I have attached the image of the trace I receive from the command line. I am completely new to Spin and Promela and so I am not entirely sure how to use the information form the trace to find my issue in the code. Any help is greatly appreciated.

Here is the code for the complete model:

mtype = {red, green, yellow, pending, none, crossing, waiting};
mtype traffic_mode;
mtype crosswalk_mode;
byte count;
chan pedestrian_chan = [0] of {byte};  
chan sigR_chan = [0] of {byte};
chan sigG_chan = [0] of {byte};
chan sigY_chan = [0] of {byte};

ltl l1 {!<> (pedestrian_chan[0] == 1) && (traffic_mode == green || traffic_mode == yellow || traffic_mode == pending)}
ltl l2 {[]<> (pedestrian_chan[0] == 1) -> crosswalk_mode == crossing }

active proctype traffic_controller(chan pedestrian_in, sigR_out, sigG_out, sigY_out)

{

do
    ::if
      ::(traffic_mode == red) -> 
        count = count + 1;
        if
        ::(count >= 60) ->
            sigG_out ! 1;
            count = 0;
            traffic_mode = green;
        fi
      ::(traffic_mode == green) -> 
        if
        ::(count < 60) ->
            count = count + 1;
            traffic_mode = green;
        ::(pedestrian_in == 1 & count < 60) ->
            count = count + 1;
            traffic_mode = pending;
        ::(pedestrian_in == 1 & count >= 60)
            count = 0;
            traffic_mode = yellow;
        fi
      ::(traffic_mode == pending) ->
        count = count + 1;
        traffic_mode = pending;
        if
        ::(count >= 60) ->
            sigY_out ! 1;
            count = 0;
            traffic_mode = yellow;
        fi  
      ::(traffic_mode == yellow) ->
        count = count + 1;
        traffic_mode = yellow;
        if
        ::(count >= 5) ->
            sigR_out ! 1;
            count = 0;
        fi
      fi
od  

}



active proctype crosswalk(chan sigR_in, sigG_in, sigY_in, pedestrian_out)

{
do
    ::if
      ::(crosswalk_mode == crossing) ->
        if
        ::(sigG_in == 1) -> crosswalk_mode = none;
        fi
      ::(crosswalk_mode == none) ->
        if  
        :: (1 == 1) -> crosswalk_mode = none;
        :: (1 == 1) -> 
            pedestrian_out ! 1;
            crosswalk_mode = waiting;
        fi
      ::(crosswalk_mode == waiting) ->
        if
        ::(sigR_in == 1) -> crosswalk_mode = crossing;
        fi
      fi
od   
}   
init

{
    count = 0;
    traffic_mode = red;
    crosswalk_mode = crossing;

    atomic
    {
        run traffic_controller(pedestrian_chan, sigR_chan, sigG_chan, sigY_chan);
        run crosswalk(sigR_chan, sigG_chan, sigY_chan, pedestrian_chan);
    }
}


[![enter image description here][1]][1]

enter image description here

Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
Flower
  • 381
  • 1
  • 6
  • 17

1 Answers1

2

The issue is very easy to spot, the system gets stuck in this code here:

    if
    ::(count >= 60) ->
        sigG_out ! 1;
        count = 0;
        traffic_mode = green;
    fi

what happens if count is not greater or equal 60?

The processes cannot execute the (only) branch, because the condition is false, so they both stop there waiting for it to become true some time in the future.

You should provide an alternative branch like else -> skip so the processes can simply get past that if ... fi statement.

Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
  • Thanks for your answer. This solved the timeout. I do have another issue however. Once the count goes above 60, It wants to do sigY_out ! 1, but I get the error, "Sending to uninitialized chan." I guess the channel that this variable is connected to is somehow uninitialized. Not entirely sure how to fix this. – Flower Apr 06 '17 at 16:03
  • 1
    @Flower it is likely because you have active processes in your system, for which the input variables are initialised to 0. Just remove the `active` keyword. – Patrick Trentin Apr 06 '17 at 16:19
  • Now it times out once the count hits 60. – Flower Apr 06 '17 at 16:34
  • And when I run with option -t, it says " error: invalid statement" – Flower Apr 06 '17 at 16:40
  • 1
    before you had 5 processes in your system, now it's 3..might be there's something else that depended on that – Patrick Trentin Apr 06 '17 at 16:43
  • Of those 5 processes, 2 were duplicates because of the "active" keyword I was using. The 3 processes now are, crosswalk, traffic_controller and the init process. – Flower Apr 06 '17 at 17:30