我不明白为什么对于这个谓词,最后一个位置是记忆位置。
elimina_diretos(_,[],_).
elimina_diretos(LA,[H|T],LP):-
member(H,LA),
elimina_diretos(LA,T,LP).
elimina_diretos(LA,[H|T],[H|LP]):-
elimina_diretos(LA,T,LP).
如果我输入
?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],L).
Prolog给了我:
L = [pedro, rocha|_G609] ;
如何清除_G609
?
答案 0 :(得分:2)
您的计划存在一些问题。但首先,_G609
只是一个逻辑变量。您可以假设此数字与具体内存位置有些相关。这种在顶层指示变量的特殊方式特定于SWI-Prolog。其他系统产生更全面的结果,例如GNU Prolog:
| ?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],L).
L = [pedro,rocha|_] ? ;
因此,此回答意味着L
是以pedro
和rocha
开始的部分列表。这是你的意图吗?这也意味着
| ?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],[pedro,rocha,jose]).
true ?
这真的是你的意图吗?我想不是。但由于你没有说明关系应该描述什么,所以很难猜测。
这不是您的程序的唯一问题。我们只看了第一个答案,但让我们看看后续的答案!
| ?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],L).
L = [pedro,rocha|_] ? ;
L = [pedro,rocha,andre|_] ?
yes
所以还有另一个答案!
这是一种非常通用的快速查找此类错误的方法。测试时,从最常见的查询开始,详细查看答案:
| ?- elimina_diretos(A, B, C).
B = [] ? ...
这意味着:elimina_diretos/3
对于所有 A
和C
B = []
为真。我非常怀疑这是你想要描述的内容。
((因为每个人都只发布答案,我必须效仿))
elimina_diretos(_,[],[]). elimina_diretos(LA,[H|T],LP):- member(H,LA), elimina_diretos(LA,T,LP). elimina_diretos(LA,[H|T],[H|LP]):- maplist(dif(H),LA), elimina_diretos(LA,T,LP).
此解决方案不依赖于(未指定)模式。 @ mbratch和@ CapelliC的解决方案确实依赖(不知何故)并且错误地失败了:
?- elimina_diretos([X], [pedro,tiago],[pedro]).
X = tiago ;
false.
答案 1 :(得分:1)
首先改变:
elimina_diretos(_,[],[]).
请注意,您的代码必须是确定性的,否则您将在回溯中获得不需要的“解决方案”:
?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],L).
L = [pedro, rocha] ;
L = [pedro, rocha, andre] ;
...
然后第二次改变(注意切割):
elimina_diretos(LA,[H|T],LP):-
memberchk(H,LA),!,
elimina_diretos(LA,T,LP).
现在应该按预期工作
?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],L).
L = [pedro, rocha] ;
false.
使用memberchk/2
代替member/2
,效率更高。
答案 2 :(得分:1)
只是为了给几个好的答案留下另一个选择。
正如CapelliC已经指出的那样,一个问题是基本情况不太正确:elimina_diretos(_, [], _).
这说明从空列表中删除任何一组项目,我得到一个匿名变量。在这种情况下,正确的“答案”将是空列表:elimina_diretos(_, [], []).
这是唯一的变化,然后您可以通过CapelliC提到的多重解决方案问题获得良好的答案。
重写条款的另一个选择如下:
elimina_diretos([], L, L). % Remove nothing from L is L
elimina_diretos([H|T], L, LP):-
( delete(H, L, L1) % L1 is L with all H's removed
-> elimina_diretos(T, L1, LP)
; elimina_diretos(T, L, LP) % There are no H's in L
).
产生:
| ?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],L).
L = [pedro,rocha] ? ;
no
| ?- elimina_diretos([a,b,c], [a,c,e,f], L).
L = [e,f]
yes
| ?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],[pedro,rocha,jose]).
no
| ?- elimina_diretos([tiago,andre],[pedro,tiago,rocha,andre],[pedro,rocha,andre]).
no