Chapter 3

Logic Programming with Type Specifications

by Michael Hanus^{1}

In Types in Logic Programming (F. Pfenning, ed.), pp. 91–140, MIT Press, 1992

In this chapter, we propose a framework for logic programming with different type systems. In this framework a typed logic program consists of a type specification and a Horn clause program which is well-typed with respect to the type specification. The type specification defines all types which can be used in the logic program. Relations between types are expressed by equations on the level of types. This permits the specification of many-sorted, order-sorted, polymorphic and polymorphically order-sorted type systems.

We present the declarative semantics of our framework and two proof procedures (deduction and resolution) for typed logic programs. An interesting application is a type system that combines parametric polymorphism with order-sorted typing and permits higher-order logic programming. Moreover, our framework sheds some new light on the rôle of types in logic programming.

3.1 Overview and Examples

2 CHAPTER 3. LOGIC PROGRAMMING WITH TYPE SPECIFICATIONS

The absence of types in logic programming languages is a disadvantage for the development of large software systems. It have been also argued that logic programs often make implicit assumptions about types and a logic program only satisfies the intended meaning if type information is added to the program [Nai87]. Therefore much research has been carried out in order to integrate types into logic programming languages. The proposed integrations can be classified into two groups: inference-based and declaration-based approaches.

1An extended abstract of a previous version of this chapter has appeared in the Proceedings of the Second International Conference on Algebraic and Logic Programming, Nancy, France, October 1990, Springer Lecture Notes in Computer Science 463, 1990.

The inference-based approaches try to compute a superset of the success set of the program. If this superset is empty (for some goal), then the goal cannot succeed which is usually a hint for a type error in the program. Examples for inferencebased approaches can be found in [Mis84] [Zob87] [XW88b] [BG89] (among others). The computation of the superset of the success set is guided by term patterns representing sets of terms. The term patterns are considered as types, i.e., types are interpreted as sets of (ground) terms. The advantage of the inference-based approach is simplicity for the programmer since he need not declare any types: The type inference system deduces type information from an untyped logic program. This information can be used by the compiler to perform optimizations in the target program [GZ86].

But there are several problems with the inference-based approach: First, the semantics of types is only based on Herbrand interpretations, i.e., types are viewed as sets of ground terms. But Herbrand models are not sufficient for characterizing the declarative semantics of a logic program (e.g., if a and b are the only ground terms in a program and the program consists of the facts p(a) and p(b), then ∀X p(X) is true in all Herbrand models but not a logical consequence of the program [Llo87]). In order to give types a declarative semantics, types must have a meaning in all interpretations and not only in Herbrand interpretations, similarly to function and predicate symbols. Therefore Barbuti and Giacobazzi [BG89] use term interpretations with variables as the semantic foundation of their type inference system.

The main problem of inference-based approaches is that the inference of types from a completely untyped program yields only in a few cases the types expected by the programmer. For instance, assume list denotes the set of all terms of the form [] or [E|L] where L is a term from list. Then the inferred type for the predicate append defined by

      append([],L,L) ←
      append([E|R],L,[E|RL]) ← append(R,L,RL)

may be “list × α × α ∪ list × β × list” [XW88a], where α and β denote arbitrary types. But the type expected by the programmer is “list×list×list” since append should be only used to concatenate lists. The problem in this example is the first clause which defines append to be true not only for lists but also for other terms. E.g., append([],2,2) is true but usually considered as an ill-typed goal. In order to obtain the expected type “list × list × list”, append must be defined by

      append([],[],[]) ←

      append([],[E|R],[E|R]) ← append([],R,R)
      append([E|R],L,[E|RL]) ← append(R,L,RL)

(the exact definition depends on the type inference system).

Another problem of inference-based approaches is the strong dependence from the syntactic form of the clauses: A type inference system may deduce different types for two declaratively equivalent programs if the clauses are syntactically different. For instance, assume the type system allows polymorphic data structures [XW88b] and list(α) denotes the set of all terms of the form [] or [E|L] where E and L are terms from α and list(α), respectively, and α is an arbitrary type. Then the type inferred for the predicate member defined by

      member(E,[E|L]) ←
      member(E,[F|L]) ← member(E,L)

is “α × list(α)”, i.e., member can be used on lists of arbitrary types. The literal member(2,[1,2,3]) is a logical consequence of the clauses for member (we assume that the natural numbers are always contained in our programs). Hence we can add this literal as a new fact and obtain the declaratively equivalent program

      member(2,[1,2,3]) ←
      member(E,[E|L]) ←
      member(E,[F|L]) ← member(E,L)

The type inferred by an ML-based inference system [DM82] is “nat × list(nat)” since almost all polymorphic type systems for logic programming require that the left-hand sides of all clauses for a predicate must have equivalent types [MO84]

[DH88] [Smo89].

These examples show that in many cases the inference of types from a completely untyped program does not yield sufficient results since an untyped logic program does not contain the type information which has the programmer in mind (see also [Nai87]). A type system should allow user declarations for types. These declarations are not a burden on the programmer but documents the expected meaning of predicates and improves the readability of large programs. Another advantage of extending logic programs by type declarations is the possibility to give types a true declarative meaning, i.e., types can be interpreted as subsets of the carrier sets in all interpretations. This will be done in our approach.

The important question which has to be answered by a declaration-based type system is: Which kind of type structures can be specified? Several answers have been given in the literature: The type system of Turbo-Prolog is comparable to many-sorted Horn logic [Pad88] and many-sorted logic programs can be executed with the same efficiency as untyped logic programs, but this type system is too restricted for a lot of applications [Han87]. A more flexible type system motivated from ML was proposed by Mycroft and O’Keefe [MO84]. It offers parametric polymorphism [DM82], needs no type-checking at run time and enables the writing of compact and reusable programs. The restrictions of Mycroft/O’Keefe’s type system have been dropped in [Han89a]: The result is a type system which allows the application of higher-order programming techniques. In general it is necessary to consider the types at run time, but it has been shown that for Prolog-like applications of higher-order programming all type information can be omitted at run time [Han89b]. This type system can also be applied to a language that combines functional and logic programming [Han90]. Another direction for typing logic programs are order-sorted type systems where different types may be related by an inclusion relation [SNGM89]. Such inclusion relations occur in Prolog (for instance, the set of all constants is the union of the set of numbers and the set of atoms) and therefore a lot of inference-based type systems offer inclusion polymorphism ([Mis84]

[Zob87] [XW88b] among others). In order-sorted logic programming [HV87] types are present at run time, but the type information can be used to avoid unnecessary computations and reduce the search space [SS85] [HV87]. Smolka [Smo89] has proposed the combination of parametric polymorphism and order-sorted typing for a logic programming language. There are several restrictions in his type system so that higher-order programming techniques cannot be used. One particular instance of the framework proposed in this chapter is a type system that combines parametric polymorphism with order-sorted typing and allows the application of higher-order logic programming techniques.

Type systems with parametric polymorphism have been extensively studied in the context of functional programming languages [DM82] [CW85]. Therefore several proposals for polymorphic type systems for logic programming are based on these ideas [MO84] [DH88] [Smo89]. But we think that logic programming languages need other type systems than functional programming languages because:

1. The data flow is not fixed in logic programs since there are no “input” and “output” parameters in contrast to functional programs.

2. In functional languages a unary function f is defined by an equation of the form

       f(A) = E

(multiple equations for different argument patterns can be seen as syntactic sugar). There is no doubt about the type of f: The argument type is the most general type of A and the result type is the most general type of E. But in logic languages the semantics of a predicate is defined by several independent clauses that should be satisfied by any model for the predicate, i.e., a logic program is a specification of the predicate’s properties. If a unary predicate p is defined by n clauses which characterizes different properties of p, i.e., p(A_{1}) ← ⋯

⋯

p(A_{n}) ← ⋯

then the type of p is unclear if the arguments A_{1}, …, A_{n} have different types. Since the type system in [MO84] is influenced from the ML system, Mycroft and O’Keefe require the argument types in different clause heads to be equivalent (equal up to type variable renaming). But this restriction prevents a useful logic programming technique: Optimization of the resolution process by lemma generation. In untyped logic programming it is possible to add a new fact L to a program without changing the program semantics if L is a logical consequence of the program. The new fact L can be used to obtain shorter proofs for subsequent goals that include L. For instance, the literal append([1,2],[3,4],[1,2,3,4]) is a logical consequence of the program

       append([],L,L) ←
       append([E|R],L,[E|RL]) ← append(R,L,RL)

and therefore it may be added at the beginning of the program. If append has type “list(α), list(α), list(α)”, then the new fact is ill-typed w.r.t. Mycroft/O’Keefe’s type system. From a declarative point of view there is no reason to forbid such specialized clauses. Therefore our language allows such clauses since any instance of the declared predicate type is allowed in the left-hand side of the clause.

Summarizing our discussion of various type systems for logic programming we think that declaration-based type systems are adequate for logic programming because in these type systems the types of functions and predicates are independent of the syntactic form of the clauses and it is possible to give types a pure declarative meaning. Since typing all variables, functions and predicates in a logic program can be tedious, it should be allowed to omit some of the type declarations in the program, but such a program is viewed as a short-hand for a fully typed program. This point of view simplifies the semantics of the language since only well-typed expressions must have a meaning (see [MH88] for a more detailed discussion in the context of ML). In some cases a type inference procedure can be used to insert the omitted type declarations (the existence of such inference procedures depends on the restrictions of the type system). For instance, in ML [HMM86] the programmer has to declare the argument and result types of data type constructors. The types of all variables and functions in an ML program are inferred by a type inference procedure [DM82].

A further requirement to a type system for logic programming is flexibility: In logic programming it is possible to define one predicate which can be applied to arguments of different types (e.g., append can be applied to lists where the elements have an arbitrary type). Therefore a type system should support some sort of polymorphism, i.e., a predicate may have several types. Furthermore, the type system should also support logic programming techniques like lemma generation and the use of higher-order predicates.

This chapter proposes a framework for such flexible type systems. We present a general mechanism for the specification of type systems where particular instances of this framework are order-sorted, polymorphic or polymorphically order-sorted type systems. Our proposal generalizes previous approaches since it allows the application of typical logic programming techniques, i.e., it is influenced but more general than type systems for functional languages. Since all predicates, functions, variables and clauses are explicitly typed in our approach, the well-typedness of a program is decidable. For practical applications it should be allowed to omit some of the type declarations in the program which should be automatically inserted by a type inference procedure. But such procedures are only known for particular instances of our general framework. The development of more powerful type inference procedures and necessary restrictions to the programs is a topic for further research.

The general idea of our framework is to divide typed logic programs into two parts: a specification of the type structure and a well-typed logic program. Since the second part depends on the first part, we may view it as a two-level approach. In the context of algebraic specifications, Poigné [Poi86] has proposed a two-level approach for algebraic specifications with higher-types. Each level consists of an equational specification where the first-level describes a type structure and the second level is an equational specification with sort expressions from the first level. While he has used the approach for the specification of the typed λ-calculus, we will use a similar approach for our framework for typed logic programming. In our two-level approach the first level consists of a specification of a type structure for the logic program and contains all types which will be used inside the logic program and some relations between types specified by equational axioms. Hence the first level is a many-sorted equational specification [EM85] and we can use results from this area for our purposes. The second level is based on the specified type structure and consists of a specification of the types of all variables, constants, functions, and predicates occurring in the logic program and a set of Horn clauses which must be well-typed with respect to the type specification. The operational semantics, which is resolution with a unification procedure on well-typed terms, ensures that type errors do not occur while executing well-typed programs. We give some examples to show the basic ideas.

Example 3.1 Parametric polymorphism is used for defining universal data structures which can be applied to different concrete types. A classical example are polymorphic lists which can be applied to integers giving lists of integers, to Booleans giving lists of Booleans, etc. The following signature specifies a type structure for a program which uses the basic types of integers and Booleans and the polymorphic types of lists and pairs of elements:

TYPEOPS int:  → type
bool:  → type
list: type  → type
pair: type, type → type

This type structure has only a single sort type. Hence all types can be used as arguments for the polymorphic type constructors list and pair. The set of all types specified by this signature is the set of all well-formed terms which may contain some type variables. For instance, types w.r.t. the above specification are

int  bool  list(int)  list(α)  pair(bool, β)  pair(α, list(α))  ⋯

where α and β are type variables. A typed logic program consists of type declarations for variables, functions and predicates (constants are functions without arguments) and a set of well-typed Horn clauses. The following program defines two polymorphic predicates on lists (throughout this chapter we use the Prolog notation for lists [CM87]):

func []: → list(α)

func [..|..]: α, list(α) → list(α)

pred append: list(α), list(α), list(α)

pred member: α, list(α)

      vars L, R, RL:list(α),  E, E1:α
      append([],L,L) ←
      append([E|R],L,[E|RL]) ← append(R,L,RL)
      member(E,[E|R]) ←
      member(E,[E1|R]) ← member(E,R)

The clauses for append and member are well-typed in our sense (cf. Section 3.2) w.r.t. the type definitions.

We view subtyping as the possibility of applying a function or predicate to all types which are subtypes of the declared type of the function or predicate. Hence we specify a type that has some subtypes as a function which is the identity on the subtypes. This will be illustrated by the next example.

Example 3.2 We want to specify a type structure with types nat, zero and posint where zero and posint are subtypes of nat. Hence we specify nat as a function on types which is the identity on zero and posint:

TYPEOPS  zero:  → type
posint:  → type
nat:  type → type
TYPEAXIOMS nat(zero)  = zero
nat(posint) = posint

The type axioms state that nat is not a free type constructor like list but is the identity on the subtypes of nat. It is possible to apply nat to other types than zero and posint, but our logic programs which are based on this specification do not contain any ground terms of type nat(τ) where τ ∉ {zero, posint}. Therefore the type nat(α) describes the union of zero and posint in the initial model of the following program:

func 0: → zero

func s: nat(α) → posint

pred plus: nat(α), nat(β), nat(γ)

vars N, N1:nat(α), N2:nat(β), N3:nat(γ)

      plus(0,N,N) ←
      plus(s(N1),N2,s(N3)) ← plus(N1,N2,N3)

The clauses for plus are well-typed in our sense (cf. Section 3.2) w.r.t. the type definitions (note that the type of the first argument of the clause head is “zero” in the first and “posint” in the second clause). Since the argument types of plus are defined to be arbitrary naturals, we can apply plus with an arbitrary subtype of the naturals. It is possible to build nonsensical types like nat(bool) (if the basic type bool is added to the type structure), but our program contains no ground term of this type and therefore such a type denotes an empty set in the initial model of this program. Moreover, our proof procedure (resolution with typed unifiers, cf. Section 3.6) ensures that such types do not occur in the computation if they are not present in the initial goal.

Since order-sorted type structures are polymorphic type specifications with equational axioms which describe the subsort relationship, it is clear that there is no problem in the combination of polymorphic and order-sorted type structures in our framework. It is also possible to express subsort relationships between polymorphic types:

Example 3.3 We want to specifiy a type structure for polymorphic lists so that the polymorphic type list is the union of elist (empty lists) and nelist (non-empty lists). Therefore we have to express the subtype relationships elist < list(α) and nelist(α) < list(α). As in the previous example, we add an additional argument to a type constructor having some subtypes and express the subtype relationship by type equations:

\begin{aligned}TYPEOPS & elist: & & → & type \\ & nelist: & type & → & type \\ & list: & type, type & → & type \end{aligned}

TYPEAXIOMS list(α, elist)  = elist
list(α, nelist(α)) = nelist(α)

The append-program is specified w.r.t. this type structure as follows:

func []: → elist

func [..|..]: α, list(α, β) → nelist(α)

pred append: list(α, β_{1}), list(α, β_{2}), list(α, β_{3})

vars R:list(α, β_{1}), L:list(α, β_{2}), RL:list(α, β_{3}), E:α

      append([],L,L) ←
      append([E|R],L,[E|RL]) ← append(R,L,RL)

The type variable α in all argument types of append expresses that append concatenates lists of the same element type, whereas the different type variables β_{1}, β_{2}, β_{3} show that an arbitrary subtype of an α-list (empty or non-empty list) can be used in each argument.

The example shows that logic programs with a polymorphically order-sorted type structure are allowed in our framework. Moreover, in Section 3.7 we will give an example of a logic program with higher-order predicates which is well-typed in our framework.

Example 3.4 The type specifications in the previous examples are single-sorted specifications with only one sort “type”. Since we also allow many-sorted specifications, this feature can be used to restrict the quantification of type variables. For instance, the following type specification may be part of a program for symbolic computations:

\begin{aligned}TYPEOPS & int: & & → & ring \\ & polynom: & ring & → & alg type \end{aligned}

Thus polynom is a type constructor where the argument is restricted to be a ring. The type polynom(int) describes the polynomials with integer coefficients. The type declaration for a generic predicate denoting the addition of two polynomials is

pred poly add: polynom(ρ), polynom(ρ), polynom(ρ)

Because of the particular type structure, the type variable ρ is not quantified over all possible types but only over types of sort “ring”, e.g., int is a valid instance of ρ.

The example shows that the sort of a type can be used to express a property of a type. It may be also desirable to use order-sorted equational specifications for the type structure which allows us to express dependencies between type properties, e.g., “alg type < type” (an algebraic type is also a general type). Though this is a useful feature for computer algebra systems (as pointed out in [SLC88]), we omit it for the sake of simplicity. But we emphasize that the restriction to many-sorted type specifications will not be used in the proofs of our results.

In the following we present our framework for typed logic programming in detail. The main topics of this chapter are:

• We present a two-level approach to typed logic programming: The first level is a specification of the basic type structure, and the second level contains a well-typed logic program which is based on the specified type structure. The type structure is specified by a many-sorted signature with equational axioms. In contrast to other approaches to polymorphic type systems for logic programming, we do not restrict the use of types inside program clauses.

