Reputation: 236
I'm new to Prolog. My "database" consists of the following rules:
teacher(1, 'Benjamin', 'Johnson').
teacher(2, 'Mike', 'Oliver').
teacher(3, 'James', 'Johnson').
school(1, 'School1','Town1').
school(2, 'School2','Town2').
school(3, 'School3','Town3').
group(1,'Group1', 1, 1).
group(2,'Group2', 3, 2).
group(3,'Group3', 2, 1).
group(4,'Group4', 2, 1).
group(5,'Group5', 3, 3).
group(6,'Group6', 1, 3).
"teacher" has the scheme:
teacher(TeacherID, TeacherFirstname, TeacherLastname)
"school" has the scheme:
school(SchoolID, SchoolName, City)
"group" has the scheme:
group(GroupID, GroupName, TeacherID, SchoolID)
I want to output all schools where teachers work whose last name is 'Johnson'.
My query is as follows:
group( GroupID, _ , TeacherID , SchoolID ) , school( SchoolID , SchoolName, _ ) , teacher( TeacherID , _ , 'Johnson' ).
I want to return the name of the schools, who fit the query, only once. However using my current query I get a single school multiple times. How can I detect duplicates and not output them? Thanks!
PS: The relational algebra would be
π SchoolName (σ TeacherLastname = 'Johnson' (teacher ⨝ group ⨝ school))
Upvotes: 0
Views: 115
Reputation: 9378
With an auxiliary predicate:
school_with_teacher_johnson(School) :-
group(_, _, Teacher, SchoolID),
school(SchoolID, School, _),
teacher(Teacher, _, 'Johnson').
You can use the setof/3
predicate with gives you a set of solutions, that is, a sorted list with duplicates removed:
?- setof(School, school_with_teacher_johnson(School), Schools).
Schools = ['School1', 'School2', 'School3'].
It's also possible to use setof/3
without an auxiliary predicate, but it's ugly and easy to get wrong.
Upvotes: 2