关于事实的Prolog程序出错

时间:2013-06-16 12:19:09

标签: prolog

我在prolog中有以下程序。这是一个简单的问答系统,它收集了一些事实并得出了新的结论。它:

  • 通过询问动物的特征(使用recognition
  • 来发现动物
  • 描述知识库中任何动物的属性(使用description

程序中有一个错误,即它表示事实/ 2未定义。只有在询问recognition(animal)时才会出现此错误; description命令运行正常。

P.S。我知道它有一个非常简单的解决方案,但我无法找到它是什么。

代码:

rule(1, animal, mammal, [c1]).
rule(2, animal, mammal, [c2]).
rule(3, animal, bird, [c3]).
rule(4, animal, bird, [c4, c5]).
rule(5, mammal, carnivore, [c6]).
rule(6, mammal, carnivore, [c7, c8, c9]).
rule(7, mammal, ungulate, [c10]).
rule(8, mammal, ungulate_toed, [c11]).
rule(9, carnivore, cheetah,[c12,c13]).
rule(10, carnivore, tiger, [c12,c14]).
rule(11, ungulate, giraffe, [c15, c16, c12,c13]).
rule(12, ungulate, zebra, [c17, c14]).
rule(13, bird, ostrich, [c18, c15, c16, c19]).
rule(14, bird, penguin,[c18, c20, c19]).
rule(15, bird, albatross, [c21]).

/* Recognition process : discover animal's name */

recognition(X):- rule(N, X, Y, Z),
discover(Z),
found(rule),
conclusion(X,Y,N),
recognition(Y),
retractall(fact(_,_)).

recognition(_):- retract(rule), write('Done.'),nl.

recognition(_):- write('Don"t know this animal.'),nl.

found(X):- X,!.
found(X):- assert(X).

/* Discovering process */
discover([]).
discover([X|Y]):- ask(X), discover(Y).

ask(X):- fact(X,Yes),!.
ask(X) :- fact(X, no),!, fail.
ask(c1):- write('has it hair?'), nl,!, complete(c1).
ask(c2):- write('does it give milk?'), nl,!, complete(c2).
ask(c3):- write('has it featherS?'), nl,!,complete(c3).
ask(c4):- write('does it fly?'), nl, !,complete(c4).
ask(c5):- write('does it lay eggs?'), nl, !, complete(c5).
ask(c6):- write('does it eat meat?'), nl, !, complete(c6).
ask(c7):- write('has it pointed teeth?'), nl, !, complete(c7).
ask(c8):- write('has it claws?'), nl, !, complete(c8).
ask(c9):- write('has it eyes pointing forward?'), nl,!, complete(c9).
ask(c10):- write('has it hoofs?'),nl, !, complete(c10).
ask(c11):- write('does it chew cud?'),nl,!, complete(c11).
ask(c12):- write('has it a tawny color?'),nl,!, complete(c12).
ask(c13):- write('has it dark spots?'),nl, !, complete(c13).
ask(c14):- write('has it black stripes?'), nl, !, complete(c14).
ask(c15):- write('has it long legs?'),nl,!, complete(c15).
ask(c16):- write('has it a long neck?'), nl, !, complete(c16).
ask(c17):- write('has it a white color?'), nl,!, complete(c17).
ask(c18):- write('does it not fly?'), nl, !, complete(c18).
ask(c19):- write('is it black and white?'),nl,!, complete(c19).
ask(c20):- write('does it swim?'),nl, !, complete(c20).
ask(c21):- write('is it a good flyer?'),nl,!, complete(c21).

complete(X):- read(Y), assert(fact(X,Y)), Y=yes.

/* Conclusion of the recognition process */
conclusion(X, Y, N):- nl, tab(4), write('--- the '), write(X),
write(' is a '), write(Y), write(' by rule '),
write(N), nl, nl.

/* Description process: discover animal's properties */
description(X):- rule(N, Y, X, Z), description1(Y,L,[]),
conclusion1(X, L, Y, Z, N).

description(_):- nl,write('Don''t know this animal.'),nl.
description1(Y, L, Ls):-rule(_, X, Y,_), description1(X, L, [X|Ls]) .
description1(_,L,L).

/* Conclusions of the description process */
conclusion1(X, L, Y, Z, N):- nl, write('a '),write(X),
write(' is an '),
output(L), write(Y),
write('satisfying conditions: '),nl,
output(Z), nl,write('by rule '),
write(N), write(' .') .

output([]).
output( [A|B] ) :- write(A), tab(1), output(B).

跟踪是:

[trace] 1 ?- recognition(animal).
   Call: (6) recognition(animal) ? creep
   Call: (7) rule(_G2040, animal, _G2042, _G2043) ? creep
   Exit: (7) rule(1, animal, mammal, [c1]) ? creep
   Call: (7) discover([c1]) ? creep
   Call: (8) ask(c1) ? creep
   Call: (9) fact(c1, yes) ? creep
   Fail: (9) fact(c1, yes) ? creep
   Redo: (8) ask(c1) ? creep
   Call: (9) fact(c1, no) ? creep
   Fail: (9) fact(c1, no) ? creep
   Redo: (8) ask(c1) ? creep
   Call: (9) write('has it hair?') ? creep
has it hair?
   Exit: (9) write('has it hair?') ? creep
   Call: (9) nl ? creep

   Exit: (9) nl ? creep
   Call: (9) complete(c1) ? creep
   Call: (10) read(_G2043) ? creep
|: yes.
   Exit: (10) read(yes) ? creep
^  Call: (10) assert(fact(c1, yes)) ? creep
^  Exit: (10) assert(fact(c1, yes)) ? creep
   Call: (10) yes=yes ? creep
   Exit: (10) yes=yes ? creep
   Exit: (9) complete(c1) ? creep
   Exit: (8) ask(c1) ? creep
   Call: (8) discover([]) ? creep
   Exit: (8) discover([]) ? creep
   Exit: (7) discover([c1]) ? creep
   Call: (7) found(rule) ? creep
   Call: (8) rule ? creep
ERROR: found/1: Undefined procedure: rule/0
ERROR:   However, there are definitions for:
ERROR:         rule/4
   Exception: (8) rule ? 

1 个答案:

答案 0 :(得分:0)

添加指令

:- dynamic fact/2.
:- dynamic rule/4.

这些目的是在程序开发过程中生成有用的消息(恰好是你所见过的消息)。

编辑:刚刚调试 - 将retract(rule)更改为retract(rule(_,_,_,_))并修复单身ask(X):- fact(X,Yes),!. - 应为ask(X):- fact(X,yes),!.。然后当我查询

?- recognition(animal).

它开始循环以要求属性。如果要调试,请使用gtrace或trace。

编辑:阅读您的追踪,我认为必须更改上述建议。应该是

:- dynamic fact/2.
:- dynamic rule/0.

retract(rule(_,_,_,_))是完全错误的!正确的是retract(rule),对不起!