When enriching DATAFUN with structures and lists we arrive at
full RELFUN (we will immediately transfer the relational
varying-arity extensions).
Returning to successor structures for natural numbers, one should
first note that it is illegal to nest active calls into passive structures like this: `s[+(M,N)]`.
The usual equational definition of binary addition could still be
transcribed by employing an `is`-call for `+`'s recursion:

+(0,N) :-& N. +(s[M],N) :- A is +(M,N) & s[A]. (or +(s[M],N) :-& +(M,s[N]).)

However, we prefer another method, relying on
functions defined to simply return ``their own call as a structure''.
Since the same functor can be a constructor and a defined function,
we can define, e.g., `s` and `tup` as the following
*self-passivating functions*:

Now,s(M) :-& s[M]. tup(|Z) :-& tup[|Z]. (or tup(|Z) :-& [|Z]. or tup(|Z) :-& Z.)

For example, the call
`tup(subfield(engineering),s(s(0)))` non-deterministically
returns the lists
`[mechanics,s[s[0]]]` or
`[architecture,s[s[0]]]`;
the LISP-`cons`-like `tup`-```|`''-use `tup(s(0)|[0])` returns `[s[0],0]`;
the COMMON LISP-`list*`-like `tup`-```|`''-use `tup(a,b,c|[d,e])` returns `[a,b,c,d,e]`.
Moreover, the `s` definition enables a direct analogue to equational addition:

+(0,N) :-& N. +(s[M],N) :-& s(+(M,N)).

It should also be noted here that RELFUN definitions obey the
``constructor discipline'' [O'D85],
which with our notation amounts to saying simply that ``clause heads must not have embedded parenthesized expressions''. This would be
violated by the `eq`-nested `signum` calls shown in the
introduction.

The earlier relation-to-function transcriptions (e.g., for the
`subfield` operator)
decreased the arity by one because one relation argument was distinguished as the function value.
Alternatively, relations can often be refined to functions of
the same arity returning an additional useful value.
One class of functions generated in this way is *filter functions* i.e.,
functions acting as the identity for certain arguments or
argument combinations, and failing for other ones.
For instance, the `sorted` relation on lists of subsection 2.2
can be refined to the following filter function, whose
recursive call is nested after the ```|`'' into a `cons`-like `tup` call:

Thissorted([]) :-& []. sorted([X]) :-& [X]. sorted([X,Y|Z]) :- lesseq(X,Y) & tup(X|sorted([Y|Z])).

Below, a sample `sorted` call is given, which occurs in an
(internally non-ground and non-deterministic) functional version of the
well-known relational slow-sort program [Llo87].
This `sort` definition also exemplifies an essential use of non-ground function calls:
since such calls both bind
request variables and return a value, they can be used to split results into
bindings, for the calls occurring somewhere above or after them,
and a value, for the
caller nested directly above them.

Let us consider this bottom-up. The auxiliary functionsort(X) :-& sorted(perm(X)). perm([]) :-& []. perm([X|Y]) :-& tup(U|perm(delete(U,[X|Y]))). delete(X,[X|Y]) :-& Y. delete(X,[Y|Z]) :-& tup(Y|delete(X,Z)).

A variant of filters is *self-testing functions*, which
can also be viewed as self-passivating functions that
yield `unknown` for an argument (sequence) considered
``ill-formed''.
For example, the varying-arity `sorted` relation of subsection
2.4
can be refined to a self-testing function that
fails for unsorted argument sequences:

Now, the non-ground callsorted() :-& sorted[]. sorted(X) :-& sorted[X]. sorted(X,Y|Z) :- lesseq(X,Y), sorted[|W] is sorted(Y|Z) & sorted[X|W].

Concluding the series of ``self''-functions, let us
proceed to *self-normalizing functions*,
a variant of self-testing functions performing argument
normalization.
For instance, the previous list `sort` function can be used to
define `bag` as a varying-arity function that
returns a `bag` structure of the sorted arguments
i.e., a normalized multiset:

Now, the callbag(|X) :- W is sort(X) & bag[|W].

The flattening, extra-arguments, and relationalize
transformations from DATAFUN to DATALOG in subsection
3.1.3
are easily generalized
to corresponding RELFUN-to-PROLOG transformations.
For example, the above varying-arity `bag` function becomes
a relation which must bind normal forms to a request variable
(the extra first argument) instead of just returning them:
`bag(bag[|W]|X) :- sort(W,X).`
However, self-normalizing functions constitute a paradigmatic
class of operators for which a relational reformulation seems
not practically useful: a concise functional nesting like
`set(bag(s[0],0),bag[0,s[0]])`
would become the relational conjunction
`bag(B,s[0],0), set(S,B,bag[0,s[0]])`,
treating the active and passive `bag`s completely differently,
even though they both evaluate to (equal) structures for the
`set`.
Again recalling subsection
3.1.3, the `X1`-reuse for value returning in the WAM
also supports full RELFUN because `X1` can point to
structured return values
on the heap just as it points to structured variable values.