Slide 1

Slide 1 text

形式手法ってなんだろう

Slide 2

Slide 2 text

設計書をかいてみる・・・ › ユーザ検索(記載例) – ユーザを検索する。

Slide 3

Slide 3 text

設計書をかいてみる・・・ › ユーザ検索(記載例) – ユーザを検索する。 以上!

Slide 4

Slide 4 text

設計書におけるさまざまなバリエーション › ユーザ検索 – ユーザを検索する。 – ユーザリストからEmailでユーザを検索する。 – 与えられたEmailをもってユーザリストから 同じEmailをもつユーザを検索し、返す。 – ①与えられたEmailをもってユーザリストから同じEmailをもつ ユーザを検索。②取得したユーザを返す。

Slide 5

Slide 5 text

設計書におけるさまざまなバリエーション › ユーザ検索 – ユーザを検索する。 – ユーザリストからEmailでユーザを検索する。 – 与えられたEmailをもってユーザリストから 同じEmailをもつユーザを検索し、返す。 – ①与えられたEmailをもってユーザリストから同じEmailをもつ ユーザを検索。②取得したユーザを返す。 人によって書き方 はそれぞれ・・・

Slide 6

Slide 6 text

形式手法ってなんだろう

Slide 7

Slide 7 text

スピーカー › 山口 寛子(べにちどり) – Twitter:@scarletplover – 金融系SIer › 金融系ではないSI担当

Slide 8

Slide 8 text

目次 1. 形式手法とは 2. 形式手法で書く 3. おわりに

Slide 9

Slide 9 text

形式手法とは

Slide 10

Slide 10 text

目次 1. 形式手法とは 2. 形式手法で書く 3. おわりに

Slide 11

Slide 11 text

形式手法とは › 仕様を記述・検証する手法 › 「数論理学を基盤としている手法」 石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』 – 数論理学:「A⋏B」「A→B」「集合」「再帰」等々・・・ – システムをモデル化し、厳密に定められた文法で仕様を記述、検証する › 厳密に定められた文法で仕様を記述することによって、抽象度の揺れや曖昧な部分を少なく する。 › 厳密に定められた文法で仕様を記述すれば、仕様のチェックを網羅的に行うことができる。 › 「開発上流工程からの品質確保への技術アプローチ」 中島震(2012年)『形式手法入門―ロジックによるソフトウェア設計― )』オーム社 › 宇宙工学系(NASAとか航空とか)のエラー処理など、「ミッションクリティ カル」なシステムで使われる。 – その他、AWSの設計等でも・・・。

Slide 12

Slide 12 text

設計書におけるさまざまなバリエーション › ユーザ検索 – ユーザを検索する。 – ユーザリストからEmailでユーザを検索する。 – 与えられたEmailをもってユーザリストから 同じEmailをもつユーザを検索し、返す。 – ①与えられたEmailをもってユーザリストから同じEmailをもつ ユーザを検索。②取得したユーザを返す。

Slide 13

Slide 13 text

設計書におけるさまざまなバリエーション › ユーザ検索 – ユーザを検索する。 – ユーザリストからEmailでユーザを検索する。 – 与えられたEmailをもってユーザリストから 同じEmailをもつユーザを検索し、返す。 – ①与えられたEmailをもってユーザリストから同じEmailをもつ ユーザを検索。②取得したユーザを返す。 検索して どうするの? 何で検索するの? 句読点を適切に 読めない人が存在する くどい 日本語難しい

Slide 14

Slide 14 text

形式手法で書いた場合・・・ public ユーザ取得byEmail: seq of char ==> ユーザ ユーザ取得byEmail(pEmail) == --下記の意味は「ユーザリストの中にあるEmailがp_Emailと同じユーザを返す」 --「let x in set s be st 『xの条件』in 『xを使った式or文』」は --「s集合の中で『xの条件』を満たすxについて『xを使った式or文』を実行する」 let u in set 登録リスト be st u.Email = pEmail in return u --検索するユーザがリストにいなければならない pre exists1 u in set 登録リスト & u.Email = pEmail;

Slide 15

Slide 15 text

形式手法で書いた場合・・・ public ユーザ取得byEmail: seq of char ==> ユーザ ユーザ取得byEmail(pEmail) == --下記の意味は「ユーザリストの中にあるEmailがp_Emailと同じユーザを返す」 --「let x in set s be st 『xの条件』in 『xを使った式or文』」は --「s集合の中で『xの条件』を満たすxについて『xを使った式or文』を実行する」 let u in set 登録リスト be st u.Email = pEmail in return u --検索するユーザがリストにいなければならない pre exists1 u in set 登録リスト & u.Email = pEmail; 仕様を厳密に書ける →明確に意味を1つに 絞れる

Slide 16

Slide 16 text

疑問:プログラム言語そのままでいいじゃない public ユーザ取得byEmail: seq of char ==> ユーザ ユーザ取得byEmail(pEmail) == --下記の意味は「ユーザリストの中にあるEmailがp_Emailと同じユーザを返す」 --「let x in set s be st 『xの条件』in 『xを使った式or文』」は --「s集合の中で『xの条件』を満たすxについて『xを使った式or文』を実行する」 let u in set 登録リスト be st u.Email = pEmail in return u --検索するユーザがリストにいなければならない pre exists1 u in set 登録リスト & u.Email = pEmail; 仕様を厳密に書ける →明確に意味を1つに 絞れる

Slide 17

Slide 17 text

疑問:プログラム言語そのままでいいじゃない public User GetUser(String pemail) { for(int i = 0; i < UserList.size();i++) { if (UserList.get(i).email == pemail){ return UserList .get(i); } } }

Slide 18

Slide 18 text

疑問:プログラム言語そのままでいいじゃない public User GetUser(String pemail) { for(int i = 0; i < UserList.size();i++) { if (UserList.get(i).email == pemail){ return UserList .get(i); } } } 何をやりたかっ たかコードには 表現されない (ことが多い) 繰り返しなどで 欠陥が混入する 可能性

Slide 19

