2011-09-18 6 views
0

J'ai donc le prédicat qui retourne vrai plusieurs fois. Le prologue swi a-t-il une méthode qui peut m'aider à exécuter ce prédicat sans taper ';'?Les prédicats retournent. Prolog

% Wished version 
?- get_all_transformed_moves. 
true. 

Répondre

2

Considérez ce qui suit:

likes(prolog). 
likes(haskell). 
likes(erlang). 

likes_something:- 
    likes(_Something). 

si maintenant vous demandez:

?- likes_something. 

vous obtiendrez

true ; 
true ; 
true. 

cela se produit parce que Prolog trouve trois façons de satisfaire la likes_something/0 prédicat (avec prologue, haskell et erlang) donc il répond vrai pour trois fois.

ce n'est pas vraiment un problème; à tout moment, vous pouvez appuyer sur et prolog va arrêter d'essayer de trouver des réponses (ce qui est très pratique quand il y a beaucoup de résultats). La même chose arrive à votre prédicat: il y a trois solutions et en appuyant sur; vous forcez le prologue à tous les trouver. Comme Rocha a suggéré que vous pourriez utiliser findall/3. Par exemple, vous pouvez écrire:

likes_something:- 
    findall(X, likes(X), _). 

et cela juste un retour yes

cependant, il ne propose pas plus d'informations que la version précédente; au lieu de cela, il cache le fait qu'il y a 3 solutions et perd du temps à essayer de trouver plus alors que la réponse ne changera pas. Pour cette raison, je pense que vous devez utiliser findall/3 si vous voulez vraiment voir les résultats:

likes_all(L):- 
    findall(X,likes(X),L). 

bien sûr, la décision de savoir si vous avez besoin de voir les résultats ou non est à vous (ou plutôt au problème que vous essayez de résoudre: p)

une autre option est d'utiliser une coupe: !/0 par exemple:

likes_something:- 
    likes(_Something), 
    !. 

cela arrêtera prolo g de la recherche de plus de solutions et vous obtiendrez juste un vrai. noter cependant que les coupes peuvent être difficiles.Si vous voulez que prolog recherche toutes les réponses (si vous décidez de les mettre dans une liste ou si vous avez des effets secondaires dans vos prédicats ou si vous le voulez): utilisez findall/3

si vous ne voulez pas avoir la possibilité de rechercher d'autres réponses: (!/0) utiliser une coupe

autre presser la touche Entrée au lieu de;

0

Vous pouvez utiliser le findall/3 prédicat:

findall (Object, but, Liste). produit une liste Liste de tous les objets Objet qui satisfont le but Objectif. Souvent Object est simplement une variable, auquel cas la requête peut être lue comme suit: Donnez-moi une liste contenant toutes les instanciations de Object qui satisfont Goal. Je suppose que c'est ce que vous voulez.

0

Si vous voulez que le prédicat réussisse au plus une fois, vous pouvez utiliser une fois/1 fourni avec SWI.

Dans votre exemple:

?- once(get_all_transformed_moves). 
true.