Вот решение, которое перебирает все решения, всегда записывая решение, которое лучше предыдущего. В итоге возвращается лучшее решение.
Запись выполняется с использованием assert/1
, вы также можете использовать глобальную переменную без возможности возврата назад, если ваш Prolog предоставляет это (SWI-Prolog делает).
Преимущество этого подхода состоит в том, что каждое решение рассматривается только один раз, то есть сложность O (n). Поэтому, хотя он выглядит хуже, чем решение Starblue, он должен работать лучше.
% Data
cat(sassy, 5).
cat(misty, 3).
cat(miisu, 10).
cat(princess, 2).
% Interface
oldest_cat(Name) :-
loop_through_cats,
fetch_oldest_cat(Name).
loop_through_cats :-
cat(Name, Age),
record_cat_age(Name, Age),
fail ; true.
:- dynamic current_oldest_cat/2.
record_cat_age(Name, Age) :-
current_oldest_cat(_, CAge),
!,
Age > CAge,
retract(current_oldest_cat(_, _)),
assert(current_oldest_cat(Name, Age)).
record_cat_age(Name, Age) :-
assert(current_oldest_cat(Name, Age)).
fetch_oldest_cat(Name) :-
retract(current_oldest_cat(Name, _Age)).
Пример использования:
?- oldest_cat(Name).
Name = miisu
Miisu - типичное эстонское имя кошки. ;)