序言递归困难

A prolog recursive difficulty

我做了这个猜数字的程序,如果用户输入10,那么程序应该打印(写,你猜对了数字)。

否则它应该打印错误并读取另一个数字,并且在用户输入正确的数字之前它不会退出(多么愚蠢的程序大声笑)。

到目前为止,这就是我所做的,但我不明白为什么这对我不起作用。

guess_num(10):- write("You have guessed right"), nl.

guess_num(X) :- X =\= 10,  write("Wrong guess"), nl , read(X),  guess_num(X).

这对我有用。

?- guess.

guess :- read(X), check_answer(X).

check_answer(10):- write("You have guessed right"), nl.

check_answer(X) :- X =\= 10,  write("Wrong guess"), nl, guess.

这在不需要(强制)递归的情况下效果更好:

guess:-
    repeat,
    read(X),
    check_answer(X),
    !.

check_answer(10) :- write("You have guessed right"), nl.

check_answer(X) :- X =\= 10, write("Wrong guess"), nl, fail.

使用@Enigmativity 在他的回答中展示的机制 repeat 可能是更好的实现方式,而不是递归。但是,除了特定问题(和一个建议)之外,您的递归方法基本上可以工作:

  1. 您正试图在第二个子句中重新实例化一个变量,Prolog 不允许这样做。因此,如果用户查询,guess_num(9). 您在 X = 9 时尝试 read(X),这将失败,除非用户再次输入 9。您需要使用一个新变量。

  2. 在这种方法中使用cut(!)会消除用户猜对时会出现的选择点。如果没有剪切,一旦用户被告知他们有正确答案,Prolog 将提示用户提供更多解决方案。

进行上述更正会给您:

guess_num(10) :-
    !,
    write("You have guessed right"), nl.

guess_num(X) :-
    X =\= 10,
    write("Wrong guess"), nl,
    read(X1),
    guess_num(X1).

使用上面的代码:

?- guess_num(9).
Wrong guess
|: 8.
Wrong guess
|: 10.
You have guessed right
true.

?-

没有剪辑:

?- guess_num(9).
Wrong guess
|: 8.
Wrong guess
|: 10.
You have guessed right
true ;
false.

?-