A est pas unifié avec quoi que ce soit dans le corps de vos règles. La façon dont prolog fonctionne est via l'unification des termes. Vous ne pouvez pas "retourner" A comme dans les langages procéduraux en tant que tels. Par exemple, que voulez-vous que la valeur de A soit lorsque la récursion arrive à son terme? Je n'ai aucune idée de ce que fait votre code, alors laissez-moi utiliser un exemple.
accumulate([], A, A).
accumulate([H|T], A, N) :- A1 is A + H, accumulate(T, A1, N).
sum([], 0).
sum(L, N) :- accumulate(L,0,N).
Voici une procédure de somme qui résumera les valeurs dans une liste et « retour N », la somme des valeurs de la liste. Pour appeler cette procédure, vous pouvez le faire:
sum([2, 3, 4], N).
Et Prolog répondra:
N = 9
Avis la procédure accumulate utilise A comme un accumulateur comme la récursion se poursuit. Autrement dit, A garde la somme courante, tandis que N est la réponse finale qu'elle renvoie. Pendant la récurrence, N n'est pas unifié avec une valeur réelle.
Dans la dernière étape de la récursion, qui est, lorsque la liste est vide, la valeur de A est unifiée avec N, en effet le retour N.
Laissez-nous faire une trace.
[trace] 4 ?- test(A, B, 0).
Call: (7) test(_G417, _G418, 0) ? creep//A unifies with _G417 (internal variable name), B with _G418 and N with 0.
Call: (8) nonvar(_G418) ? creep
Fail: (8) nonvar(_G418) ? creep
Redo: (7) test(_G417, _G418, 0) ? creep//Unifies with clause 2,
^ Call: (8) 0>2 ? creep
^ Fail: (8) 0>2 ? creep
Redo: (7) test(_G417, _G418, 0) ? creep //Unifies with clause 3
^ Call: (8) _L183 is 0+1 ? creep
^ Exit: (8) 1 is 0+1 ? creep
Call: (8) test(1, _G418, 1) ? creep //recursive call, unifies with
Call: (9) nonvar(_G418) ? creep
Fail: (9) nonvar(_G418) ? creep
Redo: (8) test(1, _G418, 1) ? creep
^ Call: (9) 1>2 ? creep
^ Fail: (9) 1>2 ? creep
Redo: (8) test(1, _G418, 1) ? creep
^ Call: (9) _L195 is 1+1 ? creep
^ Exit: (9) 2 is 1+1 ? creep
Call: (9) test(2, _G418, 2) ? creep
Call: (10) nonvar(_G418) ? creep
Fail: (10) nonvar(_G418) ? creep
Redo: (9) test(2, _G418, 2) ? creep
^ Call: (10) 2>2 ? creep
^ Fail: (10) 2>2 ? creep
Redo: (9) test(2, _G418, 2) ? creep
^ Call: (10) _L207 is 2+1 ? creep
^ Exit: (10) 3 is 2+1 ? creep
Call: (10) test(3, _G418, 3) ? creep
Call: (11) nonvar(_G418) ? creep
Fail: (11) nonvar(_G418) ? creep
Redo: (10) test(3, _G418, 3) ? creep
^ Call: (11) 3>2 ? creep
^ Exit: (11) 3>2 ? creep
Call: (11) test(3, final, 3) ? creep
Call: (12) nonvar(final) ? creep
Exit: (12) nonvar(final) ? creep
Call: (12) final=final ? creep
Exit: (12) final=final ? creep
Call: (12) true ? creep
Exit: (12) true ? creep
Exit: (11) test(3, final, 3) ? creep
Exit: (10) test(3, _G418, 3) ? creep
Exit: (9) test(2, _G418, 2) ? creep
Exit: (8) test(1, _G418, 1) ? creep
Exit: (7) test(_G417, _G418, 0) ? creep
Maintenant, notez le point dans la trace où j'ai marqué //A unifies with _G417 (internal variable name), B with _G418 and N with 0.
. À ce stade, A est votre variable externe et _G417 est votre A. interne. Si cet appel réussit, il finira par ne signaler que les valeurs des variables externes. En interne _G417 n'est jamais unifié avec autre chose. Je pense que le problème est de comprendre comment fonctionne le modèle d'unification de Prolog.
Une question rapide: que voulez-vous réellement que le code fasse? – rvirding