3

I need to write a predicate that reads user input. If the input is "yes" (ideally "yes or "y") it must assign yes to the parameter, if it is any different it must assign no.

askContinue(Answer) :-
    write("Would you like to continue ?  "), read(Input), nl,
    (Input = "yes" -> Answer = true ; Answer = false).

The output is:

?- askContinue(A).
Would you like to continue ? yes.

A = false.

?- askContinue(A).
Would you like to continue ? no.

A = false.

What am I doing wrong ?

peter.cyc
  • 1,763
  • 1
  • 12
  • 19
Trasplazio Garzuglio
  • 3,535
  • 2
  • 25
  • 25
  • 1
    Works for me, if you change the type of Input, i.e. check whether Input = yes without quotes. – tphilipp Oct 08 '20 at 08:31
  • Does this answer your question? [How to Write User Input to a List Prolog](https://stackoverflow.com/questions/54677190/how-to-write-user-input-to-a-list-prolog) – Guy Coder Oct 08 '20 at 14:12
  • thanks @GuyCoder. It's a great answer and it's close to what I needed but it does not fully answer the question since it does not explain how to conditionally assign a value to the parameter based on the result of a string matching operation (memberchk in TA_intern answer). – Trasplazio Garzuglio Oct 08 '20 at 16:41

1 Answers1

5

What you are doing wrong is that you are comparing the atom that you read using read with a string. Instead, compare it to an atom (single quotes or no quotes):

askContinue(Answer) :-
    write("Would you like to continue ?  "), read(Input), nl,
    (Input = yes -> Answer = true ; Answer = false).

You can use something else instead of read. Maybe you don't want to have to type in "." after your answer. If you read until Enter is pressed:

ask(Prompt, Answer) :-
    prompt1(Prompt),
    read_string(current_input, "\n", " \t", _Sep, Response),
    response_answer(Response, Answer).

response_answer(Response, Answer) :-
    string_lower(Response, R),
    (   memberchk(R, ["y", "yes"])
    ->  Answer = yes
    ;   Answer = no
    ).

This will correctly recognize "Yes", "yes", "y", "Y" and so on.

?- ask("Would you like to continue? ", Answer).
Would you like to continue? Y
Answer = yes.

?- ask("Would you like to continue? ", Answer).
Would you like to continue? Yeah
Answer = no.
TA_intern
  • 2,222
  • 4
  • 12
  • Finally a read input that suggest to use [read_string/5](https://www.swi-prolog.org/pldoc/man?predicate=read_string/5) before [read/1](https://www.swi-prolog.org/pldoc/man?predicate=read/1) – Guy Coder Oct 08 '20 at 14:09
  • However this is probably a duplicate question because I have been suggesting to use read_string/5 for quite some time. – Guy Coder Oct 08 '20 at 14:10