2012-04-06 48 views
1

我想从列表中删除名为a的所有谓词。结果必须如图6-8所示:从Prolog中的列表中删除谓词

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

请不要给我建在SWI或他人的解决方案,因为代码必须是暗洗,序言。

谢谢。

编辑:我曾尝试下面的代码,但它仅适用于原子正常工作:

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)] 

这是不正确:(

+0

我曾尝试以下代码: 'REMOVE_ALL(X,[],[])。 remove_all(X,[X | L],R): - remove_all(X,L,R)。删除_all(X,[Y | L],R): - 不是(X = Y),remove_all(X,L,M),R = [Y | M] 但它只删除原子。 – 2012-04-06 09:47:13

+0

用该代码编辑您的帖子 – whd 2012-04-06 10:03:49

+0

你有什么想法吗? – 2012-04-06 10:10:30

回答

2

使用的findall

findall(X, (member(X,[a(1),a(2),a(3),b(1)]),\+(X=a(_))) ,V). 
+0

谢谢。它工作完美。 ;) – 2012-04-06 10:31:03

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). 

该解决方案从unpure findall/3避而远之的优势。

希望这会有所帮助。

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的同样的说法不再被绑定到,因为的findall 创建副本,因此新的变数。

再见

仿/ 3是ISO以及在暗洗!
http://www.amzi.com/manuals/amzi/pro/ref_manipulating_terms.htm#functorTermFunctorN

+0

那么什么是指在事实与内部变量,如(A)?这将永远是真的... – whd 2012-04-06 11:21:30

+0

变量的事实是非常有用的,检查井字棋:http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/06_bench/09_programs/ 11_tictactoe/01_tictactoe.p.html,move/3和win/2就是这样的事实。 – 2012-04-06 11:27:18

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). 
+0

(假设通过“谓词命名”,你指的是函子a/1) – 2012-04-06 21:24:20