这是我的代码
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 ....
我的代码出了什么问题?
答案 0 :(得分:2)
最好先用ISO not/1
替换(\+)/1
。
对于调试,您要做的第一件事就是最小化问题。例如,查询
?- removevowels([m,m],X).
同样糟糕。但要小得多。那么你的辅音规则是什么?有一个单一规则:
removevowels([X|L1], [X|L2], Aux) :-
consonant(X),
\+member(X, Aux),
removevowels(L1, L2, [X|Aux]).
所以辅音只有只出现一次,下一次出现会导致失败。
如果您仍然不确定查询失败的原因,您可能还需要概括查询。而不是看到removevowels([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).
回到辅音: 您缺少的是对已经存在的辅音的单独规则,或者某些"默认"如果 - 则 - 否则。
此外,这种额外检查可能不是处理此问题的最有效方法。也许只是先提取元音,然后再sort/2
。
答案 1 :(得分:0)
在第二个子句中,连接中有两个条件,而最后一个子句只有一个。我会用一个cut来提交好的情况,让最后一个句子只作为一个可信的跳过子句:
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).
使用if / then / else构造最后2个子句,我们避免了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)
).