Appendix 5. Adding data types to TROEPS



TROEPS comes with a set of primitive data types declared in the trtdum module. This module must be loaded in order to uses the corresponding types ( entier, chaine, reel, booleen).
In TROEPS, primitive data types are declared in a general type system which provides the basic operations of type checking but also those of sub-type relationship inference. This is the basis for building classification mechanisms, type checking and dissimilarity computation. This type system is extensible. So, new types can be added through the definition of an abstract data type ( ADT) and will behave just like basic types.
The procedure for using new types is the following:
These steps are further detailed below.

Categories of data types and their properties

Data types are TALK structures. They are presented here for illustration purposes. However, for being recognised by TROEPS they must be declared as below.

Figure 16: The abstract data type hierarchy in the TROEPS type system. The types in italics are those defined in the trtdum standard type module; other types can be added.

Figure 17: The abstract data constructor hierarchy in the TROEPS type system. The constructors in italics are those defined in the trtdum standard type module; it not currently possible to add type constructors to TROEPS.

Declaring data types

An ADT is generally defined through a membership predicate (for deciding if something belongs to the type), an equality predicate (for testing the equality of two values of the type), a string function which returns a string representing a value of the type (for printing purpose). Moreover, a similarity function returns a measure of similarity between two values of the type and ordered types must have an order predicate.
For instance, the date abstract data type can be described with datep as membership predicate, date-equal-p for equality predicate and date-anterior-p as order function. The following table represents the definition of basic data types available in trtdum:

name
class
membership
equality
order
successor/
predecessor
dissimilarity
printer
entier
discrete
intp
i=
i>
i1+/i1-
iabs o i-
string
reel
dense
floatp
f=
f>
-
fabs o f-
string
booleen
enumerated
true
eq:t?()
-
-
eq:0.?1.
string
chaine
enumerated
stringp
string=
-
-
eq:0.?1.
id

TROEPS also uses two collection constructors: list ( liste) and set ( ensemble). A collection type is built from a collection operator and a basic type. Collectors are declared through abstract data collectors which enable to check if a collection corresponds to its type, to compare two collections, to order them and, if required, to determine the size of a collection (for cardinality checking).
In the current version of TROEPS, it is not possible to add data collectors.

Using data types

Once data types have been declared, it is possible to describe fields for which the values can be values of the new data type. For that purpose, the type descriptor of the concept field has to be filled by the corresponding ADT (see the "concept" section). Once this has been achieved, it is possible to restrict the domain of the field in particular classes with the help of the domain, intervals, except or card descriptors of the class fields (see the "class" section). These type expressions can be expressed in the knowledge representation language as follows:

typexp(ADT) = *

where v are values of the ADT and r [propersubset] N+[union]{+[infinity]}.
Now, instances of the concept can be created: the type system takes care of the membership of the field value to the type; they can be classified, it takes care of the membership of the value to the domain represented by the class field descriptors; new classes can be categorised, the sub-type relationship between their respective field definition is computed by the type module.

Examples

As an example, it is possible to create an abstract data type for the time type provided with TALK. Thanks to the generic arithmetic, it is already possible to test equality ( =) superiority ( >) and increment ( 1+) of the time structures. It is also possible to test the membership to the type ( timep) and to print time values ( string). All this is communicated to TROEPS by only one TALK statement which can be compiled and loaded:
(tr-create-adt <-discrete-> time
	member:			timep
	equal:			equal
	superior:		>
	string:			string
	successor:		1+
	predecessor:	1-
	disimilarity:	(lambda (v1 v2) (float (abs (- v1 v2))))
	printer:			print
	reader:			read
)

API

Services provided by ADT

The only necessary primitive for extending the type system is tr-create-adt.
(tr-create-adt adt name rest: listdesc ) macro in [libtrp]

