So, I am very new to Prolog and I have to write a short code about timetable. How can I add the findall function to a code itself?
happening(monday,chemistry).
happening(monday,english).
happening(tuesday,chemistry).
happening(wednesday,maths).
happening(friday,chemistry).
happening(friday,maths).
And now I want to write a command that shows how many times do I have chemistry in a week.
find_lessons(X) :-
findall(X,happening(X,chemistry), Bag).
I assume you want the result, so the Bag
, so you should rewrite find_lessons(X)
to find_lessons(Bag)
:
find_lessons(Bag) :-
findall(X, happening(X,chemistry), Bag).
This will then give a list of days when there is a chemistry lesson, so:
?- find_lessons(Bag).
Bag = [monday, tuesday, friday].
to count the number of lessons, you can use length/2
:
?- find_lessons(Bag), length(Bag, N).
Bag = [monday, tuesday, friday],
N = 3.
But one can do this more efficient. Right now there is overhead in constructing the list, and counting the elements. We can make use of the aggregate
library [swi-doc] and use the aggregate/3
predicate [swi-doc]:
?- aggregate(count, X^happening(X, chemistry), Total).
Total = 3.
so we can count the number of chemistry lessons with:
:- use_module(library(aggregate))
num_chem_lessons(N) :-
aggregate(count, X^happening(X, chemistry), N).