【问题标题】:NuSMV model checking: create a simple game modelNuSMV 模型检查:创建简单的游戏模型
【发布时间】:2016-03-28 06:24:26
【问题描述】:

我是 NuSMV 的新手,我尝试为这款简单的回合制游戏建模。 10块积木,每个玩家每回合可以拿1-3块积木,谁拿走最后一块积木获胜。假设玩家 A 先走,这是我的尝试。我想表达“最终会有赢家”,但我的代码不起作用,因为它不会阻止玩家在brick = 0之后拿砖,所以最终玩家a,b都会成为赢家。

这是我的代码:

MODULE main

VAR

bricks : 0..10; 
i : 1..3;
j : 1..3;
turn : boolean;
winner : {none, a, b};

ASSIGN

init(winner) := none;
init(bricks) := 10;
init(turn) := TRUE;
next(turn) := case
        turn : FALSE;
        !turn: TRUE;
        esac;
next(bricks) := 
            case
            bricks - j >= 0 : bricks - j;
            bricks - j < 0 : 0;
            TRUE:bricks;
            esac;

next(winner) := case
            turn=TRUE & bricks  = 0: a;
            turn=FALSE & bricks = 0: b;
            TRUE:winner;
            esac;

SPEC AF (winner = a | winner = b)

这是我在 SPEC AF 上的输出(获胜者 = a | 获胜者 = 无)来说明我的观点。

i = 1
j = 1
turn = TRUE
winner = none
State: 1.2 <-
bricks = 9
j = 3
turn = FALSE
State: 1.3 <-
bricks = 6
turn = TRUE
State: 1.4 <-
bricks = 3
turn = FALSE
State: 1.5 <-
bricks = 0
j = 1
turn = TRUE
State: 1.6 <-
turn = FALSE
winner = a
State: 1.7 <-
turn = TRUE
winner = b

如您所见,模型仍然提供了一个反例,即玩家 b 在玩 a 已经获胜后赢得游戏。

【问题讨论】:

    标签: logic model-checking ctl nusmv


    【解决方案1】:

    我不确定您是如何提供反例的,因为您指定的属性由模型验证:

    -- specification AF (winner = a | winner = b)  is true
    

    也许您模拟了程序并只是观察到它的行为方式出乎意料。您似乎真正想要验证的属性是AF (AG winner = a | AG winner = b)。事实上,使用这个属性会产生一个类似于你自己的反例

    -- specification AF (AG winner = a | AG winner = b)  is false
    -- as demonstrated by the following execution sequence
    Trace Description: CTL Counterexample 
    Trace Type: Counterexample 
      -> State: 1.1 <-
        bricks = 10
        i = 1
        j = 1
        turn = TRUE
        winner = none
      -> State: 1.2 <-
        bricks = 9
        turn = FALSE
      -> State: 1.3 <-
        bricks = 8
        turn = TRUE
      -> State: 1.4 <-
        bricks = 7
        turn = FALSE
      -> State: 1.5 <-
        bricks = 6
        turn = TRUE
      -> State: 1.6 <-
        bricks = 5
        turn = FALSE
      -> State: 1.7 <-
        bricks = 4
        turn = TRUE
      -> State: 1.8 <-
        bricks = 3
        turn = FALSE
      -> State: 1.9 <-
        bricks = 2
        turn = TRUE
      -> State: 1.10 <-
        bricks = 1
        turn = FALSE
      -> State: 1.11 <-
        bricks = 0
        turn = TRUE
      -- Loop starts here
      -> State: 1.12 <-
        turn = FALSE
        winner = a
      -> State: 1.13 <-
        turn = TRUE
        winner = b
      -> State: 1.14 <-
        turn = FALSE
        winner = a
    

    问题是,即使游戏结束,你也会翻转回合,因此,获胜者也会不断地在 A 和 B 之间翻转。

    我以更好的方式重写您的解决方案:

    MODULE main
    
    VAR
      bricks : 0..10; 
      q : 0..3;
      turn : {A_TURN , B_TURN};
    
    DEFINE
      game_won := next(bricks) = 0;
      a_won := game_won & turn = A_TURN;
      b_won := game_won & turn = B_TURN;
    
    ASSIGN
      init(bricks) := 10;
      init(turn)   := A_TURN;
    
      next(bricks) := case
         bricks - q >= 0 : bricks - q;
         TRUE : 0;
      esac;
    
      next(turn) := case
        turn = A_TURN & !game_won: B_TURN;
        turn = B_TURN & !game_won: A_TURN; 
        TRUE : turn;
      esac;
    
    -- forbid q values from being both larger than the remaining number of 
    -- bricks, and equal to zero when there are still bricks to take.
    INVAR (q <= bricks)
    INVAR (bricks > 0) -> (q > 0)
    INVAR (bricks <= 0) -> (q = 0)
    
    -- Sooner or later the number of bricks will always be
    -- zero for every possible state in every possible path,
    -- that is, someone won the game
    CTLSPEC
      AF AG (bricks = 0)
    

    我认为代码是不言自明的。

    您可以使用以下命令同时使用 NuSMVnuXmv 运行它:

    > read_model -i game.smv
    > go
    > check_property
    -- specification AF (AG bricks = 0)  is true
    

    如果您想找到可能的解决方案,只需翻转属性:

    > check_ctlspec -p "AF AG (bricks != 0)"
    -- specification AF (AG bricks != 0)  is false
    -- as demonstrated by the following execution sequence
    Trace Description: CTL Counterexample 
    Trace Type: Counterexample 
      -> State: 1.1 <-
        bricks = 10
        q = 1
        turn = A_TURN
        game_won = FALSE
        b_won = FALSE
        a_won = FALSE
      -> State: 1.2 <-
        bricks = 9
        turn = B_TURN
      -> State: 1.3 <-
        bricks = 8
        turn = A_TURN
      -> State: 1.4 <-
        bricks = 7
        turn = B_TURN
      -> State: 1.5 <-
        bricks = 6
        turn = A_TURN
      -> State: 1.6 <-
        bricks = 5
        turn = B_TURN
      -> State: 1.7 <-
        bricks = 4
        turn = A_TURN
      -> State: 1.8 <-
        bricks = 3
        turn = B_TURN
      -> State: 1.9 <-
        bricks = 2
        turn = A_TURN
      -> State: 1.10 <-
        bricks = 1
        turn = B_TURN
        game_won = TRUE
        b_won = TRUE
      -- Loop starts here
      -> State: 1.11 <-
        bricks = 0
        q = 0
      -> State: 1.12 <-
    

    希望这个答案对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      相关资源
      最近更新 更多