• Our approach to typed logic programming is declarative: In contrast to many other type systems for logic programming where types are viewed as sets of ground terms (i.e., they are only valid in the initial model), we define define the semantics of types in a model-theoretic way, i.e., types are subsets of the carrier sets in all interpretations.

• We present sound and complete deduction and resolution methods for typed logic programs. For the soundness of the resolution method it is necessary to define the unification procedure on well-typed terms which is based on a unification procedure for the equational type theory. This sheds some new light on the rôle of types in logic programming since the complexity of the type structure directly influences the complexity of the unification procedure. A powerful type structure (e.g., polymorphic types combined with subtypes) implies a complex unification procedure.

• We show that higher-order programming techniques can be applied in our general framework. We give an example of a typed logic program with higherorder predicates which is ill-typed in the sense of other polymorphic type systems for logic programming.

• The presented approach is a framework for the definition of different type structures for logic programs. The type structure influences only the unification procedure for the execution of the program. Therefore different type structures can be used for different applications where the specification of the type structure can be compiled into a specific unification procedure. It is not necessary to use a powerful order-sorted unification procedure for simple applications like those possible in Turbo-Prolog.

This chapter is organized as follows. In the next section the basic notions and the syntax of typed logic programs are defined. Section 3.3 defines the semantics of typed logic programs which is based on interpretations in algebraic structures. Section 3.4 presents a deduction method for typed logic programs. Section 3.5 presents a solution to the unification problem of typed terms which is based on a given unification procedure for the type theory. The unification procedure on typed terms will be used for the resolution method presented in Section 3.6. Section 3.7 concludes with an interesting application of our framework.

3.2 Logic Programs with Type Specifications

We use many-sorted equational logic for the specification of type structures. Therefore we recall some basic notions from algebraic specifications [GTW78] [EM85]. A many-sorted signature Σ is a pair (S, O), where S is a set of sorts and O is a family of operator sets of the form O = (O_{w,s}|w ∈ S^{∗}, s ∈ S). We write o: s_{1}, …, s_{n} → s ∈ O instead of o ∈ O_{(s_{1},...,s_{n}),s}. An operator of the form o: → s is also called a constant of sort s. A signature Σ = (S, O) is interpreted by a Σ-algebra A = (S_{A}, O_{A}) which consists of an S-sorted domain S_{A} = (S_{A,s}|s ∈ S) and an operation o_{A}: S_{A,s_{1}}, …, S_{A,s_{n}} → S_{A,s} ∈ O_{A} for any o: s_{1}, …, s_{n} → s ∈ O. A set of Σ-variables is an S-sorted set X = (X_{s}|s ∈ S). The set of Σ-terms of sort s with variables from X, denoted T_{Σ,s}(X), is inductively defined by x ∈ T_{Σ,s}(X) for all x ∈ X_{s}, c ∈ T_{Σ,s}(X) for all c: → s ∈ O, and o(t_{1}, …, t_{n}) ∈ T_{Σ,s}(X) for all o: s_{1}, …, s_{n} → s ∈ O (n > 0) and all t_{i} ∈ T_{Σ,s_{i}}(X). Given a term t, var(t) denotes the set of all variables occurring in t. We write T_{Σ}(X) for all Σ-terms with variables from X and T_{Σ} for the set of ground terms T_{Σ}(∅). By T_{Σ}(X) we also denote the term algebra.

A Σ-equation is a pair of Σ-terms (t_{1}, t_{2}) of the same sort, usually written t_{1} = t_{2}. An equational specification is a triple Sp = (S, O, E) where Σ = (S, O) is a signature and E is a set of Σ-equations. In the following we denote by Sp also the signature (S, O) contained in Sp, e.g., T_{Sp}(X) is the set of (S, O)-terms with variables from X.

A variable assignment is a mapping a: X → S_{A} with a(x) ∈ S_{A,s} for all variables x ∈ X_{s} (more precisely, it is a family of mappings (a_{s}: X_{s} → S_{A,s}|s ∈ S)). A Σ-homomorphism from a Σ-algebra A = (S_{A}, O_{A}) into a Σ-algebra B = (S_{B}, O_{B}) is a mapping (family of mappings) h: S_{A} → S_{B} with the property h_{s}(o_{A}(a_{1}, …, a_{n})) = o_{B}(h_{s_{1}}(a_{1}), …, h_{s_{n}}(a_{n})) for all o: s_{1}, …, s_{n} → s ∈ O (n ≥ 0) and all a_{i} ∈ S_{A,s_{i}}. A Σ-congruence on a Σ-algebra A = (S_{A}, O_{A}) is a family of binary equivalence relations ∼_{s}⊆ S_{A,s} × S_{A,s} (s ∈ S) so that o_{A}(a_{1}, …, a_{n}) ∼_{s} o_{A}(b_{1}, …, b_{n}) for all o: s_{1}, …, s_{n} → s ∈ O (n > 0) and all a_{i}, b_{i} ∈ S_{A,s_{i}} with a_{i} ∼_{s_{i}} b_{i}. The following lemma shows an important property of term algebras:

Lemma 3.5 (Free term algebra) Let Σ be a signature, A = (S_{A}, O_{A}) be a Σalgebra and a: X → S_{A} be an assignment for variables from X. There exists a unique Σ-homomorphism a^{∗}: T_{Σ}(X) → S_{A} with a^{∗}(x) = a(x) for all x ∈ X.

Let Sp = (S, O, E) be an equational specification and A = (S_{A}, O_{A}) be an (S, O)-algebra. An Sp-equation t_{1} = t_{2} is valid in A, denoted A ⊧ t_{1} = t_{2}, if a^{∗}(t_{1}) = a^{∗}(t_{2}) holds for all variable assignments a: var(t_{1}) ∪ var(t_{2}) → S_{A}. A is a model for Sp if every equation from E is valid in A. We write

Sp ⊧ t_{1} = t_{2}

if t_{1} = t_{2} is valid in all models for Sp. We remark that an initial model for a specification Sp is T_{Sp}/ ≡_{E}, the quotient of the ground term algebra T_{Sp} by the congruence ≡_{E} generated by the equations E.

Lemma 3.6 Let Σ be a signature, T_{Sp}(X)/ ≡_{E} be the quotient of the term algebra T_{Sp}(X) by the congruence ≡_{E} generated by the equations E, A = (S_{A}, O_{A}) be a Σ-algebra and a: X → S_{A} be an assignment for variables from X. There exists a unique Σ-homomorphism a^{∗}: T_{Sp}(X)/ ≡_{E} → S_{A} with a^{∗}([x]) = a(x) for all x ∈ X where [x] denotes the equivalence class of x w.r.t. ≡_{E}.

The definition of types is based on equational specifications: T = (T s, T op, T ax) is a specification of types if T is an equational specification. Constants from T are called basic types. By X we denote an infinite set of type variables (precisely, X = (X_{s}|s ∈ T s) is a family of infinite sets of type variables, but we identify the family of sets with one set since we assume that the sets X_{s} are disjoint). A type expression or type is a term from T_{T} (X).

A type substitution σ is a T -homomorphism σ: T_{T} (X) → T_{T} (X). T S(T , X) denotes the class of all type substitutions. Two types τ_{1}, τ_{2} ∈ T_{T} (X) are called T -equal, denoted τ_{1} =_{T} τ_{2}, if T ⊧ τ_{1} = τ_{2}.

A polymorphic signature Σ for logic programs is a triple (T , F unc, P red) with:

• T is a specification of types with T_{T ,s}(∅) ≠ ∅ for all s ∈ T s.

• F unc is a set of function declarations of the form f:τ_{1}, …, τ_{n} → τ with τ_{i}, τ ∈ T_{T} (X), n ≥ 0.

• P red is a set of predicate declarations of the form p:τ_{1}, …, τ_{n} with τ_{i} ∈ T_{T} (X) (n ≥ 0).

Since we do not deal with the problem of type checking or type inference in our framework, we do not forbid overloading in contrast to [Han89a] or [Smo89]. The type specifications together with the definitions of function and predicate types in the examples of Section 3.1 are polymorphic signatures. In the rest of this chapter we assume that Σ = (T , F unc, P red) is a polymorphic signature for logic programs. Similarly to other typed logics, the variables in a typed logic program are not quantified over all objects, but vary only over objects of a particular type. Thus each variable is annotated with a type expression: Let V ar be an infinite set of variable names that are distinguishable from symbols in polymorphic signatures and type variables. Then the set V is called a set of typed variables if

• each element of V has the form x:τ where x ∈ V ar is a variable name and τ ∈ T_{T} (X) is a type, and

• x:τ, x:τ′ ∈ V implies τ = τ′.

We only consider sets of typed variables with unique types so that type errors can be detected at compile time. For instance, if a variable in a clause occurs in two different contexts so that it has type “int” in one context and type “list(int)” in the other context, this indicates a type error if all variables in a clause are required to have unique types. In the rest of this chapter we assume that V, V′, V_{0}, V_{1}, … denote sets of typed variables.

In Church’s formulation of the theory of types [Chu40] types are embedded in terms, i.e., each symbol in a term is annotated with an appropriate type expression. These annotations are useful for the unification of typed terms (see Section 3.5). We call L ← G a typed program clause if there is a set of typed variables V and V |⊧ L ← G is derivable by the inference rules in figure 3.1. The typing rules show that both parametric polymorphism and subtype polymorphism are covered by our framework: If the declared type of a function or predicate contains type variables, then this function or predicate can be applied to any type which is the result of replacing the type variables by other types (parametric polymorphism). If the type specification contains subtype relations as in example 3.2, then a function or predicate with declared argument type nat(α) can also be applied to the subtypes nat(zero) (=_{T} zero) and nat(posint) (=_{T} posint).

Note that we have no restrictions on the use of types and type variables in the left-hand side of program clauses in contrast to [MO84] [DH88] [Smo89] and similar

Variable:  \overline{V |⊧ x:τ′}  (x:τ ∈ V and τ =_{T} τ′)

Constant:

\overline{V |⊧ c:τ′}

(c: → τ_{c} ∈ F unc so that there is a
σ ∈ T S(T , X) with σ(τ_{c}) =_{T} τ′)

Composite term: \frac{V |⊧ t_{1}:τ_{1}, …, V |⊧ t_{n}:τ_{n}}{V |⊧ f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ′}

(f:τ_{f} ∈ F unc so that there exists
σ ∈ T S(T , X) with
σ(τ_{f}) = τ_{1}, …, τ_{n} → τ
and τ =_{T} τ′, n > 0)

Atom: \frac{V |⊧ t_{1}:τ_{1}, …, V |⊧ t_{n}:τ_{n}}{V |⊧ p(t_{1}:τ_{1}, …, t_{n}:τ_{n})} (p:τ_{p} ∈ P red so that there exists σ ∈ T S(T , X) with

σ(τ_{p}) = τ_{1}, …, τ_{n}, n ≥ 0)

Goal: \frac{V |⊧ L_{1}, …, V |⊧ L_{n}}{V |⊧ L_{1}, …, L_{n}} (each L_{i} is an atom, i.e., has the form p(⋯), i = 1, …, n)

Clause:  \frac{V |⊧ L, V |⊧ G}{V |⊧ L ← G}  (L is an atom and G is a goal)

Figure 3.1: Typing rules for program clauses

polymorphic type systems.^{2} For instance, it is allowed to add the clause

      member(2,[1,2,3]) ←

to the program in example 3.1. By dropping this restriction it is also possible to apply higher-order programming techniques in our framework (cf. Section 3.7).

We call variables, constants and composite terms derivable by these inference rules (Σ, X, V )-terms or well-typed terms. T erm_{Σ}(X, V ) denotes the set of all (Σ, X, V)-terms. A ground term is a term from the set T erm_{Σ}(X, ∅). Welltyped or (Σ, X, V)-atoms, -goals and -clauses are similarly defined (a goal is a set of atoms, but for convenience we denote it without curly brackets). A Σ-term (atom, goal, clause) is a (Σ, X, V)-term (atom, goal, clause) for some set of typed variables V.

Lemma 3.7 If t:τ is a well-typed term and τ =_{T} τ′, then t:τ′ is also a well-typed term.

In the following, if s is a syntactic construction (type, term, atom, …), tvar(s) and var(s) will denote the set of type variables and typed variables that occur in s, respectively (i.e., var(s) is a set of typed variables so that s is a (Σ, X, var(s))-term, atom, …). For instance, if

2In these type systems the left-hand side of a clause for a polymorphic predicate must have a type which is equivalent to the declared type of the predicate.

T ax = {s_{1}(s_{3}) = s_{3}, s_{2}(s_{3}) = s_{3}}

and s = f(X:s_{1}(s_{3}), X:s_{2}(s_{3})):s_{3}, then both {X:s_{3}} and {X:s_{1}(s_{3})} satisfy the definition of var(s), but it is always the case that these different sets are T -equal sets of typed variables. Therefore we can choose one of these sets as var(s). Furthermore, we define uvar(s) := {x | ∃τ ∈ T_{T} (X): x:τ ∈ var(s)} as the set of variable names that occur in s.

A typed logic program or typed Horn clause program P = (Σ, C) consists of a polymorphic signature Σ and a set C of Σ-clauses. If it is clear from the context, we will omit the type annotations in the clauses of example programs. Therefore we have written the clauses of the examples in the first chapter without type annotations but we have defined the types of the variables. For instance, the clause

      member(E,[E|R]) ←

in example 3.1 denotes the fully typed clause

member(E:α,[E:α|R:list(α)]:list(α)) ←

and the clause

      plus(0,N,N) ←

in example 3.2 denotes the fully typed clause

plus(0:nat(zero),N:nat(α),N:nat(α)) ←

This clause is well-typed because “nat(zero), nat(α), nat(α)” is an instance of the declared type “nat(α), nat(β), nat(γ)” of the predicate plus and 0:nat(zero) is a well-typed term since nat(zero) =_{T} zero (where T is the type specification of example 3.2). The term

[ 1:nat | []:list(nat, elist) ]:nelist(nat)

is a well-typed term w.r.t. example 3.3 (we assume that 1 is a constant of type nat) since [] is a constant of type elist and list(nat, elist) =_{T} elist holds in the specified type structure.

3.3 Semantics of Typed Logic Programs

Typed logic programs are interpreted by algebraic structures similar to the ones introduced in [Poi86]. An interpretation of a typed logic program consists of an algebra that satisfies the type specification and a structure for the derived polymorphic signature. A structure is an interpretation of types (elements of sort type) as sets, function symbols as operations on these sets and predicate symbols as relations between these sets. Type variables vary over all types of the interpretation and typed variables vary over appropriate carrier sets. The necessary notions are defined in this section.

If T = (T s, T op, T ax) is a specification of types, a T -algebra A = (T s_{A}, T op_{A}) which satisfies all equations from T ax is also called T -type algebra. The signature Σ(A) = (T s_{A}, F unc_{A}, P red_{A}) derived from Σ and A is defined by

F unc_{A} := {f:σ(τ_{f}) | f:τ_{f} ∈ F unc, σ: X → T s_{A} is a type variable assignment}
P red_{A} := {p:σ(τ_{p}) | p:τ_{p} ∈ P red, σ: X → T s_{A} is a type variable assignment}

An interpretation of a polymorphic signature Σ (or Σ-interpretation) is a T - type algebra A = (T s_{A}, T op_{A}) together with a Σ(A)-structure (S, δ) which consists of a T s_{A}-sorted set S = (S_{τ} |τ ∈ T s_{A}) (the carrier of the interpretation) and a denotation δ with:

1. If f:τ_{1}, …, τ_{n} → τ ∈ F unc_{A}, then δ_{f:τ_{1},...,τ_{n}→τ}: S_{τ_{1}} × ⋯ × S_{τ_{n}} → S_{τ} is a function.

2. If p:τ_{1}, …, τ_{n} ∈ P red_{A}, then δ_{p:τ_{1},...,τ_{n}} ⊆ S_{τ_{1}} × ⋯ × S_{τ_{n}} is a relation.

Hence (polymorphic) functions and predicates are interpreted as families of functions and predicates on the given types. In order to compare different interpretations, we define homomorphisms between them. At first, we define Σ(A)- homomorphisms to compare different Σ(A)-structures: Let A = (T s_{A}, T op_{A}) be a T -type algebra and (S, δ), (S′, δ′) be Σ(A)-structures. A Σ(A)-homomorphism h from (S, δ) into (S′, δ′) is a family of functions (h_{τ} |τ ∈ T s_{A}) with:

1. h_{τ}: S_{τ} → S′_{τ}

2. If f:τ_{f} ∈ F unc_{A} with τ_{f} = τ_{1}, …, τ_{n} → τ (n ≥ 0) and a_{i} ∈ S_{τ_{i}} (i = 1, …, n), then: h_{τ} (δ_{f:τ_{f}} (a_{1}, …, a_{n})) = δ′_{f:τ_{f}} (h_{τ_{1}}(a_{1}), …, h_{τ_{n}}(a_{n}))

3. If p:τ_{p} ∈ P red_{A} with τ_{p} = τ_{1}, …, τ_{n} (n ≥ 0) and (a_{1}, …, a_{n}) ∈ δ_{p:τ_{p}}, then: (h_{τ_{1}}(a_{1}), …, h_{τ_{n}}(a_{n})) ∈ δ′_{p:τ_{p}}

If it is clear from the context we omit the indices τ in the functions h_{τ}. Note that the composition of two Σ(A)-homomorphisms is again a Σ(A)-homomorphism. The class of all Σ(A)-structures together with the Σ(A)-homomorphisms is a category [EM85]. We denote this category by Cat_{Σ(A)}.

If A and A′ are T -type algebras, then every T -homomorphism σ: A → A′ induces a signature morphism σ: Σ(A) → Σ(A′) and a forgetful functor U_{σ}: Cat_{Σ(A′)} → Cat_{Σ(A)} from the category of Σ(A′)-structures into the category of Σ(A)-structures (see [EM85] for details). Therefore we define a Σhomomorphism from a Σ-interpretation (A, S, δ) into another Σ-interpretation (A′, S′, δ′) as a pair (σ, h), where σ: A → A′ is a T -homomorphism and h: (S, δ) → U_{σ}((S′, δ′)) is a Σ(A)-homomorphism. The class of all Σ-interpretations with the composition

