6
votes

Comment voir toutes les réponses dans SWI-Prolog sans appuyer sur la barre d'espace?

Exemple simple:

[1, 15, 8, 22, 5, 19, 12, 25, 3|...] 

Lorsque cela est fait en utilisant SWI-Prolog en utilisant le REPL pour voir la réponse suivante, la barre d'espace doit être pressée.

Comment tous les résultats peuvent-ils être affichés à l'écran sans appuyer sur la barre d'espace?


Remarque sur une question similaire.

Si vous êtes arrivé à ceci question par une recherche et votre vrai problème est

J'utilise SWI-Prolog et j'essaye d'imprimer une liste mais si la liste a plus de 9 éléments - ça ressemble à ça -

?- between(1,10,X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 ;
X = 9 ;
X = 10.

Y a-t-il un moyen d'afficher la liste entière?

Ensuite, consultez ces questions et réponses:

SWI-Prolog - afficher la longue liste
SWI-Prolog comment afficher la réponse entière (liste)? a>


6 commentaires

Vous pouvez utiliser entre (1,10, X), print (X), nl, fail. afin que le mécanisme de retour arrière continue de soumettre les résultats à print (X) et < code> nl jusqu'à ce que tout soit épuisé.


Facile! Vous pouvez appuyer sur le point-virgule à la place!


@DanielLyons Appuyer sur le point-virgule ne fonctionne pas pour moi.


Dans GNU Prolog, à la première invite de solution, vous pouvez appuyer sur a qui affichera alors tout le reste. Je ne sais pas quel est l'équivalent dans SWI (ou s'il y en a un).


@DanielLyons Vous devriez publier cela comme des réponses pour les autres qui ne lisent pas les commentaires. Une partie de la raison pour laquelle j'ai publié la question était que je ne pouvais pas trouver facilement la réponse et je suis surpris qu'elle n'ait pas été signalée comme un doublon. Je sais que j'ai vu cela noté dans d'autres réponses, mais je ne me souviens pas l'avoir vu comme une réponse autonome. Si vous postez une réponse, je lui donnerai un vote favorable. :)


@lurker Vous devriez publier cela comme des réponses pour les autres qui ne lisent pas les commentaires. Une partie de la raison pour laquelle j'ai publié la question était que je ne pouvais pas trouver facilement la réponse et je suis surpris qu'elle n'ait pas été signalée comme un doublon. Je sais que j'ai vu cela noté dans d'autres réponses, mais je ne me souviens pas l'avoir vu comme une réponse autonome. Si vous postez une réponse, je lui donnerai un vote favorable. :)


3 Réponses :


3
votes

Une solution " hackish " consiste à ajouter print (X), nl, fail à l'appel. Ici, print (X) peut bien sûr imprimer toutes les informations pertinentes. Par exemple entre (1,10, X), print (X), nl, fail .

Cela fonctionne depuis print / 1 [swi-doc] est juste un autre prédicat qui imprime le terme qui lui est transmis. nl / 0 strong > [swi-doc] imprimera un nouveau caractère de ligne, et fail / 0 [swi-doc] échoue toujours.

Nous laissons donc Prolog proposer des solutions, les imprimer, les imprimer une nouvelle ligne, et fail "activera" le mécanisme de retour arrière qui visera à rechercher une autre solution qui sera à nouveau imprimée et échouera.

Finalement, toutes les solutions sont imprimées, et ainsi l'appel échoue. Cela donne donc:

?- between(1,10,X), print(X), nl, fail.
1
2
3
4
5
6
7
8
9
10
false.


0 commentaires

3
votes

Le modèle de code (Goal, false; true) est appelé boucle induite par l'échec .

Vous pouvez également écrire bagof (_, Goal, _) . Le Objectif peut effectuer des impressions qui apparaîtront progressivement, ou par portions si la sortie est mise en mémoire tampon. Assurez-vous d'échapper à toutes les variables libres dans Goal (comme A ^ B ^ C ^ Goal ).

Vous pouvez l'exécuter en tant que fichier de code source Prolog à une invite de commande / shell et rediriger sa sortie vers une commande shell " more ".

Ou vous pouvez simplement exécuter votre requête à l'invite de Prolog et maintenir la touche ; enfoncée tout le temps.


6 commentaires

(Objectif, faux; vrai) : joli motif!


@CapelliC Je pensais que c'était largement connu ... :)


Je connaissais la boucle pilotée par l'échec mais je ne l'ai jamais vu faire comme ça.


@GuyCoder de quelle manière avez-vous vu? Je suis juste curieux.


De quel côté avez-vous vu (boucle provoquée par l'échec)? La façon dont Willem Van Onsem a donné dans sa réponse < / a> avec fail ; J'espère que cela est considéré comme une boucle pilotée par l'échec sinon je devrai prendre plus de notes.


Oui bien sûr. le ; true bit est juste une décoration. maintenant que je google, homepages.inf.ed.ac.uk/ pbrna / prologbook / node95.html le donne aussi avec le vrai à la fin, seulement différent du point de vue syntaxique. c'est probablement ainsi que je l'ai vu dans l'un des vieux livres.



4
votes

Compte tenu de l'ajout (quelque peu) récent de la bibliothèque ( solution_sequences ), et notamment call_nth / 2, aujourd'hui vous pouvez écrire

?- * between(1,3,N), write(N), nl.
1
2
3
true.

bien sûr, lorsqu'on s'intéresse uniquement aux 100 premières réponses. Un peu de contrôle:

:- op(1100, fx, (*)).
(* Goal) :- (Goal, false ; true).

Avant call_nth / 2, j'utilisais forall / 2:

?- between(1,4,X) ?* (S is X*X, writeln(square_of(X):S)).
square_of(1):1
square_of(2):4
square_of(3):9
square_of(4):16
true.

?- between(1,4,X), write(X), nl ?+ 2.
1
2
X = 2.

edit

étant donné que call_nth et forall sont des prédicats binaires, un peu de sucre de syntaxe peut raccourcir un peu le REPL: dans ~ / .swiplrc add

:- op(100, xfx, (?*)).
Gen ?* Test :- forall(Gen, Test).

:- op(1100, xfx, (?+)).
Run ?+ Count :- call_nth(Run, Count).


0 commentaires