Светофор в НуСМВ

Я пытаюсь создать реализацию системы светофора в NuSMV. Прямо сейчас у меня есть 6 логических значений для NS/EW красный, желтый, зеленый. Однако, когда я указываю, что каждое из них всегда истинно в будущем состоянии, оно возвращается ложным. Если кто-то увидит какие-либо ошибки в моем коде, я был бы признателен за помощь. Спасибо.

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

person user3018947    schedule 21.04.2015    source источник


Ответы (2)


Причина того, что свойство F nsGreen = TRUE является ложным, заключается в том, что существует бесконечное выполнение, при котором 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 <-

Трассировка показывает, что nsRed уже имеет значение false, когда таймер достигает 0 в первый раз. Кроме того, ewYellow становится ложным, но ewRed не устанавливается в значение true.

Я бы предложил вам использовать переменную перечисления для светофоров вместо трех логических значений, например:

MODULE main
VAR
    ns : {RED, YELLOW, GREEN};
    ew : {RED, YELLOW, GREEN};
person Thomas    schedule 12.09.2015

Как насчет определения двух разных состояний, указывающих на светофоры для северной и западной сторон улицы? Я написал пример кода, надеюсь, вы найдете его полезным...

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, и еще один счетчик 5 -> 0, я назвал его timeYellow, чтобы переход от GREEN к YELLOW был плавным и менее опасным!

person Färid Alijani    schedule 14.09.2017