Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 从列表中删除重复的元素_Prolog - Fatal编程技术网

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)
现在错误地生成了一个答案。否则,元音的规则就缺乏了。他们两个都不能接受吗?