2010-09-10 9 views
3

Je ne peux pas faire de sens de ceci: Si je donne Prolog reverse([], A). cela fonctionne très bien, si je lui donne reverse(A, []). et répondez ; au premier suggestion qu'il pend!Prolog: inverse ([], A) inverse (A, [])

Pourquoi? (Même résultat pour les deux GNU Prolog et Prolog SICStus!)

[email protected]:~$ prolog 
GNU Prolog 1.3.0 
By Daniel Diaz 
Copyright (C) 1999-2007 Daniel Diaz 
| ?- reverse([], A). 

A = [] 

yes 
| ?- reverse(A, []). 

A = [] ? ; 

Fatal Error: global stack overflow (size: 32768 Kb, 
environment variable used: GLOBALSZ) 

[email protected]:~$ 
+0

Je sais que c'est deux ou trois ans, mais juste pour mettre à jour: il est fixé dans une version ultérieure de 'gprolog'. Je cours la version 1.4.2 et le comportement de l'inverse agit juste comme leur manuel indique. Les deux cas instancient 'A' avec succès à' [] '. – lurker

Répondre

4

On dirait une optimisation excès de zèle pour un prédicat intégré pour moi. Le même problème se produit indépendamment du contenu de la liste dans le deuxième argument. Basé sur le manuel GProlog c'est un bug. Notez que le template for reverse est

reverse(?list, ?list) 

Et en outre que ? signifie « l'argument peut être instancié ou une variable. »

SWI-Prolog version 5.6.64 donne le résultat attendu.

?- reverse([], A). 
A = []. 

?- reverse(A, []). 
A = [] ; 
false. 
+0

Je ne dirais pas que c'est un bug. Dans YAP 6.0.5 le même comportement. La documentation dit 'reverse (+ List,? Reverse)'. – ony

+1

Intéressant. À tout le moins, la documentation GProlog est erronée. –

0

Mon revers a fait la même chose, parce que je supposais l'argument 1 serait instancié (à savoir inverse (+ ,?), comme ci-dessus), sachant que mon Prolog indexerait sur elle. ici:

reverse(L, R) :- reverse_1(L, [], R). 

reverse_1([], X, X).  % <-- doesn't loop on unbound arg #1 if this clause cuts 
reverse_1([A|As], X, R) :- 
    reverse_1(As, [A|X], R). 
+0

Donc, celui-ci fonctionne mieux, dites-vous? Ou cette boucle de définition? – aioobe