# Brief Intro - RELFUN Source

```%    A brief introduction to basic RELFUN, using its PROLOG-like syntax
%                             Harold Boley                             Feb 1992

% In RELFUN, a LISP list (e1 ... eN) or PROLOG list [e1,...,eN] is equivalent
% to an (N-)tup(le) structure tup[e1,...,eN]. Logical variables are marked by
% an upper-case initial. The PROLOG list pattern [1,2|V] stands for tup[1,2|V],
% matching instances like tup[1,2,3,4,5] with the binding V = tup[3,4,5].

% A PROLOG clause c(...) :- b1(...), .., bM(...). in RELFUN becomes a kind of
% 'hornish' clause, except that structures, incl. tup-lists, use brackets, not
% parentheses. A conditional equation g(...) = f(...) if b1(...), .., bM(...)
% in RELFUN is generalized to g(...) :- b1(...), .., bM(...) & f(...)., an "&"
% (or 'footed') clause, whose "b" premises may accumulate partial results and
% whose "f" premise returns possibly (non-)ground/(non-)deterministic values.

% As in LISP, nestings like +(*(3,3),1-(8)) => 16 are reduced call-by-value.
% "Passive" structures like +[*[3,3],1-[8]], using brackets, return themselves.
% RELFUN's tup FUNCTION returns the tup STRUCTURE of its evaluated arguments:
% tup(|R) :-& tup[|R].  % R will be bound to the tup of all arguments.
% This permits calls like  T is 3 & tup(*[T,T],1-(8))  =>  tup[*[3,3],7].

% The below definitions of append and naive reverse illustrate our RELational/
% FUNctional merger (e.g., "is" can invert functions almost as if relations).

% PROLOGish REL style (inversion  revrel(U,tup(1,2))  loops on MORE):

apprel([],L,L).
apprel([H|R],M,[H|S]) :- apprel(R,M,S).
revrel([],[]).
revrel([H|R],L) :- revrel(R,M), apprel(M,[H],L).

% LISP-like FUN style (is-syntax  tup[1,2] is revfun[U]  exhibits inversion):

appfun([],L) :-& L.
appfun([H|R],L) :-& tup(H|appfun(R,L)). %NESTED (user) form ->
% appfun([H|R],L) :- _1 is appfun(R,L) & tup(H|_1). %FLATTENED
revfun([]) :-& [].
revfun([H|R]) :-& appfun(revfun(R),[H]). %nest and (compiler)
% revfun([H|R]) :- _1 is revfun(R) & appfun(_1,[H]). %flatten

% Using nested or flattened clauses, the RELFUN interpreter allows this dialog:

% rfi> apprel(tup(1,2),tup(a),U)      % rfi> appfun(tup(1,2),tup(a))
% true                                % [1,2,a]
% U = [1,2,a]                         %
% rfi> apprel(I,J,[1,2,a])            % rfi> [1,2,a] is appfun(I,J)
% true                                % [1,2,a]
% I = []                              % I = []
% J = [1,2,a]                         % J = [1,2,a]
% rfi> more    % 4th MORE would fail  % rfi> more         % 4th MORE would loop
% true                                % [1,2,a]     % like: for the conjunction
% I = [1]                             % I = [1]           % apprel(I,J,  F)
% J = [2,a]                           % J = [2,a]         % [1,2,a] is F
% rfi> revfun(tup(a,b|V))       % A function called with a non-ground "|"-list.
% [b,a]                         % Returned value no. 1 is ground (variableless)
% V = []                        % because V can be bound to the empty list.
% rfi> more                     % The request for MORE solutions (PROLOG's ";")
% [H:15,b,a]                    % returns a 3-list pattern starting with H:15,
% V = [H:15]                    % a (free) variable also occurring in V.
% rfi> more                     % Another MORE (of infinitely many successes)
% [H:24,H:26,b,a]               % now returns a non-ground list of length 4,
% V = [H:26,H:24]               % whose first two elements reverse those in V.
```