Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

一个供Prolog爱好者学习与交流的地方


您没有登录。 请登录注册

Prolog代码求指导

浏览上一个主题 浏览下一个主题 向下  留言 [第1页/共1页]

1 Prolog代码求指导 于 周四 九月 20, 2012 10:36 pm

disease(normal):-presure(o),appearance(transparent),pandy_test(0),protein_assay(0),glu(0),cl(0),cell(lymphocyte),bacterium(0).%定义正常人的一些检查指标。
disease(purulent_meningits):-presure(3),appearance(muddy),pandy_test(-3),protein_assay(3),glu(-3),cl(-1),cell(neutrophile),bacterium(1).%定义疾病的检查指标。

presure(X):-ask(presure,X).
appearance(X):-ask(appearance,X).
pandy_test(X):-ask(pandy_test,X).
protein_assay(X):-ask(protein_assay,X).
glu(X):-ask(glu,X).
cl(X):-ask(cl,X).
cell(X):-ask(cell,X).
bacterium(X):-ask(bacterium,X).

multivalued(bacterium).
multivalued(cell).

ask(A, V):- not multivalued(A),known(yes, A, V2), V \== V2, !, fail.%除非具有多种值,否则只问一次。
ask(A,V):-know(_,A,V),!,fail.
ask(A,V):-know(yes,A,V),!.%know为yes是直接成立。
ask(A,V):-write(A:V),write('?'),read(Y),asserta(know(Y,A,V)),Y==yes.%增加变量know记录已经回答yes的纪录。
ask(A, V):- write(A:V), write('? '), read(yes).
运行结果如下:
?- disease(X).%询问诊断。
presure : 0?yes.
appearance : transparent?yes.
pandy_test : 0?yes.
protein_assay : 0?no.
protein_assay : 0? no.
pandy_test : 0? no.
appearance : transparent? no.
presure : 0? yes.
presure : 3?yes.
appearance : muddy?no.
appearance : muddy? no.
presure : 3? no.
no
怎么实现一个问题只问一次。
比如我回答presure:0?yes.它不会再问我一次presure:0?或者是问我presure:3?
上述代码为什么不能实现呢?

查阅用户资料

2 回复: Prolog代码求指导 于 周五 九月 21, 2012 2:28 am

zxjun 写道::disease(normal):-presure(o),appearance(transparent),pandy_test(0),protein_assay(0),glu(0),cl(0),cell(lymphocyte),bacterium(0).%定义正常人的一些检查指标。
disease(purulent_meningits):-presure(3),appearance(muddy),pandy_test(-3),protein_assay(3),glu(-3),cl(-1),cell(neutrophile),bacterium(1).%定义疾病的检查指标。

presure(X):-ask(presure,X).
appearance(X):-ask(appearance,X).
pandy_test(X):-ask(pandy_test,X).
protein_assay(X):-ask(protein_assay,X).
glu(X):-ask(glu,X).
cl(X):-ask(cl,X).
cell(X):-ask(cell,X).
bacterium(X):-ask(bacterium,X).

multivalued(bacterium).
multivalued(cell).

ask(A, V):- not multivalued(A),known(yes, A, V2), V \== V2, !, fail.%除非具有多种值,否则只问一次。
ask(A,V):-know(_,A,V),!,fail.
ask(A,V):-know(yes,A,V),!.%know为yes是直接成立。
ask(A,V):-write(A:V),write('?'),read(Y),asserta(know(Y,A,V)),Y==yes.%增加变量know记录已经回答yes的纪录。
ask(A, V):- write(A:V), write('? '), read(yes).
运行结果如下:
?- disease(X).%询问诊断。
presure : 0?yes.
appearance : transparent?yes.
pandy_test : 0?yes.
protein_assay : 0?no.
protein_assay : 0? no.
pandy_test : 0? no.
appearance : transparent? no.
presure : 0? yes.
presure : 3?yes.
appearance : muddy?no.
appearance : muddy? no.
presure : 3? no.
no
怎么实现一个问题只问一次。
比如我回答presure:0?yes.它不会再问我一次presure:0?或者是问我presure:3?
上述代码为什么不能实现呢?

倒数第2个ask里没加cut,所以问了第2遍presure,
第1个presure里没加cut,所以问了第3遍presure,
倒数第2个ask里没加cut,所以问了第4遍presure,

或者,你懒得加cut的话,你可以在程序运行完后的地方加上abort强制结束,
当然,在abort之前,你可以先write('The program is over.')类似这样的句子。

查阅用户资料 http://prolog.longluntan.net

3 回复: Prolog代码求指导 于 周五 九月 21, 2012 12:06 pm

Mercury Liao 写道::

倒数第2个ask里没加cut,所以问了第2遍presure,
第1个presure里没加cut,所以问了第3遍presure,
倒数第2个ask里没加cut,所以问了第4遍presure,

或者,你懒得加cut的话,你可以在程序运行完后的地方加上abort强制结束,
当然,在abort之前,你可以先write('The program is over.')类似这样的句子。

修改了下代码如下:

