course(cmput325).
course(cmput175).
course(cmput201).
course(cmput204).
prerequisite(cmput204, cmput325).
prerequisite(cmput175, cmput201).
prerequisite(cmput175, cmput204).
I need to write a new predicate, which is
can_take(+L,?C).
Definition:
L is a given list of courses that a student has already taken. If C is also given,then the predicate should check whether the student has all the required courses for C. If C is a variable, then with backtracking, the predicate should produce one course at a time that the student can take now. Courses can be in any order, but each course should be generated only once, and you should not return any courses that the student has already taken.
Example:
?- findall(C, can_take([cmput175], C), L).
should return
L = [cmput201, cmput204].
Here is my predicate:
can_take(L,C) :- prerequisite(L,C).
can_take([L|List],C) :- prerequisite(L,C),can_take(List,C).
This predicate didn't return the correct result, and it just returned false. I think it is because I didn't determine the condition when L is empty, however, if I tried to add L \== [] in either of them. It still gave me error...what should I do so that this predicate will stop and give me result?
-------update-------
pre(X,C) :- prerequisite(X,C).
pre(X,C) :- prerequisite(X,Y), pre(Y,C).
pre2(C,L) :- findall(L1,pre(L1,C),L).
required(C,L) :- pre2(C,L1),sort(L1,L).
can_take([],_).
can_take(L,C) :- required(C,L).
can_take([L|List],C) :- prerequisite(L,C),can_take(List,C).
Here is my code test:
?- required(cmput325,L).
L = [cmput175, cmput204].
?- required(cmput204,L).
L = [cmput175].
?- can_take([cmput175],X).
X = cmput201 ;
X = cmput204 ;
?- findall(C, can_take([cmput175], C), L).
L = [cmput201, cmput204].
?- can_take([cmput204],cmput325).
false. (this one is OK)
?- can_take([cmput175,cmput204],cmput325).
true ;
false. (this one is OK)
?- can_take([cmput175],cmput204).
true ;
true ;
false.
the last one is not ok because I don't want it to return two true statements...so what I want is just let it stop when either second or last line returns true. For my assignment, I am not allowed to use cut operator !, is there any other way to do it?
L \== []
, you will make things worse as you add a further condition. – falsefindall(C, can_take([], C), L).
– gusbrofindall(C, can_take([], C), L).
which would be asking which courses you can take when you have not taken any prior courses ? – gusbro