Back to the FAQ /
Home

**
What features does lambda Prolog have?
**

### Polymorphic typing

lambda Prolog is a strongly typed language. Its typing was inspired
by that of ML, but in details it is quite different. Variables are
allowed in types, and this provides for generic polymorphism (as in,
say, ML) and certain forms of ad hoc polymorphism (types can have
significance at run-time).
All constants must be declared to be of a type, although various
implementations may try to help the programmer infer those types. The
Terzo system, for example, does not do type inference for constants
(only for variables): it seems not to be a burden for programmers to
explicitly type constants once per module. Such explicit declarations
are a useful part of the documentation of a module.

### Sound unification

Unification in lambda Prolog is sound: in particular, the occurs-check
is made on first-order terms. In the presence of higher-order
variables, the straightforward generalization for the occurs-check is
not complete. As a result, lambda Prolog implements something called
the ``rigid-path'' check: in the first-order case, this generalizes
the occurs-check. This check does not lose completeness.

### Implicational and universal quantified queries

Allowing implications and universal quantifiers in queries and the body of
clauses is the essential logical difference between lambda Prolog and
Prolog (apart from the orthogonal difference regarding quantification
at higher-order types). When Horn clauses are generalized to allow
such occurrences of these connectives, we have the class of formulas
known as ``hereditary Harrop formulas''. These two connectives allow
for hypothetical and generic queries, and they are responsible for
producing the dynamic behaviour of lambda Prolog's runtime that is
exploited for modular programming and abstract data types.
### Modular programming

lambda Prolog code is organized into modules. Modules can incorporate
other modules by accumulating or importing. The precise semantics of
these module constructs are given by the underlying logic. In
principle, these module directives can be removed so that a module
always denotes a (possibly large) formula of intuitionistic logic.
### Abstract data types

Using lambda Prolog's rich quantification, it is also possible to hide
constants within a module. The `local` directive is used for
this pursue. Such hiding can be used to support abstract data types.
### Higher-order programming

Quantification over some predicate variables is allowed in lambda
Prolog. Such quantification provides a simple and natural way to do
higher-order programming: predicate expressions can be built and
applied in much the same way that functional programming languages can
build and apply functions. Some examples are available.
### Simply-typed lambda-terms

The term structure of lambda Prolog is based on simply typed
lambda-terms and not on the simpler first-order terms. As a result,
lambda-abstractions can be used to represent bound variables in data
items, a common situation in the implementation of meta-programming
tasks, such as theorem provers, program transformers, and type
checkers/inferers.
### Unification of lambda-terms

Because lambda-terms are present, unification in lambda Prolog must
unify them. To do that, a form of depth-first search applied to
higher-order unification is implemented in a lambda Prolog
interpreter. Since higher-order unification is undecidable, such an
implementation is incomplete and simple example of unification can
easily lead to a loop in the interpreter. Even when unifiers exist
and can be found by the simple interpreter of the system, there may
not be a simple most general unifier. Thus, an interpreter will need
to backchain over choices of unifiers.
While these aspects of full higher-order unification are indeed
complex and questionable elements of the core of a programming
language, lots of experience with lambda Prolog code suggests that
problematic unification problems do not often happen. In particular,
a large percentage of unification programs generated by a wide range
of examples produce unification problems contained in the L-lambda
fragment of lambda Prolog: in this fragment, unification involves only
*higher-order patterns* and these problems have properties
similar to those of first-order unification. Furthermore,
higher-order unification can often be reduced to this fragment via the
introduction of some small logic programming to specify
substitutions.

Back to the FAQ /
Home