Next: Type Declarations, Up: Programs [Contents][Index]
A type definition is of one of the forms (with the second being a type macro)
def
type-name::=
type-expression
def
type-name==
type-expression
type-name is either an alphanumeric atom or a compound term whose arguments are distinct variables (each representing any type). A type definition with such a type name defines a parameterised type where the type variables stand for any type. Those type variables then appears in one or more of a disjunction of compound terms with other arguments that are type names. We give examples below.
Examples are given below.
This is an expression of the form M..N
where M < N
and both are integers.
Examples:
def digit ::= 0..9 def 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:
def gender ::= male | female def threeNums ::= 20 | 6.7 | -50 def 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
def indef_article::= "a" | "an" | "one"
It is possible to have an enumerated type with just one element as in
def def_article::= "the"
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 compound term containing the type variable T
.
Examples:
def tree(T) ::= empty() | tr(tree(T),T,tree(T)) def 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:
def int_atom == int || atom
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. Functions must be called by giving ground arguments of the required types and will return a ground value of the specified value type.
Examples:
(set(T), set(T)) -> set(T) (string) -> nat
The first example declares the type of a function that takes a pair of sets
of some type and returns a set of the same type. The function union
has this type.
The second example takes a string
and returns a nat
. The function
#
(when applied to a string) has this type.
This has the form rel(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 @
.
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 may be variable or a partial or ground and of type Type. If not ground in the call it 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 may be variable or a partial or ground and of type Type. It may not be ground on success of the call.
The moded type @
Type used as an argument of a relation
means, when called, the supplied argument may be variable or a partial or ground and of type Type. It will be left unchanged by the call.
If no mode is given it is taken to be !
.
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
!list(?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.
Examples:
rel(!list(T), !list(T), ?list(T)) rel(!string, ??term)
which can also be be given as
rel(list(T), list(T), ?list(T)) rel(string, ??term)
as !
is the default mode for static relation arguments.
The first example is the type of a relation whose first two arguments
must be given as ground lists of values of the same type T
and whose third argument can either be a variable or partial or ground list of values of type T
that will be a ground list of T
values if the relation call succeeds.
This is one of the types of the
append
primitive.
The second example is the type of a relation that takes a string as its first
argument and whose second argument might be instantiated to a possibly
non-ground term. This is the type of the string2term
primitive.
This has the form act(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 for a relation type.
Examples:
act(??term, !handle) act()
The first example is the type of an action that takes a term that may be a
variable or contains variables and a ground handle. It is the type of the
message send action to
.
The second example is the type of an action that takes no arguments. It is the type of kill_agent
.
This has the form tel(TE1,TE2,...,TEk)
where each TEi
is any simple, or compound type name, or type union expression, or a code type expression. The types are implicitly !
ground input moded.
Example:
tel(list(block), slot)
This is the type of a TR procedure that takes a list of blocks and a slot.
This is the type of makeTower
in one of the tower building programs in the examples directory where block
and slot
are user defined types.
Next: Type Declarations, Up: Programs [Contents][Index]