(σ′, h′) ∘ (σ, h) := (σ′ ∘ σ, U_{σ}(h′) ∘ h)

of two Σ-homomorphisms is a category. Thus we call a Σ-interpretation (A, S, δ) initial in a class of Σ-interpretations C iff for all Σ-interpretations (A′, S′, δ′) ∈ C there exists a unique Σ-homomorphism from (A, S, δ) into (A′, S′, δ′).

A homomorphism in our typed framework consists of a mapping between type algebras and a mapping between appropriate structures. Consequently, a variable assignment in the typed framework maps type variables into types and typed variables into objects of appropriate types: If I = ((T s_{A}, T op_{A}), S, δ) is a Σinterpretation, then a variable assignment for (X, V) in I is a pair of mappings v = (v_{X}, v_{V}) where v_{X}: X → T s_{A} is a type variable assignment and v_{V}: V → S′ with (S′, δ′) := U_{v_{X}} ((S, δ)) and v_{V} (x:τ) ∈ S′_{τ} (= S_{v_{X}(τ)}) for all x:τ ∈ V.

In many-sorted logic, a canonical interpretation for a signature is the term interpretation where the carrier sets consist of well-typed terms. In a term interpretation every variable assignment can be uniquely extended to a homomorphism. In our typed framework the situation is more complicated because a variable may correspond to syntactically different terms. For instance, if s_{1} = s_{2} ∈ T ax, then the variable x:s_{1} ∈ V corresponds to the (Σ, X, V)-terms x:s_{1} and x:s_{2}. In order to identify such syntactically different terms, we define canonical terms as terms where the type annotations are replaced by equivalence classes of types. For this purpose we define a mapping C which replaces all type annotations in a typed term by equivalence classes of types ([τ] denotes the equivalence class of the type τ defined by [τ] = {τ′ | τ =_{T} τ′}):

• C(x:τ′) := x:[τ] for all x:τ ∈ V and τ′ =_{T} τ

• C(f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ)  :=  f(C(t_{1}:τ_{1}), …, C(t_{n}:τ_{n})):[τ] for all

f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ ∈ T erm_{Σ}(X, V) (n ≥ 0)

CT erm_{Σ}(X, V ) := {C(t:τ) | t:τ ∈ T erm_{Σ}(X, V)} is the set of canonical terms. Now we are able to define the canonical term interpretation T_{Σ}(X, V ) over X and V: T_{Σ}(X, V) := (T_{T ax}(X), S, δ), where

1. T_{T ax}(X) := T_{T} (X)/ ≡_{T ax} is the quotient of the algebra of type expressions by the congruence relation ≡_{T ax} generated by the axioms in the type specification T = (T s, T op, T ax) (the elements of the domain of T_{T ax}(X) are equivalence classes of types).

2. For all [τ] ∈ T_{T ax}(X),

S_{[τ]} := {t:[τ] | t:[τ] ∈ CT erm_{Σ}(X, V)}

3. If f:[τ_{1}], …, [τ_{n}] → [τ] ∈ F unc_{T_{T ax}(X)} and t_{i}:[τ_{i}] ∈ S_{[τ_{i}]} for i = 1, …, n, then

δ_{f:[τ_{1}],...,[τ_{n}]→[τ]}(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]) := f(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]):[τ]

4. δ_{p:[τ_{1}],...,[τ_{n}]} := ∅ for all p:[τ_{1}], …, [τ_{n}] ∈ P red_{T_{T ax}(X)}.

The mappings δ_{f:[τ_{1}],...,[τ_{n}]→[τ]} in the definition are well-defined by lemma 3.7. Similarly to the notion of “term algebra” in the field of algebraic specification [EM85], a term interpretation T_{Σ}(X, V) does not interpret the predicates but supplies a standard structure with objects built from functions and typed variables. Therefore the denotation of predicates are empty sets.

Now we are able to show that any variable assignment can be uniquely extended to a homomorphism:

Lemma 3.8 (Free term structure) Let (A, S, δ) be a Σ-interpretation and v = (v_{X}, v_{V}) be an assignment for (X, V) in (A, S, δ). There exists a unique Σhomomorphism (σ, h) from T_{Σ}(X, V) into (A, S, δ) with σ([α]) = v_{X}(α) for all α ∈ X and h(x:[τ]) = v_{V} (x:τ) for all x:τ ∈ V.

Proof: By lemma 3.6, v_{X} can be uniquely extended to a T -homomorphism σ: T_{T ax}(X) → A with the property σ([α]) = v_{X}(α) for all α ∈ X. We define a Σ(T_{T ax}(X))-homomorphism h from T_{Σ}(X, V) into U_{σ}((S, δ)):

1. h(x:[τ]) := v_{V} (x:τ) for all x:τ ∈ V.

2. h(c:[τ]) := δ_{c:→σ([τ])} ∈ S_{σ([τ])} for all c: → τ ∈ F unc_{T_{T} (X)}.

3.

h(f(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]):[τ]) := δ_{f:σ([τ_{1}]),...,σ([τ_{n}])→σ([τ])}(h(t_{1}:[τ_{1}]), …, h(t_{n}:[τ_{n}])) for all f:τ_{1}, …, τ_{n} → τ ∈ F unc_{T_{T} (X)} and all t_{i}:[τ_{i}] ∈ CT erm_{Σ}(X, V).

Clearly h is a Σ(T_{T ax}(X))-homomorphism. Hence (σ, h) is a Σ-homomorphism. To proof uniqueness of this homomorphism, we assume another Σ-homomorphism (σ′, h′) from T_{Σ}(X, V) into (A, S, δ) with σ′([α]) = v_{X}(α) for all α ∈ X and h′(x:[τ]) = v_{V} (x:τ) for all x:τ ∈ V. σ = σ′ by lemma 3.6. We show h = h′ by induction on the term structure:

1. x:τ ∈ V: h′(x:[τ]) = v_{V} (x:τ) = h(x:[τ]).

2. c: → τ ∈ F unc_{T_{T} (X)}: h′(c:[τ]) = δ_{c:→σ′([τ])} = δ_{c:→σ([τ])} = h(c:[τ]).

3. f(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]):[τ]) ∈ CT erm_{Σ}(X, V), n > 0:

h′(f(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]):[τ])
= δ_{f:σ′([τ_{1}]),...,σ′([τ_{n}])→σ′([τ])}(h′(t_{1}:[τ_{1}]), …, h′(t_{n}:[τ_{n}]))
= δ_{f:σ([τ_{1}]),...,σ([τ_{n}])→σ([τ])}(h(t_{1}:[τ_{1}]), …, h(t_{n}:[τ_{n}]))
= h(f(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]):[τ])

This lemma is only valid if T_{Σ}(X, V) and the T -algebra A satisfies all equations from T ax. If this is not the case, there exist several different Σ-homomorphisms which extend the variable assignment. For instance, if s_{1} = s_{2} ∈ T ax and A has different interpretations of the sorts s_{1} and s_{2}, then the terms x:s_{1} and x:s_{2} may be mapped into different values by different homomorphisms, provided that x:s_{1} ∈ V.

As a special case (X = V = ∅) the lemma shows that every ground term without type variables corresponds to a unique value in a given Σ-interpretation. Generally, any variable assignment v can be extended to a Σ-homomorphism in a unique way. In the following we denote that Σ-homomorphism again by v. Since v_{X} and v_{V} are only applied to equivalence classes of type expressions and canonical terms, respectively, we omit the indices X and V and write v for both v_{X} and v_{V}.

We are not interested in all interpretations of a polymorphic signature but only in those interpretations that satisfy the clauses of a given typed logic program. In order to formalize that we define the validity of atoms, goals and clauses relative to a given Σ-interpretation I = (A, S, δ):

• Let v be an assignment for (X, V) in I.

I, v ⊧ L if L = p(t_{1}:τ_{1}, …, t_{n}:τ_{n}) is a (Σ, X, V)-atom with

(v(C(t_{1}:τ_{1})), …, v(C(t_{n}:τ_{n}))) ∈ δ′_{p:[τ_{1}],...,[τ_{n}]}

where U_{v}((S, δ)) = (S′, δ′), i.e., δ′_{p:[τ_{1}],...,[τ_{n}]} = δ_{p:v([τ_{1}]),...,v([τ_{n}])}.

I, v ⊧ G if G is a (Σ, X, V)-goal with I, v ⊧ L for all L ∈ G

I, v ⊧ L ← G if L ← G is a (Σ, X, V)-clause where I, v ⊧ G implies I, v ⊧ L

• I, V ⊧ F if F is a (Σ, X, V)-atom, -goal or -clause with I, v ⊧ F for all variable assignments v for (X, V) in I

We say “L is valid in I” if I is a Σ-interpretation with I, var(L) ⊧ L (analogously for goals and clauses). A Σ-interpretation I = (A, S, δ) is called model for a typed logic program (Σ, C) if I, var(L ← G) ⊧ L ← G for all clauses L ← G ∈ C. A (Σ, X, V)-goal G is called valid in (Σ, C) relative to V if I, V ⊧ G for every model I of (Σ, C). We shall write: (Σ, C, V ) ⊧ G.

This notion of validity is the extension of validity in untyped Horn clause logic to the typed case: In untyped Horn clause logic an atom, goal or clause is said to be true iff it is true for all variable assignments. In the typed case an atom, goal or clause is said to be true iff it is true for all assignments of type variables and typed variables. The reason for the definition of validity relative to a set of variables is that carrier sets in our interpretations may be empty in contrast to untyped Horn logic. This is also the case in many-sorted logic [GM84]. Validity relative to variables is different from validity in the sense of untyped logic. An example for such a difference can be found in [Han89a], p. 231. Validity in our sense is equivalent to validity in the sense of untyped logic if the types of the variables denote non-empty sets in all interpretations. But a requirement for non-empty carrier sets is not reasonable in the context of polymorphic types.

Example 3.9 The following interpretation is a model for the program of example 3.2. The type specification is interpreted by the T -type algebra A = (T s_{A}, T op_{A}) where T s_{A} = {nat, zero, posint} and T op_{A} contains the functions zero_{A} with zero_{A}() = zero, posint_{A} with posint_{A}() = posint, and nat_{A} with nat_{A}(τ) = τ for all τ ∈ T s_{A}. The carrier sets of the interpretation are:

S_{zero} = {0}
S_{posint} = {n ∈ Nat | n > 0}
S_{nat} = S_{zero} ∪ S_{posint}

The constant 0 and the function s are interpreted as follows:

δ_{0:→zero} = 0
δ_{s:zero→posint}(0) = 1
δ_{s:posint→posint}(n) = n + 1 for all n ∈ S_{posint}
δ_{s:nat→posint}(n) = n + 1 for all n ∈ S_{nat}
δ_{plus:nat,nat,nat} = {(n_{1}, n_{2}, n_{3}) ∈ Nat^{3} | n_{1} + n_{2} = n_{3}}
…

The remaining interpretations of plus are the restriction of δ_{plus:nat,nat,nat} to appropriate subsets. It is easy to show that this interpretation is a model.

3.4 Deduction and Initial Models

In order to define the semantics of typed logic programs we have used canonical terms which are annotated with equivalence classes of types. Since these equivalence classes are sets which may contain an infinite number of elements, this representation is unsuitable for proof procedures like deduction or resolution. Such proof procedures should work on well-typed terms which can be easily handled. Therefore we have to define substitutions on well-typed terms and introduce a relation on well-typed terms that establishes the link to canonical terms.

3.4.1 Typed substitutions

Let μ: X → T_{T} (X) be a mapping from type variables into type expressions and val: V → T erm_{Σ}(X, V′) be a mapping from typed variables into well-typed terms over X and V′ with the following properties:

• μ is a type variable assignment.

• val(x:τ) = t:μ(τ) for all x:τ ∈ V, i.e., typed variables of sort τ are mapped into well-typed terms of type μ(τ).

We extend the mappings μ and val to mappings on types and well-typed terms, respectively, in the following way:

• μ(b) = b for all basic types b in T .

• μ(h(τ_{1}, …, τ_{n})) = h(μ(τ_{1}), …, μ(τ_{n})) for all n-ary operation symbols h in T (n > 0) and all appropriate types τ_{1}, …, τ_{n} ∈ T_{T} (X).

• val(x:τ′) = t:μ(τ′) for all x:τ ∈ V with val(x:τ) = t:μ(τ) and τ′ =_{T} τ.

• val(c:τ) = c:μ(τ) for all well-typed constants c:τ ∈ T erm_{Σ}(X, V).

• val(f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ) = f(val(t_{1}:τ_{1}), …, val(t_{n}:τ_{n})):μ(τ) for all welltyped terms f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ ∈ T erm_{Σ}(X, V), n > 0.

The mappings are similarly extended on atoms, goals and clauses. We call (μ, val) a typed substitution. Sub_{Σ}(X, V, V′) denotes the class of all typed substitutions from (T_{T} (X), T erm_{Σ}(X, V)) into (T_{T} (X), T erm_{Σ}(X, V′)). id_{X,V} ∈ Sub_{Σ}(X, V, V) denotes the identity in Sub_{Σ}(X, V, V). tdom(σ) := {α ∈ X | σ(α) ≠ α} is the type domain of a typed substitution σ. A typed substitution keeps the set of type variables X but may change the set of typed variables because the types of the variables influence validity (see Section 3.3). Sometimes we represent typed substitutions by sets. For instance, the set

σ = {α/nat, x:α/0:nat}

represents a typed substitution that replaces the type variable α by the type nat and the typed variable x:α by the term 0:nat. Hence the result of applying σ to the atom p(x:α, y:α) is the atom p(0:nat, y:nat).

The next lemma shows that val is well-defined:

Lemma 3.10 Let (μ, val) defined as above. Then val(t:τ) = t′:μ(τ) ∈ T erm_{Σ}(X, V′) for all well-typed terms t:τ ∈ T erm_{Σ}(X, V).

Proof: By induction on the structure of all well-typed terms from T erm_{Σ}(X, V):

• x:τ′ where x:τ ∈ V, τ′ =_{T} τ and val(x:τ) = t:μ(τ): By definition, val(x:τ′) = t:μ(τ′). t:μ(τ) ∈ T erm_{Σ}(X, V′) is a well-typed term and μ(τ) =_{T} μ(τ′). By lemma 3.7, t:μ(τ′) is also a well-typed term.

• c:τ where c: → τ_{c} ∈ F unc and there exists a type substitution σ with σ(τ_{c}) =_{T} τ: μ ∘ σ is a type substitution with μ(σ(τ_{c})) =_{T} μ(τ). Hence val(c:τ) = c:μ(τ) is a well-typed term.

• f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ where f:τ_{f} ∈ F unc and there exists a type substitution σ with σ(τ_{f}) = τ_{1}, …, τ_{n} → τ′ and τ′ =_{T} τ. μ ∘ σ is a type substitution with μ(σ(τ_{f})) = μ(τ_{1}), …, μ(τ_{n}) → μ(τ′) and μ(τ′) =_{T} μ(τ). Hence val(f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ) = f(val(t_{1}:τ_{1}), …, val(t_{n}:τ_{n})):μ(τ) is a well-typed term since val(t_{i}:τ_{i}) = t′_{i}:μ(τ_{i}) is well-typed for i = 1, …, n by induction hypothesis.

The following lemma states the relationship between typed substitutions and Σ-homomorphisms on canonical term interpretations:

Lemma 3.11 Let (μ, val) ∈ Sub_{Σ}(X, V, V′) be a typed substitution. Then there exists a unique Σ-homomorphism σ from T_{Σ}(X, V) into T_{Σ}(X, V′) with

• σ([α]) = [μ(α)] for all α ∈ X

• σ(x:[τ]) = C(val(x:τ)) for all x:τ ∈ V

Furthermore,

σ([τ]) = [μ(τ)] for all τ ∈ T_{T} (X)  (1)

and

σ(C(t:τ)) = C(val(t:τ)) for all t:τ ∈ T erm_{Σ}(X, V)  (2)

Proof: Let σ_{X}: X → T_{T ax}(X) be defined by σ_{X}(α) := [μ(α)] for all α ∈ X. By lemma 3.6, there exists a unique T -homomorphism σ: T_{T ax}(X) → T_{T ax}(X) with σ([α]) = σ_{X}(α) for all α ∈ X. If σ_{X} also denotes the unique extension σ_{X}: T_{T} (X) → T_{T ax}(X) (which exists by lemma 3.5), then σ has the property σ_{X} = σ ∘ nat where nat is the canonical T -homomorphism nat(τ) = [τ] for all τ ∈ T_{T} (X) (cf. [EM85], p. 82). We show (1) by induction on the size of τ:

• σ([α]) = σ_{X}(α) = [μ(α)] for all α ∈ X.

• σ([b]) = σ_{X}(b) = [b] = [μ(b)] for all basic types b in T .

• For all n-ary operation symbols h in T and all appropriate types τ_{1}, …, τ_{n} ∈ T_{T} (X):

σ([h(τ_{1}, …, τ_{n})])
= σ_{X}(h(τ_{1}, …, τ_{n}))
= h′(σ_{X}(τ_{1}), …, σ_{X}(τ_{n})) (h′ is the interpretation of h in T_{T ax}(X))
= h′(σ([τ_{1}]), …, σ([τ_{n}]))
= h′([μ(τ_{1})], …, [μ(τ_{n})]) (by induction hypothesis)
= [h(μ(τ_{1}), …, μ(τ_{n}))] (by definition of h′)
= [μ(h(τ_{1}, …, τ_{n}))]

