course(cmput325).
course(cmput175).
course(cmput201).
course(cmput204).
prerequisite(cmput204, cmput325).
prerequisite(cmput175, cmput201).
prerequisite(cmput175, cmput204).
Мне нужно написать новый предикат, который будет
can_take(+L,?C).
Определение:
L - это заданный список курсов, которые студент уже прошел.Если также задан C, то предикат должен проверить, есть ли у студента все необходимые курсы для C. Если C является переменной, то при обратном отслеживании предикат должен производить один курс за раз, который студент может пройти сейчас.Курсы могут быть в любом порядке, но каждый курс должен быть создан только один раз, и вы не должны возвращать какие-либо курсы, которые студент уже прошел.
Пример:
?- findall(C, can_take([cmput175], C), L).
should return
L = [cmput201, cmput204].
Вот мойПредикат:
can_take(L,C) :- prerequisite(L,C).
can_take([L|List],C) :- prerequisite(L,C),can_take(List,C).
Этот предикат не вернул правильный результат, а просто вернул false.Я думаю, что это потому, что я не определил условие, когда L пусто, однако, если я попытался добавить L \ == [] в любой из них.Это все еще дало мне ошибку ... что я должен сделать, чтобы этот предикат остановился и дал мне результат?
------- 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).
Вот мой тест кода:
?- 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.
последний не в порядке, потому что я не хочу, чтобы он возвращал два истинных утверждения ... так что я хочу просто дать ему остановиться, когда либовторая или последняя строка возвращает true.Для моего задания я не могу использовать оператор cut !, есть ли другой способ сделать это?