Last active
August 29, 2015 14:14
-
-
Save tca/091a9764d5f652b6411f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Pair(car, cdr) { | |
this.car = car; | |
this.cdr = cdr; | |
} | |
function pairp(x) { return x instanceof Pair } | |
function cons(car,cdr) { return new Pair(car,cdr); } | |
function procedurep(x) { return x instanceof Function; } | |
function Var(c) { this.c = c } | |
function mkvar(c) { return new Var(c); } | |
function varp(x) { return (x instanceof Var); } | |
function vareq(x1, x2) { return x1.c == x2.c }; | |
function assp(pred, xs) { | |
while(true) { | |
if(xs == null) { | |
return false; | |
} else if (pred(xs.car)) { | |
return xs.car; | |
} else { | |
xs = xs.cdr; | |
} | |
} | |
} | |
function walk(u, s) { | |
var pr = varp(u) && assp(function(v) { return vareq(u, v); }, s); | |
return pr ? walk(pr.cdr, s) : u; | |
} | |
function ext_s(x, v, s) { | |
return cons(cons(x, v), s); | |
} | |
function eqeq(u, v) { | |
return function(s_c) { | |
var s = unify(u, v, s_c.car); | |
return s ? unit(cons(s, s_c.cdr)) : mzero; | |
} | |
} | |
function unit(s_c) { return cons(s_c, mzero); } | |
var mzero = null; | |
function unify(u, v, s) { | |
var u = walk(u, s); | |
var v = walk(v, s); | |
if (varp(u) && varp(v) && vareq) { return s; } | |
else if (varp(u)) { return ext_s(u, v, s); } | |
else if (varp(v)) { return ext_s(v, u ,s); } | |
else if (pairp(u) && pairp(v)) { | |
var s = unify(u.car, v.car, s); | |
return s && unify(u.cdr, v.cdr, s); | |
} else { | |
return (u == v) && s; | |
} | |
} | |
function call_fresh(f) { | |
return function(s_c) { | |
var c = s_c.cdr; | |
return f(mkvar(c))(cons(s_c.car, (c + 1))); | |
} | |
} | |
function disj(g1, g2) { | |
return function(s_c) { return mplus(g1(s_c), g2(s_c)); } | |
} | |
function conj(g1, g2) { | |
return function(s_c) { return bind(g1(s_c), g2); } | |
} | |
function mplus($1, $2) { | |
if ($1 == null) { | |
return $2; | |
} else if (procedurep($1)) { | |
return function() { return mplus($2, $1()); }; | |
} else { | |
return cons($1.car, mplus($1.cdr, $2)); | |
} | |
} | |
function bind($, g) { | |
if ($ == null) { | |
return mzero; | |
} else if (procedurep($)) { | |
return function() { return bind($(), g); }; | |
} else { | |
return mplus(g($.car), bind($.cdr, g)); | |
} | |
} | |
function pull($) { | |
return procedurep($) ? pull($()) : $; | |
} | |
function take(n, $) { | |
if (n <= 0) { | |
return null; | |
} else { | |
var $ = pull($); | |
return ($ == null) ? null : cons($.car, take(n - 1, $.cdr)); | |
} | |
} | |
function fives(x) { | |
return disj(eqeq(x, 5), | |
function(a_c) { | |
return function() { return fives(x)(a_c); } | |
}); | |
} | |
var empty_state = cons(null, 0); | |
var test1 = call_fresh(function (q) { return eqeq(q, 5); })(empty_state); | |
console.log(test1.car); | |
var test2 = call_fresh(fives)(empty_state); | |
console.log(take(5, test2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment