student(name(john,smith), [mat101, csi108, csi148, csi270]). student(name(jim,roy), []). student(name(jane,brown), [mat101, csi108]). student(name(emily,white), [mat101, csi108, mat246]). student(name(emma,smith), [mat101, csi108, csi148, mat246]). prereq(csi108, []). prereq(csi148, [csi108, mat101]). prereq(csi238, [csi148]). prereq(csi260, [csi108]). prereq(csi270, [csi148]). prereq(csi310, [[csi260, csi270], [sta107, sta205, sta255]]). prereq(csi324, [[csi148], [csi238, mat246]]). %1. took: student name and course name. %?-took(emma, mat101). %yes took(X,C):- student(name(X,_),L), member(C,L). %2 is_prereq: has two course names as arguments and verifies if the second %one is a prerequisite for the first one. Assume that the two arguments are instantiated. %?- is_prereq(csi310, sta205). %Yes is_prereq(X,Y):- prereq(X, L), helper_prereq(Y,L). helper_prereq(H,[H|_]). helper_prereq(X,[Y|_]):- is_list(Y),member(X,Y). helper_prereq(X,[Y|T]):- X\=Y, helper_prereq(X,T). %3. can-take has two arguments, a student name and a course, and succeds %if the student has all the prerequisites to take the course. %If there are alternative prerequisites, the student is required to have at %least one of them. A student cannot take a course if she/he already took it. %Example: %can_take(emma, csi324). %yes can_take(X,Y):- not(took(X,Y)), has_all_prereq(X,Y). has_all_prereq(X,Y):-prereq(Y,L), helper_can_take(X,L). helper_can_take(_,[]). helper_can_take(X,[H|T]):- taken_one(X,H), helper_can_take(X,T). taken_one(X,C):- not(is_list(C)), took(X,C). taken_one(X,[H|T]):- took(X,H); taken_one(X,T). %4. can-take-list has two arguments, a student and a list of courses, %and succeeds if the student can take all the courses in the list. %Example: %:-can_take_list(emma, [csi324, csi270]). %yes can_take_list(_,[]). can_take_list(X,[H|T]):- can_take(X,H), can_take_list(X,T). %5. %all-students has one argument: a list with the first names of all students %enumerated in the database. %Example: %?- all_students(X). % X = [john, jim, jane, emily, emma] all_students(L):- findall(X, student(name(X,_),_),L). %6. all_courses_taken has one uninstatiated argument: %a list with all the courses taken by at least one student. No duplicates. %Example: %?-all_courses_taken(X). %X = [mat246, mat101, csi108, csi148, csi270] %Note: the courses in the list can be in any order all_courses_taken(Result):- findall(L, student(name(_,_),L), [H|T]), get_elements(T,H,Result). get_elements([],A,A). get_elements([H|T],Acc, R):- get_elem(H,Acc,R1), get_elements(T,R1,R). get_elem([],A,A). get_elem([H|T], Acc, R):- member(H,Acc), get_elem(T, Acc, R). get_elem([H|T], Acc, R):- not(member(H,Acc)),get_elem(T,[H|Acc],R).