ã°ãªã¼ã³ã¨ã¢ã«ãã³ãã«ãï¼Alexander S. Green, Thorsten Altenkirchï¼ã®ãå¯éè¨ç®ããä¸å¯éè¨ç®ã¸ï¼From reversible to irreversible computationï¼ãã¨ãã10ãã¼ã¸ã®çãè«æãããã¾ããã¿ã¤ãã«ã®ã¨ãããå¯éè¨ç®ããä¸å¯éè¨ç®ãåºãããã£ã¦ããã·ããã®è«æã®ç¼ç®ãªãã§ãããå¯éè¨ç®ã®é¨åï¼ååï¼ãé¢ç½ãã£ãã®ã§ç´¹ä»ãã¾ãã
ä½ãé¢ç½ããã¨ããã¨ãå¯éè¨ç®ã ã¨å¤å ¸è¨ç®ãéåè¨ç®ãå·®ããªãã®ã§ãããåãå®å¼åã許ãã¾ããå¤å ¸è¨ç®ã«ããã¦å¯éè¨ç®ã«æ £ãã¦ãããã¨ã¯éåè¨ç®ã¸ã®ããæºåã«ãªãã¨æãã¾ããã¨ãè¨ã£ã¦ããä»åã¯é£ãã話ã¯å ¨é¨ãã£é£ã°ãã¦ãJavaScriptã®é¢æ°ãããã¤ãæ¸ãã¦ã¿ãã ãã§ãããã
ãã®ã¨ã³ããªã¼ãæ¸ããã¨ãã¦JavaScriptã§ãã¹ãç¯ããé¡æ«ã¯ãJavaScriptã§ããã£ã件ï¼ãããã«JavaScriptã ãªãã¦ã ãã«æ¸ãã¦ããã¾ãã
å 容ï¼
- ç¨èªã¨è¨å·ã«é¢ãã注æ
- å¯éå¤å¤é¢æ°
- å¯éå¤å¤é¢æ°ã®ä¾
- å¯éå¤å¤é¢æ°ã®ç©ï¼ä¸¦åçµåï¼
- æ¡ä»¶åå² if-then-else
- ã¡ã¿è¨ç®æ³å
âç¨èªã¨è¨å·ã«é¢ãã注æ
ä»åã®æèã§ã¯ããè¨ç®ãã¨ãããã°ã©ã ãã¯å義èªã§ãããã¼ãã¦ã§ã¢å®è£ ãã¤ã¡ã¼ã¸ããã¨ããã³ã³ãã¥ã¼ã¿ãããåè·¯ï¼ãµã¼ãããï¼ãããã²ã¼ãããããè¨ç®ãã¨å義èªã§ãï¼äººã«ãã£ã¦ã¯ããã²ã¼ãããåè·¯ãçµã¿ç«ã¦ãåºæ¬é¨åã¨ããæå³ã§ä½¿ãã¾ããï¼ã
å¯éè¨ç®ï¼ï¼å¯éããã°ã©ã ï¼å¯éã³ã³ãã¥ã¼ã¿ï¼å¯éåè·¯ï¼å¯éã²ã¼ãï¼ã¨ã¯ãåºåããå ¥åãå®å ¨ã«åç¾ã§ããè¨ç®ã®ãã¨ã§ãã足ãç® x, y â x + y ã¯å¯éã§ã¯ããã¾ããã符å·å転 x â -x ã¯å¯éã§ãã
è¨ç®ï¼ããã°ã©ã ï¼ãçµã¿åãããæ¹æ³ãå¶å¾¡æ§é ã¨å¼ã³ã¾ããè¨ç®ãé¢æ°ã§è¡¨ç¾ããã¨ãå¶å¾¡æ§é ã¯é«éé¢æ°ã§è¡¨ç¾ã§ãã¾ãã次ã®è¡¨ã«ããã®ã¨ã³ããªã¼ã§æ±ãå¶å¾¡æ§é ãã¾ã¨ãã¾ãã
å¶å¾¡æ§é | ã°ãªã¼ã³ï¼ã¢ã«ãã³ãã«ãã®è¨å· | ããã§ä½¿ãè¨å· | JavaScripté¢æ° |
---|---|---|---|
é次å®è¡ | ç½ãå°ããªä¸¸ | ã»ãã³ãã³ã;ã | Comp(f, g) |
並åå®è¡ | ãã³ã½ã«ç©ï¼ç°ç©ï¼ | ã·ã£ã¼ãã#ã | Prod(f, g) |
æ¡ä»¶åå² | ç¸¦æ£ | ç¸¦æ£ | Cond(f, g) |
âå¯éå¤å¤é¢æ°
å¤å¤é¢æ°ãèãã¾ãããè¤æ°ã®å¤ãã¿ãã«ï¼JavaScriptã§ã¯é åï¼ã«ã¾ã¨ãã¦è¿ãã¨ããå®ç´ãªæ¹æ³ã§å®ç¾ãã¾ãã次ã¯å¤å¤é¢æ°ã®ä¾ã§ãã
function addsub(x, y) {
return [x + y, x - y];
}
js> addsub(2, 3)
5,-1
js>
ããã«ãå¼æ°ã®åæ°ã¨æ»ãå¤ã®åæ°ï¼ãã®å ´åã¯é åã®é·ãï¼ãåããããªé¢æ°ã ããèãã¾ããå¾ã§ä½¿ãé½åãããå¼æ°ã®åæ°ï¼æ»ãå¤ã®åæ°ã§ãããï¼ãé¢æ°ã®_arityã¨ããããããã£ã«è¨é²ãã¦ããã¾ãããï¼ã¢ã³ãã¹ã³ã¢ãªãã®arityã¨ããããããã£ã¯äºç´ããã¦ãã¾ãããèªç±ã«ä½¿ãã¾ããï¼ã
function addsub(x, y) {
return [x + y, x - y];
}
addsub._arity = 2;
ãã®ãããªé¢æ°ãæ±ãéãæ®éã®é¢æ°åæã§ã¯ä¸ä¾¿ãªã®ã§ã次ã®ãããªé«éé¢æ°Compãä½ã£ã¦ããã¾ãã
function err(message) {
alert(message);
throw new Error(message);
}function Comp(f, g) {
if (f._arity != g._arity) {
err("Comp: _arityãä¸è´ãã¦ãã¾ãã.");
}
var fun = function() {
var y = f.apply(null, arguments);
return g.apply(null, y);
};
fun._arity = f._arity;
return fun;
}
js> Comp(addsub, addsub)(2, 3)
4,6
js>
addsubã¯å¯éã§ããããã¯ã次ã®ãã¨ãæå³ãã¾ãã
- addsubInvã¨ããé¢æ°*1ããããComp(addsub, addsubInv) ã Comp(addsubInv, addsub) ãä½ãããªãé¢æ°ã¨ä¸è´ããã
addsubã®éã§ããaddsubInvã¯æ¬¡ã®ãããªé¢æ°ã§ãã
function addsubInv(s, t) {
return [(s + t)/2, (s - t)/2];
}
addsubInv._arity = 2;
å®é¨ï¼
js> Comp(addsub, addsubInv)(2, 3)
2,3
js> Comp(addsubInv, addsub)(2, 3)
2,3
js>
âå¯éå¤å¤é¢æ°ã®ä¾
å¯éå¤å¤é¢æ°ã®ä¾ãããã¤ãåºãã¾ãã
function id1(x) {
return [x];
}
id1._arity = 1;function id2(x, y) {
return [x, y];
}
id2._arity = 2;function swap(x, y) {
return [y, x];
}
swap._arity = 2;
JavaScriptã¯åãã«ã¼ãºã§ãããåãå³ããè¨èªã§ã¯ãä½ç¨®é¡ãã®id1ãä½ãå¿ è¦ãããã§ããããJavaScriptã§ããããã¦å¼æ°ããã¼ã«å¤ï¼booleanï¼ã«éå®ããé¢æ°ã2ã¤å®ç¾©ãã¦ããã¾ãã
function idb(b) {
if (typeof b != 'boolean') {
err("idb: å¼æ°ãbooleanã§ã¯ããã¾ãã.");
}
return [b];
}
idb._arity = 1;function not(b) {
if (typeof b != 'boolean') {
err("not: å¼æ°ãbooleanã§ã¯ããã¾ãã.");
}
return [!b];
}
not._arity = 1;
ããã§æããid1, id2, swap, idb, notã¯ããããå¯éã§ããããããã®éé¢æ°ãæ¢ãã¦ã¿ã¦ãã ããã
âå¯éå¤å¤é¢æ°ã®ç©ï¼ä¸¦åçµåï¼
Compã¯ç´åï¼é次ãã·ã¼ã±ã³ã·ã£ã«ï¼çµåã§ãããã並åãªçµåProdãå®ç¾©ãã¾ããProdã¯ç©ï¼productï¼ããã®å½åã§ãã
function toArray(x) {
var a = [];
for (var i = 0; i < x.length; i++) {
a.push(x[i]);
}
return a;
}function Prod(f, g) {
var fun = function() {
var args = toArray(arguments);
var x = f.apply(null, args.slice(0, f._arity));
var y = g.apply(null, args.slice(f._arity));
return Array.prototype.concat.call(x, y);
};
fun._arity = f._arity + g._arity;
return fun;
}
ãªããããããããã§ãããfãgã1å¤æ°ã®ã¨ããªããh = Prod(f, g) ã¨ããã¨ãh(x, y) = concat(f(x), f(y)) ã§ããProdã®å®ä¾ãè¦ã¦ã¿ã¾ãããã
s> Prod(swap, id1)(1, 2, 3)
2,1,3
js> Prod(id1, swap)(1, 2, 3)
1,3,2
js> Prod(swap, swap)(1, 2, 3, 4)
2,1,4,3
js> var h = Comp(Prod(swap, id1), Prod(id1, swap))
js> h(1, 2, 3)
2,3,1
js>
wap, id1 ãçµã¿åãããã¨ãå®ã¯ã¢ããã®å®é¨ãã§ãã¾ãã
âæ¡ä»¶åå² if-then-else
æ¡ä»¶åå²ãã¤ã¾ã if-then-elseæã«å¯¾å¿ããé«éé¢æ°Condã¯æ¬¡ã®ããã«ãªãã¾ãã
function Cond(f, g) {
if (f._arity != g._arity) {
err("Cond: _arityãä¸è´ãã¦ãã¾ãã.");
}
var fun = function(b) {
if (typeof b != 'boolean') {
err("a function made by Cond: 第1å¼æ°ãbooleanã§ã¯ããã¾ãã.");
}
var args = toArray(arguments);
args.shift();
var x;
if (b) {
x = f.apply(null, args);
} else {
x = g.apply(null, args);
}
return Array.prototype.concat.call([b], x);
};
fun._arity = 1 + f._arity;
return fun;
}
fãgã1å¤æ°ã®ã¨ããªããCond(f, g)(b, x) ã¯ãif (b) {return f(x);} else {return g(x);} ã¨ã»ã¼åãã§ããéãç¹ã¯ãbãæ»ãå¤ã«å«ã¾ãããã¨ã§ããæ¡ä»¶ã¨ãªããã¼ã«å¤bãä¸ç·ã«è¿ããã¨ã«ãããCond(b, f, g) ãåã³å¯éå¤å¤é¢æ°ã«ãªããã¨ãä¿è¨¼ãã¾ãã
âã¡ã¿è¨ç®æ³å
å¶å¾¡æ§é ã¯ãè¨ç®ï¼ããã°ã©ã ã«ããããæ¼ç®åã¨èãããã¾ãããã£ã¦ãå¶å¾¡æ§é ãå«ãããã°ã©ã ã®è°è«ã¯ãè¨ç®ã®è¨ç®ãã¤ã¾ãã¡ã¿è¨ç®ã¨ãªãã¾ããå¶å¾¡æ§é ãæ¼ç®åãããè¨å·ã§è¡¨ãã¦ãããã¤ãã®ã¡ã¿è¨ç®æ³åãæ¸ãä¸ãã¦ã¿ã¾ãããã
è¨æ³ï¼
- fã®éã¯f-1
- fã¨gã®é次çµå㯠f;g
- fã¨gã®ä¸¦åçµå㯠f#g
- fã¨gã®æ¡ä»¶åå²ã¯ (f|g)
ã¡ã¿è¨ç®æ³åï¼
- (f;g)-1 = g-1;f-1
- (f#g)-1 = f-1#g-1
- (f|g)-1 = f-1|g-1
- (idb#h);(f|g) = (h;f)|(h;g)
- (f|g);(idb#h) = (f;h)|(g;h)
- (f|g);(f'|g') = (f;f')|(g;g')
- (f|g)#h = (f#h)|(g#h)
- (h|h) = (idb#h)
- (f|g);(not#idA) = (not#idA);(g|f)
ãããã®æ³åã®å®ä¾ï¼æ³åãã®ãã®ã§ã¯ãªãï¼ã¯ãé«éé¢æ°Comp, prod, Condã使ã£ã¦ç¢ºèªã§ãã¾ããä¾ãã°ã4çªç®ã®æ³å㧠h = swap, f = id2, g = swap ã¨ãã¦ã¿ãã¨ã(idb#swap);(id1|swap) = (swap;id2)|(swap;swap) ã¨ãªãã¾ããï¼
js> var j = Comp(Prod(idb, swap), Cond(id2, swap));
js> var k = Cond(Comp(swap, id2), Comp(swap, swap));
js> j(true, 1, 2)
true,2,1
js> k(true, 1, 2)
true,2,1
js> j(false, 1, 2)
false,1,2
js> k(false, 1, 2)
false,1,2
js>