ããä½å¹´ãèãã¦ãããã¼ãã®ã²ã¨ã¤ããã«ã¸ã¥ã¢ã«ãªãã©ã¼ãã«ã¡ã½ããï¼èªç¾©çç¾ã¯æ¿ç¥ï¼ããªãã§ãããä¸é£ã®{ãã¹ã(Test), ä»æ§(Specification), æ¯ãèã(Behaviour/Behavior)}é§åéçºãªãã¦åãã¯ãã«ã¸ã¥ã¢ã«ãªãã©ã¼ãã«ã¡ã½ãããªãã ã¨åã¯æãã¦ããããã§ãããããä¸æ©è¸ã¿è¾¼ãã§æ¬²ããæããéé´æ»çã®ä¸æºãããã¾ãã
ããã§ã¡ã¤ã¤ã¼ã«æ»ã£ã¦ãå¥ç´é§åãã¨ãããããã¯ãæ¤è¨¼é§åããªãã¦è¨èã使ã£ã¦ã¿ããã©ããã³ãã«é§åã«ã¯é£å·æ°å³ã"Offencive Programming"ã¯ããæ»æçããã°ã©ãã³ã°ãã¨è¨³ãããã¨çæãã¾ã£ããä¼ãããªããããã
ç´ä½æ²æã®æ«ãããã¥ã¢ã«ããã°ã©ãã³ã°ãã£ã¦è¨èã使ããã¨ã«ï¼æ«å®çã ãã©ï¼æ±ºãã¾ãããããã¦ã¨ã¯ã½ã·ã¹ãã²ã¼ã ã¯ããã¥ã¢ã«ããã°ã©ãã³ã°ã説æããããã«æ¡åºããâ極端åããæ¯å©âã§ãã
å 容ï¼
- è¨è¨ï¼ä»æ§ï¼ã¨å®è£
- è¨è¨ããã°ã©ãã³ã°
- æªéã®å®è£ ããã°ã©ã
- æå°æªã ãç´ ç´ãªå¥´
- æªéã追ãã¤ããæªãå°ãã®åªæ
- æ¦ãã¯ç¶ã
- ã¨ã¯ã½ã·ã¹ãã²ã¼ã ãããã¥ã¢ã«ããã°ã©ãã³ã°ã¸
âè¨è¨ï¼ä»æ§ï¼ã¨å®è£
è¨è¨ï¼ä»æ§ï¼ã¨å®è£ ã®é¢ä¿ã¯ããã¶ã次ã®ããã«æãããããã¨ãå¤ãã§ãããã
- ä»æ§ã¯ãèªç¶è¨èªãå³å¼ã使ã£ã¦æ¸ãããã
- ä»æ§ã¯ãï¼æéçã«ï¼å®è£ ã«å ã ã£ã¦ä½æãããã
ããã¯éãã¨æããã次ã®ããã«èãç´ãã¾ããã
- ä»æ§ã¯ããã種ã®ããã°ã©ãã³ã°è¨èªã§æ¸ãããï¼ã¹ãï¼ã
- ä»æ§ã¨å®è£ ã¯ãã©ã¡ããå ã¨ããããã§ããªããé©å½ã«æ··ããåã£ãé åºã§ä½æãããã
ä»æ§ã¯ããã°ã©ãã³ã°è¨èªã使ã£ã¦ä½æãããã®ã§ãããã¯ããã°ã©ã ã§ããããã¡ããï¼é©åãªå®è¡ç°å¢ã®ä¸ã§ï¼å®è¡å¯è½ï¼ã§ããã¹ãï¼ã§ãã
ä»æ§ãæ¸ããã¨ãããã°ã©ãã³ã°ãªã®ã§ããã®ä½æ¥è ãè¨è¨ããã°ã©ããå®è£ ãæ¸ãããã°ã©ãï¼å¾æ¥ã®æå³ã®ããã°ã©ãï¼ãå®è£ ããã°ã©ãã¨å¼ã³ã¾ãããã2種é¡ã®ããã°ã©ãã³ã°ä½æ¥ã2ã¤ã®å½¹å²ãããããã§ããï¼â»ãè¨è¨ãã¨ããè¨èã®ä½¿ãæ¹ãä¸é©åããç¥ããªããã©ãç®ãããç«ã¦ãªãã§ã¡ããã ããï¼
âè¨è¨ããã°ã©ãã³ã°
ä»æ§ãæ¸ããã¨ãã¤ã¾ãè¨è¨ããã°ã©ãã³ã°ã«ä½¿ãè¨èªã¯ãå½¢å¼ä»æ§è¨è¿°è¨èªã§ããVDM-SLãOBJ*ãªãã¦ãã£ã³ãããã®ããããã©ãããã§ã¯ã¤ã³ã¿ã¼ãã§ã¼ã¹ï¼ãã¼ã¢å¶ç´ã使ãã¾ãããï¼ãä»é¢¨ã®åçè«å ¥éãåç §ããã¼ã¢å¼ã«ã¯æ示çå«æã==>ããå ¥ãã¦ããï¼ã
次ã¯ãè¨è¨ããã°ã©ã ï¼å½¢å¼ä»æ§ã®ï¼æ¯åº¦ã決ã¾ãã®ï¼ä¾ã§ãã
spec IntStack {
interface {
new(); // ã³ã³ã¹ãã©ã¯ã¿ä»æ§ãè¨è¿°ã§ããã¨ãã// @Accessorã¯å¯ä½ç¨ããªããã¨ãæå³ãã
@Accessor
int top();
@Accessor;
boolean isEmpty();void push(int x);
void pop();
}// å¶ç´[1]ã«é¢ãã¦ã¯ãå¾ã«èª¬æãã
[1] forall(int x) (isEmpty()) ==> {push(x);} (!isEmpty());
[2] // ...
// ... 以ä¸çç¥
}
è¨è¨ããã°ã©ãã¯ããªãããã®æå³ãæ§æ³ãå¿ã«æã£ã¦ãã¾ãããã®æå³ï¼æ§æ³ãè¨è¨ããã°ã©ãã³ã°è¨èªï¼å½¢å¼ä»æ§è¨è¿°è¨èªã«ãã£ã¦æ¸ãä¸ãã¾ããããããè¨è¨ããã°ã©ãã³ã°ã®ä½æ¥ã§ããã
âæªéã®å®è£ ããã°ã©ã
ãã¦ãå®è£ è ã¨ãã¦æªéãç»å ´ããã¾ããããå½¼ã¯æªéãªã®ã§ãè¨è¨ããã°ã©ãã®æå³ï¼æ§æ³ã¯å®å ¨ã«ãè¦éãã§ããå½¼ã¯æªéãªã®ã§ãè¨è¨ããã°ã©ãã®æå³ï¼æ§æ³ãç¥ã£ãä¸ã§ãããã¨æå³ï¼æ§æ³ã¨éãå®è£ ããã¾ããä¾ãã°ãIntStackã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã ããæ示ããã段éã§ã¯æ¬¡ã®å®è£ ããã¾ãã
public class DemonicIntStackImpl_0 implements IntStack {
public DemonicIntStackImpl_0() {}public int top() {return 0;}
public boolean isEmpty() {return true;}public void push(int x){}
public void pop(){}
}
ãã ãããã®æªéã¯ãã£ããç´ ç´ãªå¥´ã§ãã¤ã³ã¿ã¼ãã§ã¼ã¹ãæ示ãããã°ããããimplementsããããï¼å½¢å¼çï¼å¶ç´ã課ããããã°ããããéµå®ãã¾ããã§ãæªéã§ãããããã¤ã³ã¿ã¼ãã§ã¼ã¹ãå¶ç´ã«è¨è¿°ããã¦ãªããã¨ã«é¢ãã¦ã¯ããã¨ãã¨ãè¨è¨ããã°ã©ãã®æã«åãããã¨ãããããã¾ãã
âæå°æªã ãç´ ç´ãªå¥´
ã¨ãããããforall(int x) (isEmpty()) ==> {push(x);} (!isEmpty());
ã¨ããå¶ç´ãèãã¦ã¿ãã¨ãããã¯ï¼
ãæå³ãã¾ãã
ã©ããªæ´æ°xã«å¯¾ãã¦ã
äºåã« isEmpty() ãªãã°
push(x); ãå®è¡ããã°
ãã®äºå¾ã¯ã!isEmpty() ã§ããã
ç´ ç´ãªæªéã¯å¶ç´ã«ã¯å¾ãã®ã§ãå®è£ ã次ã®ããã«å¤æ´ãã¾ãã
public class DemonicIntStackImpl_1 implements IntStack {
public DemonicIntStackImpl_1() {}public int top() {return 0;}
public boolean isEmpty() {return false;}public void push(int x){}
public void pop(){}
}
ããã§å¶ç´[1]ãæºè¶³ãããã£ã¦ï¼ å¶ç´[1]ã«ã¯ãäºåã« isEmpty() ãªãã°ãã¨ããæ¡ä»¶ãä»ãã¦ããã®ã§ããã®äºåæ¡ä»¶ãæç«ããªãã¨ãã¯ä½ãåãããªããã¤ã¾ãOKãªã®ã§ããisEmpty()ã¯å¸¸ã«falseãè¿ãã®ã§ãå¶ç´[1]ã¯å¸¸ã«æºè¶³ããã¾ãã
âæªéã追ãã¤ããæªãå°ãã®åªæ
ãããã¸ãã§ãè¨è¨ããã°ã©ããã¨ã¯ã½ã·ã¹ãï¼æªéæãã®ç¥ç¥·å¸«ï¼ã¨å¼ã³æ¿ãã¾ããå½¢å¼ä»æ§è¨è¿°ã®å¶ç´ã¯ãæªéãæªãããã®ãå°ããåªæãªã®ã§ããã©ãã©ãåªæãç©ã¿éãã¦ãæªéãæªããããä½å°ããªããã®ãã¨ã¯ã½ã·ã¹ãã®ä»äºã§ãã
次ã®åªæã追å ãã¾ãããã
[2] {new();} (isEmpty())
ããã§ãã³ã³ã¹ãã©ã¯ã¿ãæå³ããnewã ãã¯ç¹å¥æ±ãã§ãä½ããªãï¼å½è©²ãªãã¸ã§ã¯ããåå¨ããªãï¼ã¨ããã§å®è¡ããå®è¡å¾ã«ã§ãããªãã¸ã§ã¯ãã«å¯¾ãã¦äºå¾æ¡ä»¶ããã§ãã¯ãã¾ããã¨ãããããã¨ã常ã«falseãè¿ãisEmpty()ã¯å°ãããã¾ãã
念ã®ããè¨ã£ã¦ããã¨ã次ã®å®è£ ãæªéãæ¡ç¨ãããã¨ã¯ã§ãã¾ããã
public class DemonicIntStackImpl_2 implements IntStack {
private boolean justCreated;public DemonicIntStackImpl_2() {
justCreated = true;
}public int top() {return 0;}
public boolean isEmpty() {
if (justCreated) {
justCreated = false;
return true;
} else {
return false;
}
}public void push(int x){}
public void pop(){}
}
ãªããªããisEmpty()ã¯ã¢ã¯ã»ããµã ã¨æå®ããã¦ããã®ã§ãäºåº¦ç¶ãã¦å¼ã°ããã¨ãã«éãå¤ãè¿ããã¨ã¯ã§ããªãã®ã§ãã
æªéã¯ãããããã§ããï¼
public class DemonicIntStackImpl_3 implements IntStack {
private boolean empty;public DemonicIntStackImpl_3() {
empty = true;
}public int top() {return 0;}
public boolean isEmpty() {return empty;}public void push(int x){empty = false;}
public void pop(){}
}
âæ¦ãã¯ç¶ã
ã¨ã¯ã½ã·ã¹ãã¯æ¬¡ã®åªæãæå ¥ãã¾ãã
[3] forall(int x) {push(x);} (top() == x);
ããã§ãpushã®å¼æ°ãæ¨ã¦ãããã«ã¯ãããªããªãã¾ãããã¡ããæªéã¯ãpushã®å¼æ°ãä¿åããå¤æ°private int lastPushed;
ã§å¯¾å¿ãã¾ããã¨ã¯ã½ã·ã¹ãã¯è¿½ãæã¡ãããã¾ããã俺ã®ã¿ã¼ã³ãï¼
[4] forall(int y, x) (top() == x) ==> {push(y); pop();} (top() == x);
ãã¼ãããã¯å¹æçã ãã¼ãæªéãè¦ãããªã£ã¦ãããã¼ã
âã¨ã¯ã½ã·ã¹ãã²ã¼ã ãããã¥ã¢ã«ããã°ã©ãã³ã°ã¸
ã¨ãã¾ã¼ããããªæãã§é²ãã®ãã¨ã¯ã½ã·ã¹ãã²ã¼ã ã§ããã¨ã¯ã½ã·ã¹ãï¼è¨è¨ããã°ã©ãã¯ãæªããå°ããåªæï¼å½¢å¼ä»æ§è¨è¿°ãé§ä½¿ãã¦æªéã¨æ¦ãã¾ãã
ãã®æ¦ãã¯ãã¤ã¾ã§ç¶ãã®ã§ãããããã¨ã¹ã½ã·ã¹ãï¼è¨è¨ããã°ã©ãããèªåã®æå³ï¼æ§æ³ãä»æ§ï¼åªæã®ç©ã¿éãï¼ã¨ãã¦å®å ¨ã«è¡¨ç¾ãå°½ãããã¨æã£ãã¨ããããã¦æªéã®å®è£ ããã°ã©ãããã®ä»æ§ã«å¯¾ãã¦validã¨ãªãå®è£ ããã°ã©ã ãæ¸ããã¨ãããããæ¦ãã®çµããã§ãã
ããã§ãæªéã¨ã¨ã¯ã½ã·ã¹ãã¨ãã2ã¤ã®å½¹å²ãç»å ´ãã¦ãã¾ããã¾ããè¨è¨ããã°ã©ãã³ã°ã¨å®è£ ããã°ã©ãã³ã°ã¨ãã2種é¡ã®ããã°ã©ãã³ã°ãåºã¦ãã¦ã¾ããããããã対ç«ããããã§ç¸äºè£å®ããã2è ã«ã¡ãªãã§ãã¥ã¢ã«ããã°ã©ãã³ã°ã¨åä»ãã¾ããã
å®ã¯ããã¥ã¢ã«ã¨å¼ã¶çç±ã¯ããã²ã¨ã¤ãããä»æ§ã¨å®è£ ãå®éã«å対æ§ï¼duality;ããã¤ããã or ããããããï¼ãæã¡ãå対æ§ãæ¯ããæ§é ã確å®ã«åå¨ããããã§ãããã®æ§é ã«ãããè¨è¨ããã°ã©ã ã®âå®è¡âãå¯è½ã¨ãªãã¾ãããã®ã¸ãã®ããã·ã¯ãã¥ã¢ã«ããã°ã©ãã³ã°ã®ç¶ç·¨ã«ãã¾ããã¾ãããããã