disease(normal):-
presure(normal),
appearance(transparent),
pandy_test(normal),
protein_assay(normal),
glu(normal),
cl(normal),
cell(lymphocyte),
bacterium(negative).
disease(purulent_meningits):-
presure(up_3),
appearance(muddy),
pandy_test(up_3),
protein_assay(up_3),
glu(down_3),
cl(down_1),
cell(neutrophile),
bacterium(positive).
disease(tuberculous_meningits):-
presure(up_2),
appearance(light_muddy),
pandy_test(up_3),
protein_assay(up_2),
glu(down_2),
cl(down_2),
cell(lymphocyte),
bacterium(acid_fast_bacillius).

presure(X):-ask(presure,X).
appearance(X):-ask(appearance,X).
pandy_test(X):-ask(pandy_test,X).
protein_assay(X):-ask(protein_assay,X).
glu(X):-ask(glu,X).
cl(X):-ask(cl,X).
cell(X):-ask(cell,X).
bacterium(X):-ask(bacterium,X).

multivalued(bacterium).
multivalued(cell).


ask(A,V):-not(multivalued(A)),known(yes, A, V2),V\==V2, !, fail.
ask(A,V):-know(yes,A,V),!.
ask(A,V):-write(A:V),write('? '),read(Y),Y==yes,asserta(know(Y,A,V)),!.


debug调试情况如下:
Calling: disease(H1)
CALL:(1) disease(normal)
Calling: presure(normal)
CALL:(1) presure(normal)
Calling: ask(presure,normal)
CALL:(1) ask(presure,normal)
CALL: not multivalued(presure)
Calling: multivalued(presure)
FAIL: multivalued(presure)
EXIT: not multivalued(presure)
Calling: known(yes,presure,H131)
No clauses for known/3
FAIL: known(yes,presure,H131)
FAIL: not multivalued(presure)
FAIL: ask(presure,normal)
REDO:(2) ask(presure,normal)
Calling: know(yes,presure,normal)
No clauses for know/3
FAIL: know(yes,presure,normal)
FAIL: ask(presure,normal)
REDO:(3) ask(presure,normal)
CALL: write(presure : normal)
EXIT: write(presure : normal)
CALL: write('? ')
EXIT: write('? ')
CALL: read(H167)
EXIT: read(yes)
CALL: yes == yes
EXIT: yes == yes
CALL: asserta(know(yes,presure,normal))
EXIT: asserta(know(yes,presure,normal))
CALL: '!'
EXIT: '!'
EXIT: ask(presure,normal)
EXIT: presure(normal)
Calling: appearance(transparent)
CALL:(1) appearance(transparent)
Calling: ask(appearance,transparent)
CALL:(1) ask(appearance,transparent)
CALL: not multivalued(appearance)
Calling: multivalued(appearance)
FAIL: multivalued(appearance)
EXIT: not multivalued(appearance)
Calling: known(yes,appearance,H649)
No clauses for known/3
FAIL: known(yes,appearance,H649)
FAIL: not multivalued(appearance)
FAIL: ask(appearance,transparent)
REDO:(2) ask(appearance,transparent)
Calling: know(yes,appearance,transparent)
FAIL: know(yes,appearance,transparent)
FAIL: ask(appearance,transparent)
REDO:(3) ask(appearance,transparent)
CALL: write(appearance : transparent)
EXIT: write(appearance : transparent)
CALL: write('? ')
EXIT: write('? ')
CALL: read(H685)
EXIT: read(no)
CALL: no == yes
FAIL: no == yes
FAIL: read(H685)
FAIL: write('? ')
FAIL: write(appearance : transparent)
FAIL: ask(appearance,transparent)
FAIL: ask(appearance,transparent)
FAIL: appearance(transparent)
FAIL: appearance(transparent)
FAIL: presure(normal)
FAIL: presure(normal)
FAIL: disease(normal)
REDO:(2) disease(purulent_meningits)
Calling: presure(up_3)
CALL:(1) presure(up_3)
Calling: ask(presure,up_3)
CALL:(1) ask(presure,up_3)
CALL: not multivalued(presure)
Calling: multivalued(presure)
FAIL: multivalued(presure)
EXIT: not multivalued(presure)
Calling: known(yes,presure,H129)
No clauses for known/3

FAIL: known(yes,presure,H129)
FAIL: not multivalued(presure)
FAIL: ask(presure,up_3)
REDO:(2) ask(presure,up_3)
Calling: know(yes,presure,up_3)
FAIL: know(yes,presure,up_3)
FAIL: ask(presure,up_3)
REDO:(3) ask(presure,up_3)
CALL: write(presure : up_3)
EXIT: write(presure : up_3)
CALL: write('? ')
EXIT: write('? ')
CALL: read(H165)

前面不是调用asserta/1了吗,没有加入一个动态谓词know/3吗,后面提示好像是说没有记住know(yes,presure,normal)来着,求指导。
顺便问下,abort怎么用啊,我刚学这个来着。

查阅用户资料

4 回复: Prolog代码求指导 于 周五 九月 21, 2012 1:06 pm

补充提问一下,如果一个disease有两种cell属性,也就是说既有b,又有c,
disease(a):-...,cell(b),...
disease(a):-...,cell(c),...
那么该如何定义?

查阅用户资料

浏览上一个主题 浏览下一个主题 返回页首  留言 [第1页/共1页]

您在这个论坛的权限:
不能在这个论坛回复主题