2

我正在研究一个相当简单的 promela 模型。使用两个不同的模块,它充当人行横道/交通灯。第一个模块是输出当前信号(绿色、红色、黄色、待定)的交通灯。该模块还接收一个称为“行人”的信号作为输入,该信号用作指示有行人想要穿过的信号。第二个模块充当人行横道。它接收来自交通灯模块的输出信号(绿色、黄色、绿色)。它将行人信号输出到交通灯模块。该模块仅定义行人是否正在过马路、等待或不存在。我的问题是,一旦计数值达到 60,就会发生超时。我相信声明“SigG_out!1”会导致错误,但我不知道为什么。我附上了从命令行收到的跟踪图像。我对 Spin 和 Promela 完全陌生,所以我不确定如何使用跟踪中的信息在代码中找到我的问题。任何帮助是极大的赞赏。

这是完整模型的代码:

mtype = {red, green, yellow, pending, none, crossing, waiting};
mtype traffic_mode;
mtype crosswalk_mode;
int 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 }

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;
        :: else -> skip;
        fi
      ::(traffic_mode == green) -> 
        if
        ::(count < 60) ->
            count = count + 1;
        ::(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;
        if
        ::(count >= 60) ->
            sigY_out ! 1;
            count = 0;
            traffic_mode = yellow;
        ::else -> skip;
        fi  
      ::(traffic_mode == yellow) ->
        count = count + 1;
        if
        ::(count >= 5) ->
            sigR_out ! 1;
            count = 0;
            traffic_mode = red;
        :: else -> skip;
        fi
      fi
od  

}



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);
    }

}

在此处输入图像描述

4

1 回答 1

2

您使用channels不正确,尤其是这一行,我什至不知道如何解释它:

:: (sigG_in == 1) ->

  1. 您的通道是同步的,这意味着每当一个进程在一侧发送某些内容时,另一个进程必须在通道的另一端侦听才能传递消息。否则,该过程将阻塞,直到情况发生变化。您的频道同步的,因为您声明了它们的大小。0

  2. 要从频道读取,您需要使用正确的语法:

    int some_var;
    ...
    some_channel?some_var;
    // here some_var contains value received through some_channel
    

用三个不同的通道发送不同的信号似乎有点没有意义。那么使用三个不同的值呢?

mtype = { RED, GREEN, YELLOW };
chan c = [0] of { mtype };
...
c!RED
...
// (some other process)
...
mtype var;
c?var;
// here var contains RED
...
于 2017-04-07T10:57:13.980 回答