Lambda Calculus via C# (12) Church Numeral Comparison Operators

[LINQ via C# series]

[Lambda Calculus via C# series]

Latest version: https://weblogs.asp.net/dixin/lambda-calculus-via-csharp-3-numeral-arithmetic-and-predicate

Church Numeral Comparison Operators

With the predicates defined in previous part, operators can be defined in  _Numeral class. Once again, class does not exist in lambda calculus, but C# class provides a place to define operators, which greatly improve the readability.

public partial class _Numeral
{
    public static Boolean operator <=
        (_Numeral a, _Numeral b) => a.IsLessOrEqual(b);

    public static Boolean operator >=
        (_Numeral a, _Numeral b) => a.IsGreaterOrEqual(b);

    public static Boolean operator <
        (_Numeral a, _Numeral b) => a.IsLess(b);

    public static Boolean operator >
        (_Numeral a, _Numeral b) => a.IsGreater(b);

    public static Boolean operator ==
        (_Numeral a, _Numeral b) => a.AreEqual(b);

    public static Boolean operator !=
        (_Numeral a, _Numeral b) => a.AreNotEqual(b);
}

C# object equality

This has nothing to do with lambda calculus and Church encoding. In C#, since == and != are customized, Object.Equals and Object.GetHashCode are required to be overridden too:

public partial class _Numeral
{
    public override int GetHashCode
        () => this._Unchurch().GetHashCode();

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }

        _Numeral numeral = obj as _Numeral;
        if ((object)numeral == null)
        {
            return false;
        }

        return this.AreEqual(numeral)._Unchurch();
    }
}

These code are all C# specific requirement:

  • GetHashCode just returns current Church Numeral’s corresponding System.UInt32’s hash code
  • Equals just applies the AreEqual predicate, and coverts the returned Church Boolean into System.Boolean.

Unit tests

In the same (tedious) way as arithmetic operators:

[TestClass()]
public class ChurchPredicatesTests
{
    private static readonly _Numeral Zero = _Numeral.Zero;

    [TestMethod()]
    public void IsZeroTest()
    {
        Assert.AreEqual(0U == 0U, Zero.IsZero()._Unchurch());
        Assert.AreEqual(1U == 0U, 1U._Church().IsZero()._Unchurch());
        Assert.AreEqual(2U == 0U, 2U._Church().IsZero()._Unchurch());
        Assert.AreEqual(123U == 0U, 123U._Church().IsZero()._Unchurch());
    }

