Friday, December 03, 2010

Church numerals in C#.


public static class Lambda
{
    public delegate Turtle Turtle(Turtle turtle);

    static Lambda()
    {
        ID = x => x;

        T = y => n => y;
        F = y => n => n;
        and = p => q => p(q)(F);
        or = p => q => p(T)(q);
        not = p => y => n => p(n)(y);
        xor = p => q => p(not(q))(q);

        zero = s => z => z;
        one = s => z => s(z);
        succ = n => s => z => s(n(s)(z));
        iszero = n => n(x => F)(T);

        add = m => n => m(succ)(n);
        mul = m => n => m(z => add(n)(z))(zero);
        pow = b => exp => exp(mul(b))(one);

        pred = n => s => z => n(u => v => v(u(s)))(T(z))(one);
        sub = m => n => n(pred)(m);

        min = m => n => sub(m)(sub(m)(n));
        max = m => n => add(n)(sub(m)(n));
        leq = m => n => iszero(sub(m)(n));
        lt = m => n => not(leq(n)(m));
        eq = m => n => and(leq(m)(n))(leq(n)(m));

        make_pair = x => y => f => f(x)(y);
        make_triple = x => y => z => f => f(x)(y)(z);

        div = m => n => ID(bb => build => m(build)(bb)
              (cur => go => sofar => sofar))
              (make_triple(m)(T)(zero))
              (t => t(cur => go => sofar => and(go)
              (leq(n)(cur))
              (make_triple(sub(cur)(n))(T)(succ(sofar)))
              (make_triple(cur)(F)(sofar))));
        mod = m => n => ID(bb => build => m(build)(bb)
             (cur => go => cur))(make_pair(m)(T))
             (p => p(cur => go => and(go)
             (leq(n)(cur))
             (make_pair(sub(cur)(n))(T))
             (make_pair(cur)(F))));
    }

    public static readonly Turtle ID;
    public static readonly Turtle T;
    public static readonly Turtle F;
    public static readonly Turtle and;
    public static readonly Turtle or;
    public static readonly Turtle not;
    public static readonly Turtle xor;
    public static readonly Turtle zero;
    public static readonly Turtle one;
    public static readonly Turtle succ;
    public static readonly Turtle iszero;
    public static readonly Turtle add;
    public static readonly Turtle mul;
    public static readonly Turtle pow;
    public static readonly Turtle factorial;
    public static readonly Turtle div;
    public static readonly Turtle mod;
    public static readonly Turtle pred;
    public static readonly Turtle sub;
    public static readonly Turtle min;
    public static readonly Turtle max;
    public static readonly Turtle leq;
    public static readonly Turtle lt;
    public static readonly Turtle eq;
    public static readonly Turtle make_pair;
    public static readonly Turtle make_triple;

    public static int ToInt(this Turtle turtle)
    {
        if (turtle.IsZero())
            return 0;

        return 1 + pred(turtle).ToInt();
    }

    public static Turtle ToTurtle(this int i)
    {
        if (i == 0)
            return zero;

        return succ((i - 1).ToTurtle());
    }

    public static bool IsZero(this Turtle turtle)
    {
        return iszero(turtle)(Lambda.T)(Lambda.F) == Lambda.T;
    }

    public static bool ToBool(this Turtle turtle)
    {
        return !turtle.IsZero();
    }
}

No comments: