prolog列表和列表操作

时间:2010-11-02 20:11:18

标签: prolog

我正在尝试编写一个二元谓词来获取一个列表,为每个元素计算mod 5,然后将其放入另一个列表中。到目前为止,我已经这样做了,

mod5(X,L):- R = [], modhelper(R,L), write(R).  
modhelper(X,L):- memb(E,L), mod2(E,Z), addtolist(Z,X,X), modhelper(X,L).  
%Get an element from the list L.  
memb(E,[E|_]).  
memb(E,[_|V]):- memb(E,V).  
%If element is integer, return that integer mod 5 else return as is.  
mod2(N,Z):- isInt(N) -> Z is N mod 5 ; Z = N.  
%add this modified element to the output list.  
addtolist(Y,[],[Y]).  
addtolist(Y,[H|T],[H|N]):- addtolist(Y,T,N).  

memb,mod2,addtolist按预期工作,但我在modhelper中做错了,我无法弄清楚。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

在SWI-Prolog中:

mod5(X, Y) :-
    Y is X mod 5.

apply_mod5_to_list(L1, L2) :-
    maplist(mod5, L1, L2).

用法:

?- apply_mod5_to_list([2, 4, 6, 8], L2).
L2 = [2, 4, 1, 3].

?- apply_mod5_to_list([2, 4.1, 6, 8], L2).
ERROR: mod/2: Type error: `integer' expected, found `4.1'

?- apply_mod5_to_list([2, not_number, 6, 8], L2).
ERROR: is/2: Arithmetic: `not_number/0' is not a function

如果您想要稍微不同的行为,例如,您可以轻松修改此代码。如果你想容忍非整数(为什么你想要那个btw?)。

如果你不能使用maplist,你可以自己实现它,至少是它的一个更专业的版本,例如像这样的东西:

partition_the_list_into_first_and_rest([X | Xs], X, Xs).

% The result on an empty list is an empty list
apply_mod5_to_list([], []).

% If the input list contains at least one member
apply_mod5_to_list(L1, L2) :-
    partition_the_list_into_first_and_rest(L1, X, Xs),
    call(mod5, X, Y),
    partition_the_list_into_first_and_rest(L2, Y, Ys),
    apply_mod5_to_list(Xs, Ys).

对于这段代码,您仍然可以应用大量的语法简化,您可能应该将其转换为可接受的家庭作业解决方案...