Есть несколько проблем с вашим кодом.Во-первых, в большинстве систем Prolog и в стандарте Prolog должен быть объявлен несмежный предикат.Добавьте следующую директиву в начало вашего файла:
:- discontiguous([
size/2, sleeps/2, stays/2, class/2, live/2
]).
Далее, нет необходимости использовать динамические предикаты, а также утверждать и убирать факты, когда вы запрашиваете рекомендацию:
which_pet(Size, Sleep, Place, Type, Age, Pet) :-
size(Pet, Size),
sleeps(Pet, Sleep),
stays(Pet, Place),
class(Pet, Type),
live(Pet, Age0), Age0 =< Age.
recommend :-
write('Do you want a small, medium, or large sized pet? '), read(Size), nl,
write('Do you want a pet that sleeps during the day or night? '), read(Sleep),
write('Do you want an indoor or outdoor pet? '), read(Place), nl,
write('Do you want a reptile, mammal, bird, or a fish? '), read(Type), nl,
write('How long do you want your pet to live (years)? '), read(Age), nl,
findall(Pet, which_pet(Size,Sleep,Place,Type,Age,Pet), Suggestions),
write('I would recommend these pets for you: '), nl, writelist(Suggestions).
Это не идеальная перезапись, поскольку она плохо масштабируется, но гораздо лучше, чем использование динамических предикатов.
В качестве заключительного замечания ваш код для печати результатов выполняет две задачи, которые лучше разделить: (1) фильтрдубликаты и (2) распечатать уникальные результаты.Я рекомендую вам разделить эти задачи.Фильтрация результатов может быть выполнена, например, с помощью setof/2
вместо findall/3
или путем вызова sort/2
в списке, созданном с помощью вызова findall/3
.Я оставляю это переписать для вас.Также используйте стандартную конструкцию управления отрицанием \+/1
вместо устаревшего / устаревшего not/1
предиката.
Пример вызова:
| ?- recommend.
Do you want a small, medium, or large sized pet? small.
Do you want a pet that sleeps during the day or night? night.
Do you want an indoor or outdoor pet? outdoor.
Do you want a reptile, mammal, bird, or a fish? bird.
How long do you want your pet to live (years)? 20.
I would recommend these pets for you:
chicken
yes