Slide 19 text

疑問:プログラム言語そのままでいいじゃない › 「実装」ではなく「仕様」を記述することが可能 – 配列の中からデータを検索 › プログラミング – ほしいデータの探し方を記述( For文でぐるぐるまわして、○○と比較して・・・・・・) › 形式手法 – 仕様を記述する。 – 取得するデータの条件を明記することが可能 › 実装前に検証が可能

Slide 20

Slide 20 text

形式手法の側面 › 「実装」ではなく「仕様」を記述することが可能 – 配列の中からデータを検索 › プログラミング – ほしいデータの探し方を記述( For文でぐるぐるまわして、○○と比較して・・・・・・) › 形式手法 – 仕様を記述する。 – 取得するデータの条件を明記することが可能 › 実装前に検証が可能

Slide 21

Slide 21 text

形式手法の側面 › 「実装」ではなく「仕様」を記述することが可能 – 配列の中からデータを検索 › プログラミング – ほしいデータの探し方を記述( For文でぐるぐるまわして、○○と比較して・・・・・・) › 形式手法 – 仕様を記述する。 – 取得するデータの条件を明記することが可能 › 実装前に検証が可能 仕様の記述方法 仕様の検証方法

Slide 22

Slide 22 text

形式手法の側面 –仕様の記述方法- › 形式仕様記述 – 仕様を形式的に記述する – モデル規範 › 記述の要素が持つ意味を、数学的な実体(意味モデル)である集合、関係、列、関 数などに対応させる。 – VDM、Bメソッド、Alloy、SPIN・・・ › モデル化・・・システムの側面を抽象化&捨象 › 目標とする分析や検証を踏まえて、システムのどういう側面どう抽象的にモデルとして表 現する(モデル化)か※ということが肝要 – VDM・Bメソッド・・・状態ベース – Alloy・SPIN・・・状態遷移モデル ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』

Slide 23

Slide 23 text

形式手法の側面 –仕様の検証方法- › 正当性検証(Verification) – 「ある活動の実際の結果がその活動への要求と適合しているかどうかを調査決定す る過程に関わるもの。」※ – 開発製品が仕様と合致をしているかを評価すること › 妥当性検証(Validation) – 「製品が利用者のニーズに適合しているかを検査する過程にかかわるものである。」 ※ – 製品が要求に対して妥当なものかかをチェックする →「仕様」が妥当なものかをチェックする 通常ユーザ受入テスト等で行う →形式手法であれば設計段階で確認ができる(かもしれない) ※ジョン・フィッツジェラルド、ピーター・ゴルム・ラーセン、ポール・マッカージー、ニコ・プラット、マーセル・バーホフ(2010年)『VDM++によるオブジェクト指向システムの高品質設計と検証」』翔泳社

Slide 24

Slide 24 text

形式手法の側面 –仕様の検証方法- › 形式検証 – 定理証明 › 法則に基づいた検証※ › 記載された仕様に論理的な破綻がないかどうかを検証する。 – X機能で使用されているA,BがA→Bなら、Y機能でもA→Bじゃないとおかしい! – モデル検査 › 観測に基づいた検証※ › 記述されたモデルがとりうると考えられる状態を自動的に網羅することで検証を行う。並行処 理の仕様の検証に有用。 – X機能、Y機能をツールで網羅的に検証してみて、仕様の齟齬がないことを確認。 › ライトな検証 テスト・プロトタイピングによる検証 ※ジョン・フィッツジェラルド、ピーター・ゴルム・ラーセン、ポール・マッカージー、ニコ・プラット、マーセル・バーホフ(2010年) 『VDM++によるオブジェクト指向システムの高品質設計と検証」』翔泳社

Slide 25

Slide 25 text

VDMとは › VDM(Vienna Development Method) – 1970年代、IBMウィーンで始まった構造設計に主眼を置く 形式手法の名前。 – 形式仕様記述言語として、VDM-SLやVDM++を用いる。 – モデル規範。 › VDM-SL(Specification Language) – VDMを行うための形式仕様記述言語。1996年にISO標準化 › VDM++ – VDM-SLをオブジェクト指向に対応するために拡張したもの

Slide 26

Slide 26 text

VDMとは › モデル化の対象 – 機能仕様(データ型、変数、関数・操作など)をモデル化 (クラスという単位を用いる) › モデルの抽象度と開発プロセスでの位置づけ – VDM++は様々な抽象度での記載が可能。 › システム外部仕様のみを中心に記載することも可能 › Java等のプログラミングによる実装に近い書き方を行うことも可能 › 検証対象となる性質 – システムの状態が常に満たすべき条件(不変条件)や、個々の操作・関数が実行前、実行後 に満たすべき条件(事前条件・事後条件)を、インタプリタによる実行を通して検証を行う。 › 検証の方法 – 一般的にはテスト・プロトタイピングによる検証 – 定理証明を行うことも可能 ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』 荒木 啓二郎監修、近代科学社 を参考にまとめた

Slide 27

Slide 27 text

形式手法で書く

Slide 28

Slide 28 text

目次 1. 形式手法とは 2. 形式手法で書く 3. おわりに

Slide 29

Slide 29 text

VDMとは › モデル化の対象 – 機能仕様(データ型、変数、関数・操作など)をモデル化 (クラスという単位を用いる) › モデルの抽象度と開発プロセスでの位置づけ – VDM++は様々な抽象度での記載が可能。 › システム外部仕様のみを中心に記載することも可能 › Java等のプログラミングによる実装に近い書き方を行うことも可能 › 検証対象となる性質 – システムの状態が常に満たすべき条件(不変条件)や、個々の操作・関数が実行前、実行後に満たすべ き条件(事前条件・事後条件)を、インタプリタによる実行を通して検証を行う。 › 検証の方法 – 一般的にはテスト・プロトタイピングによる検証 – 定理証明を行うことも可能 ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』 荒木 啓二郎監修、近代科学社 を参考にまとめた

Slide 30

Slide 30 text

