(Пролог) первое решение из списка, которое удовлетворяет цели - PullRequest
0 голосов
/ 28 июня 2018

Мне нужно найти в списке первый элемент, который удовлетворяет заданной пользователем цели. Я имею в виду что-то вроде maplist/2, но это удается, когда цель может быть применена к хотя бы к одному элементу . include/3 было бы вариантом, но я выбрал более оптимальное решение, которое может остановиться после нахождения первого элемента.

Я думаю, что интерфейс может выглядеть так:

first(:Goal, List, First)

и это должно быть полудетель в смысле SWI-Prolog .

Код довольно легко закодировать, но я бы предпочел существующее правило. Есть ли соответствующее правило в «стандартных» библиотеках; Я использую SWI-Prolog.

Ура, Яцек

1 Ответ

0 голосов
/ 28 июня 2018

Я не думаю, что есть стандартный предикат, который делает это. Но, как вы говорите, было бы очень легко кодировать. Я бы, вероятно, написал что-то вроде этого, которое имеет шаблон, такой как предикат member/2:

includes_item(Goal, [X|_], X) :-
    call(Goal, X).
includes_item(Goal, [_|T], X) :-
    includes_item(Goal, T, X).

<ч /> Как указывает @false в комментариях, на самом деле это можно написать более четко, используя member/2:

includes_item(Goal, List, Item) :-
    member(Item, List),
    call(Goal, Item).
<ч />

includes_item(:Goal, List, Item) успешен для каждого Item в List, который удовлетворяет :Goal. Например:

3 ?- includes_item('>'(3), [1,2,3,-2, 4, 5], X).
X = 1 ;
X = 2 ;
X = -2 ;
false.

Затем вы можете использовать once/1, чтобы получить только первый предмет без точки выбора:

first(Goal, List, Item) :-
    once(includes_item(Goal, List, Item)).

А теперь вы получите:

4 ?- first('>'(3), [1,2,3,-2, 4, 5], X).
X = 1.

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