Let σ_{V}: V → CT erm_{Σ}(X, V′) be defined by σ_{V} (x:τ) := C(val(x:τ)) for x:τ ∈ V. val(x:τ) is a well-typed term of type μ(τ), hence C(val(x:τ)) has the form t:[μ(τ)] = t:σ([τ]) = t:σ_{X}(τ). Therefore (σ_{X}, σ_{V}) is a variable assignment for (X, V) in T_{Σ}(X, V′) which can be uniquely extended to a Σ-homomorphism σ from T_{Σ}(X, V) into T_{Σ}(X, V′) by lemma 3.8. We prove (2) by induction on the size of terms:

• For all x:τ ∈ V with val(x:τ) = t:μ(τ) and τ′ =_{T} τ: σ(C(x:τ′)) = σ(x:[τ′]) = σ(x:[τ]) = σ_{V} (x:τ) = C(val(x:τ)) = C(t:μ(τ)) = C(t:μ(τ′)) = C(val(x:τ′)).

• σ(C(c:τ)) = σ(c:[τ]) = c:σ([τ]) = c:[μ(τ)] = C(c:μ(τ)) = C(val(c:τ)) for all constants c:τ ∈ T erm_{Σ}(X, V).

• For all terms f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ ∈ T erm_{Σ}(X, V), n > 0:

σ(C(f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ)) = σ(f(C(t_{1}:τ_{1}), …, C(t_{n}:τ_{n})):[τ])
= f(σ(C(t_{1}:τ_{1})), …, σ(C(t_{n}:τ_{n}))):σ([τ])
= f(C(val(t_{1}:τ_{1})), …, C(val(t_{n}:τ_{n}))):[μ(τ)]
= C(f(val(t_{1}:τ_{1}), …, val(t_{n}:τ_{n})):μ(τ))
= C(val(f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ))

Uniqueness can be simply shown by induction on the size of terms.

The above lemma shows that typed substitutions which are directly applied to well-typed terms correspond to Σ-homomorphisms between canonical term interpretations in a unique way. Hence σ̂ denotes the Σ-homomorphism from T_{Σ}(X, V) into T_{Σ}(X, V′) corresponding to the typed substitution σ ∈ Sub_{Σ}(X, V, V′). The following lemma shows a relationship between variable assignments and typed substitutions w.r.t. validity:

Lemma 3.12 Let I be a Σ-interpretation, G be a (Σ, X, V)-goal, σ ∈ Sub_{Σ}(X, V, V′) and v be a variable assignment for (X, V′) in I. Then I, v ⊧ σ(G) iff I, v ∘ σ̂ ⊧ G.

Proof: Let G, σ, v = (v_{X}, v_{V}) and I = (A, S, δ) be given. The composition v′ := v ∘ σ̂ between Σ-homomorphisms is defined by v′ = (v′_{X}, v′_{V}) with v′_{X}([α]) = v_{X}(σ̂([α])) for all α ∈ X and

v′_{V,[τ]}(x:[τ]) = (Uσ̂(v_{V}) ∘ σ̂)_{[τ]}(x:[τ]) = v_{V,σ̂([τ])}(σ̂(x:[τ]))

for all x:τ ∈ V. Thus v′ is a variable assignment for (X, V) in I. Let p(… t_{i}:τ_{i} …) ∈ G. Then

I, v ⊧ σ (p(… t_{i}:τ_{i} …))
⟺ I, v ⊧ p(… σ(t_{i}:τ_{i}) …)
⟺ (… v_{V} (C(σ(t_{i}:τ_{i}))) …) ∈ δ_{p:...v_{X}(σ̂([τ_{i}]))...}
⟺ (… v_{V} (σ̂(C(t_{i}:τ_{i}))) …) ∈ δ_{p:...v_{X}(σ̂([τ_{i}]))...} (by lemma 3.11)
⟺ (… v′_{V} (C(t_{i}:τ_{i})) …) ∈ δ_{p:...v′_{X}([τ_{i}])...}
⟺ I, v′ ⊧ p(… t_{i}:τ_{i} …)

This proves the lemma.

A term t′ ∈ T erm_{Σ}(X, V′) is called an instance of a term t ∈ T erm_{Σ}(X, V) if a typed substitution σ ∈ Sub_{Σ}(X, V, V′) exists with t′ = σ(t). The definition of instances can be extended to atoms, goals and clauses. We omit the simple definitions here. The next lemma shows the relationship between the validity of a clause and the validity of all its instances:

Lemma 3.13 Let I = (A, S, δ) be a Σ-interpretation and L ← G be a (Σ, X, V)- clause. Then:

I, V ⊧ L ← G  ⟺  I, V′ ⊧ σ(L) ← σ(G) for all σ ∈ Sub_{Σ}(X, V, V′)

Proof: The direction “⟸” is trivial if we use the identity id_{X,V} for the typed substitution σ. Let I, V ⊧ L ← G and σ ∈ Sub_{Σ}(X, V, V′) be a typed substitution. We have to show I, V′ ⊧ σ(L) ← σ(G). Let v be a variable assignment for (X, V′) in I with I, v ⊧ σ(G) (if there exists no such variable assignment, I, V′ ⊧ σ(L) ← σ(G) is trivially true). Lemma 3.12 yields I, v ∘ σ̂ ⊧ G. This implies I, v ∘ σ̂ ⊧ L since I, V ⊧ L ← G. Again by lemma 3.12, it follows I, v ⊧ σ(L).

Along with a set of Σ-clauses C we define the set of instantiated clauses Ĉ as follows:

Ĉ := {L ← G | L ← G is an instance of a clause from C} The set Ĉ contains all clauses which are obtained from clauses in C by substituting type expressions for type variables and well-typed terms for typed variables.

Corollary 3.14 A Σ-interpretation is a model for (Σ, C) iff it is a model for (Σ, Ĉ).

Proof: The theorem follows by definition of Ĉ and lemma 3.13.

3.4.2 Equality w.r.t. the type structure

Our proof procedures (deduction, resolution) manipulate only well-typed terms and use typed substitutions. For that purpose we define an important relation on well-typed terms: Two Σ-terms t and t′ are called T -equal, denoted t =_{T} t′, if C(t) = C(t′). T -equality on atoms is analogously defined. Two finite sets of typed variables V_{1} and V_{2} are called T -equal if V_{1} = {x_{1}:ξ_{1}, …, x_{m}:ξ_{m}}, V_{2} = {x_{1}:ξ′_{1}, …, x_{m}:ξ′_{m}} and ξ_{i} =_{T} ξ′_{i} for i = 1, …, m.

Example 3.15 If the type specification of example 3.2 is given, then the following pairs of well-typed terms are T -equal:

0:nat(zero) =_{T} 0:zero
N:posint =_{T} N:nat(posint)

The proof of the following two lemmas is straightforward:

Lemma 3.16 If two Σ-terms t and t′ are T -equal, then var(t) and var(t′) are T -equal sets of typed variables.

Lemma 3.17 If two Σ-terms t and t′ are T -equal, then all instances σ(t) and σ(t′) are T -equal.

The next lemma shows that T -equal atoms have the same meaning in all interpretations:

Lemma 3.18 Let Σ be a polymorphic signature, V be a set of typed variables, and L_{1} and L_{2} be two T -equal (Σ, X, V)-atoms. If I is a Σ-interpretation and v is a variable assignment for V in I, then:

I, v ⊧ L_{1}  ⟺  I, v ⊧ L_{2}

Proof: Let I = (A, S, δ) be a Σ-interpretation and v be a variable assignment for V in I. Let L_{1} and L_{2} be two T -equal (Σ, X, V)-atoms. Hence L_{1} = p(t_{1}:τ_{1}, …, t_{k}:τ_{k}), L_{2} = p(t′_{1}:τ′_{1}, …, t′_{k}:τ′_{k}), and t_{i}:τ_{i} =_{T} t′_{i}:τ′_{i} for i = 1, …, k. By definition of T -equality, v(C(t_{i}:τ_{i})) = v(C(t′_{i}:τ′_{i})) for i = 1, …, k. I, v ⊧ L_{1} is equivalent to

(v(C(t_{1}:τ_{1})), …, v(C(t_{k}:τ_{k}))) ∈ δ_{p:v([τ_{1}]),...,v([τ_{k}])}

Since [τ_{i}] = [τ′_{i}] for i = 1, …, k, we obtain

(v(C(t′_{1}:τ′_{1})), …, v(C(t′_{k}:τ′_{k}))) ∈ δ_{p:v([τ′_{1}]),...,v([τ′_{k}])}

which is equivalent to I, v ⊧ L_{2}. The other direction is symmetric.

3.4.3 The typed Horn clause calculus

This section presents an inference system for proving validity in typed logic programs. In contrast to the untyped Horn clause calculus it is necessary to collect all variables used in a derivation of the inference system since validity depends on the types of variables. Let (Σ, C) be a typed logic program. We assume that equality between types (relation =_{T}) is decidable. The typed Horn clause calculus contains the following inference rules (remember that goals are finite sets of atoms and therefore we use set notations for the modification of goals):

1. Axioms: If V is a set of typed variables and L ← G ∈ C is a (Σ, X, V)-clause, then (Σ, C, V) ⊢ L ← G.

2. Substitution rule: If (Σ, C, V) ⊢ L ← G and σ ∈ Sub_{Σ}(X, V, V′), then (Σ, C, V′) ⊢ σ(L) ← σ(G).

3. Cut rule: If (Σ, C, V) ⊢ L ← G_{0} ∪ {L_{0}}, (Σ, C, V) ⊢ L_{1} ← G_{1}, and L_{0} =_{T} L_{1}, then (Σ, C, V) ⊢ L ← G_{0} ∪ G_{1}.

We write (Σ, C, V ) ⊢ L if (Σ, C, V) ⊢ L ← ∅ can be deduced by these inference rules.

The soundness of the typed Horn clause calculus can be shown by proving the soundness of each inference rule:

Theorem 3.19 (Soundness of deduction) Let (Σ, C) be a typed logic program, V be a set of typed variables and L be a (Σ, X, V)-atom. If (Σ, C, V) ⊢ L, then (Σ, C, V) ⊧ L.

Proof: Let M be a model for (Σ, C). By induction on the length of a deduction we show that M, V_{i} ⊧ L_{i} ← G_{i} for each element (Σ, C, V_{i}) ⊢ L_{i} ← G_{i} in a deduction for L ← ∅.

1. Axioms: If L_{i} ← G_{i} ∈ C, then M, var(L_{i} ← G_{i}) ⊧ L_{i} ← G_{i}. Let v be a variable assignment for (X, V_{i}) in M (if there exists no such variable assignment, then M, V_{i} ⊧ L_{i} ← G_{i} is trivially true). Let v′ be the restriction of v to (X, var(L_{i} ← G_{i})). Then M, v′ ⊧ L_{i} ← G_{i} is true and therefore M, v ⊧ L_{i} ← G_{i} is also true.

2. Substitution rule: Let σ ∈ Sub_{Σ}(X, V_{i}, V′_{i}) be a typed substitution, σ̂ be the corresponding Σ-homomorphism (cf. lemma 3.11) and v′ be a variable assignment for (X, V′_{i}) in M (if there exists no such variable assignment, then M, V′_{i} ⊧ σ(L_{i}) ← σ(G_{i}) is trivially true). v := v′ ∘ σ̂ is a variable assignment for (X, V_{i}) in M. By induction hypothesis, M, v ⊧ L_{i} ← G_{i}. Suppose now that M, v′ ⊧ σ(G_{i}). Lemma 3.12 yields M, v ⊧ G_{i}. This implies M, v ⊧ L_{i} and, again by lemma 3.12, M, v′ ⊧ σ(L_{i}). Therefore, M, v′ ⊧ σ(L_{i}) ← σ(G_{i}).

3. Cut rule: Let (Σ, C, V_{i}) ⊢ L_{i} ← G_{i} ∪ {L′_{i}} and (Σ, C, V_{j}) ⊢ L_{j} ← G_{j} be elements of the deduction with V_{i} = V_{j} and L′_{i} =_{T} L_{j}. Let v be a variable assignment for (X, V_{i}) in M with M, v ⊧ G_{i} ∪ G_{j} (if there exists no such variable assignment, then M, V_{i} ⊧ L_{i} ← G_{i} ∪ G_{j} is trivially true). By induction hypothesis, M, v ⊧ L_{i} ← G_{i} ∪ {L′_{i}} and M, v ⊧ L_{j} ← G_{j}. Since M, v ⊧ G_{j}, we obtain M, v ⊧ L_{j} which is equivalent to M, v ⊧ L′_{i} by lemma 3.18. On the other hand, M, v ⊧ G_{i}. Hence M, v ⊧ G_{i} ∪ {L′_{i}} and M, v ⊧ L_{i}. Therefore, M, v ⊧ L_{i} ← G_{i} ∪ G_{j}, as required.

The completeness of deduction is proved by the construction of a particular model that is the extension of a free term interpretation to an interpretation with particular predicate denotations.

Let V be a set of typed variables. The deductive term interpretation T_{Σ,C}(X, V ) of the typed logic program (Σ, C) is the triple (T_{T ax}(X), S, δ) with:

1. T_{T ax}(X) := T_{T} (X)/ ≡_{T ax}, the quotient of the algebra of type expressions by the congruence relation ≡_{T ax} generated by the axioms in the type specification T = (T s, T op, T ax).

2. For all [τ] ∈ T_{T ax}(X),

S_{[τ]} := {t:[τ] | t:[τ] ∈ CT erm_{Σ}(X, V)}

3. If f:[τ_{1}], …, [τ_{n}] → [τ] ∈ F unc_{T_{T ax}(X)} and t_{i}:[τ_{i}] ∈ S_{[τ_{i}]} for i = 1, …, n, then

δ_{f:[τ_{1}],...,[τ_{n}]→[τ]}(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]) := f(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]):[τ]

4. If p:[τ_{1}], …, [τ_{n}] ∈ P red_{T_{T ax}(X)}, then

\begin{aligned}δ_{p:[τ_{1}],...,[τ_{n}]} := \{(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]) | & (Σ, C, V) ⊢ p(t′_{1}:τ′_{1}, …, t′_{n}:τ′_{n}) and \\ & t_{i}:[τ_{i}] = C(t′_{i}:τ′_{i})\} \end{aligned}

The difference between T_{Σ}(X, V) and T_{Σ,C}(X, V) is the denotation of predicate symbols.

The completeness proof of the typed Horn clause calculus is based on the fact that T_{Σ,C}(X, V) is a model for (Σ, C). Therefore we need the following lemma:

Lemma 3.20 Let (Σ, C) be a typed logic program and V be a set of typed variables. T_{Σ,C}(X, V) is a model for (Σ, C).

Proof: It is clear by the above definition that T_{Σ,C}(X, V) = (T_{T ax}(X), S, δ) is a Σinterpretation. We have to prove that all clauses from C are valid in T_{Σ,C}(X, V). Let L ← G be a clause from C and v be a variable assignment for (X, V_{c}) in T_{Σ,C}(X, V) with T_{Σ,C}(X, V), v ⊧ G, where V_{c} := var(L ← G). v(α) ∈ T_{T ax}(X) for all α ∈ X and v(x:τ) ∈ S_{v(τ)} for all x:τ ∈ V_{c}, i.e., each variable from X and V_{c} is mapped into an equivalence class of types and a canonical term, respectively. We choose from each equivalence class v(α) a representative τ_{α} with v(α) = [τ_{α}] and for each canonical term v(x:τ) a well-typed term t_{x}:τ_{x} with v(x:τ) = C(t_{x}:τ_{x}). We define a typed substitution by v′(α) = τ_{α} for all α ∈ X and v′(x:τ) = t_{x}:v′(τ) for all x:τ ∈ V_{c} (t_{x}:v′(τ) is a well-typed term by lemma 3.7 since [τ_{x}] = v(τ) = [v′(τ)]). Lemma 3.11 yields v([τ]) = [v′(τ)] for all τ ∈ T_{T} (X) and v(C(t:τ)) = C(v′(t:τ)) for all t:τ ∈ T erm_{Σ}(X, V_{c}). If G = L_{1}, …, L_{k}, then T_{Σ,C}(X, V), v ⊧ L_{i}, for i = 1, …, k. If L_{i} = p_{i}(t_{i1}:τ_{i1}, …, t_{in_{i}}:τ_{in_{i}}), we obtain

(v(C(t_{i1}:τ_{i1})), …, v(C(t_{in_{i}}:τ_{in_{i}}))) ∈ δ_{p_{i}:v([τ_{i1}]),...,v([τ_{in_{i}}])}

and, by lemma 3.11,

(C(v′(t_{i1}:τ_{i1})), …, C(v′(t_{in_{i}}:τ_{in_{i}}))) ∈ δ_{p_{i}:[v′(τ_{i1})],...,[v′(τ_{in_{i}})]}

By definition of T_{Σ,C}(X, V), there exists a (Σ, X, V)-atom L′_{i} with

(Σ, C, V) ⊢ L′_{i} and L′_{i} =_{T} p_{i}(v′(t_{i1}:τ_{i1}), …, v′(t_{in_{i}}:τ_{in_{i}}))

On the other hand, (Σ, C, V_{c}) ⊢ L ← G is true, and therefore (Σ, C, V) ⊢ v′(L) ← v′(G) by the substitution rule. By the cut rule, we can infer (Σ, C, V) ⊢ v′(L) ←. If L = p(t_{1}:τ_{1}, …, t_{n}:τ_{n}), then

(Σ, C, V) ⊢ p(v′(t_{1}:τ_{1}), …, v′(t_{n}:τ_{n}))

By definition of T_{Σ,C}(X, V),

(C(v′(t_{1}:τ_{1})), …, C(v′(t_{n}:τ_{n}))) ∈ δ_{p:[v′(τ_{1})],...,[v′(τ_{n})]}

Lemma 3.11 yields

(v(C(t_{1}:τ_{1})), …, v(C(t_{n}:τ_{n}))) ∈ δ_{p:v([τ_{1}]),...,v([τ_{n}])}