VDM++の書き方 1. モデルの目的を定める。 2. 要求を読む。 3. 要求から読み取れる機能的振る舞いを分析する。 4. 候補となるクラスまたは型を(主に名詞から)抽出し、同時に操作を(主に動作指示から)抽出して一覧にする。一覧の各項目に説明を加 えて辞書を作成する。 5. UMLのクラス図を用いて、クラス群のスケッチを行う。この作業では属性やクラス間の関連の定義も行う。このモデルをVDM++へと変換し、内 部の一貫性をチェックする。 6. 操作のシグニチャを仮に決めていく。この段階でもVDM++を用いてモデルの一貫性をチェックしておく。 7. 要求から候補となる不変条件を抽出して形式化を行い、クラス(とデータ型)の構造の定義を完成させる。 8. 各操作の事前条件と事後条件そして操作本体を決定することにより、操作を完成させる。必要に応じて型の定義を変更する。 9. 仕様を体系的なテストとラピッドプロトタイピングを用いて検証する。 10. モデルから自動コード作成または手作業によるコーディングによって実装コードを作り上げる。 ジョン・フィッツジェラルド、ピーター・ゴルム・ラーセン、ポール・マッカージー、ニコ・プラット、マーセル・バーホフ(2010年) 『VDM++によるオブジェクト指向システムの高品質設計と検証」』翔泳社

Slide 31

Slide 31 text

形式手法で書く 1. 要求を読み込み、振る舞いを分析する 2. モデルにおこす 3. 形式手法で記述 – 型定義 – インスタンス変数定義 – 操作定義 etc・・・ 4. 検証を行う 5. プログラム実装etc・・・

Slide 32

Slide 32 text

1.要求を読み込み、振る舞いを分析する › テストユーザ登録システム – WACATEゲームサイトを作成するにあたり、ベータテストに参加するユーザをユーザ リストに仮登録するシステムを作成する。 – ユーザは12歳超で、30名まで登録できる。 – ニックネームはゲーム内で使うので、一意でなければならない。 – ユーザの「本名、Email、ニックネーム、誕生日」を入力してユーザリストに登録する。 – ユーザ登録状況確認のために、ユーザリストを一覧取得する必要がある。 – ユーザの調査のために、ユーザのEmailを指定してユーザリストを検索し、該当する ユーザ情報を取得できる必要がある。 – ユーザの調査のために、ユーザのニックネームを指定してユーザリストを検索し、該当 するユーザ情報を取得できる必要がある。 – ユーザリストからEmailを指定して検索し、該当するユーザの情報を削除する機能 を設ける必要がある。

Slide 33

Slide 33 text

1.要求を読み込み、振る舞いを分析する › テストユーザ登録システム – WACATEゲームサイトを作成するにあたり、ベータテストに参加するユーザをユーザリストに 仮登録するシステムを作成する。 – ユーザは12歳超で、30名まで登録できる。 – ニックネームはゲーム内で使うので、一意でなければならない。 – ユーザの「本名、Email、ニックネーム、誕生日」を入力してユーザリストに登録する。 – ユーザ登録状況確認のために、ユーザリストを一覧取得する必要がある。 – ユーザの調査のために、ユーザのEmailを指定してユーザリストを検索し、該当するユーザ 情報を取得できる必要がある。 – ユーザの調査のために、ユーザのニックネームを指定してユーザリストを検索し、該当する ユーザ情報を取得できる必要がある。 – ユーザリストからEmailを指定して検索し、該当するユーザの情報を削除する機能を設け る必要がある。

Slide 34

Slide 34 text

2.モデルにおこす › クラスとか型になりそう – ユーザリスト – ユーザ › 本名 › Email › ニックネーム › 誕生日 › 操作になりそう – 一覧取得 – Emailでのユーザの取得 – ニックネームでのユーザの取得 – ユーザの登録 – ユーザの削除 ※モデルは説明しやすさを最優先にしてます

Slide 35

Slide 35 text

3.形式手法で記述

Slide 36

Slide 36 text

3.形式手法で記述(自然言語で書いた場合) › 型定義 – ユーザ › 本名:文字列 › Email:文字列 › ニックネーム:文字列 › 誕生日:日付型 › 変数定義 – 現在日付:日付型 – 登録リスト:登録したユーザの集合 › 30人までしか登録できない。ユーザのニックネームは一意とする。 › 機能 – 一覧取得 › 登録された登録リストを返す – ユーザ検索byEmail › 与えられたEmailをもってユーザリストから同じEmailをもつユーザを特定し、該当ユーザのユーザデータを返す。 – ユーザ検索byニックネーム › 与えられたニックネームをもってユーザリストから同じニックネームをもつユーザを特定し、該当ユーザのユーザデータを返す。 – ユーザ登録 › 新規ユーザの本名、Email、ニックネーム、誕生日をユーザデータとして、登録リストに登録する。 (ただし、ユーザの年齢は12歳超とする) – ユーザ削除 › 与えられたEmailをもってユーザリストから同じEmailをもつユーザを特定し、該当ユーザを登録リストから削除する。

Slide 37

Slide 37 text

3.形式手法で記述

Slide 38

Slide 38 text

3.形式手法で記述 › クラス定義 class クラス名 end クラス名 様々な定義

Slide 39

Slide 39 text

class クラス名 end クラス名 3.形式手法で記述 › クラス定義 types 型定義・・・クラスで用いる型(データの概念) instance variables インスタンス変数定義・・・クラスで用いる変数 operations 操作定義・・・クラス内の変数を操作する処理

Slide 40

Slide 40 text

3.形式手法で記述 型定義 インスタンス変数 定義 操作定義 操作定義

Slide 41

Slide 41 text

class クラス名 end クラス名 3.形式手法で記述 ー型定義ー › 型定義 types 型定義・・・クラスで用いる型(データの概念) instance variables インスタンス変数定義・・・クラスで用いる変数 operations 操作定義・・・クラス内の変数を操作する処理

Slide 42

Slide 42 text

3.形式手法で記述 型定義 インスタンス変数 定義 操作定義 操作定義

