This research was supported by the BMFT under Grant ITW 8902 C4.

(Nested) function calls will be written with (round) parentheses, while [embedded] structures or lists will be distinguished by [square] brackets. Since in the above eq definition signum can be seen as the constructor of a structure, this version can be simulated in RELFUN, too. Since RELFUN employs a LISP-like prefix notation also for builtin relations such as < and >, the runnable RELFUN forms of the two versions are
eq(signum[X],-1) :- <(X,0). signum(X) :- <(X,0) &-1.
eq(signum[0],0). signum(0) :- &0.
eq(signum[X],1) :- >(X,0). signum(X) :- >(X,0) &1.

The syntax shown for full RELFUN will continue to be PROLOG-like. In the implementation it becomes equivalent LISP-like list expressions. Although the (older) LISP-like syntax will not be shown in this paper, some users still prefer it to the (newer) PROLOG-like syntax. RELFUN has been given two syntaxes to facilitate communication between users from the LISP and PROLOG communities.

We do not make use of the argument that is a mapping (or `functional' in, e.g., the relational database sense) while its inverse is not (some small countries' areas coincide if rounded to 1000 sq. mi.), because RELFUN does allow non-deterministic functions, as will be shown shortly.

Following LISP, RELFUN currently does not distinguish arithmetic operators as infixes, but like all other operators applies them as prefixes.

RELFUN accesses a selected subset of COMMON LISP functions as builtins. Unusually named examples are the numeric successor and predecessor functions 1+ and 1-, whose application to an argument, say 6, in mathematical or PROLOG syntax becomes 1+(6) and 1-(6), returning 7 and 5, respectively. RELFUN's ecal primitive, a combination of LISP's eval and PROLOG's metacall, permits the activation of structures, as in ecal(1-[1-[0]]), returning -2.

RELFUN's once primitive (or ``!'' symbol) could be employed above (or after) the is-call to prevent the possibly diverging search for further solutions when the first solution is found, thus simulating the usual - unbounded - minimalization of unary functions [for (1+N)-ary functions ``|'' can be used to minimalize over the first argument, making mu[F] a function structure, as shown in square brackets]:
mu(F) :- once(0 is F(naturals(0,V))) &V. (or mu(F) :- 0 is F(naturals(0,V)) ! &V.)
[mu[F](|Nargs) :- once(0 is F(naturals(0,V)|Nargs)) &V.]

While the need for non-ground terms is self-evident in relational programming (ground relational programming isn't very useful), they require some justification in functional programming. The serialise example shows how non-ground terms can be useful internally in a computation even if its external input/output is ground terms. This is analogous to an internal use of complex numbers in computing real results.

RELFUN only permits a single cut per clause, so premises to the left of ``!'' can be interpreted as the arguments of an implicit once operator followed by a neck cut. Also, as a ``single-cut language'', it is akin to a committed-choice language (CCL), obtainable by (1) restricting the left-``!'' premises to `guards' and by (2) parallelizing clause invocation. Like for PROLOG, a cut(-avoidance) discussion will be necessary for relational/functional languages. For example, wang's sole cut can be encapsulated into an if...then...else... (as shown in parentheses), a valued version of PROLOG's ...->...;..., but this entails an is-variable to avoid recomputation of the entire work. Although some relational/functional cuts may be justified by the determinism of many functions, the question of better ways of determinism specification remains. For instance, one could declare the work procedure as deterministic in one place instead of using a ``!'' in each of its clauses (in the final clause, just for uniformity and CCL kinship). Note, however, that RELFUN employs ``!'' as part of the clause syntax, like CCLs use ``|'', not as an ``extra-logical goal''. In work this syntax acts like clause-oriented determinism annotations (for a non-neck cut also specifying a clause's ``commit point''), from which a declaration for the entire procedure could be extracted.

We do not try here to capture the LISP subset in RELFUN which is required for our implementation of RELFUN in LISP; it would need some profane features for reading/printing etc., but could avoid the advanced features mentioned. This would provide a `codefinition' of RELFUN and LISP, like the one proposed for PROLOG and LISP in Kenneth M. Kahn's ``Pure Prolog in Pure Lisp'' response (Logic Programming Newsletter 5, Winter 83/84) to the ``Pure Lisp in Pure Prolog'' [PP82] paper. A direct definition of RELFUN in RELFUN has been prepared by reducing it to a meaning-preserving sublanguage (via flattening or relationalizing), for which a PROLOG-like (vanilla) metainterpreter can be given.

Harold Boley & Michael Sintek (sintek@dfki.uni-kl.de)