Как указать предикат в качестве параметра другого в прологе? - PullRequest
0 голосов
/ 12 октября 2018

Я хочу написать предикат пролога, который сохраняется, если предикат, отображаемый в качестве первого параметра, сохраняется для всех элементов списка, появляющихся во втором параметре.Вот что я пробовал:

?- listing(all).
all(pred(_), [A|B]) :-
    pred(A),
    all(pred(_), B).
all(pred(_), [x]) :-
    pred(x).

Что-то вроде следующего должно вернуть true.Возможно ли это в Прологе?

all(number, [3, 5 ,7]).

1 Ответ

0 голосов
/ 12 октября 2018

Вы можете использовать call/<i>n</i> [swi-doc] :

call(X, Y).

Дано X=number, а Y, например, 3 это будет называться number(3).В случае, если X является термином, таким как number(1), он называет его как number(1, 3), как если бы предикат был " curried ".

Таким образом, вы можете реализовать свою функцию как:

all(_, []).
all(P, [A|B]) :-
    <b>call(P, A),</b>
    all(P, B).

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

all(P, L) :-
    all2(L, P).

all2([], _).
all2([A|B], P) :-
    call(P, A),
    all2(B, P).

Но предикат, который вы здесь стремитесь реализовать, уже существует в некоторых популярных интерпретаторах Пролога maplist/2 [swi-doc] .

Это вызовет Goal для всех элементов списка или завершится ошибкой, если в какой-то момент предикат потерпит неудачу.

Вы также можете создавать функторы с помощью (=..)/2 [swi-doc] .Например:

X =.. [number, 1, 3]

приведет к X = number(1, 3).Затем вы можете использовать вызов call/1 [swi-doc] с созданным функтором для вызова функтора, как если бы это был предикат, например:

X =.. [number, 1, 3], call(X).

Обратите внимание, что предикат (=..)/2 не работает с этим «каррированием» функторов, например:

?- X =.. [number(1), 3].
ERROR: Type error: `atom' expected, found `number(1)' (a compound)
ERROR: In:
ERROR:    [8] _6428=..[number(1),3]
ERROR:    [7] <user>

.

...