0

I'm trying to write a program using swi-prolog that randomly asks people for their first or last name and prints "correct" or "incorrect" based on what they type. The current correct answers are "Hello" and "World" but regardless of what the user types, the output is false and correct/incorrect isn't printed.

start:-(Q=['What is your first name?','What is your last name?'],
    random_member(N,[0,1]),
    nth0(N,Q,X),
    writeln(X)),
    readln(S),
    check_answer(N,S).


check_answer(N,S):-A=['Hello','World'],
   nth0(N,A,X),
   writeln(X),
   (S=@=X)->writeln('correct'),
   not(S=@=X)->writeln('incorrect').

I later edited it to:

start:-(Q=['What is your first name?','What is your last name?'],
random_member(N,[0,1]),
nth0(N,Q,X),
writeln(X)),
read(S),
check_answer(N,S).


check_answer(N,S):-A=['Hello','World'],
       nth0(N,A,X),
       writeln(X),
       writeln(S),
       ((S=@=X))->writeln('correct') ; writeln('incorrect').
Joshua Snider
  • 705
  • 1
  • 8
  • 34

1 Answers1

1

I can spot two problems in your code.

a) readln/1 (undocumented) returns a list of items (then peek the first item or use read/1):

?- readln(X).
|: Hello.
X = ['Hello', '.'].

?- readln(X).
|: Hello
X = ['Hello'].

?- readln(X).
|: Hello .
X = ['Hello', '.'].

b) The pair of if then else operator (->) will always fail, because you omit the else branch on both, and the conditions are exclusives. Try

...
((S=@=X)->writeln('correct') ; writeln('incorrect')).

edit there are 2 problems. I wrongly suggested read/1. That read a Prolog term, and then read a variable if we write a variable, i.e. a UppercaseStartingSymbol. My fault. readln seems ok then, but change the pattern to select the first item.

Another problem, unrelated: you misplaced the closed parenthesis in -> 'statement'.

Here the code:

start:-(Q=['What is your first name?','What is your last name?'],
random_member(N,[0,1]),
nth0(N,Q,X),
writeln(X)),
readln(S),
check_answer(N,S).

check_answer(N,[S|_]):-A=['Hello','World'],
       nth0(N,A,X),
       writeln(X),
       writeln(S),
       ((S=@=X)->writeln('correct') ; writeln('incorrect')).
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Thanks. I've made the changes you suggested and I've added a Writeln(S) statement write before the comparison. It's printing out _L143 regardless of what I type. Can you explain what's going on and how to fix it? From previous programming experience I'd guess that _L143 is a location in memory where a string is being stored. Is there a prolog version of dereferencing I should do? – Joshua Snider Apr 04 '13 at 05:30
  • _L143 seems to mean 'uninstantiated variable'. It's difficult to test without details. Could you edit your question, adding the latest code ? – CapelliC Apr 04 '13 at 05:58