モデル検査(モデルチェッキング)を使って、いろいろ調べられるんだよ~っていう話は、
聞くと思うし、たとえば、以下のサイト
夢と笑顔をおいかけて
http://www.is.s.u-tokyo.ac.jp/ob/interviewEntry.php?eid=00006
などにも書いてあるけど、具体的に、なにを、どう書くと、なにがチェックできるのか
書いていないので、具体的にいくつか、例を挙げようと思う。
その1回目、モデル検査のPATを使って、デッドロックを調べる。
なぜPATかっていうと、ここのセミナーにでて、PATが入っているから
(SPIN今、入ってない)
なぜ、デッドロックかというと、デッドロックが分かりやすくて、簡単だから
上記サイトにある時相論理式とか使わなくてもPATだと調べられるから
では、やってみよう!
■お題
以下のようなシステムがある。
![]()
つまり、Webアプリで、ブラウザで、WebサービスModel1,Model2,Model3をテキトーに
呼び出している。
各Webサービスは、DBのテーブルにアクセスしている。
Model1では、tbl1とtbl2を・・・など。
ちなみにtbl1、tbl2、tbl3はテーブル名である。
このとき、model間で、デッドロックをおこさないかどうかを調べたい
デッドロックって何?っていう人は、自分で調べてくれ。
(ググればわかる)
■どういう風に書くか
上記サイトにあるように、モデル検査ですべての状態を描いていると、
状態爆発して調べられない。そこで、必要なこと以外は、除いてかく。
1.モデルぜんたいについて
今、システムは、model1,model2,model3が並行して動いている(ことが可能になっている)
そこで、それをあらわして
system()=model1()||model2()||model3();
と書いている。
ここで、model4,model5・・・とつづくなら、
system()=model1()||model2()||model3()||model4()||model5();
とつづけていくことになる。
そして、model1()について考えると、
いま、DBのテーブルのデッドロックについて考えているので、そこだけ、モデル化する。
テーブル1からテーブル2にアクセスし、その後、また受付にもどる(model1()にもどる)ので
model1()=tbl1->tbl2->model1();
(>は、本当は半角)ってことになる。model2,model3以降も、テーブルアクセス順にー>でつなげてかく。
最後に、systemに対して、デットロックがないかしらべるので
#assert system deadlockfree;
ってしている。
■実験結果
まず、
model1がtbl1,tbl2にアクセスし
model2がtbl1,tbl2にアクセスし
model3がtbl3,tbl1にアクセスするばあい。
このときは、model1,model2は、同じ順番でアクセスしているので、デッドロックは起こらない。
![]()
validとなっていて、おこっていないことが分かる。
次
model1がtbl1,tbl2にアクセスし
model2がtbl2,tbl1にアクセスし
典型的なデッドロック状態を起こした。
当然
![]()
NOT VALIDとなり、デッドロックが起きていることが分かる。
しかし、これなら、モデルチェックを使わないでもわかる。
問題は、ここから先
model1がtbl1,tbl2にアクセスし
model2がtbl2,tbl3にアクセスし
model3がtbl3,tbl1にアクセスするばあい。
この場合、model1,model2,model2,model3,model3,model1の組み合わせでは、デッドロックは起きない
しかし、3つ組み合わせると、
model1がtbl1処理中、tbl2待ち
model2がtbl2処理中、tbl3待ち
model3がtbl3処理中、tbl1待ち
のとき、ぐるっと回って、デッドロックになる。この場合も
![]()
NOT VALIDとなり、デッドロックが起きていることを指摘してくれる。
実際には、もっと複雑な状況(4個、5個のモジュールが絡み、呼び出し先の呼び出し先で・・みたいな感じで)
で起きる時をチェックするのであろう(実際今回の例くらいなら、人手でチェックできるので)
そのような場合、自動的に
・対象となるサービスをすべてsystem=のあとに||でつないで、
・各サービスのDBアクセスを順番にー>で並べて書いて
・最後に#assert system deadlockfree;を書く
プログラムを作って、それを流してチェックするという感じなんだろうなあ・・
聞くと思うし、たとえば、以下のサイト
夢と笑顔をおいかけて
http://www.is.s.u-tokyo.ac.jp/ob/interviewEntry.php?eid=00006
などにも書いてあるけど、具体的に、なにを、どう書くと、なにがチェックできるのか
書いていないので、具体的にいくつか、例を挙げようと思う。
その1回目、モデル検査のPATを使って、デッドロックを調べる。
なぜPATかっていうと、ここのセミナーにでて、PATが入っているから
(SPIN今、入ってない)
なぜ、デッドロックかというと、デッドロックが分かりやすくて、簡単だから
上記サイトにある時相論理式とか使わなくてもPATだと調べられるから
では、やってみよう!
■お題
以下のようなシステムがある。

