Попробуйте это для размера:
second_largest_city(City) :-
findall(Size, city(_, _, Size), Sizes),
sort(Sizes, SortedSizes),
append(_, [Size2, _], SortedSizes),
city(City, _Country, Size2).
Объяснение: findall/3
находит размеры всех city/3
фактов, которые сортируются в по возрастанию упорядочить по sort/2
с удалить дубликаты .Призыв к шаблону append/3
соответствует разбиению отсортированного списка SortedSizes
на две части;список любого размера (_
) и остаток длины два ([Size2, _]
) - это связывает переменную Size2
со вторым по величине размером города из city/3
фактов.Наконец, все города с таким размером расположены среди city/3
фактов и связаны с выводом.
Примечание: В общем случае это не будет работать должным образом, если ваш встроенный дляsort/2
не не удаляет дубликаты, поскольку это оставляет возможность того, что city/3
фактов с более чем одним равным максимумом будет возвращать только максимум (самый большой).Эта реализация, использующая append/3
для поиска второго по последнему элементу отсортированного списка размеров, также предполагает sort/2
отсортированные числа в порядке возрастания.
Также, наконец, обратите внимание, что это не получится сразу, если будет меньше двух city/3
фактов - но это, вероятно, хорошо, учитывая, что предикат ищет «второй по величине» город и, строго говоря, тамне было бы одного, если бы в БД не было хотя бы двух городов с разными размерами.Если это проблема, вы можете просто написать больше предложений для second_largest_city/1
для обработки такого случая.