    [TestMethod()]
    public void IsLessOrEqualTest()
    {
        Assert.AreEqual(0U <= 0U, (Zero <= Zero)._Unchurch());
        Assert.AreEqual(1U <= 0U, (1U._Church() <= Zero)._Unchurch());
        Assert.AreEqual(2U <= 0U, (2U._Church() <= Zero)._Unchurch());
        Assert.AreEqual(123U <= 0U, (123U._Church() <= Zero)._Unchurch());
        Assert.AreEqual(0U <= 2U, (Zero <= 2U._Church())._Unchurch());
        Assert.AreEqual(1U <= 2U, (1U._Church() <= 2U._Church())._Unchurch());
        Assert.AreEqual(2U <= 2U, (2U._Church() <= 2U._Church())._Unchurch());
        Assert.AreEqual(123U <= 2U, (123U._Church() <= 2U._Church())._Unchurch());
        Assert.AreEqual(0U <= 124U, (Zero <= 124U._Church())._Unchurch());
        Assert.AreEqual(1U <= 124U, (1U._Church() <= 124U._Church())._Unchurch());
        Assert.AreEqual(2U <= 124U, (2U._Church() <= 124U._Church())._Unchurch());
        Assert.AreEqual(123U <= 124U, (123U._Church() <= 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsGreaterOrEqualTest()
    {
        Assert.AreEqual(0U >= 0U, (Zero >= Zero)._Unchurch());
        Assert.AreEqual(1U >= 0U, (1U._Church() >= Zero)._Unchurch());
        Assert.AreEqual(2U >= 0U, (2U._Church() >= Zero)._Unchurch());
        Assert.AreEqual(123U >= 0U, (123U._Church() >= Zero)._Unchurch());
        Assert.AreEqual(0U >= 2U, (Zero >= 2U._Church())._Unchurch());
        Assert.AreEqual(1U >= 2U, (1U._Church() >= 2U._Church())._Unchurch());
        Assert.AreEqual(2U >= 2U, (2U._Church() >= 2U._Church())._Unchurch());
        Assert.AreEqual(123U >= 2U, (123U._Church() >= 2U._Church())._Unchurch());
        Assert.AreEqual(0U >= 124U, (Zero >= 124U._Church())._Unchurch());
        Assert.AreEqual(1U >= 124U, (1U._Church() >= 124U._Church())._Unchurch());
        Assert.AreEqual(2U >= 124U, (2U._Church() >= 124U._Church())._Unchurch());
        Assert.AreEqual(123U >= 124U, (123U._Church() >= 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsLessTest()
    {
        Assert.AreEqual(0U < 0U, (Zero < Zero)._Unchurch());
        Assert.AreEqual(1U < 0U, (1U._Church() < Zero)._Unchurch());
        Assert.AreEqual(2U < 0U, (2U._Church() < Zero)._Unchurch());
        Assert.AreEqual(123U < 0U, (123U._Church() < Zero)._Unchurch());
        Assert.AreEqual(0U < 2U, (Zero < 2U._Church())._Unchurch());
        Assert.AreEqual(1U < 2U, (1U._Church() < 2U._Church())._Unchurch());
        Assert.AreEqual(2U < 2U, (2U._Church() < 2U._Church())._Unchurch());
        Assert.AreEqual(123U < 2U, (123U._Church() < 2U._Church())._Unchurch());
        Assert.AreEqual(0U < 124U, (Zero < 124U._Church())._Unchurch());
        Assert.AreEqual(1U < 124U, (1U._Church() < 124U._Church())._Unchurch());
        Assert.AreEqual(2U < 124U, (2U._Church() < 124U._Church())._Unchurch());
        Assert.AreEqual(123U < 124U, (123U._Church() < 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsGreaterTest()
    {
        Assert.AreEqual(0U > 0U, (Zero > Zero)._Unchurch());
        Assert.AreEqual(1U > 0U, (1U._Church() > Zero)._Unchurch());
        Assert.AreEqual(2U > 0U, (2U._Church() > Zero)._Unchurch());
        Assert.AreEqual(123U > 0U, (123U._Church() > Zero)._Unchurch());
        Assert.AreEqual(0U > 2U, (Zero > 2U._Church())._Unchurch());
        Assert.AreEqual(1U > 2U, (1U._Church() > 2U._Church())._Unchurch());
        Assert.AreEqual(2U > 2U, (2U._Church() > 2U._Church())._Unchurch());
        Assert.AreEqual(123U > 2U, (123U._Church() > 2U._Church())._Unchurch());
        Assert.AreEqual(0U > 124U, (Zero > 124U._Church())._Unchurch());
        Assert.AreEqual(1U > 124U, (1U._Church() > 124U._Church())._Unchurch());
        Assert.AreEqual(2U > 124U, (2U._Church() > 124U._Church())._Unchurch());
        Assert.AreEqual(123U > 124U, (123U._Church() > 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsEqualTest()
    {
        Assert.AreEqual(0U == 0U, (Zero == Zero)._Unchurch());
        Assert.AreEqual(1U == 0U, (1U._Church() == Zero)._Unchurch());
        Assert.AreEqual(2U == 0U, (2U._Church() == Zero)._Unchurch());
        Assert.AreEqual(123U == 0U, (123U._Church() == Zero)._Unchurch());
        Assert.AreEqual(0U == 2U, (Zero == 2U._Church())._Unchurch());
        Assert.AreEqual(1U == 2U, (1U._Church() == 2U._Church())._Unchurch());
        Assert.AreEqual(2U == 2U, (2U._Church() == 2U._Church())._Unchurch());
        Assert.AreEqual(123U == 2U, (123U._Church() == 2U._Church())._Unchurch());
        Assert.AreEqual(0U == 124U, (Zero == 124U._Church())._Unchurch());
        Assert.AreEqual(1U == 124U, (1U._Church() == 124U._Church())._Unchurch());
        Assert.AreEqual(2U == 124U, (2U._Church() == 124U._Church())._Unchurch());
        Assert.AreEqual(123U == 124U, (123U._Church() == 124U._Church())._Unchurch());
    }

    [TestMethod()]
    public void IsNotEqualTest()
    {
        Assert.AreEqual(0U != 0U, (Zero != Zero)._Unchurch());
        Assert.AreEqual(1U != 0U, (1U._Church() != Zero)._Unchurch());
        Assert.AreEqual(2U != 0U, (2U._Church() != Zero)._Unchurch());
        Assert.AreEqual(123U != 0U, (123U._Church() != Zero)._Unchurch());
        Assert.AreEqual(0U != 2U, (Zero != 2U._Church())._Unchurch());
        Assert.AreEqual(1U != 2U, (1U._Church() != 2U._Church())._Unchurch());
        Assert.AreEqual(2U != 2U, (2U._Church() != 2U._Church())._Unchurch());
        Assert.AreEqual(123U != 2U, (123U._Church() != 2U._Church())._Unchurch());
        Assert.AreEqual(0U != 124U, (Zero != 124U._Church())._Unchurch());
        Assert.AreEqual(1U != 124U, (1U._Church() != 124U._Church())._Unchurch());
        Assert.AreEqual(2U != 124U, (2U._Church() != 124U._Church())._Unchurch());
        Assert.AreEqual(123U != 124U, (123U._Church() != 124U._Church())._Unchurch());
    }
}

1 Comment

Add a Comment

As it will appear on the website

Not displayed

Your website