《用Prolog建专家系统》学习笔记(3)

三、后向链非确定性推理

现实世界中,事物往往不是非此即彼的简单逻辑关系,而是与专家的经验直觉相关的非确定性关系。

以下,介绍一个后向链非确定性推理的专家系统,Clam,它有自己独特的规则格式和推理机。

(一)置信度(Certainty Factors)

处理非确定性问题的最常用的办法,是给系统中的每条信息加上置信度。推理机自动更新维护置信度,并将其作为推理产生的结果。

Clam 的一个用例:

置信度(cf)取值-100(全假)至+100(全真)。

以下是Clam中的小型知识库,用于诊断汽车为何不点火启动。它描述了处理非确定性的一些方法。

goal problem.

rule 1
if not turn_over and battery_bad
then problem is battery.

rule 2
if lights_weak
then battery_bad cf 50.

rule 3
if radio_weak
then battery_bad cf 50.

rule 4
if turn_over and smell_gas
then problem is flooded cf 80.

rule 5
if turn_over and gas_gauge is empty
then problem is out_of_gas cf 90.

rule 6
if turn_over and gas_gauge is low
then problem is out_of_gas cf 30.

ask turn_over
menu (yes no)
prompt 'Does the engine turn over?'.

ask lights_weak
menu (yes no)
prompt 'Are the lights weak?'.

ask radio_weak
menu (yes no)
prompt 'Is the radio weak?'.

ask smell_gas
menu (yes no)
prompt 'Do you smell gas?'.

ask gas_gauge
menu (empty low full)
prompt 'What does the gas gauge say?'.

非确定性规则

以下是用户与汽车专家系统的咨询对话:

consult, restart, load, list, trace, how, exit
:consult
Does the engine turn over?
: yes
Do you smell gas?
: yes
What does the gas gauge say?
empty
low
full
: empty
problem-out_of_gas-cf-90
problem-flooded-cf-80
done with problem

注意,这个推理机不像Prolog那样只管找出一个答案,而是找出全部合理答案,并且报告答案的可信程度。可见,置信度不是概率值,而是简单地对各个答案的可信性给出一个权重。

用户定义的置信度,可以置入系统:

:consult
Does the engine turn over?
: yes
Do you smell gas?
: yes cf 50
What does the gas gauge say?
empty
low
full
: empty
problem-out_of_gas-cfproblem-flooded-cf-40
-90
done with problem

复合置信度:

:consult
Does the engine turn over?
: no
Are the lights weak?
: yes
Is the radio weak?
: yes
problem-battery-cf-75
done with problem

该例以2条规则,确定“电池缺电”的置信度是75。

置信度的用途范围:

● 结论不确定的规则;

● 前提不确定的规则;

● 用户输入的不确定数据;

● 前提和结论都不确定的规则;

● 用不确定的信息,更新黑板中的不确定数据;

● 将已知的前提设为不确定。

(二)MYCIN的置信度

(三)规则格式

自行建造推理机,必须自行设计内部规则格式。

自定规则格式,至少要有2个参数:一个是前提(LHS),另一个是结论(RHS)。为了更实用,再加上第3个参数,规则编号或名称。于是,

完整的规则结构是:

rule(Name, LHS, RHS).

结论RHS包括一个目标模式及其相应的置信度CF:

rhs(Goal, CF)

前提LHS可以包括许多子目标,用于肯定或否定RHS:

lhs(GoalList)

表示子目标的最简单方式,是用“属性-值”配对:

av(Attribute, Value)

其中的2个参数是简单的原子。

完整的规则结构是这样的:

rule(Name, 
     lhs( [av(A1, V1), av(A2, V2), ....] ), 
     rhs( av(Attr, Val), CF) ).

上述的规则五(rule 5)是这样:

rule(5, 
     lhs( [av(turns_over, yes), av(gas_gauge, empty)] ), 
     rhs( av(problem, flooded), 80) ).

(四)推理机

有了固定格式的规则,就需要自造的推理机处理它们。处理行为包括:

● 把置信度综合起来;

● 维护工作数据库(黑板),更新信息作为推理所需的新证据;

● 找出用户所需的全部特定信息,存入黑板。

主要的谓词如图3.1所示:

工作数据库:fact( av(A, V), CF).

找出属性对应的值,例如:

?- findgoal( av(problem, X), CF).

该谓词必须处理3种情况:

● 已知的“属性-值”;

● 有谓词可推断“属性-值”;

● 必须询问用户。

可以定义新谓词:

askable(live, 'Where does it live?').

要问的问题是live,问题的提示是'Where does it live?'

于是,可写出谓词findgoal。

已知属性值:

findgoal( av(Attr, Val), CF) :- fact( av(Attr, Val), CF), !.

向用户询问属性值:

findgoal(av(Attr, Val), CF) :- not fact(av(Attr, _), _), 

                               askable(Attr, Prompt), 
                            
                               query_user(Attr, Prompt), 
                               !, 
                               findgoal(av(Attr, Val), CF).

