I am trying to write a prolog program that works out which course I can choose in the university course catalog. Each course has a unique code like cs180 and each course may have some prerequisite courses, which means the required courses must be finished before registering for this course.
Assuming that there's no circular dependency of courses, all courses in the university form a directed graph with no loops.
req(ma262, [ma261,ma182,ma174,ma271,ma27101,ma172,ma263]).
req(ma351, [ma174,ma172,ma182,ma261,ma271,ma27101,ma263]).
req(ma366, [ma351,ma265]).
req(ma341, [ma174,ma172,ma182,ma261]).
req(ma440, [ma35301]).
req(ma35301, [ma265,ma351]).
req(cs314, [ma262,ma265,ma350,ma351]).
req(cs314, [cs180,cs158,cs177,cs159]).
ok(ma172).
ok(cs180).
In this program, req(A,B) indicates that: to register for class A, I must complete at least one course from the list of classes B. If there's multiple statements of requirement, then all of the requirements must be met. For example, to register for cs314, I need to complete one course from both lists. ok/1 indicates that I've already completed the course.
Then I define a valid scheme as a list of courses such that each class in the list is either
- completed, or
- some other classes in the list fulfills its requirement.
For example, [ma172] is a valid scheme as it's completed. [ma172,ma262] is a valid scheme since the requirement of ma262 can be met with ma172.
Here's my code.
valid(Cs):-
is_set(Cs), /*Cs is distinct*/
maplist({Cs}/[C]>>( /*for each class in Cs*/
ok(C); /*either completed, or meets requirements*/
(setof(P,req(C,P),Ps), /*get all requirements*/
maplist({Cs}/[L]>>( /*check all requirements*/
member(X,L),
(member(X,Cs);ok(X))
),Ps)
)),Cs).
When I query ?- valid(N) , prolog simply returns [] and then false. However, these examples hold true:
?- valid([ma366,ma351])
true
?- valid([ma366,ma351,ma172])
true
I don't know why the solver doesn't work correctly. If my code breaks the monotonicity, would you like to point out where? And how should I change my code to get it to work?