首页 > 代码库 > Visual Prolog 的 Web 专家系统 (11)
Visual Prolog 的 Web 专家系统 (11)
GENI的核心 -- 推理机(5)处理why问题
1、why问题由客户从浏览器提出
专家系统工作时,需要向用户提出问题,收集推理求证用的事实根据。
用户有时想知道,系统为什么提出这样的问题,要求系统给出解释。这就是所谓的why问题。
why问题的提出,是按动网页按钮“why”的结果。
2、why功能的设置
GENI的第一个页面default.htm并没有按钮“why”。它的设置过程是这样的:
从上一节的谓词check第3子句说起。
check( RNO, HISTORY, [CNO|REST] ):- cond(CNO,TEXT,OPTIONS),!, inpq(HISTORY,RNO,CNO,TEXT,OPTIONS).
这时的cond是未经求证的条件,即不存在yes(CNO)和no(CNO)的事实,于是,开始求证子目标inpq。
inpq(HISTORY,RNO,CNO,TEXT,OPTIONS)
inpq(HISTORY,RNO,CNO,TEXT,_):- whymeet,!, gen_why(HISTORY,RNO,TEXT,CNO), endpage_Why(), exit. inpq(_HISTORY,_RNO,CNO,TEXT,""):-!, write("\nIs it true that: ",TEXT,"\n<BR>"), format(CONDSTR,"cond_%",CNO), endpage(CONDSTR), exit. inpq(_HISTORY,_RNO,CNO,TEXT,FILENAME):- is_htmlfile(FILENAME),!, consult_htm(FILENAME,HtmlText), gethtmlbody(HtmlText,BodyText), write(BodyText), write("\nIs it true that: ",TEXT,"\n<BR>"), format(CONDSTR,"cond_%",CNO), endpage(CONDSTR),!, exit. inpq(_HISTORY,_RNO,CNO,TEXT,PICTURE):- write("\nIs it true that: ",TEXT," ",PICTURE,"\n"), format(CONDSTR,"cond_%",CNO), endpage(CONDSTR),!, exit.
Inpq的第1子句,处理why问题,生成专门网页。下面将有介绍。
Inpq的第2、3、4子句,共同之处,都设置了进一步的提问求证和why功能。不同之处,只是显示网页的方法各异。
why功能的实际设置,在谓词endpage。
endpage(CONDITION)
Endpage前面已有介绍,不再重复啰嗦。只是强调一下其第2子句中,设置why问题。
writef("<Input type=\"BUTTON\" value=http://www.mamicode.com/"Why/" onclick=/"form.%s.value=‘why‘;submit()/">/n",CONDITION),
CONDITION的值为cond_X,X是数字。假设X=15,在按钮“why”后,form.cond_15.value=http://www.mamicode.com/‘why’。
这一变量,决定了whymeet进入事实库。
whymeet进入事实库
前面小节中已经介绍过,cond_15=why这种CGI数据,会整理成parm(“cond_15”,”why”)这种样子。
经过GOAL的assert_conditions求证,来到assert_cond(“cond_15”,”why”)的求证:
assert_cond(CNO,"yes"):-!,assert(yes(CNO)). assert_cond(CNO,"no"):-!,assert(no(CNO)). assert_cond(_CNO,"why"):-!,assert(whymeet). assert_cond(_,_):-errorexit.
第3子句,将whymeet存入事实库。
3、why问题的处理
上述谓词inpq的第1子句,负责处理why问题。
inpq(HISTORY,RNO,CNO,TEXT,_):- whymeet,!, gen_why(HISTORY,RNO,TEXT,CNO), endpage_Why(), exit.
事实whymeet的存在,说明用户在浏览器按下了按钮“why”,提出了这个问题。往下接着看gen_why和endpage_Why。
gen_why(HISTORY,RNO,TEXT,CNO)
gen_why(HISTORY,RNO,_TEXT,_CNO):- write("Why<BR>\n"), rule( RNO, Mygoal1, Mygoal2, _ ,_),!, sub_cat(Mygoal1,Mygoal2,Lstr), concat("I try to show that: ",Lstr,Lstr1), concat(Lstr1,"<BR>\nBy using rule number ",Ls1), str_int(Str_num,RNO), concat(Ls1,Str_num,Ans), show_rule(RNO,Lls1), concat(Ans,Lls1,Ans1), report(HISTORY,Sng), concat(Ans1,Sng,Answ), write(Answ),nl. gen_why(_HISTORY,_RNO,_TEXT,_CNO):- errorexit.
show_rule和report,以及endpage_Why都是外建谓词,主要用于显示网页的内容,不再介绍。其余的内建谓词,前面几节有过介绍,不再重复。
一点建议
直到写完小节(10),才发现VIP的目录EXAMPLES里有单机版的GENI。
由于没有CGI处理HTML显示等问题,程序逻辑简单许多,更适合学习研究。