Prolog 从列表中删除重复的元素
这是我的密码Prolog 从列表中删除重复的元素,prolog,Prolog,这是我的密码 removevowels(L1, L2) :- removevowels(L1, L2, []). removevowels([], [], _). removevowels([X|L1], [X|L2], Aux) :- consonant(X), not(member(X, Aux)), removevowels(L1, L2, [X|Aux]). removevowels([X|L1], L2, Aux) :- not(consonant(
removevowels(L1, L2) :-
removevowels(L1, L2, []).
removevowels([], [], _).
removevowels([X|L1], [X|L2], Aux) :-
consonant(X),
not(member(X, Aux)),
removevowels(L1, L2, [X|Aux]).
removevowels([X|L1], L2, Aux) :-
not(consonant(X)),
removevowels(L1, L2, Aux).
如果我运行这个:
?- removevowels([a,m,m,n], X).
应该打印出来
X = [m, n]
但这是假的如果我运行这个
?- removevowels([a,m,n], X).
X = [m,n]
当它没有重复的元素时就没问题了
使用的辅助谓词:
member(X, [X|_]).
member(X, [_|Tail]) :-
member(X, Tail).
consonant(b)
consonant(c), etcetc ....
我的代码出了什么问题?最好先用ISO
(\+)/1
替换而不是/1
对于调试,您要做的第一件事是将问题最小化。例如,查询
?- removevowels([m,m],X).
同样糟糕。但要小得多。那么你的辅音规则是什么?只有一条规则:
removevowels([X|L1], [X|L2], Aux) :-
consonant(X),
\+member(X, Aux),
removevowels(L1, L2, [X|Aux]).
所以辅音只能出现一次,下一次出现就已经失败了
如果您仍然不确定查询失败的原因,您可能还希望概括查询。您可能会问:删除元音([m,m],X)
失败,而不是看到它失败
?- removevowels([m,Y],X).
这意味着:是否存在任何Y
这样的解决方案。然而,这种方法只有在程序是“关系”的情况下才有效。但是,在您的情况下,最后一条规则阻止了这一点:
removevowels([X|L1], L2, Aux) :-
\+consonant(X),
removevowels(L1, L2, Aux).
如果X
是一个未实例化的变量,它将永远不会成功。我宁愿使用:
removevowels([X|L1], L2, Aux) :-
vowel(X),
removevowels(L1, L2, Aux).
回到辅音:
你所缺少的要么是对已经存在的辅音的一个单独的规则,要么是一些“默认”的规则
此外,这种额外的检查可能不是处理此问题的最有效方法。可能只是先提取元音,然后对它们进行排序。在第二个子句中,join有两个2条件,而最后一个子句只有一个。我会用一个cut来提交好的案例,并让最后一个子句仅作为一个可信的skip子句:
removevowels([], [], _).
removevowels([X|L1], [X|L2], Aux) :-
consonant(X),
not(member(X, Aux)),
!, removevowels(L1, L2, [X|Aux]).
removevowels([_X|L1], L2, Aux) :-
removevowels(L1, L2, Aux).
对最后2个子句使用if/then/else构造,我们避免了false指出的问题:
removevowels([], [], _).
removevowels([X|L1], R, Aux) :-
( consonant(X),
not(member(X, Aux))
-> R=[X|L2],
removevowels(L1, L2, [X|Aux])
; removevowels(L1, R, Aux)
).
此解决方案缺乏稳定性:
remove元音([m],])
应该失败,但在这里它成功了。条件辅音(X),\+member(X,Aux)
现在走得太远了:特别是remove元音([X],R)
现在错误地生成了一个答案。否则,元音的规则就缺乏了。他们两个都不能接受吗?