countByCountries/1 — câte cărți publicate pe fiecare țară
Determinați, pentru fiecare țară (obținută de la publisher), câte cărți au fost publicate. Scrieți un predicat countByCountries/1 care returnează lista de țări, împreună cu numărul de cărți.
?- countByCountries(Result).
Result = [('Germany',2),('UK',3),('USA',3)]
Atenție la duplicate! Vrem o singură apariție pentru fiecare țară. În rezolvare, puteți folosi predicatul
count/2de mai jos.
count([], 0) :- !.
count([_ | T], Res) :-
count(T, ResT),
Res is ResT + 1.
Notă: în șablonul original apărea
[('Germany',2), ('USA',3), ('UK',3), ('USA',3)]cuUSAdublat — asta era tocmai capcana, trebuia să deduplicăm țările. Varianta deduplicată și sortată alfabetic este cea corectă.
Te-ai blocat?
editor
soluție
fields(1, 'Mathematics').
fields(2, 'Computer Science').
fields(3, 'Philosophy').
fields(4, 'Physics').
fields(5, 'Linguistics').
authors(1, 'Donald Knuth', 'Stanford University').
authors(2, 'Bertrand Russell', 'University of Cambridge').
authors(3, 'Noam Chomsky', 'MIT').
authors(4, 'Roger Penrose', 'University of Oxford').
authors(5, 'Terence Tao', 'University of California, Los Angeles').
publishers(1, 'Springer', 'Germany').
publishers(2, 'MIT Press', 'USA').
publishers(3, 'Cambridge University Press', 'UK').
publishers(4, 'Oxford University Press', 'UK').
publishers(5, 'Addison-Wesley', 'USA').
books(101, 'The Art of Computer Programming', 1, 5, 2).
books(102, 'Principia Mathematica', 2, 3, 1).
books(103, 'Syntactic Structures', 3, 2, 5).
books(104, 'The Road to Reality', 4, 4, 4).
books(105, 'Analysis I', 5, 1, 1).
books(106, 'Modern Quantum Mechanics', 4, 1, 4).
books(107, 'Formal Semantics and Logic', 3, 3, 5).
books(108, 'Linear Algebra Done Right', 5, 5, 1).
count([], 0) :- !.
count([_ | T], Res) :-
count(T, ResT),
Res is ResT + 1.
% 1. setof adună țările distincte (și le sortează alfabetic)
% 2. pentru fiecare țară colectăm id-urile cărților publicate la edituri din acea țară
% 3. numărăm și formăm perechea (Country, N)
countByCountries(Result) :-
setof(Country,
PId^PName^publishers(PId, PName, Country),
Countries),
findall((Country, N),
(member(Country, Countries),
findall(BId,
(books(BId, _, _, PId, _),
publishers(PId, _, Country)),
Books),
count(Books, N)),
Result).
?-
Tastează o interogare (ex. father_of(sandra, X).) și apasă Enter — sau apasă pe un caz de test de mai jos.
Cazuri de test (1 — apasă pe unul ca să îl rulezi, sau Verifică pentru toate)
?
countByCountries(Result).
așteptat: Result = [('Germany',2),('UK',3),('USA',3)]