which implies T_{Σ,C}(X, V), v ⊧ L.

Now we are prepared to state the completeness of the typed Horn clause calculus:

Theorem 3.21 (Completeness of deduction) Let (Σ, C) be a typed logic program, V be a set of typed variables and L be a (Σ, X, V)-atom with (Σ, C, V) ⊧ L. Then there exists a (Σ, X, V)-atom L′ with L =_{T} L′ and (Σ, C, V) ⊢ L′.

Proof: Let (Σ, C, V) ⊧ L and L = p(t_{1}:τ_{1}, …, t_{n}:τ_{n}). By the last lemma, T_{Σ,C}(X, V) = (T_{T ax}(X), S, δ) is a model for (Σ, C). This implies T_{Σ,C}(X, V), V ⊧ L. In particular we have T_{Σ,C}(X, V), id ⊧ L (where id(α) = [α] for all α ∈ X and id(x:τ) = x:[τ] for all x:τ ∈ V) which implies

(C(t_{1}:τ_{1}), …, C(t_{n}:τ_{n})) ∈ δ_{p:[τ_{1}],...,[τ_{n}]}

By definition of T_{Σ,C}(X, V), there exist t′_{i}:τ′_{i} (i = 1, …, n) with (Σ, C, V) ⊢ L′ where L′ = p(t′_{1}:τ′_{1}, …, t′_{n}:τ′_{n}) and C(t_{i}:τ_{i}) = C(t′_{i}:τ′_{i}) for i = 1, …, n. Thus L =_{T} L′, as required.

The typed Horn clause calculus is only complete up to T -equality since T -equal atoms are only compared in the cut rule. For instance, if

p(0:zero) ←

is the only clause for predicate p:α and zero =_{T} nat(zero), then (Σ, C, ∅) ⊧ p(0:nat(zero)) (by lemma 3.18), but (Σ, C, ∅) ⊢ p(0:nat(zero)) is not provable in the typed Horn clause calculus.

3.4.4 Initial model

This section shows the existence of an initial model for any typed logic program. The carrier set of this initial model contains all canonical terms without type variables and typed variables. This result is a consequence of the previous section on the typed Horn clause calculus.

Theorem 3.22 (Initial model) Let (Σ, C) be a typed logic program. Then T_{Σ,C} := T_{Σ,C}(∅, ∅) is initial in the class of all models for (Σ, C).

Proof: Let T_{Σ,C} = (T_{T ax}, S_{I}, δ_{I}). By lemma 3.20, this is a model for (Σ, C). Let I = (A, S, δ) be another model for (Σ, C) and T_{Σ}(∅, ∅) be the term interpretation with ground terms. By lemma 3.8 (free term structure), there exists a unique Σ-homomorphism (σ, h) from T_{Σ}(∅, ∅) into I. In order to show that (σ, h) is a Σ-homomorphism from T_{Σ,C} into I, we have to prove the following implication

(t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]) ∈ δ_{I,p:[τ_{1}],...,[τ_{n}]} ⟹ (h(t_{1}:[τ_{1}]), …, h(t_{n}:[τ_{n}])) ∈ δ_{p:σ([τ_{1}]),...,σ([τ_{n}])}

because the only difference between T_{Σ}(∅, ∅) and T_{Σ,C} is the denotation of predicate symbols.

Let p:[τ_{1}], …, [τ_{n}] ∈ P red_{T_{T ax}} and (t_{1}:[τ_{1}], …, t_{n}:[τ_{n}]) ∈ δ_{I,p:[τ_{1}],...,[τ_{n}]}. By definition of T_{Σ,C}, there exist t′_{i}:τ′_{i} with C(t′_{i}:τ′_{i}) = t_{i}:[τ_{i}] (i = 1, …, n) and

(Σ, C, ∅) ⊢ p(t′_{1}:τ′_{1}, …, t′_{n}:τ′_{n})

Theorem 3.19 implies (Σ, C, ∅) ⊧ p(t′_{1}:τ′_{1}, …, t′_{n}:τ′_{n}). ⟹ I, ∅ ⊧ p(t′_{1}:τ′_{1}, …, t′_{n}:τ′_{n}) ⟹ I, (σ, h) ⊧ p(t′_{1}:τ′_{1}, …, t′_{n}:τ′_{n}) ⟹ (h(C(t′_{1}:τ′_{1})), …, h(C(t′_{n}:τ′_{n}))) ∈ δ_{p:σ([τ′_{1}]),...,σ([τ′_{n}])} ⟹ (h(t_{1}:[τ_{1}]), …, h(t_{n}:[τ_{n}])) ∈ δ_{p:σ([τ_{1}]),...,σ([τ_{n}])} Therefore (σ, h) is a Σ-homomorphism from T_{Σ,C} into I which implies the initiality of T_{Σ,C}.

3.5 Unification

In logic programming we are interested in a systematic method for proving validity of goals. The typed Horn clause calculus is very inefficient for this purpose. In untyped Horn clause logic the resolution principle [Rob65] is the basic proof method where a most general unifier of two atoms must be computed in each resolution step. We need a similar operation for the resolution method in our typed framework. As in order-sorted logic, the unification problem is not unitary in our general framework and therefore complete sets of unifiers must be considered. This section defines the unification w.r.t. a type specification T and presents a non-deterministic algorithm for computing complete sets of unifiers.

Example 3.23 Consider example 3.2. The first clause for plus

plus(0:nat(zero),N:nat(α),N:nat(α))

cannot be applied to prove the goal

plus(N1:nat(posint),N2:nat(β),N3:nat(γ))

since this would cause the binding of variable N1 to 0 which yields the ill-typed term 0:nat(posint). In order to avoid such bindings, the unification procedure has to take into account that N1 and 0 have the non-unifiable types nat(posint) and nat(zero). On the other hand, if the clause

p(N:nat(zero)) ← ⋯

is applied to prove the goal

p(N1:nat(α))

then the variable N1 is constrained to type nat(zero) which may avoid some unnecessary search and backtracking steps in the subsequent proof. Therefore the unification procedure has to consider the types of the terms. An untyped unification cannot be applied in our framework.

We have mentioned in Section 3.4 that our proof procedures should manipulate well-typed terms rather than canonical terms. Therefore we have introduced typed substitutions which are mappings on type expressions and well-typed terms and directly related to Σ-homomorphisms between canonical term interpretations. Hence we want to define a unifier w.r.t. a type specification T as a distinct typed substitution. Since the composition of two typed substitutions is again a typed substitution, we can define the following notions (we assume that V, V_{1}, V_{2} are sets of typed variables):

• Let σ, σ′ ∈ Sub_{Σ}(X, V, V_{1}) be typed substitutions. We write σ =_{T} σ′ iff σ(α) =_{T} σ′(α) for all α ∈ X and σ(x:τ) =_{T} σ′(x:τ) for all x:τ ∈ V.

• Let σ ∈ Sub_{Σ}(X, V, V_{1}) and σ′ ∈ Sub_{Σ}(X, V, V_{2}) be typed substitutions. σ is more general than σ′ w.r.t. T or σ′ is a T -instance of σ, denoted σ ≤_{T} σ′, iff there exists ϕ ∈ Sub_{Σ}(X, V_{1}, V_{2}) with ϕ ∘ σ =_{T} σ′.

• Let t and t′ be (Σ, X, V)-terms. t and t′ are T -unifiable if there exists a typed substitution σ ∈ Sub_{Σ}(X, V, V′) with σ(t) =_{T} σ(t′) for a set of typed variables V′. In this case σ is called a T -unifier for t and t′. By SU_{T} (t, t′) we denote the set of all T -unifiers for t and t′.

• Let t and t′ be (Σ, X, V)-terms. We call a set of typed substitutions CSU_{T} (t, t′) a complete set of T -unifiers for t and t′ if the following conditions hold:

– CSU_{T} (t, t′) ⊆ SU_{T} (t, t′)

– For all σ′ ∈ SU_{T} (t, t′) there exists a typed substitution σ ∈ CSU_{T} (t, t′)

with σ ≤_{T} σ′.

(T) (σ, ⟨t_{1}:τ_{1} = t_{2}:τ_{2}, E_{r}⟩) ⟹^{unif} (ϕ ∘ σ, ⟨ϕ(t_{1}:τ_{1}) = ϕ(t_{2}:τ_{2}), ϕ(E_{r})⟩)

if ϕ ∈ CSU_{T} (τ_{1}, τ_{2}) and not τ_{1} =_{T} τ_{2}

(E1) (σ, ⟨x:τ = t:τ′, E_{r}⟩) ⟹^{unif} (σ′ ∘ σ, σ′(E_{r}))

if τ =_{T} τ′, x ∈ V ar, x does not occur in t:τ′ and σ′ = {x:τ/t:τ}

(E2) (σ, ⟨t:τ′ = x:τ, E_{r}⟩) ⟹^{unif} (σ′ ∘ σ, σ′(E_{r}))

if τ =_{T} τ′, x ∈ V ar, x does not occur in t:τ′ and σ′ = {x:τ/t:τ}

(D) (σ, ⟨f(t_{1}, …, t_{n}):τ = f(t′_{1}, …, t′_{n}):τ′, E_{r}⟩) ⟹^{unif} (σ, ⟨t_{1} = t′_{1}, …, t_{n} =

t′_{n}, E_{r}⟩)

if τ =_{T} τ′ (n ≥ 0)

Figure 3.2: Rules for T -unification of well-typed terms. In the first rule (T) the type substitution ϕ is extended to a typed substitution by ϕ(x:τ) := x:ϕ(τ) for all x:τ ∈ V′ if σ ∈ Sub_{Σ}(X, V, V′).

T -unifiers and complete sets of T -unifiers for type expressions are analogously defined as particular (sets of) type substitutions.

Obviously, the set of all T -unifiers is also a complete set of T -unifiers, but usually we are interested in algorithms which enumerate a complete set of T -unifiers with some minimality condition. We do not discuss this in detail here. We assume a given algorithm that enumerates a complete set of T -unifiers for two arbitrary type expressions and construct an algorithm which enumerates a complete set of T -unifiers for two arbitrary well-typed terms. We formulate the algorithm as a non-deterministic procedure for computing a T -unifier for a given list of pairs of well-typed terms.

For that purpose we define a binary relation ⟹^{unif} on pairs of the form (σ, E) where σ is a typed substitution and E is a list of appropriate equations, i.e., if σ ∈ Sub_{Σ}(X, V, V′) then E is a list of pairs of (Σ, X, V′)-terms. We write ⟨t = t′, E_{r}⟩ for an equation list where the pair (t, t′) is the first equation and E_{r} is the list of the remaining equations. The relation ⟹^{unif} is defined by the rules in figure 3.2. In the first rule (T) the result types of the left-hand side and the right-hand side of the first equation are unified by a T -unifier, i.e., the result types are T -equal after an application of this rule. T -equality of these result types is a precondition for the applicability of the other rules. The rules (E1) and (E2) eliminate an equation containing a variable in one side. The typed substitution σ′ in these elimination rules is well-defined since t:τ is well-typed by τ =_{T} τ′ and lemma 3.7. The rule (D) decomposes an equation if the left-hand side and the right-hand side are compound terms with the same main functor and arity.

Let ⟹^{unif}^{+} be the transitive closure of ⟹^{unif}. The result of unifying the (Σ, X, V)- terms t and t′ is the set

Unif(t, t′) := { σ | (id_{X,V} , ⟨t = t′⟩) ⟹^{unif}^{+} (σ, ⟨⟩) }

where ⟨⟩ denotes the empty list of equations.

Note that ⟹^{unif}^{+} is an extension of Robinson’s unification algorithm [Rob65] [BC83]: If one term is a variable which does not occur in the other term, then this variable is bound to the other term. If two composite terms have to be unified, then all corresponding components of the terms are unified. The only (but essential) difference is that the types of two terms are T -unified before the terms will be unified.

We will show that Unif(t, t′) is a complete set of T -unifiers for t and t′. First we show that there are no infinite chains in the computation of Unif(t, t′):

Lemma 3.24 Let t and t′ be (Σ, X, V)-terms. Then any sequence

(id_{X,V} , ⟨t = t′⟩) ⟹^{unif} (σ_{1}, E_{1}) ⟹^{unif} (σ_{2}, E_{2}) ⟹^{unif} ⋯

terminates.

Proof: We define the complexity ∥t:τ∥ of a term t:τ by

• ∥x:τ′∥ := 1 for all variables x:τ ∈ V

• ∥f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ∥ := ∥t_{1}:τ_{1}∥ + ⋯ + ∥t_{n}:τ_{n}∥ + 1 for all terms f(t_{1}:τ_{1}, …, t_{n}:τ_{n}):τ ∈ T erm_{Σ}(X, V) (n ≥ 0)

and the type difference tdiff(t:τ, t′:τ′) of two terms by

