谓词从列表中过滤非常量

时间:2011-11-04 15:31:07

标签: prolog

我正在研究一个谓词only_atoms / 2(List +,Result-),我想过滤非原子。

例如:

only_atoms([1, 2, X, h(Y), 'aba'], Result).

应该返回

Result = [1, 2, 'aba'].

我不关心订单。

以下是我提出的代码:

only_atoms([], []) :- !.
only_atoms([Head | Tail], [Head | Result]) :-
    atom(Head),
    !,
    only_atoms(Tail, Result).
only_atoms([_ | Tail], Result) :-
    only_atoms(Tail, Result).

我认为这是处理这样一个问题的正确理由,但似乎是错误的,因为它产生了我[](编辑:它实际上产生[aba],见下面的精度,我的坏!)无论如何。我很感激一些帮助!

2 个答案:

答案 0 :(得分:3)

第一个提示:对于12atom会返回false

顺便说一句,我一直在寻找过滤器谓词,在标准库中恰好称为include,如果你使用已经提供的语言通常会更好; - )

?- include(atom, [1, 2, X, h(Y), 'aba'], Result).
Result = [aba].

或者您只想过滤掉变量:

?- exclude(var, [1, 2, X, h(Y), 'aba'], Result).
Result = [1, 2, h(Y), aba].

另一个方面,你的only_atoms和使用include(atom, ...)之间的一个奇怪的区别是你的第一个列表中的变量与第二个列表中的原子统一,而include赢了“T

?- only_atoms([1, x, 2, Y], [x, y]).
Y = y.

?- include(atom, [1, x, 2, Y], [x, y]).
false.

Prolog的那些微妙之处总是让我感到惊讶(我想那是因为我没有在大学xD上给予足够的重视)。

答案 1 :(得分:1)

您可能需要强制Head不要成为alternate子句中的原子,否则它也是原子的选项。

这会为我返回Result = ['aba']

only_atoms([], []).
only_atoms([Head | Tail], [Head | Result]) :- atom(Head), !, only_atoms(Tail, Result).
only_atoms([Head | Tail], Result) :- \+atom(Head), !, only_atoms(Tail, Result).

或者,您可以尝试使用findall/3

atoms_list(List, Result) :- findall(Item, (member(Item, List), atom(Item)), Result).