Slide 43

Slide 43 text

3.形式手法で記述 ー型定義ー › 型定義 – クラスで用いる型(データの概念)を定義できる

Slide 44

Slide 44 text

3.形式手法で記述 ー型定義ー › 型定義 – クラスで用いる型(データの概念)を定義できる --下記は「レコード型」といって、 --他の型の固定的な組み合わせ --個々の要素に名前と定義をつけられる --実際の値は以下のとおり記述 --mk_ユーザ(“べにちどり”,”[email protected]”,”scarletplover”,new 「日付」(2011,1,14)) --seq of char = 「文字の集合」=文字列 --「日付」は別のクラスで定義されてるものとする public ユーザ :: 本名 : seq of char Email : seq of char ニックネーム : seq of char 誕生日 : 「日付」;

Slide 45

Slide 45 text

class クラス名 end クラス名 3.形式手法で記述 ーインスタンス変数定義ー › インスタンス変数定義 types 型定義・・・クラスで用いる型(データの概念) instance variables インスタンス変数定義・・・クラスで用いる変数 operations 操作定義・・・クラス内の変数を操作する処理

Slide 46

Slide 46 text

3.形式手法で記述 型定義 インスタンス変数 定義 操作定義 操作定義

Slide 47

Slide 47 text

3.形式手法で記述 ーインスタンス変数定義ー › インスタンス変数定義 – クラスで用いる変数を定義できる

Slide 48

Slide 48 text

3.形式手法で記述 ーインスタンス変数定義ー › インスタンス変数定義 – クラスで用いる変数を定義できる – 基本はprivate等を設定し、外のクラスから触らせないようにする。 --「日付」は別のクラス --インスタンス変数には、型定義同様、別のクラスをあてることができる private 現在日付 : 「日付」; --「set of x」と記載するデータ型は --「集合型」といって、順番を持たない集まり --下記は「(型定義で記載した)ユーザ型のデータの集合」という意味 private 登録リスト: set of ユーザ := {};

Slide 49

Slide 49 text

3.形式手法で記述 ーインスタンス変数定義ー › インスタンス変数定義(不変条件:inv) – 定義した変数が絶対に守らなければならない条件を記載する

Slide 50

Slide 50 text

3.形式手法で記述 ーインスタンス変数定義ー › インスタンス変数定義(不変条件:inv) – 定義した変数が絶対に守らなければならない条件を記載する private 登録リスト: set of ユーザ; --inv:不変定義 --「card s」 は集合sの要素数を返す式 --下記の意味は「登録リストに含まれるユーザ数の上限は30まで」ということ inv card 登録リスト <= 30; --下記の意味は「登録リストにあるすべての任意のユーザ1、ユーザ2について、 -- ユーザ1とユーザ2が異なるデータのとき、ニックネームも違うこと -- (つまりニックネームは一意)」ということ --「forall x in set s 」&「条件」:集合sの中のすべてのxは「条件」を満たす --「a => b 」:aがtrueであればbもtrue inv forall ユーザ1,ユーザ2 in set 登録リスト & (ユーザ1<>ユーザ2)=>ユーザ1.ニックネーム <> ユーザ2.ニックネーム;

Slide 51

Slide 51 text

class クラス名 end クラス名 3.形式手法で記述 ー操作定義ー › 操作定義 types 型定義・・・クラス定義で用いる型(データの概念) instance variables インスタンス変数定義・・・クラス定義で用いる変数 operations 操作定義・・・クラス内の変数を操作する処理

Slide 52

Slide 52 text

3.形式手法で記述 型定義 インスタンス変数 定義 操作定義 操作定義

Slide 53

Slide 53 text

3.形式手法で記述 ー操作定義ー › 操作定義 – クラス内の変数を操作する処理を記載する。 › ユーザ取得byEmail、ユーザ登録、ユーザ削除・・・ – 基本的に入力を得て結果を返す。 – 書き方には陰定義と陽定義がある。 › 陰定義:操作定義に記載する処理のロジックではなく、 処理開始時または処理結果に要求される特性を記載する。 › 陽定義:実際の処理で行う操作の仕様を記述する。

Slide 54

Slide 54 text

3.形式手法で記述 ー操作定義ー › 操作定義(陰定義) – 陰定義:操作定義に記載する処理のロジックではなく、 処理開始時または処理結果に要求される特性を記載する。 処理で使用するインスタンス変数を明記してかく必要がある。 – 事前条件:「この処理を行うときに満たされていなきゃいけない条件はなにか」 →この処理を適用する際に期待している条件を論理式で記載する。 – 事後条件:「処理の結果、どうなっていてほしいのか」 →処理結果に要求される特性を論理式で記載する。 public ユーザ削除(pEmail:seq of char) ext wr 登録リスト:set of ユーザ pre exists1 u in set 登録リスト & u.Email = pEmail post not exists u in set 登録リスト & u.Email = pEmail;

Slide 55

Slide 55 text

3.形式手法で記述 ー操作定義ー --public/protected/private 操作定義名(引数名:引数のデータ型) public ユーザ削除(pEmail:seq of char) --ext:使用するインスタンス変数を指定。 --wrは書き込みをするという意味 ext wr 登録リスト:set of ユーザ --pre:事前条件 --「処理の前、登録リストにはEmailが同じユーザが1つだけ存在する」 --「exists1 x in set s &『条件』」の意味は -- 「s集合内に『条件』を満たす要素xがちょうど1つだけあるかどうか」 pre exists1 u in set 登録リスト & u.Email = pEmail --post:事後条件 --「処理の後、登録リストにはEmailが同じユーザが1つも存在しない」 --「exists x in set s &『条件』」の意味は -- 「s集合内に『条件』を満たす要素xがすくなくとも1つだけあるかどうか」 post not exists u in set 登録リスト & u.Email = pEmail; › 操作定義(陰定義(事前条件・事後条件))

Slide 56

Slide 56 text

