Prolog整数比较失败,error_type错误

时间:2017-06-17 21:10:03

标签: prolog

我正在尝试解决this page列表构建部分的练习2:

  

编写程序以从列表中删除特定项目的所有引用。它应该有三个参数。你想要使用的清单,   要删除的项目以及生成的列表。

这是我提出的脚本:

delete_all([],Y,[]).
delete_all([X|T],Y,[X|Result]):- 
    X =\= Y,                               /* is X different than Y       */
    delete_all(T,Y,Result).                /* if so then go find the rest */
delete_all([ThrowAway|Tail],Y,Result):-    /* disgard the head            */
    delete_all(Tail,Y,Result).             /* and look in the tail        */

以下是应该给出的更正结果:delete_all([a,b,a,c,a,d],b,Result).

% delete_all([a,b,a,c,a,d],a,Result).
% Result = [b,c,d]
% delete_all([a,b,a,c,a,d],b,Result).
% Result = [a,a,c,a,d]
% delete_all([a,b,a,c,a,d],prolog,Result).
% Result = [a,b,a,c,a,d]

相反,我收到了这个错误:

| ?- delete_all([a,b,a,c,a,d],a,Result).
uncaught exception: error(type_error(evaluable,a/0),(=\=)/2)

我在ubuntu 16.04下使用gprolog。

谢谢

3 个答案:

答案 0 :(得分:5)

首先,你在第一行收到关于singleton变量的警告,因为Y是一个单例,所以你需要替换为:

delete_all([],_,[]).

现在错误归因于=\= 仅用于算术,您需要使用\=或甚至更好的iso谓词dif/2来保持逻辑纯度

现在完整的代码:

delete_all([],_,[]).
delete_all([X|T],Y,[X|Result]):- dif(X,Y), delete_all(T,Y,Result).               
delete_all([Y|Tail],Y,Result):- delete_all(Tail,Y,Result).

答案 1 :(得分:4)

使用模块if_/3中的reif提供更高效的答案:

delete([],_,[]).
delete([H|T],X,L):- if_( 
                         H = X,
                         delete(T,X,L),
                         (L = [H|L1], delete(T,X,L1))
                       ).

答案 2 :(得分:3)

您可以使用功能设计。您需要查看 foldl / 4 差异列表(了解U-U,[In | U] -U和append_dl)。

delete_one(To_Remove, To_Remove, Cur, Cur).
delete_one(To_Remove, In, Cur, Next) :-
    dif(To_Remove, In),
    append_dl(Cur, [In|U]-U, Next).

append_dl(A-B, B-C, A-C).

delete_all(In, To_Remove, Out) :-
    foldl(delete_one(To_Remove), In, U-U, Out-[]).

示例:

 ?- delete_all([a,b,a,c,a,d],a,Result).
Result = [b,c,d] ;
false.

 ?- delete_all([a,b,a,c,a,d],X,[b,c,d]).
X = a ;
false.

 ?- delete_all([Y,b,Y,c,Y,d],X,[b,c,d]).
Y = X,
dif(X,d),
dif(X,c),
dif(X,b) ;
false.