Как вернуть список рекомендаций в Прологе? - PullRequest
1 голос
/ 08 марта 2019

Для моего задания я должен перечислить 20 потенциальных питомцев, а затем определить факты о каждом из них.Затем мне нужно задать потенциальному владельцу домашних животных пять вопросов, которые помогут решить, какие домашние животные будут хорошими рекомендациями.Я пытаюсь вернуть список домашних животных, основываясь на пользовательском вводе, но он просто возвращает true каждый раз и фактически не перечисляет рекомендуемых домашних животных.Не уверен, где я иду не так.Я только собираюсь включить некоторых из домашних животных в мой пример кода, чтобы он не был очень длинным.ночное млекопитающее в помещении 15

Он должен вернуть список с [кошка, шиншилла], но все, что он возвращает, это правда.

1 Ответ

3 голосов
/ 08 марта 2019

Есть несколько проблем с вашим кодом.Во-первых, в большинстве систем 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
...