3.形式手法で記述 ー操作定義ー › 操作定義(陽定義) – 陽定義:実際の処理で行う操作の仕様を記述する。 › 入力と結果の型を与え、結果を仮引数の組み合わせで表現する式を与える。 › 通常1文のみ (複数の文も記述できるが、処理の実装をずらずらと書くことは想定していない)。 › 事前条件、事後条件を書くことも可能。 › if文やcase文、for文も使用可能。 public ユーザ削除: seq of char ==> () ユーザ削除(pEmail) == 登録リスト :=登録リスト ¥ {let u in set 登録リスト be st u.Email = pEmail in u } pre exists1 u in set 登録リスト & u.Email = pEmail post not exists u in set 登録リスト & u.Email = pEmail;

Slide 57

Slide 57 text

3.形式手法で記述 ー操作定義ー › 操作定義(陽定義) – 陽定義:実際の処理で行う操作の仕様を記述する。

Slide 58

Slide 58 text

3.形式手法で記述 ー操作定義ー › 操作定義(陽定義) --public/protected/private 操作定義名 引数のデータ型 ==> 返り値の型 public ユーザ削除: seq of char ==> () --操作定義名(引数名)== ユーザ削除(pEmail) == --下記の意味は「登録リストに、(今までの)登録リストと、 -- 登録リストでEmailが合致するユーザを集合にしたものとの差分を抽出する --(登録リストから該当ユーザを引く)」 --「s1とs2の差を抽出」はs1 ¥ s2 登録リスト :=登録リスト ¥ {let u in set 登録リスト be st u.Email = pEmail in u } --pre:事前条件 --「処理の前、登録リストにはEmailが同じユーザがちょうど1つだけ存在する」 --「exists x in set s &『条件』」の意味は -- 「s集合内に『条件』を満たす要素xが少なくとも1つあるかどうか」 pre exists1 u in set 登録リスト & u.Email = pEmail --post:事後条件 --「処理の後、登録リストにはEmailが同じユーザが1つも存在しない」 --「exists x in set s &『条件』」の意味は --「s集合内に『条件』を満たす要素xが少なくとも1つあるかどうか」 post not exists u in set 登録リスト & u.Email = pEmail;

Slide 59

Slide 59 text

3.形式手法で記述 -完成-

Slide 60

Slide 60 text

4.検証 › 整合特性検査:仕様齟齬のチェック – 型・構文チェック › 間違った型などを使っていないかの確認 – 部分演算子についての整合性チェック › 0で割る、集合にないデータの検索など、値を返せない処理が存在しないか →不変条件・事前条件・事後条件の追加 – 不変条件のチェック › インスタンス変数などの不変条件が操作定義などの処理で守られない可能性はないか ※ツール(VDMToolsなど)では「証明課題の作成」等の補助機能あり › ツールでのテスト実行 – テストクラスの作成と、実行 →VDMToolsのAPIと組み合わせればプロトタイプでのテストも可能 ※ツールはVDMToolsやOvertureが存在 VDMTools: http://fmvdm.org/index.html Overture: http://overturetool.org/

Slide 61

Slide 61 text

4.検証 › 整合特性検査:仕様齟齬のチェック – インスタンス定義の不変条件と操作定義のユーザ登録の整合性チェック

Slide 62

Slide 62 text

4.検証 › 整合特性検査:仕様齟齬のチェック – インスタンス定義の不変条件 – 操作定義のユーザ登録 --inv:不変定義 --「card s」 は集合sの要素数を返す式 --下記の意味は「登録リストに含まれるユーザ数の上限は30まで」ということ inv card 登録リスト <= 30; public ユーザ登録: seq of char * seq of char * seq of char * 「日付」 ==> () ユーザ登録(p本名,pEmail,pニックネーム,p誕生日) == 登録リスト := {mk_ユーザ(p本名,pEmail,pニックネーム,p誕生日)} union 登録リスト --pre:事前条件 pre p誕生日.年齢算出(現在日付) > 12 --登録リストが30人以下であるためには、ユーザ登録前は29人である必要がある。 --事前条件を複数書きたいときにはandでつなげて書く。 and card 登録リスト <= 29;

Slide 63

Slide 63 text

4.検証 › 整合特性検査:仕様齟齬のチェック – 部分演算子のチェック

Slide 64

Slide 64 text

4.検証 › 整合特性検査:仕様齟齬のチェック – 部分演算子のチェック public ユーザ取得byEmail: seq of char ==> ユーザ ユーザ取得byEmail(pEmail) == --下記の意味は「ユーザリストの中にあるEmailがp_Emailと同じユーザを返す」 --「let x in set s be st 『xの条件』in 『xを使った式or文』」は --「s集合の中で『xの条件』を満たすxについて『xを使った式or文』を実行する」 let u in set 登録リスト be st u.Email = pEmail in return u --検索するユーザがリストにいなければならない pre exists1 u in set 登録リスト & u.Email = pEmail;

Slide 65

Slide 65 text

やってみよう!テストユーザ登録システム › ユーザ管理機能 1. ユーザ取得byニックネームの処理をVDM++で記載してみよう › ユーザ取得byEmailを参考に、同じように書いてみよう 2. ユーザ管理機能の不変条件・事前条件・事後条件を俯瞰して確認し、 何か問題がないか確認してみよう › 不変条件(inv)、事前条件(pre)、事後条件(post) › 登録・検索・削除で問題がないか、それぞれの定義の不変条件・事前条件・事後条件 を見比べてみよう – 不変条件はあるのに事前条件・事後条件はない、あるいはその逆 – 登録はできるのに削除はできない › 問題を見つけたら、どう定義を変更するか考えてみよう(余裕があれば)

Slide 66

Slide 66 text

やってみよう!テストユーザ登録システム

Slide 67

Slide 67 text

