2010-11-02 12 views
0

J'essaye d'écrire un prédicat binaire pour prendre une liste, calculer le mod 5 pour chaque élément et le mettre dans une autre liste. Jusqu'à présent, je l'ai fait,Listes de prologues et manipulation de listes

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, travail addtolist comme prévu, mais je fais quelque chose de mal dans modhelper que je ne suis pas en mesure de comprendre. Toute aide est appréciée.

Répondre

1

Dans SWI-Prolog:

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

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

Utilisation:

?- 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 

Vous pouvez facilement modifier ce code si vous voulez un comportement légèrement différent, par exemple si vous voulez tolérer les non-entiers (pourquoi voulez-vous cela btw?).

Si vous ne pouvez pas utiliser maplist, vous pouvez l'implémenter vous-même, au moins une version plus spécialisée, par ex. quelque chose comme ceci:

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). 

Pour ce code, vous pouvez appliquer encore beaucoup de simplification syntaxique, que vous devriez probablement faire pour la transformer en une solution acceptable ...

devoirs
+0

Merci pour la réponse. Ceci est pour les devoirs. Je ne pense pas que je suis autorisé à utiliser maplist. Je pense que je sais ce que j'ai fait mal. Je dois juste supprimer l'élément que j'ai traité avant d'envoyer la liste pour la récursion dans modhelper. Cependant, je suis confronté à un autre problème. quand l'entrée est comme, ? -mod5 (X, [[[12]], a]). X = ["/ r"]; son interprétation [12] comme "/ r". Comment puis-je empêcher cela? – sher

+0

Mettez à jour votre question en spécifiant quel type d'entrées vous voulez autoriser et quel devrait être le résultat sur les entrées qui contiennent un nombre entier. – Kaarel

+0

? -mod5 (X, [a, 16, b, c (5), [[12]], 8]). X = [a, 1, b, c (5), [[12]], 3]. Cela couvre la plupart des entrées je suppose. Un non entier doit rester intact. Cependant, dans le cas de [[12]], depuis la valeur ASCII de "\ f" (saut de page), il sort ["\ f"] quand je veux qu'il sorte [[12]] tel quel. – sher