Fall 98, CSE 520:
Lecture 10 (Sep 29)
First Order Unification
There are various algoriths to find the most general unifier for
a set of first order equations;
for instance, the algorithm of Martelli-Montanari
(see
[Apt_Pellegrini, Section 2]).
Proposition
The algorithm of Martelli-Montanari always terminates
and it gives a most general unifier
if the set of equations is solvable, failure otherwise.
Corollary Given a set of first order equations E,
it is decidable whether E is solvable or not, and, if it is
solvable, then it has a most general unifier (which is
unique modulo renaming).
Uses of unification in programming languages
- ML uses
- First order unification for type inference at compile time
(transparent to the user)
- Pattern matching (a sort of one-way unification) for
evaluating function calls
- Prolog uses first order unification for evaluating goals.
For efficiency reasons the occur-check is usually not implemented.
- Lambda Prolog uses Higher Order Unification (unification of Higher-Order
terms modulo alpha, beta and eta conversion) for evaluating goals.
This is a conservative extension of FO unification, in the sense that
if we give to lambda Prolog a FO equation, then we get
back the FO most general unifier.
Those who are interested
can find the algorithm for HO unification in
[G. Huet, A Unification Algorithm for Typed lambda-Calculus,
Theoretical Computer Science 1:27-57, 1973.]
Properties of the type system of Curry
From the properties of FO unification, we have that:
Proposition
For any term M, it is decidable whether M is typable or not,
and in case it is, then it has a principal type.
This proposition is very important
because it states that type inference/checking can be done
effectively and without risk of looping.
Another important property is the following, which states that
type inference/checking can be done once and for all at compile time,
in the sense that if a program typechecks correctly then there is
no risk of getting type errors at execution time.
Theorem (Subject reduction) If M : A and M ->> M' then M' : A.
Note that the converse (subject expansion) of this theorem does not
hold. Namely, there are terms M and M' such that
M ->> M' and M': A, but M is not typeable.
Take for instance M = (\y x. x) Y and M' = \x. x.
Note that the reason why subject expansion does not hold is
related to lazy evaluation.
The system of Church and the Simply Typed Lambda Calculus
The system of Church is very similar to the system of
Curry, the only difference is that each variable is explicitly
typed (in the term) at the moment in which it is introduced.
This philosophy (declare the type of every variable)
is adopted in several programming languages, for instance
C, C++, Java, Pascal, lambda Prolog, ...
On the contrary, ML adopts the more liberal approach of
the system of Curry.
The language of Simply Typed lambda terms is defined by the following
grammar:
Term ::= Var | \Var : Type . Term | Term
Type expressions are defined as usual:
Type ::= TVar | Type -> Type
The rules are identical to those of Curry,
the only difference is the abs rule, which
is forced to introduce the argument type specified in the
abstraction variable:
G , x : A |- M : B
(abs) -------------------------
G |- (\x:A. M) : A -> B
Properties of the Simply Typed Lambda Calculus
The important properties of the Lambda Calculus and of the
Curry system hold also for the Simply Typed Lambda Calculus
and the Church system. In particular the following properties hold:
- Church-Rosser
- Consistency (not all terms are convertible to each other)
- Decidability of typing
- Subject reduction
Furthermore, in this system the type of a term is unique:
Proposition
- If M : A and M : B in Church, then A and B are identical type expressions.
- If M and M' are convertible, and they are both typable in Church, then
they have the same type.
Relation between the systems of Curry and of Church
Let M be a simply-typed lambda term and let |M| denote the
lambda term obtained from M by removing the type decorations.
Then we have that M is Church-typeable if and only |M| is
Curry-typeable. More precisely:
Proposition
- If M : A in Church, then |M| : A in Curry
- If |M| : A in Curry, and A is its principal type, then
M : B in Church d for some instance B of A.
- If |M| : A in Curry, then there exists N such that
N : A in Church and |M|=|N|.
Note that, as a consequence of this proposition, we have
that a type is inhabited in Curry iff it is inhabited in Church.