tdiff(t:τ, t′:τ′) := \{ \begin{matrix}0 & if τ =_{T} τ′ \\ 1 & otherwise \end{matrix}

The complexity of a list of equations E = ⟨t_{1} = t′_{1}, …, t_{k} = t′_{k}⟩ is defined to be the triple

∥E∥ := (|⋃_{i=1}^{k} uvar(t_{i}) ∪ uvar(t′_{i})| , ∑_{i=1}^{k} ∥t_{i}∥ + ∥t′_{i}∥, ∑_{i=1}^{k} tdiff(t_{i}, t′_{i}))

where | ⋯ | denotes the cardinality of a set. The lexicographic ordering on tuples of natural numbers is a noetherian ordering, i.e., there is no infinite sequence ⟨e_{1}, e_{2}, e_{3}, …⟩ with e_{i} > e_{i+1}. By definition of the relation ⟹^{unif} it is clear that ∥E∥ > ∥E′∥ if (σ, E) ⟹^{unif} (σ′, E′) since the first rule decrements only the third component of the complexity, the rules (E1) and (E2) eliminate a variable which reduces the first component of the complexity, and the last rule decreases the second component of the complexity. Therefore any ⟹^{unif}-sequence terminates.

In the proofs of the following lemmas we use the notion of T -unifiers on lists of equations: If ⟨t_{1} = t′_{1}, …, t_{k} = t′_{k}⟩ is a list of equations, then a T -unifier for this list is a typed substitution that T -unifies each pair t_{i} = t′_{i} (i = 1, …, k). The next lemma shows the soundness of the T -unification procedure:

Lemma 3.25 Let t and t′ be (Σ, X, V)-terms and σ ∈ Unif(t, t′). Then σ ∈ SU_{T} (t, t′), i.e., σ is a T -unifier for t and t′.

Proof: Since σ ∈ Unif(t, t′), there is a sequence

(σ_{0}, E_{0}) ⟹^{unif} (σ_{1}, E_{1}) ⟹^{unif} ⋯ ⟹^{unif} (σ_{k}, ⟨⟩)

where σ_{0} = id_{X,V} and E_{0} = ⟨t = t′⟩. We show by induction on the elements of the sequence: For each 0 ≤ i ≤ k there exists a typed substitution ϕ_{i} with σ_{k} = ϕ_{i} ∘ σ_{i} and ϕ_{i} ∈ SU_{T} (E_{i}).

For i = k we choose ϕ_{k} = id_{X,V′} (where σ_{k} ∈ Sub_{Σ}(X, V, V′)). For the induction step we assume the existence of a typed substitution ϕ_{i} with σ_{k} = ϕ_{i} ∘ σ_{i} and ϕ_{i} ∈ SU_{T} (E_{i}). Since (σ_{i−1}, E_{i−1}) ⟹^{unif} (σ_{i}, E_{i}), there are four possible cases:

1. Rule (T) has been applied in this step. Then E_{i−1} = ⟨t_{1}:τ_{1} = t_{2}:τ_{2}, E_{r}⟩ and ϕ ∈ CSU_{T} (τ_{1}, τ_{2}) with σ_{i} = ϕ ∘ σ_{i−1} and E_{i} = ⟨ϕ(t_{1}:τ_{1}) = ϕ(t_{2}:τ_{2}), ϕ(E_{r})⟩. Hence σ_{k} = ϕ_{i} ∘σ_{i} = ϕ_{i} ∘ϕ∘σ_{i−1} = ϕ_{i−1} ∘σ_{i−1} with ϕ_{i−1} := ϕ_{i} ∘ϕ. Moreover, if l = r occurs in E_{i−1}, then ϕ(l) = ϕ(r) occurs in E_{i} and ϕ_{i} is a T -unifier for ϕ(l) and ϕ(r) which implies ϕ_{i−1} ∈ SU_{T} (E_{i−1}).

2. Rule (E1) has been applied in this step. Then E_{i−1} = ⟨x:τ = t:τ′, E_{r}⟩ with τ =_{T} τ′, x ∈ V ar, x ∉ uvar(t:τ′), σ_{i} = σ′ ∘ σ_{i−1} and E_{i} = σ′(E_{r}) where σ′ = {x:τ/t:τ}. Hence σ_{k} = ϕ_{i} ∘ σ_{i} = ϕ_{i} ∘ σ′ ∘ σ_{i−1} = ϕ_{i−1} ∘ σ_{i−1} with ϕ_{i−1} := ϕ_{i} ∘ σ′. Moreover,

ϕ_{i−1}(x:τ) = ϕ_{i} ∘ σ′(x:τ)
= ϕ_{i}(t:τ)
=_{T} ϕ_{i}(t:τ′) (since τ =_{T} τ′)
= ϕ_{i} ∘ σ′(t:τ′) (since x ∉ uvar(t:τ′))
= ϕ_{i−1}(t:τ′)

If E_{r} contains an equation l = r, then σ′(l) = σ′(r) occurs in E_{i} and ϕ_{i} is a T -unifier for σ′(l) and σ′(r), i.e., ϕ_{i−1} is a T -unifier for l and r. Thus ϕ_{i−1} ∈ SU_{T} (E_{i−1}).

3. The application of rule (E2) is symmetric to the previous case.

4. Rule (D) has been applied in this step. Then E_{i−1} = ⟨f(t_{1}, …, t_{n}):τ = f(t′_{1}, …, t′_{n}):τ′, E_{r}⟩ with τ =_{T} τ′, σ_{i} = σ_{i−1} and E_{i} = ⟨t_{1} = t′_{1}, …, t_{n} = t′_{n}, E_{r}⟩. Hence σ_{k} = ϕ_{i} ∘ σ_{i} = ϕ_{i} ∘ σ_{i−1}. Moreover,

ϕ_{i}(f(t_{1}, …, t_{n}):τ)
= f(ϕ_{i}(t_{1}), …, ϕ_{i}(t_{n})):ϕ_{i}(τ)
=_{T} f(ϕ_{i}(t_{1}), …, ϕ_{i}(t_{n})):ϕ_{i}(τ′) (since τ =_{T} τ′)
=_{T} f(ϕ_{i}(t′_{1}), …, ϕ_{i}(t′_{n})):ϕ_{i}(τ′) (ϕ_{i} ∈ SU_{T} (E_{i}) by ind. hypothesis)
= ϕ_{i}(f(t′_{1}, …, t′_{n}):τ′)

If E_{r} contains an equation l = r, then l = r occurs also in E_{i}, i.e., ϕ_{i} is a T -unifier for l and r. Thus ϕ_{i} ∈ SU_{T} (E_{i−1}).

We obtain for i = 0: σ_{k} = ϕ_{0} ∘ σ_{0} = ϕ_{0} and σ_{k} ∈ SU_{T} (t, t′).

The next lemma shows the completeness of the T -unification procedure:

Lemma 3.26 Let t and t′ be (Σ, X, V)-terms and θ ∈ SU_{T} (t, t′). Then there exists a typed substitution σ ∈ Unif(t, t′) such that θ =_{T} ϕ ∘ σ for a typed substitution ϕ.

Proof: First we prove the following proposition:

Let σ ∈ Sub_{Σ}(X, V, V′) be a typed substitution, E be a non-empty list of (Σ, X, V′)-equations, θ ∈ SU_{T} (E). Then there exists a pair (σ′, E′) with (σ, E) ⟹^{unif} (σ′, E′) and θ ∘σ =_{T} θ′ ∘σ′ for some typed substitution θ′ ∈ SU_{T} (E′).

To prove this proposition we assume a T -unifier θ for the non-empty list of equations E. We distinguish the following cases:

1. E = ⟨t_{1}:τ_{1} = t_{2}:τ_{2}, E_{r}⟩ and not τ_{1} =_{T} τ_{2}. Since θ ∈ SU_{T} (t_{1}:τ_{1}, t_{2}:τ_{2}), the restriction of θ on T_{T} (X) is also a T -unifier for τ_{1} and τ_{2}. Hence there exists a type substitution ϕ ∈ CSU_{T} (τ_{1}, τ_{2}) with θ|_{T_{T} (X)} =_{T} ψ ∘ ϕ for some type substitution ψ. It is straightforward to extend ϕ and ψ to typed substitutions such that θ =_{T} ψ ∘ϕ. Thus there is the following unification step by rule (T):

(σ, E) ⟹^{unif} (ϕ ∘ σ, ϕ(E))

and θ ∘ σ =_{T} ψ ∘ ϕ ∘ σ. To see that ψ ∈ SU_{T} (ϕ(E)) assume an equation l = r from E. Then

ψ(ϕ(l)) =_{T} θ(l) =_{T} θ(r) =_{T} ψ(ϕ(l))

since θ is a T -unifier for E.

2. E = ⟨t_{1}:τ_{1} = t_{2}:τ_{2}, E_{r}⟩ and τ_{1} =_{T} τ_{2}. Then there are the following cases:

(a) t_{1} ∈ V ar: Since θ is a T -unifier for t_{1}:τ_{1} and t_{2}:τ_{2}, t_{1} ∉ uvar(t_{2}:τ_{2}) and thus there is the following unification step:

(σ, E) ⟹^{unif} (σ′ ∘ σ, σ′(E_{r}))

where σ′ is the typed substitution {t_{1}:τ_{1}/t_{2}:τ_{1}}. It is easy to show that θ∘σ′ =_{T} θ and therefore θ∘σ =_{T} θ∘σ′∘σ. To see that θ ∈ SU_{T} (σ′(E_{r})) assume an equation l = r from E_{r}. Then

θ(σ′(l)) =_{T} θ(l) =_{T} θ(r) =_{T} θ(σ′(l))

since θ is a T -unifier for E.

(b) t_{2} ∈ V ar: This is symmetric to the previous case.

(c) t_{1}:τ_{1} = f(r_{1}, …, r_{n}):τ_{1} and t_{2}:τ_{2} is not a typed variable: Since θ is a T -unifier for t_{1}:τ_{1} and t_{2}:τ_{2}, it must be t_{2}:τ_{2} = f(r′_{1}, …, r′_{n}):τ_{2}. Then there is the following unification step:

(σ, E) ⟹^{unif} (σ, ⟨r_{1} = r′_{1}, …, r_{n} = r′_{n}, E_{r}⟩)

θ is a T -unifier for all equations r_{i} = r′_{i} and for E_{r} since θ is a T -unifier for E.

Hence the proposition is true. Let θ be a T -unifier for the (Σ, X, V)-terms t and t′. By the above proposition, there is a sequence

(id_{X,V} , ⟨t = t′⟩) ⟹^{unif} (σ_{1}, E_{1}) ⟹^{unif} (σ_{2}, E_{2}) ⟹^{unif} ⋯

with θ =_{T} θ ∘ id_{X,V} =_{T} θ_{1} ∘ σ_{1} =_{T} θ_{2} ∘ σ_{2} =_{T} ⋯ for some typed substitutions

θ_{1}, θ_{2}, … Since all ⟹^{unif}-sequences are finite (lemma 3.24), there must be a last element (σ_{k}, ⟨⟩) in the sequence. Thus σ_{k} ∈ Unif(t, t′) and θ =_{T} θ_{k} ∘ σ_{k}.

Theorem 3.27 (T -unification) Let t and t′ be (Σ, X, V)-terms. Then Unif(t, t′) is a complete set of T -unifiers.

Proof: Unif(t, t′) ⊆ SU_{T} (t, t′) follows from lemma 3.25 and completeness follows from lemma 3.26.

Example 3.28 Consider the polymorphic signature of example 3.2. The terms 0:zero and N:nat(α) should be unified by our unification procedure. First, the types of terms zero and nat(α) are T -unified and the result is the T -unifier {α/zero}. Then N is bound to 0 and the result is the T - unifier {α/zero, N:nat(α)/0:nat(zero)}. For the unification of the terms s(N1:nat(posint)):posint and s(N2:nat(α)):nat(posint) the following steps are performed:

• The types posint and nat(posint) are T -equal and need not be unified.

• By the decomposition rule, the terms N1:nat(posint) and N2:nat(α) are unified in the next unification step.

• The types nat(posint) and nat(α) are T -unified. The result is the type substitution {α/posint}.

• N2 is bound to N1 (or vice versa). Thus the complete result of the unification is the typed substitution

{α/posint, N2:nat(α)/N1:nat(posint)}

Example 3.29 Consider the following type specification T :

\begin{aligned}TYPEOPS & s_{0}: & & → & type \\ & s_{1}: & type & → & type \\ & s_{2}: & type & → & type \end{aligned}

    TYPEAXIOMS s_{1}(s_{0}) = s_{0}

s_{2}(s_{0}) = s_{0}

Thus s_{0} is a common subtype of s_{1} and s_{2}. The unification of the typed terms X:s_{1}(α) and Y:s_{2}(β) requires a T -unifier for the type expressions s_{1}(α) and s_{2}(β) which can be computed by the narrowing procedure (see remarks at the end of Section 3.6). Hence the type substitution {α/s_{0}, β/s_{0}} is a T -unifier for the type expressions s_{1}(α) and s_{2}(β) and the typed substitution

{α/s_{0}, β/s_{0}, X:s_{1}(α)/Y:s_{1}(s_{0})}

is a T -unifier for the terms X:s_{1}(α) and Y:s_{2}(β). Therefore the variables X and Y are constrained to the common subsort s_{0} by the unification procedure (note the analogy to order-sorted unification [SNGM89]).

In the next section we will see that resolution is a sound and complete proof procedure for typed logic programs if the unification procedure used in the resolution steps computes a complete set of T -unifiers. Therefore the unification procedure presented in this section gives us some information about the rôle of different type systems for logic programming. We have seen that the classical unification algorithm of Robinson can be adapted to the typed framework if the types of terms are unified before unifying the terms. Hence our unification procedure shows that the decidability of the typed unification problem is dependent on the decidability of the unification problem in the type theory: If it is decidable whether two types are unifiable w.r.t. the type specification T , then the unification problem for typed terms w.r.t. T is also decidable because all ⟹^{unif}-sequences terminate (lemma 3.24) and unifiable terms can always be derived to an empty equation list (lemma 3.26). Moreover, different type structures influence the complexity of the unification procedure. For the general case a complex procedure for the unification of type terms w.r.t. the equational type specification is necessary. But for simpler type structures a less complex unification procedure may be sufficient:

• If the type structure is many-sorted without overloading, i.e., there are only basic types and no equations in the type structure and there is exactly one type declaration for each function and predicate symbol, then all types can be omitted while unifying two terms or atoms since two composite terms or atoms with the same functor or predicate, respectively, have always the same type.

• If the type structure is polymorphic without any equations between types, then the T -unifier for two types is the unifier of the type expressions in the free type term algebra. Hence there exists a most general unifier for two unifiable type terms which can be computed by Robinson’s unification algorithm. This implies the existence of a most general unifier for two T - unifiable typed terms and Robinson’s unification algorithm can be used as a T -unification procedure on typed terms if type expressions are represented as first-order terms (cf. [Han89a]). Moreover, if the polymorphic signature and the typed program satisfy some additional restrictions, it has been shown that such programs are executable without any type information at run time [Han89b]. The type system of Mycroft and O’Keefe [MO84] is a special case of a polymorphic type structure.

• If the type structure is order-sorted, i.e., the type specification contains equations between types, then there does not exist a most general T -unifier for any two type expressions. Hence the T -unification procedure on typed terms must compute complete sets of T -unifiers. Nevertheless, for practical applications it is desirable that the complete sets of T -unifiers are finite which depends on the type specification. Criteria for finitary or unitary order-sorted unification can be found in [Wal89]. An overview of unification in equational theories can be found in [SS82].

• For polymorphically order-sorted type structures a full unification procedure for the equational type theory is necessary. Nevertheless, Smolka [Smo89] has shown that there are also restricted classes of polymorphically order-sorted typed logic programs where more efficient unification procedures exist.

From a conceptual point of view our unification procedure shows up the influence of types in logic programming. But for an efficient operational semantics it is necessary to omit type information at run time whenever it is possible. In [Han89a] and [Han89b] it is shown how this could be done in the polymorphic case. Similar results for the general case are a topic for further research.

3.6 Resolution

The resolution principle in untyped Horn logic (see [Rob65]) can be used as a proof procedure for typed Horn clause programs if the untyped unification is replaced by the T -unification as defined in the last section. We call a Σ-clause a variant of another Σ-clause if it is obtained by replacing type variables and typed variables by other type variables and typed variables, respectively, such that different variables are replaced by new different variables. Let (Σ, C) be a typed logic program.

a) Let G be a (Σ, X, V)-goal and the (Σ, X, V)-clause L′ ← G′ be a variant of a clause from C with tvar(G) ∩ tvar(L′ ← G′) = ∅ and uvar(G) ∩ uvar(L′ ← G′) = ∅. If there exists a T -unifier σ ∈ Sub_{Σ}(X, V, V′) for an atom L ∈ G and L′, then σ(G − {L}) ∪ σ(G′) is said to be derived by T -resolution from G relative to σ and L′ ← G′. Notation:

(Σ, C, V) G ⊢_{R} σ σ(G − {L}) ∪ σ(G′)

b) Let G_{0} be a (Σ, X, V_{0})-goal. A (Σ, C, V_{0})-resolution or T -resolution of G_{0} is a sequence of the form

(Σ, C, V_{0}) G_{0} ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} G_{2} ⊢_{R} ⋯ ⊢_{R} σ_{n} G_{n}

where (Σ, C, V_{i}) G_{i} ⊢_{R} σ_{i+1} G_{i+1} with σ_{i+1} ∈ Sub_{Σ}(X, V_{i}, V_{i+1}) for i = 0, 1, 2, …, n − 1. The (Σ, C, V_{0})-resolution is called successful if G_{n} = ∅. In this case n is called the length of the (Σ, C, V_{0})-resolution and σ := σ_{n}∘⋯∘σ_{1} is called a computed answer. Notation:

(Σ, C, V_{0}) ⊢_{R} σ G_{0}

If we replace the requirement for a T -unifier for L and L′ by the condition “σ ∈ CSU_{T} (L, L′)”, then the resolution is called a CSU_{T} -resolution (resolution with complete sets of T -unifiers) and the symbol ⊢_{R} is replaced by ⊢_{RC} . If we drop the requirement for disjoint sets of type variables and typed variables in the goal and the applied clause, we call the resolution unrestricted and replace the symbol ⊢_{R} by ⊢_{UR} .

The soundness of T -resolution can be directly proved:

Theorem 3.30 (Soundness of T -resolution) Let (Σ, C) be a typed logic program and G be a (Σ, X, V)-goal. If there is a successful T -resolution (Σ, C, V) ⊢_{R} σ G with computed answer σ ∈ Sub_{Σ}(X, V, V′), then (Σ, C, V′) ⊧ σ(G).

Proof: By induction on the length n of a successful (Σ, C, V)-resolution: n = 1: Then there is a (Σ, C, V)-resolution

(Σ, C, V) G ⊢_{R} σ ∅

where σ ∈ Sub_{Σ}(X, V, V′), i.e., G is a (Σ, C, V)-atom. By definition of T -resolution, there exists a variant L′ ← of a clause from C with σ(L′) =_{T} σ(G). Hence there exist V′′, a (Σ, X, V′′)-clause L′′ ← from C and σ′′ ∈ Sub_{Σ}(X, V′′, V) with σ′′(L′′) = L′. By lemma 3.13, (Σ, C, V′) ⊧ σ(L′) since σ(L′) = σ ∘ σ′′(L′′) and (Σ, C, V′′) ⊧ L′. Hence (Σ, C, V′) ⊧ σ(G) by lemma 3.18. n > 1: Then there is a (Σ, C, V)-resolution

(Σ, C, V) G ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} G_{2} ⊢_{R} ⋯ ⊢_{R} σ_{n} ∅

with σ = σ_{n} ∘ ⋯ ∘ σ_{1} ∈ Sub_{Σ}(X, V, V′). By definition of T -resolution, there exists a variant L′ ← G′ of a clause from C with σ_{1}(L′) =_{T} σ_{1}(L_{0}) where G = G_{0} ∪{L_{0}}. Let σ_{1} ∈ Sub(X, V, V_{1}). Then

(Σ, C, V_{1}) σ_{1}(G′) ∪ σ_{1}(G_{0}) ⊢_{R} σ_{2} G_{2} ⊢_{R} ⋯ ⊢_{R} σ_{n} ∅

is a (Σ, C, V_{1})-resolution of length n − 1. By induction hypothesis, (Σ, C, V′) ⊧ σ(G′) ∪ σ(G_{0}). Since L′ ← G′ is a variant of a clause from C, there exist V′′, a (Σ, X, V′′)-clause L′′ ← G′′ ∈ C and σ′′ ∈ Sub_{Σ}(X, V′′, V) with σ′′(L′′ ← G′′) = L′ ← G′. By lemma 3.13, (Σ, C, V′) ⊧ σ(L′ ← G′). From the fact (Σ, C, V′) ⊧ σ(G′) we infer (Σ, C, V′) ⊧ σ(L′). Lemma 3.17 and lemma 3.18 yield (Σ, C, V′) ⊧ σ(L_{0}). Hence we have (Σ, C, V′) ⊧ σ(G).

The completeness of resolution in untyped Horn logic can be proved by a fixpoint theorem using a transformation on Herbrand interpretations [vEK76] [Llo87]. In [Han91] this proof method is adapted to polymorphic logic programs. In this chapter we will show the completeness of T -resolution for typed logic programs by simulating each deduction in the typed Horn clause calculus by T -resolution.

[Pad88] has presented such a proof for many-sorted Horn clause logic with equality, but he has required that all types are interpreted as non-empty sets. This simplifies the proof but is not reasonable in our context.

In the rest of this section we assume that (Σ, C) is a typed logic program. A few technical lemmas will help to structure the completeness proof. The first lemma shows that the substitution rule is not necessary if Ĉ (the set of instantiated clauses) is used in a deduction.

Lemma 3.31 Let (Σ, C, V) ⊢ L ← G. Then for any typed substitution σ ∈ Sub_{Σ}(X, V, V′) there exists a deduction for (Σ, Ĉ, V′) ⊢ σ(L ← G) where only axioms and cut rules are applied.

Proof: We prove the lemma by induction on the number n of cut rule applications in a shortest deduction of (Σ, C, V) ⊢ L ← G. The case n = 0 is trivial since σ_{0}(L_{0}) ← σ_{0}(G_{0}) ∈ Ĉ for all L_{0} ← G_{0} ∈ C and all appropriate typed substitutions σ_{0}. Otherwise there is a last application of the cut rule in the deduction, say

(Σ, C, V_{i}) ⊢ L_{i} ← G_{i} ∪ {L′_{i}} and (Σ, C, V_{i}) ⊢ L_{j} ← G_{j} with L′_{i} =_{T} L_{j}

occur in the deduction before the last application of the cut rule. Let σ_{1} ∈ Sub_{Σ}(X, V_{i}, V′_{i}). We have to show that (Σ, Ĉ, V′_{i}) ⊢ σ_{1}(L_{i}) ← σ_{1}(G_{i} ∪ G_{j}) can be deduced without an application of the substitution rule. The number of cut rule applications in shortest derivations of