つまり、Webアプリで、ブラウザで、WebサービスModel1,Model2,Model3をテキトーに
呼び出している。
各Webサービスは、DBのテーブルにアクセスしている。
Model1では、tbl1とtbl2を・・・など。
ちなみにtbl1、tbl2、tbl3はテーブル名である。
このとき、model間で、デッドロックをおこさないかどうかを調べたい
デッドロックって何?っていう人は、自分で調べてくれ。
(ググればわかる)
■どういう風に書くか
上記サイトにあるように、モデル検査ですべての状態を描いていると、
状態爆発して調べられない。そこで、必要なこと以外は、除いてかく。
1.モデルぜんたいについて
今、システムは、model1,model2,model3が並行して動いている(ことが可能になっている)
そこで、それをあらわして
system()=model1()||model2()||model3();
と書いている。
ここで、model4,model5・・・とつづくなら、
system()=model1()||model2()||model3()||model4()||model5();
とつづけていくことになる。
そして、model1()について考えると、
いま、DBのテーブルのデッドロックについて考えているので、そこだけ、モデル化する。
テーブル1からテーブル2にアクセスし、その後、また受付にもどる(model1()にもどる)ので
model1()=tbl1->tbl2->model1();
(>は、本当は半角)ってことになる。model2,model3以降も、テーブルアクセス順にー>でつなげてかく。
最後に、systemに対して、デットロックがないかしらべるので
#assert system deadlockfree;
ってしている。
■実験結果
まず、
model1がtbl1,tbl2にアクセスし
model2がtbl1,tbl2にアクセスし
model3がtbl3,tbl1にアクセスするばあい。
このときは、model1,model2は、同じ順番でアクセスしているので、デッドロックは起こらない。

validとなっていて、おこっていないことが分かる。
次
model1がtbl1,tbl2にアクセスし
model2がtbl2,tbl1にアクセスし
典型的なデッドロック状態を起こした。
当然

NOT VALIDとなり、デッドロックが起きていることが分かる。
しかし、これなら、モデルチェックを使わないでもわかる。
問題は、ここから先
model1がtbl1,tbl2にアクセスし
model2がtbl2,tbl3にアクセスし
model3がtbl3,tbl1にアクセスするばあい。
この場合、model1,model2,model2,model3,model3,model1の組み合わせでは、デッドロックは起きない
しかし、3つ組み合わせると、
model1がtbl1処理中、tbl2待ち
model2がtbl2処理中、tbl3待ち
model3がtbl3処理中、tbl1待ち
のとき、ぐるっと回って、デッドロックになる。この場合も

NOT VALIDとなり、デッドロックが起きていることを指摘してくれる。
実際には、もっと複雑な状況(4個、5個のモジュールが絡み、呼び出し先の呼び出し先で・・みたいな感じで)
で起きる時をチェックするのであろう(実際今回の例くらいなら、人手でチェックできるので)
そのような場合、自動的に
・対象となるサービスをすべてsystem=のあとに||でつないで、
・各サービスのDBアクセスを順番にー>で並べて書いて
・最後に#assert system deadlockfree;を書く
プログラムを作って、それを流してチェックするという感じなんだろうなあ・・