% Programs B.2
% Utility predicates
% append(Xs, Ys, Zs) ---list Zs is list Xs followed by list Ys
append([], Ys, Ys).
append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).
% reverse(Xs, Ys) ---list Ys is list Xs in reverse order
reverse([], []).
reverse([X|Xs], Ys) :- reverse(Xs, Zs), append(Zs, [X], Ys).
% Prolog code which executes other Prolog code, such as would be
% enclosed between curly braces in BH-GRN rules
'{}'(X) :- call(X).
evaluate(no_code) :- !.
evaluate(((C1), C2)) :- !, evaluate(C1), evaluate(C2).
evaluate(Code) :- !, call(Code).
% remove(X, Ys, Zs) ---lists Zs is the results of removing an occurrence of
% item X from list Ys
remove(X, [X|Xs], Xs).
remove(X, [Y|Ys], [Y|Zs]) :- remove(X, Ys, Zs).
% member(X, Ys) ---determine whether X is a member of list Ys
member(X, [X|Xs]).
member(X, [Y|Ys]) :- member(X, Ys).
% read_string(Xs) ---Xs will be a list of atoms read in from user input
% This code is based on code given in Clocksin & Mellish (1984)
read_string(Words) :-
get0(Char),
read_string(Char, Words).
read_string(C, []) :- newline(C), !.
read_string(C, Words) :- space(C), !,
get0(Char),
read_string(Char, Words).
read_string(Char, [Word|Words]) :-
read_word(Char, Chars, Next),
name(Word, Chars),
read_string(Next, Words).
read_word(C, [], C) :- space(C), !.
read_word(C, [], C) :- newline(C), !.
read_word(Char, [Char|Chars], Last) :-
get0(Next),
read_word(Next, Chars, Last).
space(32).
newline(10).
% length(Xs, N) ---N is the length of list Xs
% ---This is in-built in our Prolog, so we have commented out
% ---this definition.
% length([], 0).
% length([X|Xs], N) :- length(Xs, M), N is M+1.
% subset(Xs, Ys) ---determine whether all members of list Xs are contained
% in list Ys
subset([], Ys).
subset([X|Xs], Ys) :- member(X, Ys), subset(Xs, Ys).
SJ Harlow