(Σ, C, V_{i}) ⊢ L_{i} ← G_{i} ∪ {L′_{i}}  and  (Σ, C, V_{i}) ⊢ L_{j} ← G_{j}

is less than n. By induction hypothesis,

(Σ, Ĉ, V′_{i}) ⊢ σ_{1}(L_{i}) ← σ_{1}(G_{i} ∪ {L′_{i}})  and  (Σ, Ĉ, V′_{i}) ⊢ σ_{1}(L_{j}) ← σ_{1}(G_{j})

can be deduced without an application of the substitution rule. Lemma 3.17 yields σ_{1}(L′_{i}) =_{T} σ_{1}(L_{j}). By an application of the cut rule, we obtain

(Σ, Ĉ, V′_{i}) ⊢ σ_{1}(L_{i}) ← σ_{1}(G_{i} ∪ G_{j})

This proves the lemma.

Lemma 3.32 If (Σ, C, V) ⊢ L ← G where only axioms and cut rules are applied, then (Σ, C′, V) ⊢_{UR} id_{X,V} L′ for all (Σ, X, V)-atoms L′ =_{T} L where C′ = C ∪ {P ← | P ∈ G}, and each substitution in the T -resolution is equal to id_{X,V}.

Proof: The lemma is proved by induction on the length of the deduction. Let d_{1}, …, d_{n} be a deduction for (Σ, C, V) ⊢ L ← G where only axioms and cut rules are applied and L′ be a (Σ, X, V)-atom with L′ =_{T} L.

If L ← G ∈ C, then (Σ, C′, V) L′ ⊢_{UR} id_{X,V} G is a T -resolution step since id_{X,V} (L′) =_{T} id_{X,V} (L). If G consists of k Σ-atoms, then we achieve the empty goal with k further unrestricted T -resolution steps with substitutions id_{X,V}.

If L ← G ∉ C, then the clause must be derived by an application of the cut rule, i.e., there are

d_{i} = (Σ, C, V) ⊢ L ← G_{0} ∪ {L_{0}}
d_{j} = (Σ, C, V) ⊢ L_{1} ← G_{1}

with L_{0} =_{T} L_{1}, G = G_{0} ∪ G_{1} and i, j < n. By induction hypothesis,

(Σ, C′ ∪ {L_{0} ←}, V) ⊢_{UR} id_{X,V} L′ for all L′ =_{T} L  (1)

and

(Σ, C′, V) ⊢_{UR} id_{X,V} L′_{1} for all L′_{1} =_{T} L_{1}  (2)

since G = G_{0} ∪ G_{1}. If the clause L_{0} ← is used in resolution (1), then, by (2), it is possible to replace the resolution step by a sequence of resolution steps that derives L_{0} to the empty goal using clauses from C′. Thus (Σ, C′, V) ⊢_{UR} id_{X,V} L′ for all L′ =_{T} L and each substitution in this T -resolution is equal to id_{X,V}.

Now we can prove the completeness of T -resolution:

Theorem 3.33 (Completeness of T -resolution for atoms) Let V, V′ be finite sets of typed variables and A be a (Σ, X, V)-atom. If σ ∈ Sub_{Σ}(X, V, V′) is a typed substitution with (Σ, C, V′) ⊧ σ(A), then there exists a set of typed variables V_{0} and a typed substitution σ_{0} ∈ Sub_{Σ}(X, V_{0}, V′) with (Σ, C, V_{0}) ⊢_{R} σ_{0} A and σ_{0}(A) = σ(A).

Proof: W.l.o.g. we assume that σ affects only a finite number of type variables since V is finite, i.e., the type domain tdom(σ) is finite. Let (Σ, C, V′) ⊧ σ(A). By theorem 3.21, there exists a (Σ, X, V)-atom A′ with A′ =_{T} σ(A) and (Σ, C, V′) ⊢ A′. By lemma 3.31 and lemma 3.32, there exists a successful unrestricted T - resolution of the form

(Σ, Ĉ, V′) σ(A) ⊢_{UR} id_{X,V′} G_{1} ⊢_{UR} id_{X,V′} ⋯ ⊢_{UR} id_{X,V′} ∅

In the first resolution step there exist L_{0} ← R_{0} ∈ C, V′_{0} and σ_{0} ∈ Sub_{Σ}(X, V′_{0}, V′) with σ_{0}(L_{0}) =_{T} σ(A) and σ_{0}(R_{0}) = G_{1}.

W.l.o.g. we assume (tdom(σ) ∪ tvar(A)) ∩ tvar(L_{0} ← R_{0}) = ∅ and uvar(V) ∩ uvar(V′_{0}) = ∅ (otherwise we choose an appropriate variant of L_{0} ← R_{0} and an appropriate typed substitution σ_{0}). We define V_{0} := V ∪ var(L_{0} ← R_{0}) and combine σ and σ_{0} into a typed substitution σ_{1} ∈ Sub_{Σ}(X, V_{0}, V′) with

σ_{1}(α) = \{ \begin{matrix}σ(α) & if α ∈ tdom(σ) ∪ tvar(A) \\ σ_{0}(α) & otherwise \end{matrix}

and

σ_{1}(x:τ) = \{ \begin{matrix}σ(x:τ) & if x:τ ∈ V \\ σ_{0}(x:τ) & if x:τ ∈ var(L_{0} ← R_{0}) \end{matrix}

Then σ_{1}(A) = σ(A) =_{T} σ_{0}(L_{0}) = σ_{1}(L_{0}) and σ_{1}(R_{0}) = σ_{0}(R_{0}) = G_{1}. Therefore

(Σ, C, V_{0}) A ⊢_{R} σ_{1} G_{1}

is a T -resolution step. If G_{1} = ∅, then the proof is finished, otherwise there is a second resolution step

(Σ, Ĉ, V′) G_{1} ⊢_{UR} id_{X,V′} G_{2}

Let L′_{1} ← R′_{1} ∈ Ĉ be the clause used in this resolution step, i.e., there exist L_{1} ← R_{1} ∈ C, V′_{1} and σ′_{1} ∈ Sub_{Σ}(X, V′_{1}, V′) with σ′_{1}(L_{1} ← R_{1}) = L′_{1} ← R′_{1}. Similarly to the first resolution step, we combine σ′_{1} and id_{X,V′} into a typed substitution σ_{2} ∈ Sub_{Σ}(X, V_{1}, V′), where V_{1} := V′ ∪ var(L_{1} ← R_{1}), such that

(Σ, C, V_{1}) G_{1} ⊢_{R} σ_{2} G_{2}

is a T -resolution step. Since V′ ⊆ V_{1}, we can extend σ_{1} to a typed substitution σ_{1} ∈ Sub_{Σ}(X, V_{0}, V_{1}). Hence we obtain the T -resolution

(Σ, C, V_{0}) A ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} G_{2}

with σ_{2}(σ_{1}(A)) = σ_{2}(σ(A)) = σ(A) and σ_{2} ∘ σ_{1} ∈ Sub_{Σ}(X, V_{0}, V′). If we apply the transformation of the second resolution step in the same way to the remaining resolution steps, we obtain a T -resolution

(Σ, C, V_{0}) A ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} ⋯ ⊢_{R} σ_{n} ∅

with σ_{n} ∘ ⋯ ∘ σ_{1}(A) = σ(A) and σ_{n} ∘ ⋯ ∘ σ_{1} ∈ Sub_{Σ}(X, V_{0}, V′).

We need the next lemma to prove the completeness of T -resolution for general goals:

Lemma 3.34 Let G be a (Σ, X, V)-goal with var(G) = {x_{1}:τ_{1}, …, x_{n}:τ_{n}}. Let p be a new symbol that does not occur in Σ, Σ′ := (H, F unc, P red ∪ {p:τ_{1}, …, τ_{n}}), L := p(x_{1}:τ_{1}, …, x_{n}:τ_{n}) and C′ := C ∪ {L ← G}. Then

(Σ, C, V′) ⊧ σ(G)  ⟹  (Σ′, C′, V′) ⊧ σ(L)

for all σ ∈ Sub_{Σ′}(X, V, V′).

Proof: Let (Σ, C, V′) ⊧ σ(G) and M′ be a model for (Σ′, C′). Then M′ is also a model for (Σ′, C) and M′, var(L ← G) ⊧ L ← G. By lemma 3.13, M′, V′ ⊧ σ(L) ← σ(G). Suppose v is a variable assignment for (X, V′) in M′. M′ is also a model for (Σ, C) if we omit the interpretation of the predicate symbol p in M′. Therefore M′, v ⊧ σ(G). M′, v ⊧ σ(L) ← σ(G) implies M′, v ⊧ σ(L). Hence we obtain M′, V′ ⊧ σ(L).

Theorem 3.35 (Completeness of T -resolution) Let V be a finite set of typed variables and G be a (Σ, X, V)-goal. If σ ∈ Sub_{Σ}(X, V, V′) is a typed substitution with (Σ, C, V′) ⊧ σ(G), then there exist a set of typed variables V_{0} and a typed substitution σ_{0} ∈ Sub_{Σ}(X, V_{0}, V′) with (Σ, C, V_{0}) ⊢_{R} σ_{0} G and σ_{0}(G) = σ(G).

Proof: Let var(G) = {x_{1}:τ_{1}, …, x_{n}:τ_{n}} and p, L, Σ′ and C′ be defined as in the last lemma. (Σ, C, V′) ⊧ σ(G) implies (Σ′, C′, V′) ⊧ σ(L). By theorem 3.33, there exist V_{0} and a typed substitution σ_{0} ∈ Sub_{Σ}(X, V_{0}, V′) with (Σ′, C′, V_{0}) ⊢_{R} σ_{0} L and σ_{0}(L) = σ(L). Since the only clause for the elimination of an atom with predicate symbol p is L ← G, there is a resolution

(Σ, C′, V_{0}) L ⊢_{R} σ_{1} σ_{1}(G) ⊢_{R} σ_{2} G_{2} ⋯ ⊢_{R} σ_{n} ∅

with σ_{0} = σ_{n} ∘ ⋯ ∘ σ_{1}. We can combine the typed substitution σ_{1} with the typed substitution σ_{2} in the second resolution step and obtain a (Σ, C, V_{0})-resolution for G with the same computed answer.

We need the following lemma to prove completeness of CSU_{T} -resolution:

Lemma 3.36 (CSU-lemma) If there is a T -resolution

(Σ, C, V) G ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} G_{2} ⊢_{R} ⋯ ⊢_{R} σ_{n} ∅

for the (Σ, X, V)-goal G, then there exists a CSU_{T} -resolution

(Σ, C, V) G ⊢_{RC} σ′_{1} G′_{1} ⊢_{RC} σ′_{2} G′_{2} ⊢_{RC} ⋯ ⊢_{RC} σ′_{n} ∅

where σ′_{n} ∘⋯∘σ′_{1} ∈ Sub_{Σ}(X, V, V′). Furthermore, there exists a typed substitution ϕ ∈ Sub_{Σ}(X, V′, V′′) with ϕ ∘ σ′_{n} ∘ ⋯ ∘ σ′_{1} =_{T} σ_{n} ∘ ⋯ ∘ σ_{1}.

Proof: By induction on the length n of the T -resolution: If n = 1, then (Σ, C, V) G ⊢_{R} σ_{1} ∅. Hence there exists a variant L ← ∅ of a clause from C with σ_{1}(G) =_{T} σ_{1}(L). By definition of complete sets of T -unifiers, there exist a unifier σ′_{1} ∈ CSU_{T} (G, L) with σ′_{1} ∈ Sub_{Σ}(X, V, V′) and a typed substitution ϕ ∈ Sub_{Σ}(X, V′, V′′) with ϕ ∘ σ′_{1} =_{T} σ_{1}. Thus (Σ, C, V) G ⊢_{RC} σ′_{1} ∅ is a CSU_{T} - resolution for G.

If n > 1, then there is a T -resolution

(Σ, C, V) G ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} G_{2} ⊢_{R} ⋯ ⊢_{R} σ_{n} ∅

Hence there exists a variant L′ ← G′ of a clause from C with σ_{1}(L′) =_{T} σ_{1}(L) where G = G_{0} ∪ {L}. By definition of CSU_{T}, there exist a unifier σ′_{1} ∈ CSU_{T} (L′, L) with σ′_{1} ∈ Sub_{Σ}(X, V, V′) and a typed substitution ϕ ∈ Sub_{Σ}(X, V′, V′′) with ϕ ∘ σ′_{1} =_{T} σ_{1}. If G′_{1} := σ′_{1}(G_{0} ∪ G′), then

(Σ, C, V) G ⊢_{RC} σ′_{1} G′_{1} ⊢_{R} σ_{2} ∘ ϕ G′′_{2}

is a T -resolution with G′′_{2} =_{T} G_{2} (w.l.o.g. we assume that ϕ does not alter any type variables or typed variables from the clause used in the second resolution step). Since

(Σ, C, V′′) G_{2} ⊢_{R} σ_{3} ⋯ ⊢_{R} σ_{n} ∅

is a T -resolution for G_{2} and G_{2} =_{T} G′′_{2}, it is clear from the definition of T -resolution that there exists a T -resolution

(Σ, C, V′′) G′′_{2} ⊢_{R} σ_{3} ⋯ ⊢_{R} σ_{n} ∅

for G′′_{2} of the same length and with the same T -unifiers. Hence

(Σ, C, V′) G′_{1} ⊢_{R} σ_{2} ∘ ϕ G′′_{2} ⊢_{R} σ_{3} ⋯ ⊢_{R} σ_{n} ∅

is a T -resolution for G′_{1} of length n − 1. By induction hypothesis, there exists a CSU_{T} -resolution

(Σ, C, V′) G′_{1} ⊢_{RC} σ′_{2} G′_{2} ⊢_{RC} ⋯ ⊢_{RC} σ′_{n} ∅

where σ′_{n} ∘ ⋯ ∘ σ′_{2} ∈ Sub_{Σ}(X, V′, V_{1}), and there exists a typed substitution ρ ∈ Sub_{Σ}(X, V_{1}, V_{2}) with ρ ∘ σ′_{n} ∘ ⋯ ∘ σ′_{2} =_{T} σ_{n} ∘ ⋯ ∘ σ_{2} ∘ ϕ. Hence we obtain a CSU_{T} -resolution

(Σ, C, V) G ⊢_{RC} σ′_{1} G′_{1} ⊢_{RC} σ′_{2} G′_{2} ⊢_{RC} ⋯ ⊢_{RC} σ′_{n} ∅

where σ′_{n}∘⋯∘σ′_{1} ∈ Sub_{Σ}(X, V, V_{1}), and ρ ∈ Sub_{Σ}(X, V_{1}, V_{2}) is a typed substitution with

ρ ∘ σ′_{n} ∘ ⋯ ∘ σ′_{1} =_{T} σ_{n} ∘ ⋯ ∘ σ_{2} ∘ ϕ ∘ σ′_{1} =_{T} σ_{n} ∘ ⋯ ∘ σ_{2} ∘ σ_{1}.

The completeness of CSU_{T} -resolution follows from completeness of T -resolution and CSU-lemma 3.36:

Theorem 3.37 (Completeness of CSU_{T} -resolution) Let (Σ, C) be a typed logic program, V be a finite set of typed variables and G be a (Σ, X, V)-goal. If σ ∈ Sub_{Σ}(X, V, V′) is a typed substitution with (Σ, C, V′) ⊧ σ(G), then there exist a set of typed variables V_{0} and a typed substitution σ_{0} ∈ Sub_{Σ}(X, V_{0}, V_{1}) with (Σ, C, V_{0}) ⊢_{RC} σ_{0} G, and there is a typed substitution ϕ ∈ Sub_{Σ}(X, V_{1}, V′) with ϕ(σ_{0}(G)) =_{T} σ(G).

Proof: By completeness theorem 3.35, there exist a set of typed variables V_{0} and a T -resolution of the form

(Σ, C, V_{0}) G ⊢_{R} σ_{1} G_{1} ⊢_{R} σ_{2} G_{2} ⊢_{R} ⋯ ⊢_{R} σ_{n} ∅

with σ_{n} ∘ ⋯ ∘ σ_{1} ∈ Sub_{Σ}(X, V_{0}, V′) and σ_{n} ∘ ⋯ ∘ σ_{1}(G) = σ(G). CSU-lemma 3.36 yields a CSU_{T} -resolution

(Σ, C, V_{0}) G ⊢_{RC} σ′_{1} G′_{1} ⊢_{RC} σ′_{2} G′_{2} ⋯ ⊢_{RC} σ′_{n} ∅

and a typed substitution ϕ ∈ Sub_{Σ}(X, V_{1}, V′) (where σ_{0} := σ′_{n} ∘ ⋯ ∘ σ′_{1} ∈ Sub_{Σ}(X, V_{0}, V_{1})) with ϕ ∘ σ′_{n} ∘ ⋯ ∘ σ′_{1}(G) =_{T} σ_{n} ∘ ⋯ ∘ σ_{1}(G) = σ(G).

Soundness theorem 3.30 and completeness theorem 3.37 justify the implementation of CSU_{T} -resolution as a proof method for typed logic programs. A complete resolution method must enumerate all possible derivations. If we use a backtracking method like Prolog, the resolution method becomes incomplete because of infinite derivations (in our typed framework the search tree may have an infinite depth as well as an infinite breadth because CSU_{T} (L, L′) may be an infinite set). If we accept this drawback, we can implement the resolution like Prolog with the difference that the unification is extended to typed terms. In Section 3.5 we have shown that the classical unification algorithm can be used if the types of the terms are unified before unifying the terms. For the unification of type expressions w.r.t. the type specification a unification procedure for equational theories is needed. It is known that the narrowing procedure [Sla74] [Fay79] [Hul80] (a combination of unification and term rewriting) can be used for this purpose. Narrowing an expression is applying to it the most general substitution such that the expression is reducible and then reduce it. But the narrowing procedure computes a complete set of unifiers w.r.t. an equational theory only if the set of equations is a canonical (i.e., confluent and terminating) term rewriting system. A set of equations can be transformed into a canonical term rewriting system by the Knuth-Bendix procedure [KB70] which is successful for our applications. For instance, let T be a type structure for integer numbers with appropriate subtype relationships, i.e., zero and posint are subtypes of the natural numbers, and the negative integers and the natural numbers are subtypes of the integer numbers. Therefore T is the following equational specification:

