Visual Prolog 的 Web 专家系统 (9)

GENI的核心 -- 推理机(3)一些谓词

为了集中注意力,较好地分析GENI推理机核心程序,应该做些准备工作,弄明白一些起辅助作用的谓词功能。

is_htmlfile(Rulexpl)

  is_htmlfile(FILE):-
  	filenameext(File,_Name,Mask),
  	Mask = ".htm",!.
  is_htmlfile(FILE):-
  	filenameext(File,_Name,Mask),
  	Mask = ".html",!.

如果FILE的扩展名是“.htm”,或者“.html”,该谓词成功。否则失败。

consult_htm(Rulexpl,HTMLtext)

  consult_htm(FileName,HTMLTEKST):-
	syspath(ExeStartupPath,_ProgName),
	filenamepath(FullName,ExeStartupPath,FileName),
	trap(file_str(FullName,HTMLTEKST),_,writef("File % is not found! Correct problem!\n",FullName)),!.
  consult_htm(_,""):-
        errorexit. 

按照指定路径和文件名,把html文件内容读入变量HTMLTEKST,“返回”。

若子句1出错,回溯到子句2后报错退出。


gethtmlbody(HTMLtext,Bodytext)

  gethtmlbody(TEXT,BODY):-
  	upper_lower(TEXT,LOWERTEXT),
	searchstring(LOWERTEXT,"<body",LEN1),
	frontstr(LEN1,LOWERTEXT,_,TXT1),
	searchchar(TXT1,‘>‘,BODY_TAG_LEN),
	STARTPOS = LEN1+BODY_TAG_LEN+1,
	searchstring(LOWERTEXT,"</body>",ENDPOS),
	LEN = ENDPOS-STARTPOS,
	substring(TEXT,STARTPOS,LEN,BODY),!.
  gethtmlbody(_,""):-
	errorexit.

介绍下其中的谓词:

upper_lower(TEXT,LOWERTEXT)

VIP内建谓词。流模式(i, i), (i, o), (o, i)
upper_lower (STRING UpperCase, STRING LowerCase)
upper_lower (CHAR UpperCase, CHAR LowerCase)
用于大写的字符(串),与小写的字符(串)相互转换

searchstring(LOWERTEXT,"<body",LEN1)

VIP内建谓词。流模式(i, i, o)
searchstring (STRING SourceStr, STRING SearchStr, UNSIGNED Position)
确定字符串中,子串的一端位置

substring(TEXT,STARTPOS,LEN,BODY)

VIP内建谓词。流模式(i, i, i, o)
ubstring (STRING Source, UNSIGNED Pos, UNSIGNED Len, STRING Part)
返回字符串中指定的一部分(子串)Part

子句gethtmlbody(TEXT,BODY),从字符串TEXT中,抠出子串BODY,

算法清楚直观,不必细说。


endpage("")

  endpage("") :-!,
	write_kb,
	write_conditions,
        write("<Center>"),
        write("<FONT SIZE=+6 ><I><B>"),
        write("</Center>"),
        write("</FONT>\n"),
        write("</BODY>\n"),
        write("</HTML>\n"). 

  endpage(CONDITION) :-
	write_kb,
	write_conditions,
	writef("<input type=\"hidden\" name=\"%s\"  value=\"yes\">\n",CONDITION),
        write("<FONT SIZE=+6 ><I><B>"),
        write("<input type=\"hidden\" name=\"answer\" value=\"Yes\">\n"), %%这一句没用,可删除
	write("<p><Input type=\"SUBMIT\" value=\"Yes\">\n"),
	writef("<Input type=\"BUTTON\" value=\"No\" onclick=\"form.%s.value=‘no‘;submit()\">\n",CONDITION),
	writef("<Input type=\"BUTTON\" value=\"Why\" onclick=\"form.%s.value=‘why‘;submit()\">\n",CONDITION),
        writef("</Form>\n"),%<Form action=\"/geni.htm\">\n"),
        write("</p></form>\n"),
        write("</FONT>\n"),
        write("</BODY>\n"),
        write("</HTML>\n").

