CSI 2165, Winter 2006
Assignment 2
Due Monday, Feb 27, 11am
Submission instructions: The submission is done electronically through Virtual Campus.
Please submit a file called a2.pl with comments inside. The first comment should include your name and student number. The file should contain the Prolog code for the required predicates, and comments explaining what they do and how they do it. Add in comments example queries that you ran for testing each predicate and what the Prolog output was (thorough testing is important). Make sure your program can be loaded (consulted) in Prolog without giving errors. Make sure the name of the file and the names of the predicates are the required ones.
Note: No late assignments are allowed.
The Prolog application that you are going to implement will provide access to a database of students and a database of courses.
We encode the database of students using a predicate student (one Prolog fact for each student). The first argument the full name of the student and the second argument a list of courses that the student took. The name of a student is a data structure called name with two arguments: the first name and the last name of the student. A course name is simply a symbol such as csi324.
student(name(john, smith),
[mat101, csi108, csi148, csi270]).
student(name(jim,
student(name(jane, brown),
[mat101, csi108]).
student(name(emily, white),
[mat101, csi108, mat246]).
student(name(emma, smith),
[mat101, csi108, csi148, mat246]).
We encode the database of courses and their prerequisites as a predicate prereq, with one Prolog fact for each course. The first argument is the name of the course and the second argument is a list of prerequisites required in order to take that course. A prerequisite can be a course name or a list of alternative prerequisites. For example, the fact that csi324 has the prerequisites csi148 and one of csi238 and mat246 is expressed in the last clause below. A list of alternative prerequisite contains two or more alternatives.
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]]).
Implement the following Prolog predicates:
(Make sure your predicates are general, so that they can be used with any Prolog database in this format; do not hard-code for the given example.)
1. took has two arguments: a student’s first name and a course name. It verifies if the student already took that course. Assume the two arguments are instantiated. Also assume that the first name uniquely identifies a student (this is not the case in reality, students numbers would be used as unique identifiers).
Example:
?- took(emma, mat101).
Yes
?- took(jim, mat246).
No
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.
Example:
?- is_prereq(csi310,
sta205).
yes
3. can-take with two arguments, a student’s first name and a course, and succeeds if the student has all the prerequisites necessary 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(john, csi310).
No
4. can-take-list has two arguments, a student’s first name and a list of courses, and succeeds if the student can take all the courses in the list (fails otherwise).
Example:
?-can_take_list(emma, [csi324,
csi270]).
yes
5. all-students with 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]
6. all_courses_taken has one uninstatiated argument in which it returns a list of all the courses
taken by at least one student. No duplicates should be included in the list.
Example:
?- all_courses_taken(X).
X = [mat246, mat101, csi108,
csi148, csi270]
Note: For 5. and 6. the elements in the resulting list can be in any order.
Hint: you could use the built-in predicate findall.
Have fun!!!