TYPEOPS  zero:  → type
posint:  → type
nat:  type → type
negint:  → type
int:  type → type
TYPEAXIOMS nat(zero)  = zero
nat(posint) = posint
int(negint) = negint
int(nat(α)) = nat(α)

The Knuth-Bendix procedure transforms this specification into the following set of rewrite rules:

\begin{aligned}nat(zero) & ⇒ & zero \\ nat(posint) & ⇒ & posint \\ int(negint) & ⇒ & negint \\ int(nat(α)) & ⇒ & nat(α) \\ int(zero) & ⇒ & zero \\ int(posint) & ⇒ & posint \end{aligned}

All equations are oriented from left to right and two additional rewrite rules are generated (“zero and posint are subtypes of the integer numbers”) which corresponds to the computation of the transitive closure of the subtype relation specified in T . This set of rewrite rules is a canoncial term rewriting system and therefore the narrowing procedure w.r.t. these rules can be used to compute T -unifiers for two type expressions. Thus the resolution procedure can be implemented by the following two steps:

1. Transform the given type specification into a canonical term rewriting system. For this purpose the Knuth-Bendix completion procedure can be applied. It computes the transitive closure of the subtype relation.

2. The T -unification procedure for typed terms can be implemented like the classical unification procedure with the difference that types are T -unified by the narrowing procedure w.r.t. the rewrite rules computed in step 1 before unifiying corresponding terms.

Note that the T -unification procedure can be simplified if the type specification does not contain subtype relations (see remarks at the end of Section 3.5). If the type specification contains subtype relations, then these subtype relations have influence on the success or failure of unification. Therefore type information at run time is not superfluous in the context of logic programming but may avoid unnecessary computations since variables can be constraint to values and to types by the T -unification prodedure. Therefore typed logic programs can be executed more efficiently than their untyped equivalents [SS85] [HV87]. One reason for this efficiency is the existence of a procedure which decides whether a system of type constraints has a solution. As shown above, we solve type constraints by a narrowing procedure which is based on the type equations. This is sufficient to solve type constraints in order-sorted type structures, but in a more general setting narrowing cannot decide the solvability of constraints but enumerates only a complete set of solutions. Narrowing can only be used as a decision procedure if each narrowing derivation is finite. Hullot [Hul80] has shown that a terminating T -unification algorithm can be constructed by narrowing if any basic narrowing derivation for the right-hand sides of the rules is finite. This is the case in our simple examples and therefore narrowing on type expressions yields a decidability unification procedure for our examples. For another polymorphically order-sorted typed framework, Smolka [Smo89] has shown that type constraints can be efficiently solved. Therefore the development of efficient type constraint solvers for (restricted classes of) our framework is a topic for further research.

3.7 Applications

We have mentioned in the introduction that a new application of our proposed framework for typed logic programming is the possibility of higher-order logic programming with polymorphic and order-sorted type structures. It is clear that our framework combines polymorphic and order-sorted type structures (take the union of the type specifications of examples 3.1 and 3.2, or example 3.3). A semantically clean amalgamation of higher-order objects with logic programming needs a higher-order logic. Miller and Nadathur [MN86] have proposed a higher-order logic programming language based on the typed lambda calculus. The operational semantics is based on resolution with a unification procedure for typed lambda expressions which is a complex and semi-decidable problem. Moreover, the proof procedure is only complete for goals which contain no type variables.

Warren [War82] has argued that no extension to Horn clause logic is necessary because the usual higher-order programming techniques can be simulated in firstorder Horn clause logic. The general idea is an explicit definition of a predicate apply which is used for the application of an (at compile time) unknown predicate to some arguments. It is shown in [Han89b] that Warren’s approach is incompatible with polymorphic type systems for logic programming like [MO84] and [Smo89]. Since we have dropped some restrictions of these type systems, we can use Warren’s approach to integrate higher-order programming techniques in our framework.

Example 3.38 We give an example for the definition of a predicate map which applies a binary predicate to corresponding elements of two lists. To define the type of map we must express the type of binary predicates which are arguments to other predicates. Therefore we introduce a type constructor pred2 that denotes the type of binary predicates, i.e., the type specification for our example program is:

TYPEOPS int:  → type
bool:  → type
list: type → type
pred2: type, type → type

For each binary predicate p of type “τ_{1}, τ_{2}” we introduce a corresponding constant λp of type “pred2(τ_{1}, τ_{2})”. The relation between each predicate p and the constant λp is defined by clauses for the predicate apply2. Hence we get the following example program for the predicate map (we omit the definitions of the predicates inc and bool and the type annotations in program clauses):

func []: → list(α)

func [..|..]: α, list(α), → list(α)

func λnot: → pred2(bool, bool) func λinc: → pred2(int, int) … pred not: bool, bool pred inc: int, int pred map: pred2(α, β), list(α), list(β) pred apply2: pred2(α, β), α, β

vars P:pred2(α, β), E1:α, E2:β, L1:list(α), L2:list(β),

          B1,B2:bool, I1,I2:int

      map(P,[],[]) ←
      map(P,[E1|L1],[E2|L2]) ← apply2(P,E1,E2), map(P,L1,L2)
      apply2(λnot,B1,B2) ← not(B1,B2)
      apply2(λinc,I1,I2) ← inc(I1,I2)

…

The first two clauses constitute the standard definition of the predicate map (cf. [SS86], p. 281), and the clauses for apply2 relate the predicate names to the corresponding binary predicates. Since the semantics of typed logic programs is based on a typed first-order logic, the predicate symbol map is semantically not interpreted as a higher-order predicate. The constants λnot and λinc are also interpreted as values and not as relations. But the clauses for apply2 ensures that in every model of the program the constants λnot and λinc are related to the binary predicates not and inc, respectively.

This example shows the possibility to deal with higher-order objects in our typed framework. Higher-order objects are related to predicates by particular clauses for an apply predicate. It is also possible to permit lambda expressions which can be translated into new identifiers and apply clauses for these identifiers (see [War82] and [CvER90] for more discussion). The translation was explicitly done in our examples, but this is a simple task and can be automatically done. If the underlying system implements indexing on the clauses, e.g., indexing on the first arguments of predicates (as done in most compilers for Prolog, cf. [War83] [Han88]), then there is no essential loss of efficiency in our translation scheme for higher-order objects in comparison to a specific implementation of higher-order objects [War82].

More details about this method of higher-order logic programming in a polymorphically typed framework can be found in [Han89b].

3.8 Conclusions

We have presented a general framework for typed logic programming. It consists of a specification of a type structure and a set of well-typed Horn clauses together with type declarations for the syntactic objects occurring in the set of Horn clauses. For the definition of the type structure we have used equational specifications. This allows the specification of both polymorphic and order-sorted type structures and has the advantage that there exist well-known unification procedures for a lot of equational theories. We have defined a procedure to enumerate complete sets of unifiers for typed terms with respect to a type specification which is based on a unification procedure for the equational type specification. Furthermore, we have shown that resolution is sound and complete if this unification procedure is used to unify an atom with a clause head. This framework permits polymorphic and order-sorted type structures and the possibility of the application of useful logic programming techniques like lemma generation and higher-order programming.

The presented framework yields a new view on the rôle of types in logic programming. A type specification can be compiled into a suitable unification algorithm which is used in the resolution procedure. Therefore different type structures imply different unification algorithms. A many-sorted type structure does not require any type information at run time, in a polymorphic type structure a most general unifier exists for two unifiable terms and can be computed by Robinson’s unification algorithm, and in order-sorted type structures there may exist several unifiers which are not comparable, but a complete set of unifiers can be computed by a procedure which is based on a unification procedure for the type theory.

Further work remains to be done. We have mentioned that the presence of types at run time is not superfluous but may reduce the search space of the resolution method. Nevertheless, there are a lot of cases where type annotations can be omitted at run time and the unification remains to be correct. For polymorphic type structures these cases are analyzed in [Han89a] and [Han89b]. New criteria for omitting type annotations must be developed in our general typed framework. Another important point is the automatic inference of types. For practical applications it is tedious to write typed program clauses since each syntactic element must be given an appropriate type. Therefore it is necessary to deduce the right types for a clause without type annotations by a type inference algorithm. This is a difficult problem in our general framework but their are successful approaches to the type inference problem for restricted classes of type structures. For instance, in the case of polymorphic type structures the type inference algorithm of ML [DM82] can be used to infer the types of the variables in a clause if the types of all functions and predicates are explicitly declared [Han89a]. For a restricted class of polymorphically order-sorted type structures Smolka has found an algorithm which infers the types of variables in most cases [Smo89]. Similar solutions must be developed for particular instances of our approach.

52 CHAPTER 3. LOGIC PROGRAMMING WITH TYPE SPECIFICATIONS

Bibliography

[BC83] M. Bidoit and J. Corbin. A Rehabilitation of Robinson’s Unification Algorithm. In Proc. IFIP ’83, pp. 909–914. North-Holland, 1983.

[BG89] R. Barbuti and R. Giacobazzi. A Bottom-Up Polymorphic Type Inference in Logic Programming. Technical Report 27/89, Dip. di Informatica, Università di Pisa, 1989.

[Chu40] A. Church. A formulation of the simple theory of types. Journal of Symbolic Logic, Vol. 5, pp. 56–68, 1940.

[CM87] W.F. Clocksin and C.S. Mellish. Programming in Prolog. Springer, third rev. and ext. edition, 1987.

[CvER90] M.H.M. Cheng, M.H. van Emden, and B.E. Richards. On Warren’s Method for Functional Programming in Logic. In Proc. Seventh International Conference on Logic Programming, pp. 546–560. MIT Press, 1990.

[CW85] L. Cardelli and P. Wegner. On Understanding Types, Data Abstraction, and Polymorphism. acm computing surveys, Vol. 17, No. 4, pp. 471–523, 1985.

[DH88] R. Dietrich and F. Hagl. A polymorphic type system with subtypes for Prolog. In Proc. ESOP 88, Nancy, pp. 79–93. Springer LNCS 300, 1988.

[DM82] L. Damas and R. Milner. Principal type-schemes for functional programs. In Proc. 9th Annual Symposium on Principles of Programming Languages, pp. 207–212, 1982.

[EM85] H. Ehrig and B. Mahr. Fundamentals of Algebraic Specification 1: Equations and Initial Semantics, volume 6 of EATCS Monographs on Theoretical Computer Science. Springer, 1985.

[Fay79] M.J. Fay. First-Order Unification in an Equational Theory. In Proc. 4th Workshop on Automated Deduction, pp. 161–167, Austin (Texas), 1979. Academic Press.

[GM84] J.A. Goguen and J. Meseguer. Completeness of Many-Sorted Equational Logic. Report No. CSLI-84-15, Stanford University, 1984.

[GTW78] J.A. Goguen, J.W. Thatcher, and E.G. Wagner. An Initial Algebra Approach to the Specification, Correctness, and Implementation of Abstract Data Types. In R. Yeh, editor, Current Trends in Programming Methodology, volume 4, pp. 80–149. Prentice Hall, Englewood Cliffs NJ, 1978.

[GZ86] Y. Gang and X. Zhiliang. An Efficient Type System for Prolog. In Proc. IFIP ’86, pp. 355–359. North-Holland, 1986.

[Han87] W. Hankley. Feature Analysis of Turbo Prolog. SIGPLAN Notices, Vol. 22, No. 3, pp. 111–118, 1987.

[Han88] M. Hanus. Formal Specification of a Prolog Compiler. In Proc. of the Workshop on Programming Language Implementation and Logic Programming, pp. 273–282, Orléans, 1988. Springer LNCS 348.

[Han89a] M. Hanus. Horn Clause Programs with Polymorphic Types: Semantics and Resolution. In Proc. of the TAPSOFT ’89, pp. 225–240. Springer LNCS 352, 1989. Extended version in [Han91].

[Han89b] M. Hanus. Polymorphic Higher-Order Programming in Prolog. In Proc. Sixth International Conference on Logic Programming (Lisboa), pp. 382–397. MIT Press, 1989.

[Han90] M. Hanus. A Functional and Logic Language with Polymorphic Types. In Proc. Int. Symposium on Design and Implementation of Symbolic Computation Systems, pp. 215–224. Springer LNCS 429, 1990.

[Han91] M. Hanus. Horn Clause Programs with Polymorphic Types: Semantics and Resolution. Theoretical Computer Science, Vol. 89, pp. 63–106, 1991.

[HMM86] R. Harper, D.B. MacQueen, and R. Milner. Standard ML. LFCS Report Series ECS-LFCS-86-2, University of Edinburgh, 1986.

[Hul80] J.-M. Hullot. Canonical Forms and Unification. In Proc. 5th Conference on Automated Deduction, pp. 318–334. Springer LNCS 87, 1980.

[HV87] M. Huber and I. Varsek. Extended Prolog with Order-Sorted Resolution. In Proc. 4th IEEE Internat. Symposium on Logic Programming, pp. 34–43, San Francisco, 1987.

[KB70] D.E. Knuth and P.B. Bendix. Simple Word Problems in Universal Algebras. In J. Leech, editor, Computational Problems in Abstract Algebra, pp. 263–297. Pergamon Press, 1970.

[Llo87] J.W. Lloyd. Foundations of Logic Programming. Springer, second, extended edition, 1987.

[MH88] J.C. Mitchell and R. Harper. The Essence of ML. In Proc. of the 15th ACM Symposium on Principles of Programming Languages, pp. 28–46, San Diego, 1988.

[Mis84] P. Mishra. Towards a theory of types in Prolog. In Proc. IEEE Internat. Symposium on Logic Programming, pp. 289–298, Atlantic City, 1984.

[MN86] D.A. Miller and G. Nadathur. Higher-Order Logic Programming. In Proc. Third International Conference on Logic Programming (London), pp. 448–462. Springer LNCS 225, 1986.

[MO84] A. Mycroft and R.A. O’Keefe. A Polymorphic Type System for Prolog. Artificial Intelligence, Vol. 23, pp. 295–307, 1984.

[Nai87] L. Naish. Specification = Program + Types. In Proc. Foundations of Software Technology and Theoretical Computer Science, pp. 326–339. Springer LNCS 287, 1987.

[Pad88] P. Padawitz. Computing in Horn Clause Theories, volume 16 of EATCS Monographs on Theoretical Computer Science. Springer, 1988.

[Poi86] A. Poigné. On Specifications, Theories, and Models with Higher Types. Information and Control, Vol. 68, No. 1-3, 1986.

[Rob65] J.A. Robinson. A Machine-Oriented Logic Based on the Resolution Principle. Journal of the ACM, Vol. 12, No. 1, pp. 23–41, 1965.

[Sla74] J.R. Slagle. Automated Theorem-Proving for Theories with Simplifiers, Commutativity, and Associativity. Journal of the ACM, Vol. 21, No. 4, pp. 622–642, 1974.

[SLC88] Ph. Schnoebelen, D. Lugiez, and H. Comon. A Semantics for Polymorphic Subtypes in Computer Algebra. Technical Report RR 711, Laboratoire d’Informatique Fondamentale et d’Intelligence Artificelle, Grenoble, France, 1988.

[Smo89] G. Smolka. Logic Programming over Polymorphically Order-Sorted Types. Dissertation, FB Informatik, Univ. Kaiserslautern, 1989.

[SNGM89] G. Smolka, W. Nutt, J.A. Goguen, and J. Meseguer. Order-Sorted Equational Computation. In Hassan Aït-Kaci and Maurice Nivat, editors, Resolution of Equations in Algebraic Structures, Volume 2, Rewriting Techniques, chapter 10, pp. 297–367. Academic Press, New York, 1989.

[SS82] J. Siekmann and P. Szabó. Universal Unification and a Classification of Equational Theories. In Proc. 6th Conference on Automated Deduction, pp. 369–389. Springer LNCS 138, 1982.

[SS85] M. Schmidt-Schauss. A Many Sorted Calculus with Polymorphic Functions Based on Resolution and Paramodulation. In Proc. 9th IJCAI. W. Kaufmann, 1985.

[SS86] L. Sterling and E. Shapiro. The Art of Prolog. MIT Press, 1986.

[vEK76] M.H. van Emden and J.A. Kowalski. The Semantics of Predicate Logic as a Programming Language. Journal of the ACM, Vol. 23, No. 4, pp. 733–742, 1976.

[Wal89] U. Waldmann. Unification in Order-Sorted Signatures. Technical Report 298, FB Informatik, Univ. Dortmund, 1989.

[War82] D.H.D. Warren. Higher-order extensions to PROLOG: are they needed? In Machine Intelligence 10, pp. 441–454, 1982.

[War83] D.H.D. Warren. An Abstract Prolog Instruction Set. Technical Note 309, SRI International, Stanford, 1983.

[XW88a] J. Xu and D.S. Warren. A Theory of Types and Type Inference in Logic Programming. Technical Report 88/15, SUNY at Stony Brook, 1988.

[XW88b] J. Xu and D.S. Warren. A Type Inference System For Prolog. In Proc. 5th Conference on Logic Programming & 5th Symposium on Logic Programming (Seattle), pp. 604–619, 1988.

[Zob87] J. Zobel. Derivation of Polymorphic Types for Prolog Programs. In Proc. Fourth International Conference on Logic Programming (Melbourne), pp. 817–838. MIT Press, 1987.