-> adt , adt adt, name stringnas, listdesc [key value]*
Creates a new ADT of kind adt and name name and returns it. The attributes of the ADT are provided through a set of descriptors ( listdesc) whose meaning is given by the following:
key
applicabi-lity
value
meaning
member:
all
anything -> B
Does the value belong to the ADT?
equal:
all
VxV -> B
Are the values equal?
string:
all
V -> string
The string representation of a value
disimilarity:
all
VxV -> float
The dissimilarity measure between two values
superior:
ordered
VxV -> B
Does the first value precede the second one?
successor:
discrete
V -> V
The successor of a value
predecessor:
discrete
V -> V
The predecessor of a value
reader:
all
strm -> V
The reading of a value in a stream
printer:
all
Vxstrm -> void
The printing of a value in readable format

These primitives can be exported to anyone.
(tr-find-adt name) function in [libtrp]

-> adt, name stringnas
Retrieves and returns the ADT of name name. When no such ADT is known, returns ().
(tr-adt-p anything) function in [libtrp]

-> boolean, anything anything
Returns anything if anything is an ADT, () otherwise.
(tr-adt-top name) function in [libtrp]

-> type, name stringnas
Returns the type which corresponds to the domain of all the members of the ADT adt.

Services provided for types and values

These primitives are supported for types declared through ADT. The type argument is the one stored into the concept and class fields (e.g. the result of the call to (.conceptslot-type conceptslot) ). These primitives are used for programming efficiently the classification and categorisation systems. It is possible to use them when only an ADT (and not a type) is available by retrieving the most general type (through (tr-adt-top adt) ).
(tr-type-p anything) macro in [libtrp]

-> boolean, anything anything
Returns anything if anything is a type, () otherwise.
(tr-type-member-p type value ) function in [libtrp]

-> boolean, type type, value anything
Checks the membership of value to the type (domain) type. Returns value if it is type compliant, () otherwise.
(tr-type-equal-p type value1 value2 ) function in [libtrp]

-> boolean, type type, value1 anything, value2 anything
Tests the equality of two values declared through the type type. Returns value1 if value1 and value2 are equal (in the sense of the ADT equal predicate) and () otherwise.
(tr-type-disimilarity type value1 value2 ) function in [libtrp]

-> float, type type, value1 anything, value2 anything
Computes a dissimilarity measure (in the sense of the ADT dissimilarity function) for two values declared through the type type and returns it.
(tr-type-cardinal type value ) function in [libtrp]

-> integer, type type, value anything
Computes a size measure (in the sense of the ADC size function) for a value declared through the type type and returns it.
(tr-type-successor type value ) function in [libtrp]

-> anything, type type, value anything
Computes the successor (in the sense of the ADT successor function) for a value declared through the type type and returns it.
(tr-type-predecessor type value ) function in [libtrp]

-> anything, type type, value anything
Computes the predecessor (in the sense of the ADT predecessor function) for a value declared through the type type and returns it.
(tr-type-superior-p type value1 value2 ) function in [libtrp]

-> boolean, type type, value1 anything, value2 anything
Tests the superiority of two values declared through the type type. Returns value1 if value1 is superior (in the sense of the ADT order predicate) to value2 and () otherwise.
( tr-type-string type value ) generic in [libtrp]

-> string, type type, value anything
Returns a string corresponding to the representation (in the sense of the ADT string function) of the value value declared through the type type.
(tr-type-read-value type string ) function in [libtrp]

-> anything, type type, string string
Returns the value of type type corresponding to the string string.
(troeps.type.compare type1 type2 ) -- generic in [libtrp]

-> symbol, type1 type, type2 type NIY
Checks the sub-typing of the type (domain) type1 with regard to that of type2. Returns type1 if type1 is a super-type of type2, type2 if it is a super-type of type1, their intersection otherwise (which can be ()).

Accessing TROEPS types

TROEPS primitives allows to access the types stored by the type system (in order, for instance, to compare them). These accessors are provided by the representation model in order to store the information related to the type system. They are used in read-write mode by the type module and in read mode by the any other module.
(troeps.type.class-type class) function in [libtrp]
(troeps.type.concept-type concept) function in [libtrp]
(troeps.type.classslot-type classslot) function in [libtrp]
(troeps.type.conceptslot-type conceptslot) function in [libtrp]

-> type, class class,concept concept, classslot classslot, conceptslot conceptslot, type type
Returns the type associated to the entity.