Reputation: 742
The fact base stores exam schedule information in the form: exam ('group', 'subject', 'teacher', date). Write a program that allows you to select exam information for the group / teacher, sorting it by date.
So, I already know how to get data from base depending on what you want (by Group number or by teacher name):
exam('426-1', 'PROGRAMMING', 'John', 08-12-2019).
exam('426-1', 'MATH', 'John', 18-12-2019).
exam('426-3', 'ENG', 'Gabe', 16-12-2019).
exam('426-4', 'LITERATURE', 'Homer', 11-12-2019).
findByGroup(Number, Exams) :-
findall([A,B|C], exam(Number, A,B,C), Exams).
findByTeacher(Name, Exams) :-
findall([A,B|C], exam(A, B, Name,C), Exams).
Here's the input
findByGroup('426-1', X).
And here's the output
X = [['PROGRAMMING', 'John'|8-12-2019], ['MATH', 'John'|18-12-2019]]
But I have no idea how should I sort my output by date. For example, how can I sort the data by ascending of the date?
Example:
Before X = [['MATH', 'John'|18-12-2019], ['PROGRAMMING', 'John'|8-12-2019]]
After X = [['PROGRAMMING', 'John'|8-12-2019], ['MATH', 'John'|18-12-2019]]
Upvotes: 0
Views: 245
Reputation: 58244
There are a couple of things that need to be considered:
exam
item needs to be organized into a term that will sort based upon the dateFor the date format, you are using a -
functor with integer arguments. This is Ok. To make it sortable chronologically, the order needs to be year-month-day
. You can either change your original data to be in that form, or translate to the sortable form before you do your sorting.
Regarding the exam data record, if you create a record formatted as a term with the date as the first argument, then sorting the records will sort by date. For example, any of the following terms will sort by date in Prolog:
exam(Date, Number, A, B)
[Date, Number, A, B]
...etc...
Now we apply this to your problem. Sorting can be done using setof/3
instead of findall/3
if your date is formatted in a sortable form:
% exam(Number, Class, Name, Date)
exam('426-1', 'PROGRAMMING', 'John', 2019-12-08).
exam('426-1', 'MATH', 'John', 2019-12-18).
exam('426-3', 'ENG', 'Gabe', 2019-12-16).
exam('426-4', 'LITERATURE', 'Homer', 2019-12-11).
findByGroup(Number, Exams) :-
setof([Date, Number, Class, Name], exam(Number, Class, Name, Date), Exams).
findByTeacher(Name, Exams) :-
setof([Date, Number, Class, Name], exam(Number, Class, Name, Date), Exams).
This will provide terms with attributes in a slightly different order: [Date, Number, Class, Name]
. You can either just work with that, or you could easily change it:
reformat_exam_list([Y-M-D, Number, Class, Name], [Number, Class, Name, D-M-Y]).
And then call maplist(reformat_exam_list, Exams, ReformattedExams)
.
If you can't change the date format in your original facts, you can pre-process them as part of your setof/3
call.
reformat_sorted_exam(exam(Y-M-D, Number, Class, Name), exam(Number, Class, Name, D-M-Y)).
findByGroup(Number, Exams) :-
setof(exam(Y-M-D, Number, Class, Name), exam(Number, Class, Name, D-M-Y), ExamList),
maplist(reformat_sorted_exam, SortedExams, Exams).
Here I also used an exam
structure instead of a list to represent an exam. You get the idea...
Upvotes: 2