(DEFINE-PROCEDURAL-TYPE <name> <function> :syntax <checker> :copier <copier>)
Declares <name> to be a special attribute, whose value can only be
interpreted by <function>.
The special types are considered `atomic' types (unifier cannot access to
components from outside).
The unification procedure must be deterministic (no backtracking
allowed) and must be a real `unification' procedure: that is, the type must
be a lattice (or partial order).
<FUNCTION> must be a function of 3 args: the vals to unify and the path
where the result is to be located in the total fd.
It must return :fail if unification fails, otherwise, it must return a
valid object of type <type>.
NOTE: <FUNCTION> must be such that NIL is always acceptable as an
argument and is always neutral, ie, (<FUNCTION> x nil) = x.
NOTE: <FUNCTION> must be such that (<FUNCTION> x x) = x
<CHECKER> must be a function of 1 arg:
It must return either True if the object is a syntactically correct
element of <TYPE>, otherwise, it must return 2 values:
NIL and a string describing the correct syntax of <TYPE>.
<COPIER> must be a function of 1 arg:
it must copy an object of <TYPE> that has no cons in common with its
argument. By default, COPY-TREE is used.
NOTE: (<COPIER> x) = (<FUNCTION> x nil)