Bメソッドの抽象機械の証明責務
授業でBメソッドに入門してきた。
参考文献:「先端スキル開発特別講義?:形式手法を使ったデータ指向モデリングと検証」の資料
http://honiden-lab.ex.nii.ac.jp/u-tokyo/lecture2009/
BメソッドのツールであるAtelier Bのマニュアル
http://www.atelierb.eu/index-en.php
Bメソッド概要
わかったこと。
- Bメソッドは、形式的に証明できる形で仕様を記述し、検証する形式手法の一種である。
- Bメソッドは、操作というインターフェースをもつ抽象機械としてシステムを記述する。
- 抽象機械は、変数をもち、操作の際の代入(substitution)によってその状態を変える。代入は非決定的でもよい。
- 各操作には、操作を行うための条件(事前条件)がある。
- 不変条件(invariant, 抽象機械が常に満たすべき命題)は、集合によって記述する。(2項関係、関数なども集合で表現できる。)
- 仕様の詳細化(refinement)の機能があり、より抽象的な仕様とより実装(implementation)に近い仕様の関係の整合性が証明される。
証明責務
Bメソッドの(抽象機械の)検証の特徴は、
「抽象機械への操作(operation)を行っても常に不変条件が成り立っている」
という命題が自動的につくられ、
これを示しなさい、と言われる(証明責務, proof obligation)ことである。
それを以て抽象機械の正しさとするため、不変条件をどう書くかが非常に重要である。
Atelier Bはある程度自動で証明をしてくれるが、それで証明できない場合、
対話的に証明を完了させることになる。
抽象機械に対して生成される証明責務は、
- 初期状態が不変条件を満たす
- 事前条件と不変条件が満たされているとき、操作を行っても不変条件が満たされる
らしい。
理解を深めるため、抽象機械および証明責務をCoqで記述してみた。
ただし変数および代入などはとりあえずVariableで後回しにした。
気が向いたら実装するかも。
Require Import List. Section B. Variable (value : Set) (* 値 *) (state : Set) (* 状態 *) (substitution : Set) (* 代入文。 stateを変化させる *) . Definition stateSet := state -> Prop. (* stateの集合を命題で表現 *) Variable (substDenote : substitution -> state -> stateSet) (* 代入文の効果。非決定的 *) . Definition predicate := state -> Prop. (* stateを使って表現される命題 *) Variable wp : substitution -> predicate -> predicate (* 代入文から最弱事前条件 (weakest precondition) が決まるとする *) . Hypothesis wp_ok : forall (subst : substitution) (predic : predicate) (st1 st2 : state), substDenote subst st1 st2 -> let P := wp subst predic in (P st1 -> predic st2) /\ (forall P' : state -> Prop, (P' st1 -> predic st2) -> P st1) (* wpは最弱事前条件を計算する *) . Record Operation : Type := { subst : substitution; (* 操作本体 *) pre : predicate; (* 事前条件 *) returnValue : state -> value (* 戻り値 *) }. Definition pred_preserved (predic : predicate)(op : Operation) : Prop := forall st1 st2 : state, predic st1 -> pre op st1 -> (substDenote (subst op) st1 st2) -> wp (subst op) predic st2 (* 事前条件が満たされている場合、predicがopによって保存される *) . Fixpoint all_list {A} (P : A -> Prop)(xs : list A) := match xs with | nil => True | x :: xs' => P x /\ all_list P xs' end. Record Machine := { initState : stateSet; (* 初期状態。非決定的 *) invariant : predicate; (* 不変条件 *) ops : list Operation; (* 操作の列 *) init_invariant : forall st : state, initState st -> invariant st; (* 初期状態は不変条件を満たす *) ops_invariant : all_list (pred_preserved invariant) ops (* すべての操作で不変条件が保存される *) }. End B.
Machineをレコードにし、フィールドinit_invariantと、ops_invariantで
証明責務を表現した。
「最弱事前条件(weakest precondition)」は、
Atelier Bのマニュアルには出てこなかったが
代入によって条件に現れる変数を代入後の式に書き換えることは
ダイクストラの最弱事前条件を計算していることに対応するため、
参考: http://en.wikipedia.org/wiki/Predicate_transformer_semantics
この表現を用いた。(授業では最弱事前条件、で教わった)
wp_okは、このままではwpに何も条件がついていないため、
「wpは最弱事前条件を計算する」という仮説をつけておいた。
しかしこの仮説の型、間違っているかもしれない。
非決定性をstate -> stateSet (= state -> state -> Prop)で表現すると
最弱事前条件が計算できる必要はないなと思った。