7 votes

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

Exemple simple :

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

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é à cette question en effectuant une recherche et que votre problème réel est

Je suis en train d'utiliser SWI-Prolog et j'essaie d'afficher une liste mais si la liste a plus de 9 éléments - cela ressemble à ça -

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

y a-t-il un moyen d'afficher toute la liste ?

Alors voir ces questions-réponses :

SWI-Prolog - montrer une longue liste
SWI-Prolog comment afficher toute la réponse (liste) ?

5voto

CommuSoft Points 6439

Une solution "hackish" consiste à ajouter print(X), nl, fail à l'appel. Ici, print(X) peut bien sûr imprimer toute information pertinente. Par exemple between(1,10,X), print(X), nl, fail.

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

Nous laissons donc Prolog proposer des solutions, les imprimer, imprimer une nouvelle ligne, et le fail "active" le mécanisme de retour en arrière qui cherchera une autre solution qui est à nouveau imprimée et échoue.

Finalement, toutes les solutions sont imprimées, puis 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.

4voto

CapelliC Points 30055

Étant donné l'ajout (quelque peu récent) de la bibliothèque(solution_sequences), et notamment call_nth/2, aujourd'hui vous pourriez écrire

?- call_nth((between(1,4,X), writeln(X)), 100).
1
2
3
4
false.

bien sûr, lorsque vous êtes intéressé par les 100 premières réponses. Un peu de contrôle:

?- call_nth((between(1,4,X), writeln(X)), 2).
1
2
X = 2.

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

?- forall(between(1,4,X), writeln(X)).
1
2
3
4
true.

modifier

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

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

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

puis redémarrez swipl, et maintenant

?- 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.

Remarquez les différentes priorités (100 vs 1100) et l'effet sur le mini DSL.

modifier

Étendre uDSL avec le joli motif de WillNess:

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

et ensuite

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

3voto

Will Ness Points 18581

Le modèle de code (Goal, false ; true) est connu sous le nom de boucle pilotée par l'échec.

Vous pouvez également écrire bagof( _, Goal, _). Le Goal 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 exécuter cela en tant que fichier source Prolog à une invite de commande/terminal et rediriger sa sortie vers une commande shell "more".

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X