Получение списка решений в Прологе - PullRequest
9 голосов
/ 16 ноября 2010

Я изучаю пролог и читаю книгу под названием «Пролог программирования для искусственного интеллекта». В качестве практики я хочу научиться расширять один из примеров в этой книге. Может кто-нибудь помочь, пожалуйста?

Скажем, у вас есть эти факты:

parent(pam, bob). %pam is a parent of bob
parent(george, bob). %george is a parent of bob

Как бы я написал предикат пролога, который бы дал мне список родителей Бобса? Например:

list_parents(bob, L).

L = [pam, george] ;
L = [george, pam] ;
true.

Ответы [ 2 ]

17 голосов
/ 16 ноября 2010

Предикат "все решения", такой как findall/3, может помочь:

list_parents(P, L) :-
    findall(Parent, parent(Parent, P), L).

Проще говоря, findall/3 находит все привязки для Parent в цели "backtrack-способны" parent(Parent, P)и помещает все привязки Parent в список L.Обратите внимание, что это не удалит дубликаты, но вы можете сделать от sort/2 до L перед возвратом, чтобы создать набор.Выполнение этого:

?- list_parents(bob, L).
L = [pam, george].

Если у вас нет findall/3 в вашей реализации PROLOG, вы можете сделать это вручную следующим образом:

list_parents(P, L) :-
    list_parents(P, [], L).

list_parents(P, Acc, L) :-
    parent(Parent, P),
    \+ member(Parent, Acc), !,
    list_parents(P, [Parent|Acc], L). 
list_parents(_, L, L).

Эта версия отправляет вызовы на list_parents/2 до аккумуляторной версии, list_parents/3.Последний также пытается собрать привязки Parent, пока мы их не видели (следовательно, проверка \+ member), и возвращает список, в котором не может быть никаких новых привязок Parent, накопленных в списке Acc.найденный.Выполнение этого дает нам тот же результат, что и первый вариант:

?- list_parents(bob, L).
L = [pam, george].
2 голосов
/ 16 ноября 2010

Попробуйте это:

parent(pam, bob). %pam is a parent of bob
parent(george, bob). %george is a parent of bob
list_parents(A, Es, [X|Xs]) :- parent(X, A), \+ member(X, Es), list_parents(A, [X|Es], Xs).
list_parents(A, Es, []).

Это был неэффективный метод, более эффективному методу понадобится предикат высшего порядка "solutions".

list_parents (X, Ys): - решения (родитель, [X, W], 1, Ys)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...