Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
形式手法入門VDM++チュートリアル
1
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
目的n 世界的に成功したほとんどの形式手法仕様システムは、以下
の導入方法で成功している。 n 参考資料: IPA形式手法適用調査 調査概要資料
l https://www.ipa.go.jp/files/000004548.pdf)
l 1週間程度のセミナー受講
l 経験ある専門家のコンサルティング
n 今回のチュートリアルは、上記導入方法の肝を紹介することで形式手法導入のための基礎知識を得ることを目的としている。具体的には、 l 実用的な仕様例である運賃計算モデル(現実の仕様の100分の1モデル)
を紹介し、
l そこで使用している重要で頻繁に使用するVDM++言語要素を紹介し、
l 実用的な仕様を作成するための基本を紹介する。
2
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
目次
n 形式手法の概要 n VDMツールのインストールと設定
l Overture Tools l VDMTools
n VDM++言語入門 l 簡単な例題を通して説明 l モデル化の方法 l ツールの使い方と文法 l 簡単な演習
3
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
セミナー資料一覧
n マニュアル
l VDM++ 演算子要約 n Quick_Overview_of_VDM_Operators_J.pdf
l VDMTools VDM++ 言語マニュアル n langmanpp_a4J.pdf
l VDMTools ユーザーマニュアル(VDM++) n usermanpp_a4J.pdf
l Overture VDM-10 Tool Support: User Guide n OvertureIDEUserGuide.pdf
n セミナー資料
l 形式手法入門VDM++チュートリアル n 形式手法入門VDM++チュートリアル.pdf
l Overture Toolsのインストールと設定 n Overture Toolsのインストールと設定(Mac OS X版).pdf n Overture Toolsのインストールと設定(Windows版) .pdf
l 演習解答 n 後ほど配布
l 運賃計算モデル n Fare0.zip
n 参考資料 l 対象を如何にモデル化するか? (形式記述サンプル付き)
l SEC-FM1-B-1対象を如何にモデル化するか.pdf l How2MakeModel.zip
4
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
形式手法の概要
n 形式手法(正式手法?)
l 特定の数学モデルに基づく形式言語を用い、記述の曖昧さを除去し、分析や検証を容易にすることにより、高品質ソフトウェアを効率よく開発するための手法
n 形式手法の種類
l モデル規範型
n システムの内部構造の構成的定義をデータや操作を用いてモデル化し検証する
n 種類: VDM, RAISE(VDM+OBJ+CSP的仕様), B, Z
n 従来のプログラミングに近い考えなので、現場の技術者に理解しやすい
l 性質規範型
n システムを外部から見た性質を公理や抽象データ型を用いてモデル化し検証する
n 種類: CafeOBJ, Maude,...
n 代数を使うため抽象度が高く、モデル規範型より現場に適用するのはやや難しい
l モデル検査
n システムの振舞仕様に対し可能な実行パターンを網羅的かつ自動的に検証する
n 種類: SPIN, SMV,...
n 採用する意味は場合によって大きいが、システム全体をモデル化できない
5
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
なぜ厳密な仕様(形式仕様)でモデル化するか?
n 日本語仕様で大規模システムを記述するのはコストが掛かるから!
l形式仕様で「モデル」を記述し検証するほうが、高品質で生産性が高いから!
n 形式仕様の方が技術移転が容易だから!
n 形式仕様の方が仕様修正が容易だから!
6
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
なぜ厳密な仕様としてVDM(ウィーン開発手法)を採用したか?
n 形式手法の種類
n モデル規範型
n VDM, RAISE( 初に勉強した手法で、VDM+OBJ+CSP的仕様), B, Z
n 現場の技術者に理解しやすいので採用
n 性質規範型
n CafeOBJ( 初にツールを使用したのが、OBJ3), Maude,...
n まだ現場に適用するには時期尚早
n モデル検査
n SPIN, SMV,...
n 採用する意味はあるが、現場の技術者にはやや難しい
n 形式手法の検証方法とツール
n 証明
n 段階的洗練
n RAISE Tool, Rodin
n 採用する意味はあるが、現場の技術者にはかなり難しい
n モデル検査
n 仕様実行
n VDMTools
n 現場の技術者に理解しやすく、形式検証の第一歩として採用
7
実用までに3ヶ月
実用までに3年
実用までに5年
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
日本での、形式手法による仕様作成の成果例
対象システム 適用工程 仕様規模 欠陥数 生産性 開発期間
備考
(1) SCSK 証券業務 実システムUseCaseレベル
要求仕様
3+3万行仕様+テストケース
0 2.5倍 45% 開発チームに業務知識無し
(2) フェリカネットワークス
SONY
おサイフケータイ・ファームウェアモバイルFelica
ICチップ第2世代
実システムAPI外部仕様
7.4+6.6万行仕様+テストケース
0 2倍 85% 開発チームに形式手法知識無し
EAL4+
モバイルFeliCaICチップ第3世代
実システムAPI外部仕様
5.5万行 EAL5+予定
FeliCa ICチップ(RC-SA00)第3世代
実システムAPI外部仕様
同上+VDM 1.7万行+Promela 0.45万行
第3世代基本部分は同一EAL6+
(3) 産業技術総合研究所,オムロン
鉄道関係駅務システム
データ
既存システム厳密仕様作成実験
0.75+80万行仕様+テストデータ
欠陥発見数29
「暗黙知は仕様の欠陥」
8
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
目次
n ✔形式手法の概要 n VDMツールのインストールと設定
l Overture Tools l VDMTools
n VDM++言語入門 l 簡単な例題を通して説明 l モデル化の方法 l ツールの使い方と文法 l 簡単な演習
9
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
VDMツールのインストールと設定
n Overture Tools
l インストールと設定
nMac OS X l 後述: Overture Toolsのインストールと設定(Mac OS X版)
nWindows l 後述: Overture Toolsのインストールと設定(Windows版)
n VDMTools
l Mac OS X
nThe VDM++ Toolbox-9.0.6-64bit.pkg をダブルクリック
l Windows
nsetuppp-9.0.6-i586.exe をダブルクリック
10
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Mac OS X版) 実行環境
▾☐
▾☐
▾☐
• ☐ http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html
▾☐
• ☐
• ☐
▾☐
• ☐
11
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Mac OS X版) インストール
▾ ☐
▾☐ http://overturetool.org/download/ • ☐
12
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Mac OS X版) 環境設定
▾ ☐
▾ ☐
▾ ☐
▾ ☐
•☐▾ ☐
▾ ☐
•☐▾ ☐
▾ ☐
▾ ☐
•☐▾ ☐
▾ ☐
▾ ☐
•☐
13
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Mac OS X版) プロジェクト設定
▾ ☐
▾☐
▾ ☐
▾☐▾ ☐
• ☐
14
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Windows版) 実行環境
▾☐
▾☐
▾☐
• ☐ http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html
▾☐
• ☐
• ☐
▾☐
• ☐
15
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Windows版) インストール
▾☐
▾☐ http://overturetool.org/download/ •☐
16
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Windows版) Preference設定
▾ ☐
▾ ☐
▾ ☐
▾ ☐
•☐
▾ ☐
▾ ☐
•☐
▾ ☐
▾ ☐
▾ ☐
•☐
▾ ☐
▾ ☐
▾ ☐
▾ ☐
▾ ☐
•☐
17
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsのインストールと設定(Windows版) プロジェクト設定
▾☐
▾☐
▾☐
▾☐
▾☐
• ☐
18
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
目次
n ✔形式手法の概要 n ✔VDMツールのインストールと設定
l ✔Overture Tools l ✔VDMTools
n VDM++言語入門 l 簡単な例題を通して説明 l モデル化の方法 l ツールの使い方と文法 l 簡単な演習
19
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
n VDM++言語入門
n 集合を使った運賃表から運賃を求めるVDM++モデルFare0の紹介
l Overture ToolsのView
l Fare0のプロジェクトを読み込む
l 運賃表クラス定義と型定義
l 運賃表集合の型定義
l 「運賃表集合に存在する」か判定する関数
l 運賃計算クラス
l 「運賃を得る」操作(operation)
l テストケースの作成: 簡易回帰テスト
l 組み合わせ(Combinatorial)テスト20
l 「運賃表を検索する」関数
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
集合を使った運賃表から運賃を求めるVDM++モデルFare0の紹介
21
テストケース階層
業務論理階層
要求辞書階層
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture ToolsのView
22
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture ToolsでFare0のプロジェクトを読み込む
n workspaceを切り替える(switch)
l Fileメニュー -> Switch workspace -> Other…
nFare0を含むフォルダーをworkspaceに指定する
n Welcomeウィンドウを閉じる
n VDM Explorer viewで
l Fileメニュー -> New -> Project から、
nSelect WizardからVDM-PP Projectを選択し、 l Project nameにFare0を設定してFinishボタンを押す
23
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture ToolsにFare0フォルダーが表示される
24
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
FareTable.vdmppを選択するとエディタに表示
25
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Fare0プロジェクトの確認: Fare0モデルの簡易回帰テスト
26
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsから、VDMToolsの起動確認
27
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
VDMToolsによる組み合わせテストの確認
28
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
Overture Toolsによる組み合わせテストの確認
29
Window -> Open Perspective -> Other... -> Combinatorial Testing メニュー
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
運賃表クラス定義と型定義
30
class 運賃表 --運賃表クラスを定義する。
types --型定義public 駅 = seq of char --文字型の列、すなわち文字列。ここでは、駅型が文字列であると定義する。--publicは、どのクラスからもアクセスできることを示す。inv w駅 == w駅 <> ""; -- inv以下の不変条件定義で、駅型が空文字列ではないことを定義する。--‘;’は、文法要素の区切り記号である。public 運賃 = nat; -- 運賃が自然数型であることを定義する。public 運賃レコード ::
-- f駅1とf駅2とf運賃を項目(欄, fieldとも言う)として持つレコード型「運賃レコード」を定義する。f駅1 : 駅 --欄名の先頭のfは、他の識別子と区別をするために付けている。
--VDM++では、識別子がモデル内でユニークでならないため、このような名付規則を決めたほうが良い。f駅2 : 駅f運賃 : 運賃 --ここは、不変条件定義のinvが続くため、セミコロンを付けると構文エラーになる。
inv --駅1と駅2が異なることを、型不変条件で示している。w運賃レコード == w運賃レコード.f駅1 <> w運賃レコード.f駅2;
VDM++言語マニュアル(今後LMと略記)4.2.5 レコード型
LM 4.3 不変条件 (型の不変条件)
LM 4.2.2 列型
LM 4.2.2 列型 (空列)
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
VDMToolsの実行ウィンドウ
31
ここに p mk_運賃表`運賃レコード(“a”,"b",130) を入力
レコード型構成子 LM 4.2.5レコード型
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
レコード型インスタンスの表示
演習問題: 以下のレコード型インスタンスを、VDMToolsのインタプリタ・ウインドウで実行するとどうなるかを確かめよ。 print mk_運賃表`運賃レコード(“a","b",130) print mk_運賃表`運賃レコード(“a","a",130) print mk_運賃表`運賃レコード("a","",130)
32
レコード構成子の構文 構文: 式= . . . | レコード構成子 | . . . ;レコード構成子= ‘mk ’, 名称, ‘(’, [ 式リスト], ‘)’ ;
LM 7.11 レコード式
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
運賃表集合の型定義
public 運賃表集合 = set of 運賃レコード -- 運賃表集合型が、運賃レコード型のデータの集合であることを示す。 -- 集合は、順序がなく、重複がないものの集まりである。
inv w運賃表集合 == -- 型の不変条件invの後の識別子名は、型の値を表す名前で、 "==™ の後の式中で使う。w運賃表集合 = {} or -- {}は空集合を表す。forall w運賃レコード1, w運賃レコード2 in set w運賃表集合 &
-- forallは全称限量式で、w運賃表集合の要素、w運賃レコード1と -- w運賃レコード2が、’&’の後の条件式を満たす事を示す。
w運賃レコード1.f駅1 = w運賃レコード2.f駅1 and -- ここでは、w運賃表集合で駅1と駅2が等しければ、運賃も等しいことを示す。
w運賃レコード1.f駅2 = w運賃レコード2.f駅2 => -- "=>"は、bool型の「含意」演算子で、a => b は、not a or b と等しい。
w運賃レコード1.f運賃 = w運賃レコード2.f運賃;/* 上の全称限量式は、以下の様な運賃表の集合列挙式の定義を、型エラーとして検出するために記述した。
{mk_運賃表`運賃レコード("東京", "新宿", 180), mk_運賃表`運賃レコード("新宿", "品川", 190), mk_運賃表`運賃レコード("新宿", "品川", 300)};*/
33
LM 4.2.1 集合型
LM 7.5 限量式
LM 4.1.1 ブール型含意演算子
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
ブール型含意演算子と集合型演算子
34
VDMToolsのインタプリタ・ウインドウで、以下を実行するとどうなるか? print 1 in set {3,1,2} print (1 not in set {3,1,2}) => false
LM 7.7 集合式 (集合列挙)
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
集合の列挙式と型の不変条件のチェック
35
演習問題: VDMToolsのインタプリタ・ウインドウで、以下の運賃表集合列挙式を引数として構成子運賃計算を実行するとどうなるかを確かめよ。 create c := new 運賃計算( {mk_運賃表`運賃レコード("東京", "新宿", 180), mk_運賃表`運賃レコード("新宿", "品川", 190), mk_運賃表`運賃レコード("新宿", "品川", 300)})
集合式の構文構文: 式 = . . . | 集合列挙 | . . . ;集合列挙 = ‘{’, [ 式リスト], ‘}’ ;式リスト = 式, { ‘,’, 式} ;
LM 7.7 集合式 (集合列挙)
集合の要素の値を返す式
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
限量式n 限量式は、制約に関する仕様の記述に便利な1階述語論理式
l 「全ての〜について〜が成り立つ」を記述するのに全称限量式
l 「〜がなりたつ〜が存在する」を記述するのに存在限量式
l 「〜がなりたつ〜が唯一つ存在する」を記述するのに1存在限量式
l 不変条件(inv)、事前条件(pre)、事後条件(post)で使うことが多い
36
限量式の構文 構文: 式 = . . . | 限量式 | . . . ; 限量式 = 全称限量式 | 存在限量式 | 1存在限量式; 全称限量式 = ‘forall’, 束縛リスト, ‘&’, 式; 存在限量式 = ‘exists’, 束縛リスト, ‘&’, 式; 束縛リスト = 多重束縛, { ‘,’, 多重束縛} ; 1存在限量式 = ‘exists1’, 束縛, ‘&’, 式;
LM 7.5 限量式
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
限量式 (全称限量式)
37
VDMToolsのインタプリタ・ウインドウで、以下を実行するとどうなるか?
print forall a,b : bool & a => b <=> not a or b print forall a,b : bool & not (a and b) <=> not a or not b
LM 9 束縛 (型束縛)普通、型束縛は実行できないが、bool型は{true, false}しか値がないので実行できる
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
限量式 (存在限量式)
38
VDMToolsのインタプリタ・ウインドウで、以下を実行するとどうなるか?
print exists a,b in set {1,...,9} & a mod 2 = 0 print exists a,b in set {1,...,9} & a+b = 18 print exists a,b in set {1,...,9} & a+b = 19
LM 7.7 集合式 (集合範囲式)
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
限量式 (1存在限量式)
39
VDMToolsのインタプリタ・ウインドウで、以下を実行するとどうなるか?
print exists1 a in set {1,...,9} & a mod 2 = 0 print exists1 a in set {1,...,9} & a mod 5 = 0 print exists1 a in set {1,...,9} & 2 * a = 18
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
「運賃表を検索する」関数
40
protected 運賃表を検索する : 運賃表集合 * 駅 * 駅 -> 運賃レコード --関数「運賃表を検索する」の関数名と引数の型と返値の型を示す。--protectedはサブクラスからのみアクセスできることを示す。運賃表を検索する(a運賃表集合, a駅1, a駅2) == --関数「運賃表を検索する」の、仮引数を示す。
let w運賃レコード in set a運賃表集合 be st -- let be st式で、a運賃表集合の要素で、次の行の条件式を満たす値が「w運賃レコード」に束縛される。
{a駅1, a駅2} = {w運賃レコード.f駅1, w運賃レコード.f駅2} --駅1と駅2の集合が、a運賃表集合の駅1と駅2の集合と等しい「w運賃レコード」が得られる。
in w運賃レコード --得られた「w運賃レコード」が、この関数の返り値となる。
pre -- preは、関数の事前条件であり、次の事前条件式がtrueを返さねばならない。 -- 関数の場合、事前条件は受け入れ可能な引数であることを保証する。
運賃表集合に存在する(a運賃表集合, a駅1, a駅2)post -- postは関数の事後条件で、次の事後条件式が、関数実行後の状態を示す条件式であり、trueを返さねばならない。
exists1 w運賃レコード in set a運賃表集合 & --exists1は「1存在限量式」で、 --a運賃表集合の要素で'&'の後の条件式を満たす唯1つの要素「w運賃レコード」が存在することを主張する
{a駅1, a駅2} = {w運賃レコード.f駅1, w運賃レコード.f駅2} andRESULT = w運賃レコード; -- RESULTは、事後条件式の中だけで使える予約後で、返り値の値を示す。
LM 7.1 let式 (let be式)
LM 6 関数定義
LM 5 アルゴリズム定義 (予約語RESULT)
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
let be式
41
構文: 式 = let 式 | let be 式 | . . . ;let 式 = ‘let’, ローカル定義{ ‘,’, ローカル定義}, ‘in’, 式;let be 式 = ‘let’, 束縛, [ ‘be’, ‘st’, 式], ‘in’, 式;ローカル定義 = 値定義 | 関数定義;値定義 = パターン, [ ‘:’, 型], ‘=’, 式;
LM 7.1 let式 (let be式)
VDMToolsのインタプリタ・ウインドウで、以下を実行するとどうなるか?
p let s1 = {1,...,9} in let w in set s1 be st w mod 3 = 0 in wp let s1 = {1,...,9} in let w in set s1 be st w mod 3 = 0 and w mod 2 = 0 in wp let w in set {1,...,9} in w
LM 8 パターン
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
パターン
n パターン l パターンはある特定の型の1つの値に一
致する。
n パターン識別子 l どんな型のどんな値にも一致する。 l 識別子の場合
n 識別子がその値に束縛される
l don't-care記号'-'の場合 n 束縛は起きない
n 他のパターンは中級以上で使用するので、説明しない
42
構文: パターン = パターン識別子 | 一致値 | 集合列挙パターン | 集合合併パターン | 列列挙パターン | 列連結パターン | 写像列挙パターン | 写像併合パターン | 組パターン | レコードパターン;パターン識別子 = 識別子 | ‘-’
識別子 = ( 文字), { ( 文字 | ‘'’ | ‘_’ } ;
LM 8 パターン
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
パターン識別子の例
43
let w運賃レコード = 運賃表を検索する(s運賃表集合, a駅1, a駅2) in -- let式で、「運賃表を検索する」関数の返り値を「w運賃レコード」に束縛し、return w運賃レコード.f運賃 -- 運賃レコードのf運賃欄の値をreturn文で返している。
public print : seq of char ==> ()print(a文字列) == let - = new IO().echo(a文字列) in skip; /*標準ライブラリIOクラスのecho操作は、標準出力に引数の文字列を表示するが、 表示に失敗するとfalseを返してくるが、そのようなことはまず無いので、 don't-care記号'-'と一致させて、束縛が起きないようにし、 この後使わないようにしている。 */
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
束縛
44
構文: 束縛 = 集合束縛 | 型束縛;集合束縛 = パターン, ‘in set’, 式;型束縛 = パターン, ‘:’, 型;束縛リスト = 多重束縛, { ‘,’, 多重束縛} ;多重束縛 = 多重集合束縛 | 多重型束縛;多重集合束縛 = パターンリスト, ‘in set’, 式;多重型束縛 = パターンリスト, ‘:’, 型;
LM 9 束縛
n 束縛は、パターンと一致する値の範囲を指定する。 n 集合束縛では、値は集合から選ばれ、
n 型束縛では、値は型から選ばれるので、自然数(nat)型など無限の要素がある型は実行できない。
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
束縛の例
45
集合束縛 {e | e in set power {1,...,4} & card e = 2}型束縛
{e | e : bool | <日本> | <韓国> | <中国> | <朝鮮>}
多重集合束縛 {{a,b} | a in set {1,2,3,4}, b in set {3,4,5,6} & card {a,b} = 2}多重型束縛 forall a,b : bool & a => b <=> not a or b
LM 4.2.1 集合型 演算子 有限べき集合(power), 濃度(card)
protected 運賃表集合に存在する : 運賃表集合 * 駅 * 駅 -> bool運賃表集合に存在する(a運賃表集合, a駅1, a駅2) ==
{a駅1, a駅2} in set {{e.f駅1, e.f駅2} | e in set a運賃表集合}; -- in set は、集合型の演算子で、左辺の要素が右辺の集合の要素であればtrueを返す。--{{e.f駅1, e.f駅2} | e in set a運賃表集合 & {a駅1, a駅2} = {e.f駅1, e.f駅2}} <> {};
--上の行と同じ結果を返す式-- {{e.f駅1, e.f駅2} | e in set a運賃表集合}は、'&'の後の条件式が無い形の集合内包式。-- a運賃表集合の要素をeとして、{e.f駅1, e.f駅2}を要素とする集合を返す。-- 両側の{}は集合を表し、'|'は分離記号である。-- '{'と'|'の間に、集合の要素となる式を書き、'|'と'}'の間に集合の要素の元となる集合を記述する。-- ここで出てくる in set は集合の演算子ではなく、e in set S の形式で、eが集合Sの要素であることを示す。-- 集合の内包式は、集合に含む要素が満たすべき条件式も記述することができるが、ここでは説明しない。
end 運賃表 --運賃表クラスの定義がここで終わることを示す。
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
「運賃表集合に存在する」か判定する関数
46
LM 7.7 集合式 (集合内包)
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
集合内包式
47
集合式の構文構文: 式 = . . . | 集合内包 | . . . ;式リスト = 式, { ‘,’, 式} ;集合内包 = ‘{’, 式, ‘|’, 束縛リスト, [ ‘&’, 式], ‘}’ ;多重集合束縛= パターンリスト, ‘in set’, 式;
集合の要素の値を返す式
束縛リストと思って良い
VDMToolsのインタプリタ・ウインドウで、以下を実行するとどうなるか?
p {w | w in set {1,...,9} & w mod 3 = 0}p {w | w in set {1,...,9} & w mod 3 = 0 and w mod 2 = 0}p let w in set {1,...,9} in w
LM 7.7 集合式 (集合内包)
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
運賃計算クラス
48
class 運賃計算 is subclass of 運賃表 --運賃計算クラスが運賃表クラスのサブクラスであることを示す。instance variables --インスタンス変数の定義。VDM++では、インスタンス変数のみが広域(グローバル)変数。s運賃表集合 : 運賃表集合 := {}; --s運賃表集合は、他のクラスからはアクセスできないprivateな運賃表集合型のインスタンス変数で、--初期値は空集合である。operations-- 構成子はクラスのインスタンスを生成する。-- 引数なしの構成子は自動的に生成されるので、ここで定義する必要はない。public 運賃計算 : 運賃表集合 ==> 運賃計算 --構成子の操作名と返り値の型名はクラス名と同じでなければならない。運賃計算(a運賃表集合) == s運賃表集合 := a運賃表集合; --引数で受け取った内容を、インスタンス変数に代入(記号は":=")する。
LM 11 インスタンス変数
{mk_運賃表`運賃レコード("東京", "品川", 220), mk_運賃表`運賃レコード("東京", "新宿", 180), mk_運賃表`運賃レコード("新宿", "品川", 190)};
LM 13.4 代入文
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
「運賃を得る」操作(operation)
49
public 運賃を得る : 駅 * 駅 ==> 運賃 --操作「運賃を得る」の操作名と引数の型と返値の型を示す。引数がない場合、返り値がない場合は"()"を使用する。運賃を得る(a駅1, a駅2) == --操作「運賃を得る」の、仮引数を示す。 let w運賃レコード = 運賃表を検索する(s運賃表集合, a駅1, a駅2) in -- let式で、「運賃表を検索する」関数の返り値を「w運賃レコード」に束縛し、 return w運賃レコード.f運賃 -- 運賃レコードのf運賃欄の値をreturn文で返している。pre --操作の事前条件。操作の場合、事前条件は受け入れ可能な引数とインスタンス変数であることを保証する。 運賃表集合に存在する(s運賃表集合, a駅1, a駅2)post --操作の事後条件。操作の事後条件では、インスタンス変数を使用できる。 exists1 w運賃レコード in set s運賃表集合 & --exists1は「1存在限量式」で、 --s運賃表集合の要素で'&'の後の条件式を満たす唯1つの要素「w運賃レコード」が存在することを主張する。 {a駅1, a駅2} = {w運賃レコード.f駅1, w運賃レコード.f駅2} and RESULT = w運賃レコード.f運賃;
end 運賃計算
LM 7.5 1存在限量式
LM 13.10 return文
LM 13.1 let文
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
ここまでのまとめ
50
テストケース階層
✔業務論理階層
✔要求辞書階層
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
テストケースの作成: 簡易回帰テスト
51
class Test is subclass of 運賃計算 --Testクラスが運賃計算クラスのサブクラスであることを示す。
values --定数の定義v運賃レコード集合 : 運賃表集合 = {
--定数「v運賃レコード集合」が運賃表集合型で、値が右辺の運賃レコードの集合であることを示す。mk_運賃レコード("東京", "品川", 220), --「mk_運賃レコード」は運賃レコード型のデータのインスタンスを作る。mk_運賃レコード("東京", "新宿", 180),mk_運賃レコード("新宿", "品川", 190)
};
operationspublic run : () ==> seq1 of bool --簡易回帰テストを行う操作。結果をbool型の列で返す。seq1は空列にはならない列型を示す。run() ==
return [t1(), t2(), t3()]; -- 回帰テストがうまくいけば、[true, true, true]を返す。-- 回帰テストのn番目にエラーがあれば、n番目の返り値がfalseになる。-- 例えば、2番目のテストケースがエラーだと、[true, false, true]を返す。
LM 10 値(定数)定義
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
簡易回帰テストの個々のテストケース
52
operationspublic t1 : () ==> bool --1番目の回帰テストケースの操作。うまく行ったか否かをbool型で返す。t1() == ( -- '('から')'までが1つのブロック分で、複数の文を記述できる。--今は、1つのdef文が記述されていて、その中に、return文が記述されている。 let w運賃計算 = new 運賃計算(v運賃レコード集合) in -- let式の中で、v運賃レコード集合を持った運賃計算オブジェクトを生成し、w運賃計算に束縛する。 return w運賃計算.運賃を得る("東京", "品川") = 220 -- w運賃計算の「運賃を得る」をcallし、結果が220であればtrueをreturn文で返す。);
public t2 : () ==> boolt2() == ( let w運賃計算 = new 運賃計算(v運賃レコード集合) in return w運賃計算.運賃を得る("東京", "新宿") = 180);... end Test
LM 13.3 ブロック文
LM 13.1 let文
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
VDMToolsで簡易回帰テスト
53
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
ここまでのまとめ
54
✔テストケース階層
✔業務論理階層
✔要求辞書階層
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
組み合わせ(Combinatorial)テスト
55
class UseFare0
values --定数の定義v運賃レコード集合 : 運賃表`運賃表集合 = { -- 「運賃表`運賃表集合」は、運賃表クラスの運賃表集合を示す。
mk_運賃表`運賃レコード("東京", "品川", 220),mk_運賃表`運賃レコード("東京", "新宿", 180),mk_運賃表`運賃レコード("新宿", "品川", 190)
};
instance variablessTest : Test := new Test();s運賃計算 : 運賃計算 := new 運賃計算(v運賃レコード集合);
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
組み合わせ(Combinatorial)テスト
56
traces --以下が、組み合わせテストであることを示す。文法が、通常のVDM++ソースと多少異なる。
T0: sTest.run() -- 回帰テストの呼び出し':'の前の名前は、trace名で組み合わせテストの区別に使用する。
T1: let w駅1 in set {"東京", "品川", "新宿"} in -- w駅1は{"東京", "品川", "新宿"}のいずれか、 let w駅2 in set {"東京", "品川", "新宿", "武蔵境", ""} in ( -- w駅2は{"東京", "品川", "新宿", "武蔵境", ""}のいずれか、 s運賃計算.運賃を得る(w駅1, w駅2) -- {w駅1, w駅2}の組み合わせ全てについて「運賃を得る」を実行する。
) /* let w駅1 in set {"東京", "品川", "新宿"} in ... は、 普通のVDM++構文では、w駅1に{"東京", "品川", "新宿"}のうちどれか1つが束縛され、 let w駅2 in set {"東京", "品川", "新宿", "武蔵境", ""} in ... は、 w駅2に"東京", "品川", "新宿", "武蔵境", ""}のうちどれか1つが束縛されるが、 traces定義の中では、w駅1が3通り✕ w駅2が5通り = 15通りの組み合わせが生成され、 運賃を得る(w駅1, w駅2)が15回実行される。*/
LM 17 traces定義
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
簡単な演習
57
class 例外処理例 --演習に使う構文の使用例(ExitSample.vdmpp)
operationspublic 割る : nat * nat ==> real割る(n1, n2) ==
if n2 = 0 thenexit <割り算の分母が0である>
-- このexit文は、<割り算の分母が0である>という引用型の例外を発生させる。else
return n1 / n2;
public 例外処理をする : nat * nat ==> bool * real --この返値は、bool型とreal型の組型を返す例外処理をする(n1, n2) ==
trap <割り算の分母が0である> -- このtrap文は、in以下のreturn文で <割り算の分母が0である>というパターンに一致する例外が発生したら、 -- mk_(false, -1)という組型の値を返す
with return mk_(false, -1) in return mk_(true, 割る(n1, n2));
-- 例外が発生しなければ、mk_(true, 割る(n1, n2)の結果) という組型の結果を返す
end 例外処理例
LM 13.11 例外処理文 (exit文)
LM 13.11 例外処理文 (trap文)
LM 4.2.4 組型 (演習には使わない)
LM 4.1.4 引用型
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
演習問題1
n 例外処理文を使って、Fare0モデルのエラー処理仕様を記述せよ
l ヒント:
n業務論理階層のクラス内の操作の事前条件を注釈とし、exit文
でエラーの場合に例外を発生させる文を追加する
l Fare0モデルの場合、「運賃を得る」操作を修正すれば良い
l Fare0.vdmppを修正
n発生する例外の処理をtrap文で記述するクラスを記述する
l Fare0モデルの場合、回帰テストケースでtrap文を使用して、
意図的に発生させたエラーの例外をキャッチして、trueを返す
テストケースを書けば良い
l Fare0_testspec.vdmppを修正
58
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
演習問題2
n 演習問題1で修正したFare0モデルをテストするため、組み合わせテストを修正せよ l ヒント:
n traces名 T1 にテストデータを追加すれば良い
59
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
まとめ
n 形式手法の導入で成功している導入方法を参考に、実際の仕様の100分の1モデルを通して、実用的なVDM++仕様を作成し検証するための基本を紹介した。
n 今回、実際の仕様記述と検証で使用することの多いVDM++関連の主な機能で紹介できなかったこと: l 写像型、列型、トークン型、合併型と選択型
l インスタンス変数の不変条件
l 実用的な回帰テストライブラリ
n より詳しい副読本は、以下を参考にしていただきたい。 l SEC-FM1-B-1 対象を如何にモデル化するか? 形式記述サンプル付き (簡易製本配布)
60
Software Reliability Enhancement CenterCopyright © 2016 IPA, All Rights Reserved
参考: VDMのツール
61
ツール 開発者 仕様 インタープリタ IDEベース環境 特徴
VDMTools SCSK 独自(C++) 独自(Qt使用)Java, C++生成。オブジェクト数が多い場合、vdmjより速い。クラス図生成。
vdmiNick Battle Fujitsu
Services(英国)独自(Java) IDE無し
オブジェクト数が少ない場合は、VDMToolsより速い。
Overture Tools
Overture Project (デンマーク、英国、オランダ、ポルトガル、日本)
VDMJのソースを利用 Eclipse
Java生成。オブジェクト数が少ない場合は、VDMToolsより速い。クラス図生成?
Vienna Talk 小田朋宏 SRA
VDMJをプロセス間通信で
利用
Pharo Smalltalk
VDM-SL仕様が対象。Smalltalk生成。