Control 版 (精华区)
发信人: dagam (断情), 信区: Control
标 题: [转载]专家系统[3]
发信站: 哈工大紫丁香 (2001年07月01日11:49:08 星期天), 站内信件
用户菜单
我们可以进一步的改进用户的界面,例如可以添加让用户选择答案的菜单功能。
我们使用menuask谓词来完成这个功能。它和ask很相像,不过多了一个用来保存所有可
能的属性值的列表参数。把原来的ask
谓词出现的地方用menuask来替代:
size(X):- menuask(size, X, [large, plump, medium, small]).
flight(X):- menuask(flight, X, [ponderous, agile, flap_glide]).
menuask的具体程序如下:
menuask(A, V, MenuList) :-
write('What is the value for'), write(A), write('?'), nl,
write(MenuList), nl,
read(X),
check_val(X, A, V, MenuList),
asserta( known(yes, A, X) ),
X == V.
check_val(X, A, V, MenuList) :- %如果用户输入的值在列表中可以找到。
member(X, MenuList), !.
check_val(X, A, V, MenuList) :- %如果找不到。
write(X), write(' is not a legal value, try again.'), nl,
menuask(A, V, MenuList).
这是一个最最简单的menuask的例子,用户需要输入属性值的内容,而不能通过输入1、
2、3或者是a、b、c来选择属性值。
一个简单的外壳程序
很明显这个识别鸟类的专家系统由两个完全不同的部分组成,一个是知识库,另一个是
控制用户界面的。
我们应该尽量把这两部分分离开来,这样我们就可以制作出一个外壳程序,使用这个外
壳程序和不同的知识库联接,就可以快速的开发不同的专家系统了。
为了能够把这两部分分开,就要定义统一的接口。由于不同的专家系统要完成的目标不
一样,例如识别鸟的系统的目
标是bird(X),而识别鱼的系统则是fish(X),因此在每个知识库中都定一个相同的
最顶层目标top_goal(X)。对于识别鸟的系统这个目标为:
top_goal(X):-bird(X).
在外壳程序中我们可以定义solve谓词做一些初始化工作,以及调用知识库的顶层目标t
op_goal:
solve :-
abolish(known, 3),
define(known, 3),
top_goal(X),
write('The answer is '), write(X), nl.
solve :-
write('No answer found.'), nl.
内部谓词abolish是用来删除系统中所有的known子句的。这样用户就可以使用solve来解
决不同的问题,而不至于把两次对话的内容搞混淆。
由于一开始系统中没有known子句,所以需要使用define来定义一下,这样系统再找不到
known子句的时候就不会报告错误了。不同的prolog
系统的这种内部谓词不一定相同。
现在总结一下:
solve ask menuask谓词都是外壳程序中的谓词,也就是说它们对于所有的类似的专家系
统都是相同的。
top_goal bird order family region size color eats wings multivalue这样的谓词
都是属于知识库的谓词,它们是和具体的知识挂钩的。
top_goal是外壳程序和知识库之间的桥梁。
如果我们把这些谓词分别保存在不同的文件中,例如外壳程序保存在文件native中,而
鸟类的知识库保存在birds.kb中的话,我们只要在解
释器中进行如下的对话就可以使用专家系统了。
?- consult(native).
yes
?- consult('birds.kb').
yes
?- solve.
nostrils : external_tubular?
... ...
命令循环
我们还可以增强外壳程序的功能,增加一个叫做go的谓词,go可以识别三种命令:load
consult和quit。
load命令用来调入某个知识库,consult命令用来调用知识库的top_goal从而开始对话,
quit用来退出外壳程序。
下面是go谓词的具体程序:
go :-
greeting,
repeat,
write('> '),
read(X),
do(X),
X == quit.
greeting :-
write('This is the Native Prolog shell.'), nl,
write('Enter load, consult, or quit at the prompt.'), nl.
do(load) :- load_kb, !.
do(consult) :- solve, !.
do(quit).
do(X) :-
write(X),
write('is not a legal command.'), nl,
fail.
go谓词使用repeat循环不停的从用户取得命令。do谓词用来识别用户的命令。这里的lo
ad_kb谓词的具体程序如下:
load_kb :-
write('Enter file name: '),
read(F),
reconsult(F).
我们还可以增加一些其他的外壳命令,例如:help,用来显示所有的命令的使用方法,
list用来列出所有的known
子句以供调试之用。
最后我们的专家系统和用户之间的对话如下:
?- consult(native).
yes
?- go.
This is the native Prolog shell.
Enter load, consult, or quit at the prompt.
>load.
Enter file name: 'birds.kb'.
>consult.
nostrils : external_tubular ? yes.
...
The answer is black_footed_albatross
?-
通过使用外壳程序,我们可以屏蔽一些prolog编程的难点。让开发人员在编写专家系统
的时候只需要把注意
力集中在知识库的表达上面,而使用prolog表达知识库是很容易的,就和我们平时说话
没有什么两样。
到这里,你应该对专家系统的编写有个初步的了解了吧,下一章我们将研究一些比较深
的专家系统的知识了。
(由于本章介绍的专家系统还只是雏形,所以没有提供完整的程序,你可以自己把上面
的程序片断拼凑起来,
在解释器中测试一下。)
(原文转自垂钓听竹轩)
--
--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: heart.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:5.311毫秒