(序言)满足目标的列表中的第一个解决方案

时间:2018-06-28 14:06:21

标签: prolog

我需要在列表中找到满足用户提供的目标的 first 元素。我的意思是类似maplist/2的东西,但是当目标可以应用于至少一个元素时,它就会成功。 include/3是一种选择,但我正在寻求一种更优化的解决方案,该解决方案在找到第一个元素后就可以停止。

我认为界面可能如下:

first(:Goal, List, First)

,它应该是SWI-Prolog sense中的 semidet

编写代码相当容易,但是我更喜欢现有规则。 “标准”库中是否有相关规则?我正在使用SWI-Prolog。

干杯,   雅西克

1 个答案:

答案 0 :(得分:2)

我认为没有标准的谓词可以做到这一点。但是正如您所说,编写代码非常容易。我可能会写这样的东西,它的模式类似于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 ?-