endpage里调用了2个谓词write_kb和write_conditions。

write_kb

  write_kb:-
	kb(KB),!,
	writef("<input type=\"hidden\" name=\"knowledgebase\"  value=\"%s\">\n",KB).
  write_kb:-
	errorexit().

kb是事实库谓词,当前的KB="animal",表示知识库的名字

在CGI方式下,程序所需变量,要在各网页接续下传。这里的writef,正在做这件事情。

write_conditons

  write_conditions:-
	yes(CNO),
	format(CONDITION,"cond_%",CNO),
	writef("<input type=\"hidden\" name=\"%s\"  value=\"yes\">\n",CONDITION),
	fail.
  write_conditions:-
	no(CNO),
	format(CONDITION,"cond_%",CNO),
	writef("<input type=\"hidden\" name=\"%s\"  value=\"no\">\n",CONDITION),
	fail.
  write_conditions.

对这个谓词有点说道。

yes(CNO)和no(CNO)是事实库谓词,分别代表用户对第CNO号(条件)询问,
已经做出的肯定或否定的回答。
format(CONDITION,"cond_%",CNO)是VIP内建谓词。
format (STRING OutputString, STRING FormatString, Arg1, Arg2, ..., ArgN)
流模式(o, i, i, i, i....) ,将多个参数格式化为字符串
本例的结果(假设CNO=5)是:CONDITION = "cond_5"

not(rule(_,Mygoal,_,_,_))

VIP内建谓词,流模式(i), 进行逻辑非运算。
如果rule(_,Mygoal,_,_,_)不在事实库里,not(rule(_,Mygoal,_,_,_))为真;否则为假。

check(RNO,HISTORY, COND)

这个谓词的第3和第4子句(红色部分),目前没有实际用处,可以删除。

  check( RNO, HISTORY, [CNO|REST] ):-
	yes(CNO),!,
	check(RNO, HISTORY, REST).
  check( _, _, [CNO|_]):-
	no(CNO),
	!,fail.

  check( RNO, HISTORY, [CNO|REST]):-
	cond(CNO,NCOND,OPTIONS),
	fronttoken(NCOND,"not",_COND),
	frontchar(_COND,_,COND),
	cond(CNO1,COND,OPTIONS),
	notest(CNO1), !,
	check(RNO, HISTORY, REST).
  check(_,_, [CNO|_] ):-
	cond(CNO,NCOND,OPTIONS),
	fronttoken(NCOND,"not",_COND),
	frontchar(_COND,_,COND),
	cond(CNO1,COND,OPTIONS),
	yes(CNO1),
	!,
	fail.

  check( RNO, HISTORY, [CNO|REST] ):-
	cond(CNO,TEXT,OPTIONS),!,
	inpq(HISTORY,RNO,CNO,TEXT,OPTIONS),
	check(RNO, HISTORY, REST).
  check( _, _, []).

check的第3第4子句,处理的对象,是知识库中的谓词cond(编号,询问的问题,提示)。

如果“询问的问题”是以“not”开头,check的第3第4子句会做出相应处理。

但是,“询问的问题”没有以“not”开头的,check的第3第4子句没有实际用处。

同样,check的第4子句求证的notest(CNO1),也没有用处,可以一并删除。

notest(CNO1)

 notest(CNO):-no(CNO),!.
  notest(CNO):-not(yes(CNO)),!.

可将以上“没用的”子句,从geni.pro代码中注释掉,编译运行验证。



这一节的内容已经不少,但没说到专家系统的重要功能 -- 对 why 问题的处理。

对why问题的处理,比较复杂,增加一节,专门说说。

Visual Prolog 的 Web 专家系统 (9)

时间: 2024-08-28 08:25:39

Visual Prolog 的 Web 专家系统 (9)的相关文章

Visual Prolog 的 Web 专家系统 (10)

