2008-12-08 7 views
1

J'essaye de faire une fonction qui a une liste de listes, elle multiplie la somme de la liste interne avec la liste extérieure. Jusqu'à présent, je peux sommer une liste, j'ai fait une fonction sumlist ([1..n], X) qui retournera X = (résultat). Mais je ne peux pas obtenir une autre fonction pour travailler utilement avec cette fonction, j'ai essayé à la fois est et = en vain.Passer des résultats dans prolog

+0

Veuillez clarifier. On ne sait pas ce que sont les listes "interne" et "externe". – atzz

+0

En Prolog vous avez des prédicats qui décrivent des relations, pas des fonctions (avec une exception: les fonctions arithmétiques). –

Répondre

1

La partie «il multiplie la somme de la liste intérieure avec la liste extérieure » est pas vraiment clair, mais je crois que vous voulez dire que, étant donné une liste [L1,...,Ln] des listes de numéros, vous voulez calculer S1*..*SnSi est la somme des éléments dans Li (pour chaque i).

Je suppose l'existence de plus et mult avec leur signification évidente (par exemple plus(N,M,R) tient précisément quand R est égal à N+M). D'abord nous avons besoin de prédicat sum tel que sum(L,S) tient si, et seulement si, S est la somme des éléments de L. Si L est vide, S doit évidemment être 0:

sum([],0). 

Si L n'est pas vide, mais de la forme [N|L2], alors nous avons que S doit être N plus la somme S2 des éléments L2. En d'autres termes, nous devons avoir les deux sum(L2,S2) (pour que S2 soit la somme des éléments de L2) et plus(N,S2,S). C'est:

sum([N|L2],S) :- sum(L2,S2), plus(N,S2,S). 

De la même façon, vous pouvez comprendre le prédicat p que vous recherchez. Nous voulons que p(L,R) se bloque si, et seulement si, R est le produit de S1 à SnL=[L1,...,Ln] et sum(Li,Si) pour tous i. Si L est vide, R doit être 1:

p([],1). 

Si L n'est pas vide, mais de la forme [LL|L2], nous avons que R doit être le produit de « S », la somme des éléments de LL, et «P», le produit de la somme des listes au L2. Pour S nous avons déjà sum(LL,S), donc cela nous donne ce qui suit.

p([LL|L2],R) :- sum(LL,S), p(L2,P), mult(S,P,R). 

Une chose que je voudrais ajouter est qu'il est probablement pas une bonne idée de voir ces prédicats fonctions que vous pourriez être habitué de la programmation impérative ou fonctionnelle. Ce n'est pas le cas sumlist([1,..,n],X) renvoie X = (result); (result) est une valeur pour X telle que sumlist([1,...,n],X) est vraie. Cela nécessite un état d'esprit quelque peu différent. Au lieu de penser "Comment puis-je calculer X tel que p (X) tient?" Vous devez penser "Quand P (X) tient-il?" et utilisez la réponse ("Eh bien, si q (X) ou r (X)!") pour faire les clauses (p(X) :- q(X) et p(X) :- r(X)).

2

Est-ce ce que vous voulez dire?

prodsumlist([], 1). 

prodsumlist([Head | Tail], Result) :- 
    sumlist(Head, Sum_Of_Head), 
    prodsumlist(Tail, ProdSum_Of_Tail), 
    Result is Sum_Of_Head * ProdSum_Of_Tail. 

sumlist/2 est intégré dans SWI-Prolog.

Exemple d'utilisation:

?- prodsumlist([[1, 2], [3], [-4]], Result). 
Result = -36. 
0

Voici une réécriture de Kaarel's answer (c'est l'intention de toute façon!), Mais tail-recursive.

prodsumlist(List, Result) :- 
    xprodsumlist(List,1,Result). 

xprodsumlist([],R,R). 

xprodsumlist([Head|Rest],Sofar,Result) :- 
    sumlist(Head, Sum_Of_Head), 
    NewSofar is Sofar * Sum_Of_Head, 
    xprodsumlist(Rest, NewSofar, Result). 
Questions connexes