# NuSMV 超入門
NuSMV をインストールして、簡単なモデルを書いて、それをバッチモードと対話モードで動かします。
## インストール
[NuSMV の公式サイトのダウンロードページ](https://nusmv.fbk.eu/downloads.html)に行って、バイナリを取ってきます。適当なところで展開してください。`bin` ディレクトリの中に NuSMV の実行可能バイナリがあります。
## モデルを書く
NuSMV が読み込める形で、有限状態マシンを書きます。ここでは簡単に、変数 `v1` と `v2` があって、`v1` は 1 と 2、`v2` は 3 と 4 を交互に繰り返すようなモデルを書きます。図にすると以下のような感じです。
![simplefsm](https://hackmd.io/_uploads/HklshyD2p.png)
以下のような内容のファイルを `test.smv` という名前で保存します。
```
MODULE main
VAR
v1 : {1,2};
v2 : {3,4};
ASSIGN
init(v1) := 1;
init(v2) := 3;
next(v1) :=
case
v1 = 1 : 2;
v1 = 2 : 1;
esac;
next(v2) :=
case
v2 = 3 : 4;
v2 = 4 : 3;
esac;
```
## NuSMV に読み込ませてシミュレーションする
NuSMV の対話モードを使って、上で書いたモデルを読み込ませます。`-int` オプションとファイル名 `test.smv` を指定して NuSMV を起動します。
```
$ ./NuSMV -int test.smv
*** This is NuSMV 2.6.0 (compiled on Wed Oct 14 15:36:56 2015)
*** Enabled addons are: compass
*** For more information on NuSMV see <http://nusmv.fbk.eu>
*** or email to <nusmv-users@list.fbk.eu>.
*** Please report bugs to <Please report bugs to <nusmv-users@fbk.eu>>
*** Copyright (c) 2010-2014, Fondazione Bruno Kessler
*** This version of NuSMV is linked to the CUDD library version 2.4.1
*** Copyright (c) 1995-2004, Regents of the University of Colorado
*** This version of NuSMV is linked to the MiniSat SAT solver.
*** See http://minisat.se/MiniSat.html
*** Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
*** Copyright (c) 2007-2010, Niklas Sorensson
NuSMV >
```
プロンプトが表示されるので、まず `go` と打ってモデルを読み込ませます。
```
NuSMV > go
```
とりあえずシミュレーションを実行してみて、作ったモデルが意図通りかを確認します。`pick_state -i` で初期状態を決めます。今は `v1 = 1 & v2 = 3` の 1 状態しかないので、その旨が表示されます。
```
NuSMV > pick_state -i
*************** AVAILABLE STATES *************
================= State =================
0) -------------------------
v1 = 1
v2 = 3
There's only one available state. Press Return to Proceed.
Chosen state is: 0
```
続いて 1 ステップ状態を進めます。`simulate -k 1 -i` を使います。`-k` はステップ数です。進む先は `v1 = 2 & v2 = 4` の 1 状態しかないので、やはりその旨が表示されます。
```
NuSMV > simulate -k 1 -i
******** Simulation Starting From State 1.1 ********
*************** AVAILABLE STATES *************
================= State =================
0) -------------------------
v1 = 2
v2 = 4
There's only one available state. Press Return to Proceed.
Chosen state is: 0
```
さらにもう 1 ステップ進めると、初期状態に戻ってきます。
```
NuSMV > simulate -k 1 -i
******** Simulation Starting From State 1.2 ********
*************** AVAILABLE STATES *************
================= State =================
0) -------------------------
v1 = 1
v2 = 3
There's only one available state. Press Return to Proceed.
Chosen state is: 0
```
うまくできてそうです。
## CTL と LTL でモデル検査する
続いて CTL を使ってモデル検査をしてみます。例えば、どんなときも `v1 = 1` かつ `v2 = 4` になることは絶対にないこと(`AG !(v1 = 1 & v2 = 4)`)を検査してみます:
```
NuSMV > check_ctlspec -p "AG !(v1 = 1 & v2 = 4)"
-- specification AG !(v1 = 1 & v2 = 4) is true
```
続いて、常に `v1 = 1` かつ `v2 = 3` であること `AG (v1 = 1 & v2 = 3)` 検査してみます。これは偽なので、反例が表示されます:
```
NuSMV > check_ctlspec -p "AG (v1 = 1 & v2 = 3)"
-- specification AG (v1 = 1 & v2 = 3) is false
-- as demonstrated by the following execution sequence
Trace Description: CTL Counterexample
Trace Type: Counterexample
-> State: 3.1 <-
v1 = 1
v2 = 3
-> State: 3.2 <-
v1 = 2
v2 = 4
```
同様に LTL でもモデル検査できます:
```
NuSMV > check_ltlspec -p "G !(v1 = 1 & v2 = 4)"
-- specification G !(v1 = 1 & v2 = 4) is true
NuSMV > check_ltlspec -p "G (v1 = 1 & v2 = 3)"
-- specification G (v1 = 1 & v2 = 3) is false
-- as demonstrated by the following execution sequence
Trace Description: LTL Counterexample
Trace Type: Counterexample
-- Loop starts here
-> State: 4.1 <-
v1 = 1
v2 = 3
-> State: 4.2 <-
v1 = 2
v2 = 4
-> State: 4.3 <-
v1 = 1
v2 = 3
```
対話モードは `quit` で終了できます。
```
NuSMV > quit
```
## バッチモードでモデル検査する
NuSMV には対話モードのほかにバッチモードもあります。単にファイル名を指定して NuSMV を起動すると、ファイルに書かれたモデルを読み込み、モデル検査を行います。
先程のモデルにモデル検査を行うための記述を追加します:
```
MODULE main
VAR
v1 : {1,2};
v2 : {3,4};
ASSIGN
init(v1) := 1;
init(v2) := 3;
next(v1) :=
case
v1 = 1 : 2;
v1 = 2 : 1;
esac;
next(v2) :=
case
v2 = 3 : 4;
v2 = 4 : 3;
esac;
-- 以下を追加
CTLSPEC AG !(v1 = 1 & v2 = 4);
CTLSPEC AG (v1 = 1 & v2 = 3);
LTLSPEC G !(v1 = 1 & v2 = 4);
LTLSPEC G (v1 = 1 & v2 = 3);
```
NuSMV をバッチモードで起動すると、指定した仕様が検証できたことがわかります。違反する仕様があると、対話モードときと同様に反例を出してくれます:
```
$ ./NuSMV test.smv
*** This is NuSMV 2.6.0 (compiled on Wed Oct 14 15:36:56 2015)
*** Enabled addons are: compass
*** For more information on NuSMV see <http://nusmv.fbk.eu>
*** or email to <nusmv-users@list.fbk.eu>.
*** Please report bugs to <Please report bugs to <nusmv-users@fbk.eu>>
*** Copyright (c) 2010-2014, Fondazione Bruno Kessler
*** This version of NuSMV is linked to the CUDD library version 2.4.1
*** Copyright (c) 1995-2004, Regents of the University of Colorado
*** This version of NuSMV is linked to the MiniSat SAT solver.
*** See http://minisat.se/MiniSat.html
*** Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
*** Copyright (c) 2007-2010, Niklas Sorensson
-- specification AG !(v1 = 1 & v2 = 4) is true
-- specification AG (v1 = 1 & v2 = 3) is false
-- as demonstrated by the following execution sequence
Trace Description: CTL Counterexample
Trace Type: Counterexample
-> State: 1.1 <-
v1 = 1
v2 = 3
-> State: 1.2 <-
v1 = 2
v2 = 4
-- specification G !(v1 = 1 & v2 = 4) is true
-- specification G (v1 = 1 & v2 = 3) is false
-- as demonstrated by the following execution sequence
Trace Description: LTL Counterexample
Trace Type: Counterexample
-- Loop starts here
-> State: 2.1 <-
v1 = 1
v2 = 3
-> State: 2.2 <-
v1 = 2
v2 = 4
-> State: 2.3 <-
v1 = 1
v2 = 3
```
## おわり
おわりです。
## 参考情報
NuSMV 公式のチュートリアルとユーザーマニュアルが詳しいのでオススメです。
- チュートリアル https://nusmv.fbk.eu/tutorials.html
- ユーザーマニュアル https://nusmv.fbk.eu/user-manual.html
NuSMV を使ったモデル検査のもう少し実用的な例は、[Masaki Waga さんのかき氷の形式検証のツイート](https://twitter.com/MasWag/status/1532183190697172992)などを参考にしてください。
あと自分が NuSMV を使うきっかけになった [Mahout の例](https://github.com/ushitora-anqou/mahout/blob/bb08eb5bc3fa3c9079e009c15f02ba50465463fe/mahout.smv)などもどうぞ。