8.4 MSSS の適用例
8.4.4 変数名統一
8.4.3項のマッチングでは図8.15で示したレンタカーシステムの細分化モデルRentC6
に対してそれぞれ図8.14の部品CG5がマッチした.この節では6.2.3項で示した変数名 統一手順に沿って部品CG5 の実装依存モデルと細分化実装の変数名をRentC6の変数名
第8章 手法適用例 118
RentC5の事前条件より GroupC3の事前条件が厳しい limit : NAT1
maxCar : 1..10000 maxUser : 1..10000
rent : POW(0..maxCar * 0..maxUser) dom(rent) : POW(0..maxCar) dom(rent~) : POW(0..maxUser) (rent~;rent):POW(id(0..maxUser))
!(user).(user : dom(rent~) =>
card(rent~[{user}]) <= limit) car : 0..maxCar
user : 0..maxUser
card(rent~[{user}]) + 1 <= limit not(car : dom(rent))
not(user = rent(car)) rent := rent <+ {car |-> user}
パラメタ制約
不変条件
事前条件
代入
limit : NAT1 &
maxPerson : 1..10000 &
maxGroup : 1..10000
belong : POW((0..maxPerson) * (0..maxGroup)) dom(belong) : POW(0..maxPerson)
dom(belong~) : POW(0..maxGroup) (belong~;belong):POW(id(0..maxGroup))
!(group).(group:dom(belong~) =>
card(belong~[{group}]) <= limit) person : 0..maxPerson &
group : 0..maxGroup &
max(dom(belong))+1 <= maxPerson &
card(belong~[{group}]) + 1 <= limit &
not(person : dom(belong)) &
not(group = belong(person))
belong := belong <+ {person |-> group}
パラメタ制約
不変条件
事前条件
代入
図 8.17: 細分化モデルRentC5と細分化モデルGroupC3間のマッチング に置換する.図8.18に部品CG5と部品CG5に変数名置換を適用した結果を示す.
モデル実装間変数対応付けとして部品CG5は (belong, belong i.value) を持つ.まず,
部品CG5の細分化モデルGroupC5の変数名を置換する.これは細分化モデルGroupC5 の変数名を登場順に細分化モデルRentC6に書き換えることで行う.これにより,limit, maxPerson, maxGroup, belong, userがそれぞれlimit, maxCar, maxUser, rent, car に置 換される.次に実装依存モデルGroupC5 dの変数名を置換する.実装依存モデルの変数 名置換は細分化モデルの変数名置換と同様に置換を行った上で,細分化モデルに存在し ない変数名に対して部品名をプレフィックスとすることで部品毎に固有の変数名を与え る.GroupC5 d では変数fileOpen がGroupC5に存在しない変数であるため,fileOpen
を GroupC5 fileOpen に置換する.また,細分化実装に現れるモデル変数に対しても実
装依存モデルの変数名置換を適用する.次に細分化実装の変数名を置換する.細分化実装 の変数名は‘輸入で生じる変数’,‘細分化実装のCONCRETE VARIABLESで宣言される 変数’,‘局所変数’ に分類される.‘輸入で生じる変数’ には belong i.val が該当する.部 品CG5はモデル実装間変数対応付けとして (belong, belong i.value)を持ち,モデル変数 belong は rent に置換されるため,モジュールの別名belong i をrent i に置換する.こ れにより,belong i.valは rent i.val になる.部品CG5は局所変数を持たないため,局所 変数名の置換は生じない.以上により部品CG5の実装依存モデルと細分化実装は図8.18 の部品CG50 のようになる.
同様に細分化モデルRentC7にマッチする図8.14の部品CB5に変数名置換を適用する と図8.18の部品CB50 のようになる.
第8章 手法適用例 119
IMPLEMENTATION RentC7_i(maxUser, maxPoint) REFINES RentC7_d
IMPORTS
points_i.PFunc((0..maxUser), (0..maxPoint)) INVARIANT
points = points_i.value &
((BankC5_fileOpen = TRUE) =>
(points_i.fileOpen = TRUE))
OPERATIONS returnCar(user, point) = VAR bal, arg1, arg2 IN /*REF*/
MACHINE Rent_C7_d(maxUser, maxPoint) ...
CONCRETE_VARIABLES BankC5_fileOpen INVARIANT
points : 0..maxUser +-> 0..maxPoint &
dom(points) <: 0..maxUser &
ran(points) <: 0..maxPoint &
BankC5_fileOpen : BOOL OPERATIONS returnCar(user, point) = PRE
user : 0..maxUser &
point : NAT &
points(user) + point <= maxPoint &
BankC5_fileOpen = TRUE THEN
RentC7と同じ END
実装依存モデルRentC7_d 細分化実装RentC7_i 部品C’B5
IMPLEMENTATION RentC6_i(limit, maxCar, maxUser) REFINES RentC6_d
IMPORTS
rent_i.PFunc((0..maxCar), (0..maxUser)) INVARIANT
rent_i.value = rent &
((GroupC5_fileOpen=TRUE) =>
(belong_i.fileOpen=TRUE)) MACHINE RentC6_d(...)
CONCRETE_VARIABLES GroupC5_fileOpen INVARIANT
rent : 0..maxCar +-> 0..maxUser &
!(user).(user : ran(rent)) => ...) &
dom(rent) <: 0..maxCar &
ran(rent) <: 0..maxUser &
GroupC5_fileOpen : BOOL OPERATIONS returnCar(car) = PRE car : 0..maxCar &
car : dom(rent) &
GroupC5_fileOpen = TRUE THEN
細分化モデルと同じ END
細分化実装RentC6_i 実装依存モデルRentC6_d
部品CG5
OPERATIONS returnCar(car) = /*DEF*/
rent_i.delVal(car)
END Zx
bal <-- points_i.getVal(user);
arg1 := user;
arg2 := bal + point;
/*DEF*/
points_i.setVal(arg1, arg2) END
END
Wy
Zy
図 8.18: 部品CG5, CB5 の変数名置換結果
第8章 手法適用例 120
MACHINE DbBankC1_d(maxUser, maxBalance) CONSTRAINTS
maxUser : 1..10000 &
maxBalance : 1..10000000 ...
CONCRETE_VARIABLES transaction INVARIANT ... & transaction : BOOL OPERATIONS
res_newUser <-- registUser(name, addr) = PRE ... & transaction = TRUE
THEN 細分化モデルの代入文と同じ
実装依存モデルDbBankC1_d
細分化実装DbBankC1_i 部品C’B1
IMPLEMENTATION DbBankC1_i(maxUser, maxBalance) REFINES Bank_registUserAnyDefP1_DB_d IMPORTS
table.DbTable(0..maxUser, 1, 0..maxBalance, 2) INVARIANT
users = table.keys &
userName = table.strFields(1) &
userAddr = table.strFields(2) &
((transaction = TRUE) => table.transaction = TRUE)
OPERATIONS
res_newUser <-- registUser(name, addr) = VAR corFlag, pp, xxres IN
/*REF*/
corFlag <-- table.existsWithStr(1, name, 2, addr);
pp := corFlag;
IF corFlag = FALSE THEN
xxres <-- table.nextKey END;
/*DEF*/
IF corFlag = FALSE THEN
res_newUser := xxres END
END END
図 8.19: 細分化モデルBankC1のデータベースによる実装