やってみよう!テストユーザ登録システム › ユーザ管理機能 1. ユーザ取得byニックネームの処理をVDM++で記載してみよう › ユーザ取得byEmailを参考に、同じように書いてみよう 2. ユーザ管理機能の不変条件・事前条件・事後条件を俯瞰して確認し、 何か問題がないか確認してみよう › 不変条件(inv)、事前条件(pre)、事後条件(post) › 登録・検索・削除で問題がないか、それぞれの定義の不変条件・事前条件・事後条件 を見比べてみよう – 不変条件はあるのに事前条件・事後条件はない、あるいはその逆 – 登録はできるのに削除はできない › 問題を見つけたら、どう定義を変更するか考えてみよう(余裕があれば)

Slide 68

Slide 68 text

やってみよう!テストユーザ登録システム

Slide 69

Slide 69 text

やってみよう!テストユーザ登録システム › ユーザ管理機能 1. ユーザ取得byニックネームの処理をVDM++で記載してみよう › ユーザ取得byEmailを参考に、同じように書いてみよう 2. ユーザ管理機能の不変条件・事前条件・事後条件を俯瞰して確認し、 何か問題がないか確認してみよう › 不変条件(inv)、事前条件(pre)、事後条件(post) › 登録・検索・削除で問題がないか、それぞれの定義の不変条件・事前条件・事後条件を見 比べてみよう – 不変条件はあるのに事前条件・事後条件はない、あるいはその逆 – 登録はできるのに削除はできない › 問題を見つけたら、どう定義を変更するか考えてみよう(余裕があれば) 所要時間:10分

Slide 70

Slide 70 text

やってみよう!テストユーザ登録システム › 問題1解答 public ユーザ取得Byニックネーム: seq of char ==> ユーザ ユーザ取得Byニックネーム(pニックネーム) == -「ユーザリストの中にあるニックネームがpニックネームと同じユーザを返す」 let u in set 登録リスト be st u.ニックネーム = pニックネーム in return u --検索するニックネームのユーザがリストにいなければならない pre exists1 u in set 登録リスト & u.ニックネーム = pニックネーム;

Slide 71

Slide 71 text

やってみよう!テストユーザ登録システム › 問題2解答① --inv:不変定義 --下記の意味は「登録リストにあるすべての任意のユーザ1、ユーザ2について、ユーザ1とユーザ2が異なるデータのとき、 --ニックネームも違うこと(つまりニックネームは一意)」ということ inv forall ユーザ1,ユーザ2 in set 登録リスト & (ユーザ1<>ユーザ2)=>ユーザ1.ニックネーム <> ユーザ2.ニックネーム; public ユーザ登録: seq of char * seq of char * seq of char * 「日付」 ==> () ユーザ登録(p本名,pEmail,pニックネーム,p誕生日) == 登録リスト := {mk_ユーザ(p本名,pEmail,pニックネーム,p誕生日)} union 登録リスト --pre:事前条件 pre p誕生日.年齢算出(現在日付) > 12; and card 登録リスト <= 29 --ニックネームが一意であるためには、登録時に同じニックネームのユーザがいてはならない。 and not exists u2 in set 登録リスト & u2.ニックネーム = pニックネーム and ・・・

Slide 72

Slide 72 text

やってみよう!テストユーザ登録システム › 問題2解答② – ユーザ登録処理で同じEmailアドレスを登録すると以下の問題 › ユーザ削除処理で削除処理をすると、事前条件エラー › ユーザ取得byEmail処理をすると、事前条件エラー public ユーザ登録: seq of char * seq of char * seq of char * 「日付」 ==> () ユーザ登録(p本名,pEmail,pニックネーム,p誕生日) == 登録リスト := {mk_ユーザ(p本名,pEmail,pニックネーム,p誕生日)} union 登録リスト --pre:事前条件 pre p誕生日.年齢算出(現在日付) > 12; and card 登録リスト <= 29 and not exists u2 in set 登録リスト & u2.ニックネーム = pニックネーム --ユーザ削除で適切に削除されるためには、登録時に同じEmailのユーザがいてはならない。 and not exists u in set 登録リスト & u.Email = pEmail pre exists1 u in set 登録リスト & u.Email = pEmail;

Slide 73

Slide 73 text

やってみよう!テストユーザ登録システム › 問題2解答③ public ユーザ登録: seq of char * seq of char * seq of char * 「日付」 ==> () ユーザ登録(p本名,pEmail,pニックネーム,p誕生日) == 登録リスト := {mk_ユーザ(p本名,pEmail,pニックネーム,p誕生日)} union 登録リスト --pre:事前条件 pre p誕生日.年齢算出(現在日付) > 12; and card 登録リスト <= 29 and not exists u2 in set 登録リスト & u2.ニックネーム = pニックネーム --ユーザ削除で適切に削除されるためには、登録時に同じEmailのユーザがいてはならない。 and not exists u in set 登録リスト & u.Email = pEmail --inv:不変定義 --Emailも一意であるべきであった。 inv forall ユーザ1,ユーザ2 in set 登録リスト & (ユーザ1<>ユーザ2)=>ユーザ1.Email <> ユーザ2.Email;

Slide 74

Slide 74 text

やってみよう!テストユーザ登録システム › Toolによる証明課題の作成 ※自分の環境 – エディタ:Overture – 証明課題:Overture(VDMToolでもできます) – 実行・テスト:VDMTools(Overtureでもできます)

Slide 75

Slide 75 text

やってみよう!テストユーザ登録システム › Toolによるテスト実行 ※自分の環境 – エディタ:Overture – 証明課題:Overture(VDMToolでもできます) – 実行・テスト:VDMTools(Overtureでもできます)

Slide 76

Slide 76 text

形式手法のいいところ › 仕様を厳密にかける。 – 読み手側で行間を推測して読む必要がない。 – 資料の抽象度を一定にしやすい。 › 「実装」ではなく「仕様」を記述することが可能 – 検索などの仕様を、実装ではなくそのまま厳密に記述することが可能 › 実装前に検証が可能 – 不変条件・事前条件・事後条件などが厳密に書かれており、 確認しやすい – 厳密に書いているのでツールでの検証・デバックができる。 →仕様状態でのデバック実行が可能

Slide 77

Slide 77 text

