Next: Type Declarations, Up: Programs [Contents][Index]

A type definition is of the form

*type-name*` ::= `

*type-expression*

*type-name* is either an alphanumeric atom or a single argument compound term whose only argument is a variable (representing any type). A type definition with such a type name defines a parameterised type where the type variable stands for any type. That type variable then appears in one or more of a disjunction of compound terms with other arguments that are type names. We give examples below.

*type-expression* may be another user or system defined type, in which case the type definition is essentially a type alias, for example

speed ::= num

More usually it is one of the following type expressions defining a new data type.

This is an expression of the form `M..N`

where `M < N`

and both are integers.

Examples:

digit::= 0..9 small_int::= -10..10

As in the examples different range types may overlap but only when one is completely contained inside the other. To have overlapping sets of integers corresponding to different types, type union must be used (see below).

This is an expression of the form `C1 | C2 | ... | Ck`

where each `Ci`

is the same kind of constant, except that we can mix different types of numbers.

Examples:

gender::= male | female threeNums::= 20 | 6.7 | -50 article::= "a" | "an" | "one" | "the" | "that" | "those"

Different type definitions using overlapping disjunctions of constants are allowed providing one is completely contained inside the other. So, as well as the `article`

type we could define

indef_article::= "a" | "an" | "one"

A disjunction of integers can also overlap with a range type providing it either comprises a subset or a superset of the integers of the range type.
These constraints ensure that each constant
belongs to a unique minimal type. For example `"a"`

would belong to the types `indef_artcle`

, `article`

, `string`

, `atomic`

, `term`

, `top`

.

To have partially overlapping disjunctions of constants corresponding to different types, type union expressions must be used to define each partially overlapping type (see below).

This is an expression of the form `CT1 | CT2 | ... | CTk`

where each `CTi`

is a compound term with arguments that are type names, or a single type variable `T`

, or a parameterised type name with argument the same type variable `T`

. Such a type expression can only appear as the right hand side of a parameterised type definition with left hand side a unary compound term containing the type variable `T`

.

Examples:

tree(T) ::= empty() | tr(tree(T),T,tree(T)) an_indexed(T)::= rec(int,T)

This is an expression of the form `Ty1 || Ty2 || ... || Tyk`

where each `Tyi`

a simple type name or a ground parameterised type name or a code type expression.

Examples:

int_atom ::= int || atom int2intOrstring::= int -> int || int -> string

The last example above was the union of two function type expressions. There are four code type expressions in `Qulog/TeleoR`

. These are: a function type, a relation type, and action type and a `TeleoR`

procedure type.

This has the form `(TE1,TE2,...,TEk) -> TE`

where each `TEi`

and `TE`

is any simple, or compound type name, or type union expression, or a code type expression.

This has the form `(MTE1,MTE2,...,MTEk) <=`

where each `MTEi`

is a moded type where the type is any simple, or compound type name, or type union expression, or a code type expression.

The possible modes of a moded type are the prefixes `!`

, `?`

and `??`

and the postfix `?`

.

The moded type `!`

*Type* used as an argument of a relation
means, when called, the supplied argument must be ground and of type *Type*.

The moded type `?`

*Type* used as an argument of a relation
means, when called, the supplied argument must either be ground and of type *Type* or will be ground to a term of type *Type* by the call.

The moded type *Type*`?`

used as an argument of a relation
means, when called, the supplied argument must either be ground and of type *Type* or, if ground by the call, will be ground to a term of type *Type*.

The moded type `??`

*Type* used as an argument of a relation
means, when called, the supplied argument, if ground, must be of type *Type* and the call will not further instantiate the argument.

Modes can be used multiple times in structured types as long as inner modes are more liberal than outer modes. For example, the moded type

![?int]

means that the top-level list structure must be given (i.e. the number or elements are known at call time) but the elements of the list can be a mixture of integers and variables with the variables instantiated to integers by the call.

This has the form `(MTE1,MTE2,...,MTEk) ~>>`

where
each `MTEi`

is a moded type where the type is any simple, or compound type name, or
type union expression, or a code type expression.

The modes are as described above.

This has the form `(TE1,TE2,...,TEk) ~>`

where each `TEi`

is any simple, or compound type name, or type union expression, or a code type expression.

Next: Type Declarations, Up: Programs [Contents][Index]