0

我想a从列表中删除所有命名的谓词。结果必须如下所示:

?- delete_all(a(_), [a(1),a(2),a(3),b(1)], R).
R = [b(1)]

请不要为我提供 SWI 或其他内置解决方案,因为代码必须在 Amzi-Prolog 中。

谢谢。

编辑:我尝试了以下代码,但它仅适用于原子:

remove_all(X,[],[]).
remove_all(X,[X|L],R):-remove_all(X,L,R).
remove_all(X,[Y|L],R):-not(X=Y), remove_all(X,L,M), R=[Y|M].

?-remove_all(a(_), [a(1),a(2),a(3),b(1)], R).
R=[a(2),a(3),b(1)]

这不是真的:(

4

4 回答 4

2

使用 findall

findall(X, (member(X,[a(1),a(2),a(3),b(1)]),\+(X=a(_))) ,V).
于 2012-04-06T10:19:18.757 回答
2

我知道你说没有 swi-prolog。然而,这是一项简单的任务(与主要任务相比),实现与所使用的行为相同的递归,exclude/3其余的应该是 ISO prolog 或存在于 amzi 中。它使用lambda.pl,一个允许更容易进行高阶编程的库:

:- [lambda].
filter(Term, List, Result) :-
    Term =.. [Pred|Args],
    length(Args, Arity),
    exclude(\X^(X =.. [Pred2|Args2],
                length(Args2, Arity2),
                Pred == Pred2,
                Arity == Arity2), List, Result).

这种解决方案的优点是远离不纯的findall/3.

希望这可以帮助。

于 2012-04-06T10:53:35.710 回答
1

小修复,它应该工作:

% remove_same_indicator(+Callable,+List,-List)
remove_same_indicator(_, [], []).
remove_same_indicator(X, [Y|L], R) :- 
       functor(X, F, N), 
       functor(Y, F, N), 
       !, 
       remove_same_indicator(X, L, R).
remove_same_indicator(X, [Y|L], [Y|R]) :- 
       remove_same_indicator(X, L, R).

试一试吧:

?- remove_same_indicator(a(_), [a(1),a(2),a(3),b(1)], R).
R = [b(1)]

优于 findall 解决方案,不会丢失变量。例如,可以这样做:

?- remove_same_indicator(a(_), [a(A),a(B),a(C),b(A)], R).
R = [b(A)]

但是通过 findall 解决方案,我们得到:

?- L=[a(A),a(B),a(C),b(A)], findall(X, (member(X,L),\+ (X = a(_))), R).
L = [a(A), a(B), a(C), b(A)],
R = [b(_I)]

b 的参数不再绑定到 A,因为 findall 创建了副本并因此创建了新变量。

再见

functor/3 是 ISO,也在 Amzi 中!
http://www.amzi.com/manuals/amzi/pro/ref_manipulating_terms.htm#functorTermFunctorN

于 2012-04-06T11:07:07.593 回答
0
remove_all(_, [], []).
remove_all(X, [Y|R], L):- \+ X \= Y, remove_all(X, R, L).
remove_all(X, [Y|R], [Y|R2]):- X \= Y, remove_all(X, R2, L).
于 2012-04-06T21:21:36.293 回答