GENI的核心 -- 推理机(4)求证过程分析 1.GENI知识库结构 专家系统推理机的设计运行,与其知识库结构紧密相关. GENI知识库结构是一棵逻辑推理树.根节点是animal,即求证的目标. Animal有2个子节点,即求证的子目标.节点或子目标,用rule表示.例如: rule(8,"animal","mammal",[12,13],"") rule(9,"animal","bird",[9,14]

Visual Prolog 的 Web 专家系统 (7)

GENI的核心 -- 推理机(1)知识表示 GOAL段最后一句是子句infer(),它的含意是"推理". 由此,进入GENI的核心,察看推理机的运行. infer() infer():- topic(Maingoal,_), go([],MainGoal,""),!. infer():- errorexit. topic(Maingoal,_) topic现存于事实库geni中,取出的Maingoal = "animal", 详见<Visu

Visual Prolog 的 Web 专家系统 (5)

使用现成网页 再说个小伎俩. 在VIP开发环境中,可以随时测试代码,不必编译成exe文件. 比如,想看看VIP内建谓词filenameext的执行结果,可以在一空白.pro文件中写入: GOAL filenameext("prolog.exe",Name,Ext), filenameext(NewName,"prolog.exe",".err"). 然后点选菜单"Project | Test Goal",就会看到以下结果: N

Visual Prolog 的 Web 专家系统 (6)

保存用户对询问的回答结果,作为进一步推理的条件 还是从GOAL段开始.起始句是write_startform() write_startform():- write("<form action=\"\cgi-bin\geni.exe\"method=\"post\">\n"). 注意!上一句应为write("<form action=\"geni.exe\"method=\"post\&q

Visual Prolog 的 Web 专家系统 (3)

深入探究WEB GENI源程序 折腾WEB GENI的目的,是为了摸清它的结构设计.运行机制,为山寨出自己的专家系统外壳,积累经验,启发思路. 为此,必须深入细致地研读源程序代码. WEBGENI包括2个模块:geni.pro和cgitools.pro.前者是主程序,负责推理.生成网页等:后者负责相对底层的CGI数据处理.本文探究的对象,主要是geni.pro. Visual Prolog(以下简称VIP)程序由几种代码段构成: PREDICATES :谓词段.相当于C语言的函数声明 CLAUS

Visual Prolog 的 Web 专家系统 (4)

知识库操作 先说个小伎俩. 在VIP中打开geni.prj,菜单选Options,打开Application Expert,点击Other Options, 点击Project Directories,点击Output,在Final文本框填入d:\Apache2.2\htdocs\GENI 这个目录是GENI虚拟主机所在之处. 这样做的目的,是编译后geni.exe会自动存入上述目录,省去了人工搬运的麻烦. 开始今天的话题,进行知识库操作. 下一步是执行GOAL段的子句consult_kb(Pa

Visual Prolog 的 Web 专家系统 (8)

GENI的核心 -- 推理机(2)流程控制 1.细说fail."!"与回溯 与其他语言相比,Prolog最大的特点,是它的回溯机制. 回溯机制,主要手段有2个,一是用谓词fail引发回溯,二是用特别谓词"!"(读作cut)取消回溯. Prolog运用fail引发回溯,实现程序的循环,并运用"!"对回溯进行控制. 看一个典型示例: FACTS f(integer) PREDICATES a() b() c() CLAUSES a():- write

Visual Prolog 的 Web 专家系统 (2)

Web 专家系统 WWWGENI 在目录<VIP_root>\WWW\Programs\GENI中,有个例程,展示如何创建在WEB服务器支持下,以CGI脚本方式在因特网上工作的小型专家系统. GENI 使用极为简单的规则表示知识,当满足某些条件时,适用这些规则. rule(1,"carnivore","cheetah",[1,2],"") rule(2,"carnivore","tiger",[

Visual Prolog 的 Web 专家系统 (11)

GENI的核心 -- 推理机(5)处理why问题 1.why问题由客户从浏览器提出 专家系统工作时,需要向用户提出问题,收集推理求证用的事实根据. 用户有时想知道,系统为什么提出这样的问题,要求系统给出解释.这就是所谓的why问题. why问题的提出,是按动网页按钮"why"的结果. 2.why功能的设置 GENI的第一个页面default.htm并没有按钮"why".它的设置过程是这样的: 从上一节的谓词check第3子句说起. check( RNO, HISTO