NuSMV的红绿灯

时间:2015-04-21 16:26:00

标签: model-checking nusmv

我正在努力在NuSMV中创建一个红绿灯系统。现在我有6个布线用于NS / EW红色,黄色,绿色。但是,当我指定它们在未来状态中每个都是真的时,它会返回false。如果有人在我的代码中看到任何错误,我将不胜感激。感谢。

MODULE main
VAR
    nsRed : boolean;
    nsYellow : boolean;
    nsGreen : boolean;

    time : 0..60;

    ewRed : boolean;
    ewYellow : boolean;
    ewGreen : boolean;
ASSIGN
    init(nsRed) := TRUE;
    init(nsYellow) := FALSE;
    init(nsGreen) := FALSE;
    init(ewRed) := FALSE;
    init(ewYellow) := FALSE;
    init(ewGreen) := TRUE;
    init(time) := 60;
next(nsRed) :=
    case
        (nsYellow = TRUE & (ewGreen = TRUE | ewYellow = TRUE) & time = 0) : TRUE;
        (nsRed = TRUE & time = 0) : FALSE;
        TRUE : nsRed;
    esac;
next(nsYellow) :=
    case
        (nsGreen = TRUE & ewRed = TRUE & time = 0) : TRUE;
        (nsYellow = TRUE & time = 0) : FALSE;
        TRUE : nsYellow;
    esac;
next(nsGreen) :=
    case
        (nsRed = TRUE & ewRed = TRUE & time = 0) : TRUE;
        (nsGreen = TRUE & time = 0) : FALSE;
        TRUE : nsGreen;
    esac;

next(ewRed) :=
    case
        (ewYellow = TRUE & (nsGreen = TRUE | nsYellow = TRUE) & time = 0) : TRUE;
        (ewRed = TRUE & time = 0) : FALSE;
        TRUE : ewRed;
    esac;
next(ewYellow) :=
    case
        (ewGreen = TRUE & nsRed = TRUE & time = 0) : TRUE;
        (ewYellow = TRUE & time = 0) : FALSE;
        TRUE : ewYellow;
    esac;
next(ewGreen) :=
    case
        (ewRed = TRUE & nsRed = TRUE & time = 0) : TRUE;
        (ewGreen = TRUE & time = 0) : FALSE;
        TRUE : ewGreen;
    esac;

next(time) :=
    case
        (time > 0) : time - 1;
        (time = 0 & nsRed = TRUE) : 60;
        (time = 0 & nsYellow = TRUE) : 60;
        (time = 0 & nsGreen = TRUE) : 3;
        (time = 0 & ewRed = TRUE) : 60;
        (time = 0 & ewYellow = TRUE) : 60;
        (time = 0 & ewGreen = TRUE) : 3;
        --(time = 0 & nsRed = TRUE & ewRed = TRUE) : 3
        TRUE : time;
    esac;

-- specification 
SPEC AG !(nsRed = TRUE & nsYellow = TRUE)
SPEC AG !(nsGreen = TRUE & nsRed = TRUE)
SPEC AG !(nsGreen = TRUE & ewGreen = TRUE)
SPEC AG !(nsYellow = TRUE & ewYellow = TRUE)
SPEC AG !(nsRed = TRUE & ewRed = TRUE)
SPEC AG (nsRed = TRUE | nsYellow = TRUE | nsGreen = TRUE | ewRed = TRUE | ewYellow = TRUE | ewGreen = TRUE)
--LTLSPEC F nsGreen = TRUE
LTLSPEC F ewGreen = TRUE

2 个答案:

答案 0 :(得分:2)

属性F nsGreen = TRUE为false的原因是存在无限执行,其中nsGreen永远不为真。这是NuSMV生成的反例(我减少了计时器的倒计时)。请注意,仅打印变量更新。

-- specification  F nsGreen = TRUE  is false
-- as demonstrated by the following execution sequence
Trace Description: LTL Counterexample
Trace Type: Counterexample
-> State: 1.1 <-
  nsRed = TRUE
  nsYellow = FALSE
  nsGreen = FALSE
  time = 60
  ewRed = FALSE
  ewYellow = FALSE
  ewGreen = TRUE
-> State: 1.2 <-
  time = 59
  ...
-> State: 1.61 <-
  time = 0
-> State: 1.62 <-
  nsRed = FALSE
  time = 60
  ewYellow = TRUE
  ewGreen = FALSE
-> State: 1.63 <-
  time = 59
  ...
-> State: 1.122 <-
  time = 0
-> State: 1.123 <-
  time = 60
  ewYellow = FALSE
-> State: 1.124 <-
  time = 59
  ...
-> State: 1.182 <-
  time = 1
-- Loop starts here
-> State: 1.183 <-
  time = 0
-> State: 1.184 <-

跟踪显示当计时器第一次达到0时,nsRed已设置为false。此外,ewYellow变为false,但ewRed未设置为true。

我建议你使用enum变量代替三个布尔值来代替三个布尔值:

MODULE main
VAR
    ns : {RED, YELLOW, GREEN};
    ew : {RED, YELLOW, GREEN};

答案 1 :(得分:0)

如何定义两个不同的状态,指示街道的NS和EW侧的交通灯? 我写了一个示例代码,希望你发现它很有用......

val partitionsDF = hiveContext.sql("show partitions TABLE_NAME")

当我们处于MODULE main VAR nsLight : {RED, YELLOW, GREEN}; ewLight : {RED, YELLOW, GREEN}; timeMove : 0..10; timeYellow : 0..5; ASSIGN init(nsLight) := RED; init(ewLight) := GREEN; init(timeMove) := 10; init(timeYellow):= 5; -- NS: | EW: -- R (10 sec) -> R -> G (10 sec) | G (10 sec) -> Y (5 sec) -> R (10 sec) -- / \ | | | | -- | \ / | | \ / -- |------------------- Y (5 sec) | |--------------------------- R next(nsLight) := case (nsLight = RED & ewLight = GREEN & timeMove = 0) : RED; (nsLight = RED & ewLight = YELLOW & timeYellow = 0) : GREEN; (nsLight = GREEN & ewLight = RED & timeMove = 0) : YELLOW; (nsLight = YELLOW & ewLight = RED & timeYellow = 0) : RED; TRUE : nsLight; esac; next(ewLight) := case (ewLight = GREEN & nsLight = RED & timeMove = 0) : YELLOW; (ewLight = YELLOW & nsLight = RED & timeYellow = 0) : RED; (ewLight = RED & nsLight = GREEN & timeMove = 0) : RED; (ewLight = RED & nsLight = YELLOW & timeYellow = 0) : GREEN; TRUE : ewLight; esac; next(timeMove) := case timeMove > 0 & ewLight != YELLOW & nsLight != YELLOW : timeMove - 1; timeMove = 0 : 10; TRUE : timeMove; esac; next(timeYellow) := case timeYellow > 0 & (ewLight = YELLOW | nsLight = YELLOW) : timeYellow - 1; timeYellow = 0 : 5; TRUE : timeYellow; esac; 10 -> 0状态以及另一个计数器GREEN时,我的想法是从RED获得一个移动的计数器,我称之为{{ 1}},以确保从5 -> 0timeYellow的转换顺利且不那么危险!