Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get user console input into a Prolog list

Tags:

list

input

prolog

I am trying to write the user input into a list but am running into two problems. Using this code

getInput([Symptom|List]):-
    writeln('Enter Element:'),
    read(Symptom),
    dif(Symptom,stop),
    getInput(List).
getInput([]).

I am able to get symptoms from the user but the output shows the first user input as the Head, and the others as the tail. How do I make the Head "Symptoms" and only ad the user input to the Tail? Secondly, when I change "stop" to "Done" the program no longer stops?

So I was told "Done" doesn't work because it is capitalized. If I want to use a capital word, how would I do that?

like image 301
user10876930 Avatar asked Dec 07 '25 05:12

user10876930


2 Answers

This works

get_symptoms(Symptoms) :-
    write('Enter Symptom: ' ),
    read_string(user, "\n", "\r", _, Response),
    (
        Response == "Stop"
    ->
        Symptoms = []
    ;
        get_symptoms(Symptoms0),
        Symptoms = [Response|Symptoms0]
    ).

Uses
1. ==/2 instead of dif/2.
2. read_string/5 instead of read/1 so that strings can be entered.
3. write/1 instead of writeln/1 so that input is on same line as prompt.
4. ->/2 instead of separate clauses.

You can change the value of the exit word to something other than "Stop", you can even use single characters like "." if you like.

Notice also that this does not require a cut (!).

Example runs:

?- get_symptoms(List).
Enter Symptom: Stop
List = [].

?- get_symptoms(List).
Enter Symptom: A
Enter Symptom: Stop
List = ["A"].

?- get_symptoms(List).
Enter Symptom: a
Enter Symptom: A
Enter Symptom: A line with some spaces
Enter Symptom: Notice that a period is not needed at the end
Enter Symptom: Stop
List = ["a", "A", "A line with some spaces", "Notice that a period is not needed at the end"].

How do I make the Head "Symptoms" and only add the user input to the Tail?

You want to make the user input the head and have the following entries as the tail. The trick for this example is to put the list constructor |/2 after the recursive call, e.g.

    get_symptoms(Symptoms0),           % Recursive call
    Symptoms = [Response|Symptoms0]    % List constructor

Secondly, when I change "stop" to "Done" the program no longer stops?

Since Done starts with a capital letter it is a Prolog variable which is causing the problem. stop starts with a lower case letter and is an atom so works as expected with the compare.

If I want to use a capital word, how would I do that?

You can use read/1 which requires the user to input "" when entering the value, e.g.

?- read(X).
|: "Hello".

X = "Hello".

but read/1 reads a term so requires the user to not only add the double quotes but end with a period. Using read_string/5 allows the user to enter data as they would expect. The input will be read and stored as a string. If the data is then to be converted there are predicates that operate on strings

like image 104
Guy Coder Avatar answered Dec 08 '25 21:12

Guy Coder


Try something like this:

get_input( Rs ) :-
  get_input( [], Rs )
  .

get_input( Ss , Rs ) :-
  writeln('Enter Element:'),
  read( S ),
  dif( S , stop ),
  !,
  get_input( [S|Ss] , Rs )
  .
get_input( Rs, Rs ).
like image 34
Nicholas Carey Avatar answered Dec 08 '25 21:12

Nicholas Carey