2017-04-06 378 views
1

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

下面是完整的模型代码:

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

} 

enter image description here

回答

1

您使用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 
... 
+0

我想我解决了这个问题,但现在程序超时,代码从语句“::(count> = 60) - >”到“sigY_out!1;”。此转换位于traffic_mode ==挂起块下方。人行横道模块进入等待状态,等待sigR信号,所以我不相信那是什么引起的问题。 – Flower

+0

另外,是否可以像我上面那样检查ltl规范中的会合通道? – Flower