The following examples can be replicated by importing the provided logic example program.

>>> from logic import *
    

Both queries and facts are represented as Scheme lists in the logic language, using the same Pair class and nil object in the previous chapter. For example, the query expression (?x c ?x) is represented as nested Pair instances.

>>> read_line("(?x c ?x)")
    Pair('?x', Pair('c', Pair('?x', nil)))
    

As in the Scheme project, an environment that binds symbols to values is represented with an instance of the Frame class, which has an attribute called bindings.

The function that performs pattern matching in the logic language is called unify. It takes two inputs, e and f, as well as an environment env that records the bindings of variables to values.

>>> e = read_line("((a b) c (a b))")
    >>> f = read_line("(?x c ?x)")
    >>> env = Frame(None)
    >>> unify(e, f, env)
    True
    >>> env.bindings
    {'?x': Pair('a', Pair('b', nil))}
    >>> print(env.lookup('?x'))
    (a b)
    

Above, the return value of True from unify indicates that the pattern f was able to match the expression e. The result of unification is recorded in the binding in env of ?x to (a b).