Prolog - 奇怪的问题

时间:2012-02-08 16:15:41

标签: prolog

所以我有一个任务,我必须做一个猜谜游戏(bulls and cows)。 首先,我制作了一个小程序,你输入两个数字然后检查 如果他们有相同的长度,然后他们是相同的。 *数字在列表中,以便能够在每个猜测中给出公牛和奶牛的数量(参见游戏规则)。

    equal([],[]).
    equal([Ha|Ta],[Hb|Tb]) :-
        Ha = Hb, equal(Ta,Tb).

    check_length(List1,List2):-
            same_length(List1,List2),writeln('The Lists have the same length!').

    check_equality(List1,List2):-
            equal(List1,List2),writeln('The Lists are equal!').
start:-
    write('give 1st list:'), read(X),atom_chars(X, List1),
    write('give 2nd list:'), read(Y),atom_chars(Y, List2),
    check_length(List1,List2),
    check_equality(List1,List2).

到目前为止一切顺利。它工作正常。然后我继续下一步并对其进行了更改,因此它生成一个包含4个随机整数的列表,然后等待用户进行猜测并比较之前的两个列表。 *显然我将生成的数字打印到屏幕上,以便知道程序是否正常工作。

start:-
    A is random(9),
    B is random(9),
    C is random(9),
    D is random(9),
    List2=[A,B,C,D],
    write('Generated number:'),writeln(List2),
    write('Make a guess:'), read(Guess),atom_chars(Guess, List1),
    nl,
    check_length(List1,List2),
    check_equality(List1,List2).

问题在于,即使您键入正确的数字,此程序也会确定列表(数字)是否具有相同的长度但是在相等检查中失败。 我做错了什么?

提前致谢。

2 个答案:

答案 0 :(得分:2)

在第二段代码中,List2是一个数字列表。 List1但是,由atom_chars/2生成的是一个引用原子的列表。数字和原子不是一回事。在完成相等检查之前,您必须将其中一个列表转换为另一个列表(例如,使用atom_number/2)。

答案 1 :(得分:2)

以下是来自跑步的痕迹:

[trace] 42 ?- start.
   Call: (6) start ? creep
^  Call: (7) _G537 is random(9) ? creep
^  Exit: (7) 6 is random(9) ? creep
^  Call: (7) _G539 is random(9) ? creep
^  Exit: (7) 6 is random(9) ? creep
^  Call: (7) _G541 is random(9) ? creep
^  Exit: (7) 1 is random(9) ? creep
^  Call: (7) _G543 is random(9) ? creep
^  Exit: (7) 4 is random(9) ? creep
   Call: (7) _G555=[6, 6, 1, 4] ? creep
   Exit: (7) [6, 6, 1, 4]=[6, 6, 1, 4] ? creep
   Call: (7) write('Generated number:') ? creep
Generated number:
   Exit: (7) write('Generated number:') ? creep
   Call: (7) writeln([6, 6, 1, 4]) ? creep
[6,6,1,4]
   Exit: (7) writeln([6, 6, 1, 4]) ? creep
   Call: (7) write('Make a guess:') ? creep
Make a guess:
   Exit: (7) write('Make a guess:') ? creep
   Call: (7) read(_G555) ? creep    
|    6614.
   Exit: (7) read(6614) ? creep
   Call: (7) atom_chars(6614, _G556) ? creep
   Exit: (7) atom_chars(6614, ['6', '6', '1', '4']) ? creep
   Call: (7) nl ? creep
   Exit: (7) nl ? creep
   Call: (7) check_length(['6', '6', '1', '4'], [6, 6, 1, 4]) ? creep
   Call: (8) length(['6', '6', '1', '4'], _G568) ? creep
   Exit: (8) length(['6', '6', '1', '4'], 4) ? creep
   Call: (8) length([6, 6, 1, 4], 4) ? creep
   Exit: (8) length([6, 6, 1, 4], 4) ? creep
   Call: (8) writeln('The Lists have the same length!') ? creep
The Lists have the same length!
   Exit: (8) writeln('The Lists have the same length!') ? creep
   Exit: (7) check_length(['6', '6', '1', '4'], [6, 6, 1, 4]) ? creep
   Call: (7) check_equality(['6', '6', '1', '4'], [6, 6, 1, 4]) ? creep
   Call: (8) equal(['6', '6', '1', '4'], [6, 6, 1, 4]) ? creep
   Call: (9) '6'=6 ? creep
   Fail: (9) '6'=6 ? creep
   Fail: (8) equal(['6', '6', '1', '4'], [6, 6, 1, 4]) ? creep
   Fail: (7) check_equality(['6', '6', '1', '4'], [6, 6, 1, 4]) ? creep
   Fail: (6) start ? creep
false.

重要的是这个:

   Call: (9) '6'=6 ? creep
   Fail: (9) '6'=6 ? creep

所以问题是char'6'与数字6不相等 另一个问题是,开头的零将被删除

23 ?- atom_chars(0042,L).
L = ['4', '2'].

所以我建议摆脱atom_chars / 2并做其他事情;逐个读取四个数字或手动分割数字