Alloyã§ç´åãèãã
前回ã®è¨äºã«æªå±±ãããåå¿ãã¦ãã ããã¾ãã¦ãããã¬ã¹ã¤ãã«ããè¨äºã§ããã¾ããã
ãã£ãããªã®ã§ãæªå±±ããã®è¨äºãã¾ãã¾Alloyã«ç¿»è¨³ãã¦ã¿ããâ¦ã¨æã£ãã®ã§ãã*1ãå®ã¯å¤§ããªåé¡ããã£ã¦ã
Alloyã«ã¯ãç´åãç´æ¥æ±ãè¨èªè¦ç´ ããªããã§ããªã¼ã
ã¨ãããã¨ã§åæ¯ãã¨ãã¦ãAlloyã§ç´åãæ¸ãä¸ãã¦ã¿ã¦ãã©ããªããã£ã¦ã®ã観å¯ãã¦ã¿ã¾ãã
ä»å使ãAlloyã®è¨è¿°å ¨æã¯Gistã«è²¼ã£ãã®ã§ããããããã°ãã¡ããåç §ã®ãã¨ã
ãã¼ã¾ã
ãããªãã§ãããç´åããããã¾ããã©ã¼ãã
enum Tag { Fst, Snd } fun prod1(a, b: univ): Tag -> univ { Fst -> a + Snd -> b }
prod1ããé©å½ãªéåa, bãåãåã£ã¦ï¼univã¯ä½ã§ãã¢ãªãªåã§ããjava.lang.Objectã¿ãããªï¼ãaã¨bã®ç´åãè¿ãé¢æ°ãè¿ãå¤ã®å Tag -> univ ãç´ååã§ããè³å
ã§ãããã風ã«ãã£ã«ã¿ããã¦èªãã§ä¸ããã
ãã£ã¦ããã¨ã¯è¦ã¦ã®éããï¼çªãã»ï¼çªãï¼Fst, Sndï¼ã£ã¦ã¿ã°ãä»ããä¸ã§éååãåããã§ããã
prod ã£ã¦æ¸ãã¦ãã®ã¯ãä¸è¨ã®æªå±±ããã®è¨äºã«ãããï¼åè«çï¼ç´ç©ï¼ï¼åè«çï¼ç´åãã«å£ã£ã¦ãã®ã§ãããã§ã¯è¯ããã¼ãã³ã°ãããªãããã§ããã
試ãã«
run prod1
ã¨ãæã£ã¦evaluate ... ãã¦ã¿ã¦ãããã¸ã¥ã¢ã«çã«ã¯ããã¾ãé¢ç½ããªããã®ãåºã¾ããEvaluatorãã¿ã³ãæ¼ãã¦ãprod1ã«é©å½ãªå¼æ°æ¸¡ãã¦è©ä¾¡ãã¦ã¿ã¦ãã ããã
対è§ãä½å¯¾è§
ãã¦ãä»»æã®è¦ç´ ãç´åã«æã£ã¦ãã対è§Îã¯æ¬¡ã®ããã«æ¸ãã¾ãã
fun diag (a: univ): Tag -> univ { Fst -> a + Snd -> a }
diagãÎã«ç¸å½ããé¢æ°ã§ããFstã¿ã°ãSndã¿ã°ã«åãè¦ç´ ãå ¥ããç´åãè¿ãã¾ãã
ä¸æ¹ãç´åããè¦ç´ ã«æ½°ãä½å¯¾è§âã¯
fun codiag (a: Tag -> univ): univ { { b: univ | b in Fst.a or b in Snd.a } }
ã¨ãæ¸ãã¾ããç´åã®Fstã¿ã°å´ãSndã¿ã°å´ããã©ã¡ããã«ããè¦ç´ ã®éåãã§ãã
â¦ã§ããããããã£ã¨ç°¡åã«ããã¦ã
fun codiag (a: Tag -> univ): univ { Tag.a }
ã§ããã¤ãã¦ãã¿ã°ãå¿ããæä½ã
ããã¦ã対è§ã¨ä½å¯¾è§ãåæããã¨ãidã¨åãã«ãªãã¾ãã
ããã¯ä»¥ä¸ã®ã¢ãµã¼ã·ã§ã³ã§åä¾ãåºãªããã¨ããããã£ã¦ããã ãããã¨ã
cmp_id: check { all x: univ | x.diag.codiag = x }
åä½å
ãã¦ããã§ãç´åæä½ã®åä½å
ã«ã¤ãã¦èãã¦ã¿ã¾ããããã¯ã空éåï¼Alloyã§ãã noneï¼ã§ãããã¾ããæªå±±ããã®è¨äºã«ãã£ããé¶å¯¾è±¡ãããã«å½ããã¾ãã
noneã¨ã®ç´ååã£ããã®ã¯å
ã®è¦ç´ ã¨ååã§ãã
ããã¯ãnoneã¨ã®ç´ååã£ã¦ãã¿ã°å¿ãããå
ã«æ»ããã¨ããæå³ã®ä»¥ä¸ã®ã¢ãµã¼ã·ã§ã³ã§åä¾ãåºãªããã¨ãã確ããããã¾ãã
zero_is_unit1: check { all x: univ { prod1 [x, none].codiag = x prod1 [none, x].codiag = x } }
ï¼é é¢ä¿ã«æ¡å¼µ
ãã¦ãã¦ãéåï¼ï¼åé
é¢ä¿ï¼ã¢ãªãã£ï¼ã®é¢ä¿ï¼ã«ã¤ãã¦ãç´åãèãããã¨ãã§ãã¾ããã
次ã¯ãï¼é
é¢ä¿ï¼ã¢ãªãã£ï¼ã®é¢ä¿ã®ç´åã«ã¤ãã¦ãã¾ããã¡ãã¡ãããã¾ãã
fun prod2 (f, g: univ -> univ): Tag -> (univ -> univ) { Fst -> f + Snd -> g }
prod1 ã¨ã¾ã£ããçå±ã¯åãã§ãã
ããã¦ï¼é
é¢ä¿ãèããããã«ã¯ãä»ã®ãã®ã¨ã®çµåãèããããªãã¾ããããªãã¾ãããï¼ãªãã§ããï¼
ã¨ãããã¨ã§ãçµåãä½ãã¾ããï¼è¨èªè¦ç´ ã«ãªãã£ã¦ããã©ããããã¼ï¼
fun join2 (x: Tag -> univ, r: Tag -> (univ -> univ)): Tag -> univ { Fst -> (Fst.x.(Fst.r)) + Snd -> (Snd.x.(Snd.r)) }
ãããã¾ãã§ãããããFstã¿ã°ä»ãã¯Fstã¿ã°ä»ãå士ãSndã¿ã°ä»ãã¯Sndã¿ã°ä»ãå士ã§çµåãã¦ãæ¹ãã¦ã¿ã°ãä»ãç´ãã¦ããã¾ãã
ç´æçã«ã¯ x.r ã£ã¦æä½ããããã訳ãªãã§ãããç´æ¥ã¯ä¸æããããªãã®ã§ããã®é¢æ°ã§çµåã®ãããã代ç¨ãããã¨ããè
¹ã§ãã
ã§ããããã¦ããã¨ãå ã®æªå±±ããã®è¨äºã«ãã£ã足ãç®ã®å®ç¾©
Î;(fÃg);â
ã£ã¦ã®ãæ¸ããããã«ãªãã¾ãããããªâæãã
fun sum2 (f, g: univ -> univ): univ -> univ { { x, y: univ | y in x.diag.join2 [ prod2 [f, g] ].codiag } }
diagãÎãprod2[f,g] ã fÃgãcodiagãâã
é©å½ãªxã«å¯¾ã㦠y â x;Î;(fÃg);â ã¨ãªããããªyãéãã¦ãã㢠(x, y) ã®éåãä½ã£ã¦ããããã§ãã2é
é¢ä¿ã¯ãã¢ã®éåã§ã§ãã¦ãã¾ãããã£ã¦ããã¯ãéã« Î;(fÃg);â ãæãç«ã¤ãããª2é
é¢ä¿ãä½ã£ã¦ããããã§ãã
ããã run sum2 ã¨ããã£ã¦ãEvaluatorã§éãã§ã¿ã¦ãã ãããªã
ããããã§ããã
Alloyã§ã¯ãï¼é
é¢ä¿å士ã®è¶³ãç®ã¯ç´æ¥æ¸ãã¦
f+g
ãªãã§ããªã¼ã
ã¨ãããã¨ã§ããã®ï¼ç¨®é¡ã®è¶³ãç®ãåããã®ãã£ã¦ããã以ä¸ã®æ§ãªã¢ãµã¼ã·ã§ã³ãæ¸ãã¦ã¿ã¾ããåä¾ã§ãªãã¯ãã§ãã
sum_equiv: check { all f, g: univ -> univ | sum2 [f, g] = (f + g) }
çµè«
以ä¸ãåããã©ããªãã¾ãããã
Alloyã«ã¯è¡¨é¢ä¸ããªããã£ãã«åå¨ããªãç´åã§ãããè£å´ã«æé»çã«åå¨ãã¦ã¦ãç«æ´¾ã«è¶³ãç®ãæç«ããããã¨ãã§ãã¦ããã®ã§ãã
ã¨ãããã¨ã§ãæéããã£ãããã®çµæã使ã£ã¦ãAlloyã§æªå±±ããã®è¨äºãæ¸ãç´ã試ã¿ããã£ã¦ã¿ã¾ããæéãããã°ã
*1:å®ã¯ååãåããããªãã¨ãèãã¦éä¸ã§ãã¿ããã®ã§ããã