--下記の意味は「ユーザリストの中にある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;
--下記の意味は「ユーザリストの中にある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つに 絞れる
--下記の意味は「ユーザリストの中にある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つに 絞れる
→この処理を適用する際に期待している条件を論理式で記載する。 – 事後条件:「処理の結果、どうなっていてほしいのか」 →処理結果に要求される特性を論理式で記載する。 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;
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; › 操作定義(陰定義(事前条件・事後条件))
(複数の文も記述できるが、処理の実装をずらずらと書くことは想定していない)。 › 事前条件、事後条件を書くことも可能。 › 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;
ユーザ削除: 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;
==> ユーザ ユーザ取得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;
ユーザ取得Byニックネーム(pニックネーム) == -「ユーザリストの中にあるニックネームがpニックネームと同じユーザを返す」 let u in set 登録リスト be st u.ニックネーム = pニックネーム in return u --検索するニックネームのユーザがリストにいなければならない pre exists1 u in set 登録リスト & u.ニックネーム = pニックネーム;
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 ・・・
ユーザ登録: 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;
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;
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++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの
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++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの
『条件』 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++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの
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++による形式仕様記述 (トップエスイーシリーズ 実践講座)』をもとにまとめたもの