Predicate Algebra in Python

Date: November 9, 2009 Last modified: March 22, 2016

Updated for Python3 recently:

class Predicate:
    """
    Define predicate algebra.

    >>> isEven=Predicate(lambda x: x % 2 == 0)
    >>> isOdd=Predicate(lambda x: x % 2 == 1)
    >>> isEven(6)
    True
    >>> isOdd(6)
    False

    >>> isEmpty=Predicate(lambda s: s == "")
    >>> isNotEmpty=~isEmpty
    >>> isEmpty("c")
    False
    >>> isNotEmpty("")
    False
    >>> isNotEmpty("hello")
    True
    """
    def __init__(self, predicate):
        self.predicate = predicate

    def __or__(self, other):
        return Predicate(lambda x: self.predicate(x) or other(x))

    def __and__(self, other):
        return Predicate(lambda x: self.predicate(x) and other(x))

    def __xor__(self, other):
        return Predicate(lambda x: self.predicate(x) ^ other(x))

    def __invert__(self):
        return Predicate(lambda x: not self.predicate(x))

    def __call__(self, x):
        return self.predicate(x)

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Output from python PredicateAlgebra.py -v:

Trying:
    isEven=Predicate(lambda x: x % 2 == 0)
Expecting nothing
ok
Trying:
    isOdd=Predicate(lambda x: x % 2 == 1)
Expecting nothing
ok
Trying:
    isEven(6)
Expecting:
    True
ok
Trying:
    isOdd(6)
Expecting:
    False
ok
Trying:
    isEmpty=Predicate(lambda s: s == "")
Expecting nothing
ok
Trying:
    isNotEmpty=~isEmpty
Expecting nothing
ok
Trying:
    isEmpty("c")
Expecting:
    False
ok
Trying:
    isNotEmpty("")
Expecting:
    False
ok
Trying:
    isNotEmpty("hello")
Expecting:
    True
ok
7 items had no tests:
    __main__
    __main__.Predicate.__and__
    __main__.Predicate.__call__
    __main__.Predicate.__init__
    __main__.Predicate.__invert__
    __main__.Predicate.__or__
    __main__.Predicate.__xor__
1 items passed all tests:
   9 tests in __main__.Predicate
9 tests in 8 items.
9 passed and 0 failed.
Test passed.