VDM++を書くときのガイドライン 1. 辞書中の名詞は、モデルの目的に照らして、もし読み書きに加えて警備な機能しか必要としていないなら、型としてモデル化されるべきである。 2. 異なるクラス間の正確な関係と関連を表現するための全体クラスを作成する。 3. 関連を定義するときには、いつでもその多重度を考慮しなければならない。そしてその関連が利用される方向にロール名を付ける。 4. もし関連がある値に依存している場合には、その関連は、限定子を加えたものとする。限定子の名前はVDM++の型名と同じものとする。 5. カプセル化を保つためには、インスタンス変数をprivateまたはprotectedとして宣言する。もし利用者が何も指定しなけらばprivateが自動的に想定される。 6. クラスのスケルトンが生成されたら、それ以上の機能を追加する前に、、すぐ一貫性をVDMToolsでチェックすること。 7. token型は、まだ詳細が決まっていない値を扱う。抽象的モデルを定義する際に有用である。 8. 引数と戻り値の型について注意深く考えることは、しばしばクラス図中で不足している関連を発見する役に立つ。 9. 重要な性質や性質を不変条件として記述せよ。 10. ある昨日を実現する複数の手段がある場合には、陰定義を用いて開発の後工程に影響を与えないようにすることができる。 11. 操作を定義する際には、同時により多くの不変条件を探すようにせよ。 12. 陽操作定義を精確かつ明解に行うこと。その場合でもプログラミング言語による記述よりも抽象的であるように心がけること。 13. あるクラスがインスタンス変数に関する不変条件を持ち、かつ構成子を定義しているときに、もしその構成子が不変条件に関係する変数への代入を行うなら、不変条件 を分離した関数として定義しておくことには価値がある。 ジョン・フィッツジェラルド、ピーター・ゴルム・ラーセン、ポール・マッカージー、ニコ・プラット、マーセル・バーホフ(2010年) 『VDM++によるオブジェクト指向システムの高品質設計と検証」』翔泳社

Slide 78

Slide 78 text

おわりに

Slide 79

Slide 79 text

目次 1. 形式手法とは 2. 形式手法で書く 3. おわりに

Slide 80

Slide 80 text

形式手法で大事なこと › 何が複雑なのかを把握 – 何が複雑だから形式手法を用いたいのか →使用する手法、モデリングの内容を考える →どの抽象度でモデルを記載するべきなのかを考える › どう検証するか – 並行処理を検証したいのか – 仕様の整合性を確認したいのか – 実際の実装に入るまえに仕様を確認したいのか →適している形式手法を考える

Slide 81

Slide 81 text

形式手法の種類 › VDM – 開発者に受け入れられやすい、ライトな形式手法。 – インタプリタ実行による検証。 › Bメソッド – 段階的詳細化と定理証明を軸とした技法。 › Alloy – 自動解析可能なモデル規範形式仕様言語。 › SPIN – モデル検査検証ツール。状態遷移モデルの観点で仕様を記述。並行処理 の検証で使われる。

Slide 82

Slide 82 text

参考文献 1. ジョン・フィッツジェラルド、ピーター・ゴルム・ラーセン、ポール・マッカージー、ニコ・プラット、マーセル・バーホフ (2010年)『VDM++によるオブジェクト指向システムの高品質設計と検証」』翔泳社 2. 石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』 荒木 啓二郎監修、近代科学社 3. 中島震(2012年)『形式手法入門―ロジックによるソフトウェア設計― )』オーム社 4. SQuBOK策定部会 (2014年)『ソフトウェア品質知識体系ガイド -SQuBOK Guide-(第2版) 』 オーム社 5. 「「VDM++による形式仕様記述」Webサイト」 http://research.nii.ac.jp/~f-ishikawa/vdm/index.html(2019月12月アクセス) 6. 「ディペンダプルシステムのための形式手法の実践ポータル」 http://formal.mri.co.jp/ (2019月12月アクセス)

Slide 83

Slide 83 text

おわり › ご清聴ありがとうございました。

Slide 84

Slide 84 text

(補足)VDM++の書き方 ※ワークで使用したところを中心に 抜き出してみました

Slide 85

Slide 85 text

VDM++の書き方 › クラス定義 class クラス名 value 定数値定義 types 型定義 instance variables インスタンス変数定義 operations 操作定義 end クラス名 fucntions 関数定義 thread スレッド定義 sync 同期制約

Slide 86

Slide 86 text

VDM++の書き方 -データ型ー › データ型 型 意味 例 bool ブール型 true/false nat1 非負整数(n≧1) 1、2、3・・・ nat 正整数(n≧0) 0、1、2、3・・・ rat 有理数(整数または分数で表せる数値) -1/3、-1/2、0、1/2・・・ real 実数 -√2、-1、1/3・・・ char 文字型 a、b、c、あ・・・ quote 引用型(列挙型のときに用いられる) <赤>、<青>、<黄> token トークン型(内部構造を指定しない) ※ 文字列は「seq of char」と記載する ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 87

Slide 87 text

VDM++の書き方 -データ型ー › 演算子(共通) 演算子 意味 a = b 相当判定(aとbは同じ) a <> b 不等判定(aとbは違う) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 88

Slide 88 text

VDM++の書き方 -データ型ー › 演算子(bool型) 演算子 意味 not a bではない(否定) a and b aとbの両方が成り立つ(論理積) a or b aとbの少なくとも片方が成り立つ(論理和) a => b aが成り立つならばbが成り立つ a <=> b aとbの真偽値が一致する(同値) →aがtrueならbもtrue aがfalseならbもfalse ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 89

Slide 89 text

VDM++の書き方 -データ型ー › 演算子(数値型) 演算子 意味 -x 負等号 abs x xの絶対値 floor x xを超えない最大の整数 x + y x – y x * y x / y 四則計算 x div y 整数除算の商 (x ÷ y = a 余り b のaの部分) x mod y x rem y 整数除算の余り (x ÷ y = a 余り b のbの部分) x ** y べき乗(xのy乗) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 90

Slide 90 text

