2010-11-24 2 views
4

Cela peut paraître idiot, mais permet de dire que mon plus grand prédicat/2 renvoie le plus grand élément dans une liste ... la sortie devrait ressembler à ceci:Comment retourner un résultat variable et un vrai/faux dans Prolog?

?- largest([1,2,3,4,5], X). 
X = 5. 
false. 

I mis en œuvre le plus grand, et il fonctionne comme ci-dessus, sauf qu'il doesn 't sortie "faux". Comment puis-je faire en sorte qu'il produise également ce "faux". valeur? C'est pour une tâche ennuyante que je dois terminer. :(

Répondre

8

Ce supplémentaire false. ou No signifie simplement que la personne qui exécute le programme a demandé d'obtenir toutes les solutions possibles pour X, pas seulement la première solution possible.

Sur la plupart des interprètes Prolog interactifs, vous vérifiez si il y a une autre solution en appuyant sur le point-virgule (;) clé.

1

sonne comme impossible, comme en cas d'échec prédicat, aucune liaison de variables libres qui se passe, voir

?- A=5. 
A = 5. 

?- A=5,false. 
false. 

cependant

?- A=5;false. 
A = 5 ; 
false. 

Pour ce faire, vous devez faire votre prédicat "plus grand" non-déterministe. Mais pour moi, cela semble assez idiot.

+0

s (X) : si je suis la question à un T, cette réponse quelque peu étrange est ** it **. Et ça a aussi du bon timing! – repeat

1

Si cela faisait partie d'une affectation, cela signifie probablement que votre prédicat ne devrait pas donner un deuxième résultat (éventuellement différent) après le retour en arrière. Le retour en arrière se produit si l'utilisateur veut la solution suivante, souvent en appuyant sur ;. L'interprète indique souvent qu'une autre solution est possible quand il sait qu'il y a encore des chemins qui ne sont pas complètement évalués.

Supposons que vous ayez un prédicat foo/1 comme suit:

foo(1). 

foo(Bar) :- 
    foo(Baz), 
    Bar is Baz + 1. 

Si vous demandez foo(Bar), l'interprète répondra avec Bar = 1. Après avoir appuyé plusieurs fois sur ;, l'interprète reviendra avec Bar = 2, Bar = 3 et ainsi de suite. Dans votre exemple, trouver la plus grande d'une liste devrait être déterministe. Le retour en arrière ne devrait pas donner une réponse différente. C'est à vous d'interpréter l'assignation comme signifiant que vous devez autoriser le retour arrière, mais que cela doit échouer, ou que ce serait bien de ne même pas avoir de retour en arrière du tout.

+0

s (X): Il est amusant de voir comment même des spécifications courtes mènent à des conclusions fondamentalement opposées. – repeat

0

Il est quelque chose aux réponses précédentes par @aschepler, @Xonix et @SQB.

Dans cette réponse, nous utilisons pour exprimer l'arithmétique déclarative entière.

:- use_module(library(clpfd)). 

Nous définissons largest/2 en utilisant le haut-prédicat member/2, bibliothèque maplist/2, et la contrainte de domaine fini (#>=)/2:

largest(Zs, X) :- 
    member(X, Zs),   % X is a member of the list Zs 
    maplist(#>=(X), Zs).  % all Z in Zs fulfill X #>= Z 

exemples de requêtes:

?- largest([1,2,3,4,5], X). 
X = 5. 

?- largest([1,2,3,4,5,4], X). 
X = 5 ; 
false. 

?- largest([1,2,3,4,5,5], X). 
X = 5 ; 
X = 5. 

?- largest([1,2,3,4,5,5,4], X). 
X = 5 ; 
X = 5 ; 
false. 

?- largest([A,B,C,D], X). 
A = X, X#>=D, X#>=C, X#>=B ; 
B = X, X#>=A, X#>=D, X#>=C ; 
C = X, X#>=A, X#>=D, X#>=B ; 
D = X, X#>=A, X#>=C, X#>=B. 
Questions connexes