Je vais essayer d'introduire le moins de changements possible à votre code.
Une chose qui est définitivement fausse est l'endroit où vous essayez de calculer la différence. Prolog effectue des calculs arithmétiques uniquement avec l'opérateur is
. Votre code:
if((Hi1row - Hi2row), IsumDiff, Hi1row),
se contente de transmettre l'expression de la forme (X-Y) au prédicat if
, et non pas le calculer. Plus tard à l'intérieur de if
, vous ne calculez pas la différence, mais essayez de comparer l'expression à zéro ... qui échoue, car vous ne pouvez comparer les nombres qu'aux nombres, et non aux expressions - et Diff
est assigné à une expression.
Il fonctionnerait si vous réécrivez la première clause de se comme suit (même si vous devriez également vous débarrasser de cette is
ici):
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry.
De cette façon, votre if
prédicat obtiendra X et Y de la expression pour pouvoir les comparer.
De même, vous devez éviter votre prédicat if
pour obtenir deux réponses possibles. Votre deuxième clause if
sera invoquée même lorsque X> Y: dans le processus de retour arrière. Le plus simple est de mettre !
à la fin de la première clause. Cela signifie: "Jusqu'à présent, j'accepte la première solution dans ce programme et je ne veux pas revenir d'ici pour trouver d'autres solutions". La clause sera modifiée:
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry,
!.
Mais ... ce qui est bon dans les petits programmes, et si vous avez besoin réellement faire marche arrière dans d'autres parties de votre programme, cela peut casser. Le moyen le plus propre serait de vérifier l'état correct dans les deux clauses. les récrire à:
if((X-Y), Iresult, Entry) :-
X > Y,
Iresult is Entry.
if((X-Y), Iresult, _) :-
X =< Y,
Iresult is 0.
Ensuite, vous êtes sûr que si X> Y, la deuxième clause échouera.
Après ces modifications, votre code devrait fonctionner ... Veuillez le signaler si ce n'est pas le cas. Ce ne sera toujours pas très prolog-ish cependant; c'est un peu trop verbeux.
Edit:
Ok, je l'écrire d'une manière simple:
sum_if_bigger([], [], 0).
sum_if_bigger([A|L1], [B|L2], Result) :-
sum_if_bigger(L1, L2, Partial),
Result is Partial + max(0, A-B).
...ou d'une manière récursive:
sum_if_bigger_tr(L1, L2, R) :-
sum_if_bigger_tr(L1, L2, 0, R).
sum_if_bigger_tr([], [], R, R).
sum_if_bigger_tr([A|L1], [B|L2], Partial, Result) :-
NewPartial is Partial + max(0, A-B),
sum_if_bigger_tr(L1, L2, NewPartial, Result).
Lequel avez-vous besoin de calculer: somme (max (A [i], B [i]) pour i dans 1..len (A)) ou somme (max (A [i] -B [i], 0) pour i dans 1..len (A))? – liori
(BTW, vous surutilisez 'is'. Vous avez besoin de' is' pour calculer la somme et la différence, ce n'est pas nécessaire pour les affectations simples – liori
Je ne suis pas sûr de comprendre votre question Si j'ai deux listes, la liste 1 est [ 0,0,0,1] et la liste 2 est [0,0,3,0]. J'ai besoin de faire une recherche dans la liste jusqu'à ce que je trouve un élément correspondant dans la liste 1 qui est plus grand que celui de la liste 2. Dans ce cas, cela se produirait avec 1> 0. Prédicat "si" renvoie cette valeur qui est plus grande (1) qui est ajoutée à un total cumulé Ce total cumulé dont j'ai besoin est retourné à la fin –