Пролог списки и параметры и возвращаемые значения - PullRequest
2 голосов
/ 05 июня 2010

Я новичок в прологе и просто не могу понять это.

Я пытаюсь создать простую программу, которая получает список предикатов, ищет определенный предикат в списке и применяет функцию к параметрам этого предиката.

Что-то в этом роде:

?- program([pred1(a,b,p), pred2(d,b,p), pred2 (a,c,p)]). 

program (list1) :- 
search(pred2(X,Y,p),list1).
doSomething (X,Y) % with the X and Y returned from search function, both of them.

По сути, я хочу использовать все значения, которые будут возвращаться из цели search(pred2(X,Y,p),list1), и использовать их в другой функции.


Хорошо, я попробовал кое-что в прологе и пришел к этому:

member(X, [X | _]).

member(X, [_ | R]) :- member(X, R).

prog(L1,Out) :- member(pred2(X,Y), L1).

?- prog ([(pred1(a,b),pred2(c,b),pred2(d,a)],Out).

Это дает истину в 2 раза, как положено, но я хотел получить Out = [c,b] и Out = [d,a]. Как мне этого добиться?

Относительно ответа Оака: я понял, что это не процедурный язык, но я не могу понять, как получить доступ к значениям и использовать их в прологе. Ваш пример не был таким полезным.

Ответы [ 2 ]

7 голосов
/ 05 июня 2010

Для начала, я бы избегал называть эти вещи "функциями". Пролог не является процедурным языком, а правила / предикаты не являются функциями.

По сути, когда вы используете правило, вы действительно спрашиваете Пролога: «Дайте мне все значения, которые удовлетворят этому правилу». Само по себе правило ничего не возвращает.

Скажем, у вас на процедурном языке было следующее:

f(g(3))

Как бы вы сделали это в Прологе? Вам нужно написать некоторый предикат f(X,Y) и некоторый предикат g(X,Y), а затем вам нужно будет использовать запрос f(3,Y), g(Y,Z) - что означает, что Prolog найдет для вас значения для Y и Z, которые удовлетворят этот. Z - это то, что вас интересует.

0 голосов
/ 22 августа 2011

На мой взгляд, лучший способ приблизиться к этим требованиям фильтра и проекта в прологе - написать выражение фильтра так, чтобы оно принимало один аргумент и успешно выполнялось, если входной аргумент проходит фильтр -

iseven(Num) :- 0 is Num % 2 .

Затем запишите код проекции как принимающий один аргумент, а входной -

triple(NumIn, NumOut) :- NumOut is NumIn * 3 .

Тогда свяжите их вместе -

triple_evens(NumIn, NumOut) :- iseven(NumIn), triple(NumIn, NumOut).

Затем, чтобы запустить это для каждого члена списка, мы должны использовать findall -

triple_evens_in_list(Lin, Lout) :-
    findall(Num, ( member(NumL, Lin),
                   triple_evens(NumL, Num)
                 ), LOut).

Это можно обобщить так, чтобы в качестве аргументов было взято имя предикатов фильтра и карты. И это может быть сжато до одного stmt в виде -

findall(Num, ( member(M, List), 0 is M % 2, Num is M * 3 ), ListOut).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...