谓词query_user提示用户,输入属性值和置信度CF,并将其声明(保存)为“事实”。递归调用findgoal会用到这一事实。

query_user(Attr, Prompt) :- write(Prompt), 
                            read(Val), 
                            read(CF), 
                            asserta( fact(av(Attr, Val), CF)).
用规则推论出属性值:

findgoal(Goal, CurCF) :- fg(Goal, CurCF).

fg(Goal, CurCF) :- rule(N, lhs(IfList), 
                   rhs(Goal, CF)), 
                   prove(IfList, Tally), 
                   adjust(CF, Tally, NewCF), 
                   update(Goal, NewCF, CurCF), 
                   CurCF == 100,
                   !.

fg(Goal, CF) :- fact(Goal, CF).

在fg中有3个新谓词:

● prove – 对LHS前提作出证明,并且给出其置信度CF;

● adjust – 合并LHS的CF和RHS的CF;

● update – 用新的结论,更新现有工作数据库的值。

prove(IfList, Tally) :- prov(IfList, 100, Tally).

prov([], Tally, Tally).

prov([H|T], CurTal, Tally) :- findgoal(H, CF), 
                              min(CurTal, CF, Tal), 
                              Tal >= 20, 
                              prov(T, Tal, Tally).

min(X, Y, X) :- X =< Y,
                !.
min(X, Y, Y) :- Y =< X.

After prove succeeds, adjust computes the combined CF based on the RHS CF and the Tally from the LHS.

成功证明后,调整复合CF值。

adjust(CF1, CF2, CF) :- X is CF1 * CF2 / 100, 
                        int_round(X, CF).

int_round(X, I) :- X >= 0, 

                   I is integer(X + 0.5).

int_round(X, I) :- X < 0, 

                   I is integer(X - 0.5).

然后,谓词update 将已知证据与新证据进行整合。第一个参数是推论得出的“属性-值”对,第二个参数是其CF。第三个参数合并CF后,返回的新CF值。

update(Goal, NewCF, CF) :- fact(Goal, OldCF), 
                           combine(NewCF, OldCF, CF), 
                           retract( fact(Goal, OldCF) ), 
                           asserta( fact(Goal, CF) ), 
                           !.

update(Goal, CF, CF) :- asserta( fact(Goal, CF) ).

combine(CF1, CF2, CF) :- CF1 >= 0, 
                         CF2 >= 0, 
                         X is CF1 + CF2*(100 - CF1)/100, 
                         int_round(X, CF).

combine(CF1, CF2, CF) :- CF1 < 0, 
                         CF2 < 0, 
                         X is - ( -CF1 -CF2 * (100 + CF1)/100), 
                         int_round(X, CF).

combine(CF1, CF2, CF) :- (CF1 < 0; CF2 < 0), 
                         (CF1 > 0; CF2 > 0), 
                         abs_minimum(CF1, CF2, MCF), 
                         X is 100 * (CF1 + CF2) / (100 - MCF), 
                         int_round(X, CF).


表示否定的CF负值:

findgoal(not Goal, NCF) :- findgoal(Goal, CF), 
                           NCF is - CF,
                           !.

(五)实现Clam外壳

super :- repeat, 
         write('consult, load, exit'), nl, 
         write(':'), 
         read_line(X), 
         doit(X), 
         X == exit.

doit(consult) :- top_goals,
                 !.
doit(load) :- load_rules,
              !.
doit(exit).

调用top_goals,开始推理:

top_goals :- top_goal(Attr), 
             top(Attr), 
             print_goal(Attr), 
             fail.

top_goals.

top(Attr) :- findgoal(av(Attr, Val), CF),
             !.
top(_) :- true.

print_goal(Attr) :- nl, 
                    fact(av(Attr, X), CF), 
                    CF >= 20, 
                    outp(av(Attr, X), CF), 
                    nl, 
                    fail.

print_goal(Attr) :- write('done with '), 
                    write(Attr), nl, nl.

outp(av(A, V), CF) :- output(A, V, PrintList), 
                      write(A-'cf'-CF), 
                      printlist(PrintList),
                      !.

outp(av(A, V), CF) :- write(A-V-'cf'-CF).

printlist([]).

printlist([H|T]) :- write(H), 
                    printlist(T).

(六)英语化的规则

load_rules(F) :- clear_db, see(F), 
                 lod_ruls, 
                 write('rules loaded'), nl, 
                 seen,
                 !.

lod_ruls :- repeat, 
            read_sentence(L), 
            process(L), 
            L == eof.

process(eof) :- !.

process(L) :- trans(R, L, []), 
              assertz(R),
              !.

process(L) :- write('translate error on:'), nl, 
              write(L), nl.

clear_db :- abolish(top_goal, 1), 
            abolish(askable, 4), 
            abolish(rule, 3).

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值