% --------------------------------------------------------------------------
%   FILE:       UTILITY.PL
%   AUTHOR:     Tim Duncan
%   UPDATED:    Tue Jul 21 17:28:15 BST 1987
%   PURPOSE:    Utilities for ATTENDING
% --------------------------------------------------------------------------


:- op(100,fx,*).        % punctuation
:- op(100,xfy,:).       % connects text to nodes of augmented tree
                        % and conditional risks in pmframes.



readline(L) :-
    prolog_eval(prolog_safereadline('> '),L), !.

bell :- prolog_eval(rawcharout(7)), !.




/*  Execute a goal and succeed even if it fails. */
do(Goal) :- call(Goal), !.
do(_) :- true.


&([]).
&([Goal|Others]) :-
    call(Goal), !,
    &(Others).



/*  B comes before A in List */
before(B,A,[A|_]) :- !, fail.
before(B,A,[B|Rest]) :- !, member(A,Rest).
before(B,A,[_|Rest]) :- !, before(B,A,Rest).

head(H,[H|_]).
tail(T,[_|T]).
null([]).
null_dl(X/X).   /* for difference lists */

;;; This comes free in library(record).
;;; member(X,[X|_]).
;;; member(X,[_|T]) :- member(X,T).

append([],X,X).
append([A|B],C,[A|D]) :- append(B,C,D).

append_dl(A/B,B/Bs,A/Bs).   /* for difference lists */


reverse(U,S) :- reverse(U,[],S).

reverse([],X,X).
reverse([H|T],Acc,Rev) :- !,
    reverse(T,[H|Acc],Rev).


delete(_,[],[]).
delete(Item,[Item|Rest],List) :- !, delete(Item,Rest,List).
delete(Item,[X|Rest],[X|Tail]) :- delete(Item,Rest,Tail).


/* flatten nested list using difference lists - from Shapiro & Stirling */
flatten(L,F) :- flatten_dl(L,F/[]).

flatten_dl([],X/X) :- !.
flatten_dl([X|Xs],Y/Z) :-
    flatten_dl(X,Y/Ys),
    flatten_dl(Xs,Ys/Z).
flatten_dl(X,[X|Xs]/Xs).


/*  Clocksin & Mellish - pretty printer.  */
pp(L) :- pp(L,0).
pp([H|T],I) :- !, J is I+3, pp(H,J), ppx(T,J).
pp(X:Y,I) :- not(recorded(pp_all,_,_)), !, tab(I), write(X), nl.       
pp(X,I) :- tab(I), write(X), nl.
ppx([],_).
ppx([H|T],I) :- pp(H,I), ppx(T,I).
