
% cantake(Taken, ReadyFor)
% ------------------------
% given Taken is the list of courses already taken,
%    unifies ReadyFor with the list of remaining courses
%    that can be taken now, e.g.
% cantake([math12, math121, csci160, csci162, csci261], L).
%  gives  [math122, math123, csci112, csci115, csci161, csci400]
%
cantake(Taken, ReadyFor) :- 
       % get the list of all courses, remove the ones taken, giving the potentials
       allCourses(Total), subtract(Total, Taken, Potential),
       % then, out of the potentials, see what you have the pre-reqs for
       readyFor(Taken, Potential, ReadyFor).

% readyFor(Taken, Possibles, AbleToTake)
% --------------------------------------
% given Taken is the list of courses already taken,
%    and Possibles is a list of potential other courses,
%    unifies AbleToTake with the subset of those courses
%    the the student has the pre-requisites for
%
readyFor(_, [], []).
readyFor(Taken, [H|T], [H|AbleToTake]) :- prereqs(H, Needed),
     subset(Needed, Taken), readyFor(Taken, T, AbleToTake).
readyFor(Taken, [_|T], AbleToTake) :- readyFor(Taken, T, AbleToTake).

% allCourses(Total)
% -----------------
% unifies Total with a list of all possible courses
%
allCourses(Total) :- findall(Course, prereqs(Course,_), WithDups), sort(WithDups, Total).

% List of each course and its associated pre-requisites
% -----------------------------------------------------
prereqs(csci460, [csci355,csci360]).
prereqs(csci400, [csci160]).
prereqs(csci400, [csci115]).
prereqs(csci400, [csci112]).
prereqs(csci375, [csci162,csci265]).
prereqs(csci370, [csci260,csci265]).
prereqs(csci360, [csci260,csci261,csci265]).
prereqs(csci355, [math123,csci162,csci261]).
prereqs(csci331, [csci260,csci265]).
prereqs(csci330, [csci162,csci260,csci261,csci265]).
prereqs(csci320, [csci260]).
prereqs(csci311, [csci265,csci310]).
prereqs(csci310, [csci161,csci162]).
prereqs(csci265, [csci161]).
prereqs(csci261, [csci160]).
prereqs(csci260, [csci161, math123]).
prereqs(csci251, [csci161,csci162]).
prereqs(csci162, [csci160]).
prereqs(csci161, [csci160]).
prereqs(csci160, [math12]).
prereqs(csci115, []).
prereqs(csci112, []).
prereqs(math241, [math122]).
prereqs(math223, [math123]).
prereqs(math123, [math121]).
prereqs(math122, [math121]).
prereqs(math121, [math12]).
prereqs(math12, []).
