In my discrete mathematics course, we have a single prolog assignment that goes as follows
Create a program that models students, classes, rooms, dates, and their relations. Include relevant functions
My initial thought was that there needs to be generated a lot of data, and I am still curious whether this assignment can be completed without explicitly mapping every single relation explicitly.
Apparently it seemed as if there were two strategies, to use a graph (seemed complex) or use this mapping strategy relation(value, value2)
(I want to call it a predicate, but I am not sure if that is right).
However I can't seem to figure out how to access the relations within the rules? (I mean the :- syntax, seems more like functions to me than rules)
I feel like I am on a sidetrack, I have issues finding the information I need to solve this problem since I have difficulties with the terminology.
%student(name, class, semester)
student(søren, 101, 1).
student(jens, 101, 1).
student(peter, 101, 2).
student(eskild, 101, 1).
student(jørgen, 101, 2).
student(signe, 101, 1).
student(pernille, 101, 2).
student(katrine, 101, 2).
student(sophie, 101, 1).
student(liva, 101, 1).
%semester_subjects(semester, subject)
semester_subjects(2, DM).
semester_subjects(1, test).
semester_subjects(2, BI).
semester_subjects(1, SI).
semester_subjects(1, LSD).
semester_subjects(2, SI).
semester_subjects(2, LSD).
%class(name, subject)
class(101, DM).
class(101, test).
class(101, SI).
class(101, LSD).
class(101, BI).
%schedule(weekday(0-6), subject)
schedule(0, test).
schedule(1, test).
schedule(1, BI).
schedule(2, SI).
schedule(2, LSD).
schedule(4, DM).
%has_class_today(student_name, day) :-.
%has_sudent(class, student_name) :-.
%has_subject(student_name, subject_name) :-.
I feel like I should be able to do something like
has_class_today(student_name, day) :- {
Class = student(søren).class
Semester = student(søren).semester
SemesterSubjects = semester_subjects.forAll( if(semester == Semester) return subject)
SubjectsToday = schedule(day).forAll(if(SemesterSubjects.includes(subject))
if(SubjectsToday > 0) return true
else return false
}
But I relaly cannot figure out how to do so. To summarize my question.
Should my current aproach work how can I retrieve the values of one relation (Peter <-> Susan) based on the other? If my current approach does not work, how would you suggest to tackle this assignment
That's hard to explain and needs at least 2 hours of instruction.
This is a standard database modelling assignment.
You have the "objects"
Which is modelled by the predicate student/3
in Prolog. In relational database terminology / the relational model, this is called a relation or a table.
Appears differently (imagine it is in tabular form), but ... same thing.
You have the "elided objects"
DM
, test
etc..which are not listed explicitly using a predicate (though that would be possible, and recommended depending on the application) as in:
semester(1).
semester(2).
subject("DM").
subject("test").
Instead these objects are implicitly listed by giving a 2-place relationship between them
and this is modelled through the predicate (aka relation) semester_subjects/2
.
etc.
(Note that you code is erroneous. Prolog will consider anything starting with an uppercase letter as a variable, so you have to type "DM"
or 'DM'
rather than DM
.)
Go to SWISH and enter your data.
% The student relation: student(name, class, semester)
% A predicate made up by a set of facts.
student('søren', 101, 1).
student('jens', 101, 1).
student('peter', 101, 2).
student('eskild', 101, 1).
student('jørgen', 101, 2).
student('signe', 101, 1).
student('pernille', 101, 2).
student('katrine', 101, 2).
student('sophie', 101, 1).
student('liva', 101, 1).
% The relation expressing the connection/relationship
% between semester and subjects
% semester_subjects(semester, subject)
% A predicate made up by a set of facts.
semester_subjects(2, 'DM').
semester_subjects(1, 'test').
semester_subjects(2, 'BI').
semester_subjects(1, 'SI').
semester_subjects(1, 'LSD').
semester_subjects(2, 'SI').
semester_subjects(2, 'LSD').
% The relation expressing the connection/relationship
% between class and subject
% class(name, subject)
% A predicate made up by a set of facts.
class(101, 'DM').
class(101, 'test').
class(101, 'SI').
class(101, 'LSD').
class(101, 'BI').
% The relation expressing the connection/relationship
% between weekday and subject
% schedule(weekday(0-6), subject)
% A predicate made up by a set of facts.
schedule(0, 'test').
schedule(1, 'test').
schedule(1, 'BI').
schedule(2, 'SI').
schedule(2, 'LSD').
schedule(4, 'DM').
Once that is done, you can ask queries:
For example:
student(SNAME,CLASS_ID,SEMESTER),class(CLASS_ID,CLASS_NAME).
which means:
Retrieve all the tuples "SNAME,CLASS_ID,SEMESTER,CLASS_NAME" where you can juxtapose an element of the student
relation (or, a fact of the student
predicate) and an element of the class
relation (or, a fact of the class
predicate) such that the value CLASS_ID
appears in both identically those as stated. This is evidently a database JOIN operation.
You can then repack that query by defining a new predicate with a single clause in which the values that interest you appear:
interesting(SNAME,CLASS_NAME) :- student(SNAME,CLASS_ID,SEMESTER),class(CLASS_ID,CLASS_NAME).
and add it to the program.
Once that is done, you can issue new queries of the form
interesting(S,C).
In the end, you need to try this yourself. It's the only way.