我正在尝试编写一个二元谓词来获取一个列表,为每个元素计算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中做错了,我无法弄清楚。 任何帮助表示赞赏。
答案 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).
对于这段代码,您仍然可以应用大量的语法简化,您可能应该将其转换为可接受的家庭作业解决方案...