списки пролога и манипулирование списками

я пытаюсь написать двоичный предикат, чтобы взять один список, вычислить мод 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, чего не могу понять. Любая помощь приветствуется.


person sher    schedule 02.11.2010    source источник


Ответы (1)


В SWI-Прологе:

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

Вы можете легко изменить этот код, если хотите немного другого поведения, например. если вы хотите терпеть нецелые числа (кстати, зачем вам это?).

Если вы не можете использовать 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).

К этому коду вы все еще можете применить много синтаксических упрощений, что вам, вероятно, следует сделать, чтобы превратить его в приемлемое решение для домашней работы...

person Kaarel    schedule 02.11.2010
comment
Спасибо за ответ. Это для домашнего задания. Я не думаю, что мне разрешено использовать список карт. Я думаю, что знаю, что я делал неправильно. Мне просто нужно удалить элемент, который я обработал, прежде чем отправить список для рекурсии в modhelper. однако я столкнулся с другой проблемой. когда ввод похож на ?-mod5(X,[[[12]],a]). Х=[/р]; его интерпретация [12] как /r. Как мне предотвратить это? - person sher; 03.11.2010
comment
Обновите свой вопрос, указав, какие входные данные вы хотите разрешить, и каким должен быть результат для входных данных, содержащих нецелые числа. - person Kaarel; 03.11.2010
comment
?-mod5(X,[a,16,b,c(5),[[12]],8]). X = [a,1,b,c(5),[[12]],3]. Я думаю, это охватывает большинство входных данных. Нецелое должно оставаться нетронутым. Однако в случае [[12]], поскольку значение ascii \f (подача формы), он выводит [\f], когда я хочу, чтобы он выводил [[12]] как есть. - person sher; 03.11.2010
comment
Начните новый вопрос о красиво печатных списках, содержащих символ подачи формы, описывая, как вы это делаете в настоящее время и что с этим не так. Это обсуждение больше не относится к этому вопросу/ответу. - person Kaarel; 03.11.2010
comment
Спасибо за помощь, Карел. Ваше решение не совсем сработало. Но я нашел другое более простое решение mod5 проблемы со списком. Я до сих пор не могу понять, как решить проблему подачи формы, но, как вы предложили, я начал новый вопрос, и я надеюсь, что кто-то знает, как его решить, потому что я пытался часами и не могу найти решение для тот. - person sher; 03.11.2010
comment
Пожалуйста, опубликуйте свое решение здесь, как ответ. Мне любопытно узнать, что делает его проще, чем то, что я предоставил. ;) - person Kaarel; 04.11.2010
comment
теперь, если бы я опубликовал решение, как бы оно помогло другим, которым пришлось делать ту же домашнюю работу. я многому научился, решая эту проблему, и я думаю, что другие тоже должны. - person sher; 04.11.2010