How to turn off "true" and "false" outputs in Prolog?
Asked Answered
N

1

7

I would like to write a small text-based adventure game using Prolog (this might be a dumb idea but I am not here to discuss that).

The only problem is that I can't manage to print text on screen without the "true" and "false" values to appear as well.

For instance if I try something like:

take(desk) :- write('This thing is way too heavy for me to carry!').

where take is a one place predicate and desk a name I get as an output:

?- take(desk).
   This thing is way too heavy for me to carry!
   true.

How can I get rid of this "true" or "false" outputs?

Just to mention that I also tried with the format/1 one place predicate for simple text output and also the format/2 two place predicate (when I want to output the name of a variable) but it gives exactly the same problem.

I have also seen this answer but first it is not detailed enough (at least not for someone like me) and second, I hope deep inside that there is a simpler manner to do it.

And finally, I am using SWI-Prolog.

Thank you.

Negotiable answered 23/6, 2014 at 14:3 Comment(2)
I'm a prolog novice at best, but if you use the --quiet/-q switch, does that work? source: swi-prolog.org/pldoc/…Seaquake
@Gray. Maybe I don't use it properly but basically if I launch prolog -q game.pl, it doesn't work.Negotiable
F
10

A simplistic method would be to create a little REPL (read, evaluate, print loop) of your own. Something like this:

game :-
    repeat,
    write('> '),
    read(X),
    call(X),
    fail.

This will just prompt and execute whatever you enter at the prompt. In conjunction with your take fact (and another I added for illustration):

take(desk) :- write('This thing is way too heavy for me to carry!'), nl.
take(chair) :- write('This is easier to carry.'), nl.

You would get:

?- game.
> take(desk).
This thing is way too heavy for me to carry!
> take(chair).
This is easier to carry.
>

You don't get the true or false because the game goal doesn't resolve until you exit the loop somehow. You could add checks for a quit or bye or whatever to exit the game loop. Ctrl-C or Ctrl-D can be used as well to abort the loop. You might need to add some other "features" to make it work to your needs or liking.

Frivol answered 24/6, 2014 at 2:29 Comment(2)
That's an amazing answer and simple on top of that!! Now, I have a slight problem because I am using dynamical predicates for things. One of them is say inventory(X) that means that X is in my inventory. To account for it, I define the take predicate as follows take(X) :- visible(X), write('done'), assert(inventory(X)), retract(visible(X)) ; inventory(X), write('I have taken it already'). My problem is that when called in the loop you proposed take(X) outputs the two propositions in the disjunction regardless of their truth values (which it doesn't do outside of the loop). Why is that?Negotiable
Ok my bad, I have just realized that written in this order i.e. first (visible -> inventory) and then inventory will make the whole disjunction true as soon as an object is visible. This should not happen if I swap the two premisses.Negotiable

© 2022 - 2024 — McMap. All rights reserved.