VDM++の書き方 -データ型ー › 複合データ型 型 意味 宣言例 値例 合併型 列挙されている値のいず れか char|int <赤>|<青>|<黄> a <青> 選択型 列挙されている値のいず れか またはnil(未選択) [bool] [<赤>|<青>|<黄>] true <赤> nil 組型 他の型の固定的な組み合 わせ nat1 *bool mk_(3,true) レコード型 他の型の固定的な組み合 わせ 個々の要素に名前をつけ られる ユーザ :: ID : nat1 名前 : seq of char mk_ユーザ(31,”やま”) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 91

Slide 91 text

VDM++の書き方 -データ型ー › 複合データ型 – 動的な集合の場合は以下のとおり記載する {f(x) | x in set s & 『論理式』} (集合sの中の値で『論理式』を満たすxについて、f(x)を計算した値を、新たな集合とする。) › 例){x + 1 | x in set {1,2,3,4,5} & x mod 2 = 0} →{1…5}の中で2で割ると0の値について、1を加えた値の集合 → {1…5}の中で2で割ると0になる値は「2、4」、これらにそれぞれ1を加える →答えは{3,5} 型 宣言 宣言例 値例 集合型 順番を持たない集まり {1,2,3,4} seq of char (文字の塊) {1,2,3,4} {‘a’,’b’,’t’} (={‘b’,’a’,’t’}) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 92

Slide 92 text

VDM++の書き方 -データ型ー › 演算子(集合型1ページ目) 演算子 意味 例 s1 union s2 s1とs2を合併する {1,2,3} union {2,3,4} → {1,2,3,4} s1 inter s2 s1とs2の共通部分を抽出 {1,2,3} inter {2,3,4} → {2,3} s1 ¥ s2 s1とs2の差を抽出 {1,2,3} ¥ {2,3} → {1} e in set s1 eはs1に帰属する 1 in set {1,2,3,4} → true e not in set s1 eはs1に帰属しない 1 not in set {2,3,4} → true s1 subset s2 s1はs2に含まれている {2,2,3} subset {2,3,4} → true {2,3,4} subset {2,2,3} → false s1 psubset s2 s1はs2に含まれているが、 s1はs2と同じではない {2,2,3} psubset {2,3,4} → true {2,3,4} psubset {2,3,4} → false ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 93

Slide 93 text

VDM++の書き方 -データ型ー › 演算子(集合型2ページ目) 演算子 意味 例 s1 = s2 s1とs2は同じ {2,4,3} = {2,3,4} → true ([2,4,3] = [2,3,4] → false) s1 <> s2 s1とs2は同じではない {2,4,3} <> {2,3,4} → false ([2,4,3] <> [2,3,4] → true) card s1 s1の要素数 card {2,3,4} → 3 dunion ss ss内のすべての集合を 合併する dunion {{1,2},{2,3,4},{4,5}} →{1,2,3,4,5} dinter ss ss内のすべての集合について 共通部分を抽出 dinter {{1,2,3},{2,3,4}} → {2,3} power s1 有限冪集合 power {1,2} → {{},{1},{2},{1,2}} ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 94

Slide 94 text

VDM++の書き方 -データ型ー › 複合データ型 型 宣言 宣言例 値例 列型 順番をもつ集まり [1,2,3,4] seq of char (文字列) [1,2,3,4] [’b’,’a’,’t’] (<>[‘a’,’b’,’t’]) “bat” 写像型 ある値の集合 (domain=定義域) から、別の値の集合 (range=値域) を紐づけた型 map (seq of char) to nat map 型1 to 型2 Inmap 型1 to 型2 (単射) {“太郎” |-> 1, “次郎” |-> 2} 定義 値 太郎 1 太郎 2 ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 95

Slide 95 text

VDM++の書き方 -式または文ー 文 意味 例 a := b aにbを代入する X := 9; (Xに9に代入する →Xは9になる) X :=N; (XにNを代入する →XはNに入っていた値になる) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 96

Slide 96 text

VDM++の書き方 -式または文ー 意味 構文 例(式) もし『条件』に該当するならば 『文また式』を実行する。 合わない場合には『その他』を実 行する。 if 『条件』 then 『文or式』 else 『文or式』 if x = 3 then “参” else “零” (xが3だったら参、違う場合は零) 『式』が『パターンn』のとき 『式または文n』を行う、 パターンがどれにも合わない場合 には『その他』を実行する。 cases 『式』: 『パターン1』-> 『式or文1』, 『パターン2』-> 『式or文2』, ・・・ 『パターンn』-> 『式or文n』, others -> 『その他』 end cases x : 3 -> “参” , 4 -> “肆” , others -> 0 end (xが3だったら参、4だったら肆、 全部違う場合は零) 『パターン』を『式1』とし、 『パターンを使った式or文』を実 行 def (let)『パターン』=『式1』 in 『パターンを使った式or文』 def x = 3 in x + 3 (xが3としてx+3を計算→6) s集合の中で『xの条件』を満たす xについて『xを使った式or文』を 実行する let x in set s be st 『xの条件』 in 『xを使った式or文』 let x in set {1,2,3} be st x>2 in x+1 (1,2,3の中で2より大きいものにつ いて、1を加える→4) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの

Slide 97

Slide 97 text

VDM++の書き方 -式または文ー 意味 構文 例 s集合内のすべての要素xが、 『条件』を満たすかどうか forall x in set s &『条件』 forall x in set {1,2,3} & x>0 (集合「1,2,3」のすべての要 素はxよりも大きいか) s集合内に『条件』を満たす 要素xが少なくとも1つある かどうか exists x in set s &『条件』 exists x in set {1,2,3} & x>1 (集合「1,2,3」の要素の中で 1よりも大きい要素が存在す るか) s集合内に『条件』を満たす 要素xがちょうど1つだけあ るかどうか exists1 x in set s &『条件』 exists1 x in set {1,2,3} & x>2 (集合「1,2,3」の要素の中で 2よりも大きい要素がちょう ど1つだけあるか) ※石川冬樹(2011年)『VDM++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの