基于prolog的信念网络推理

基于prolog的信念网络推理,prolog,bayesian-networks,reasoning,Prolog,Bayesian Networks,Reasoning,我在最后一个项目的Prolog中有一个问题。我尝试使用贝叶斯网络和prolog对列车系统中断模式进行推理。我的贝叶斯网络如下图所示: 我阅读了Ivan Bratko为Articial Intellegent第三版添加的Prolog编程书籍,发现了如何在Prolog中表示贝叶斯网络。 您可以看到Prolog代码,如下所示: %here is the rule for reasoning in bayesian network from the book : prob([X|Xs],Cond,P)

我在最后一个项目的Prolog中有一个问题。我尝试使用贝叶斯网络和prolog对列车系统中断模式进行推理。我的贝叶斯网络如下图所示:

我阅读了Ivan Bratko为Articial Intellegent第三版添加的Prolog编程书籍,发现了如何在Prolog中表示贝叶斯网络。 您可以看到Prolog代码,如下所示:

%here is the rule for reasoning in bayesian network from the book :
prob([X|Xs],Cond,P) :- !,
prob(X, Cond, Px),
prob(Xs, [X|Cond], PRest),
P is Px * PRest.

prob([],_,1):- !.

prob(X, Cond, 1) :-
    member(X, Cond),!.



prob(X, Cond, 0) :-
    member(\+ X, Cond), !.

prob(\+ X, Cond, P) :- !,
    prob(X, Cond, P0),
    P is 1-P0.

%Use Bayes rule if condition involves a descendant of X
prob(X, Cond0, P):-
    delete(Y, Cond0, Cond),
    predecessor(X,Y),!,             %Y is a descendant of X
    prob(X, Cond, Px),
    prob(Y, [X|Cond], PyGivenX),
    prob(Y, Cond, Py),
    P is Px * PyGivenX / Py.        %Assuming Py > 0

%Cases when condition does not involves a descendant

prob(X, Cond, P) :-
    p(X, P),!.                      % X a root cause - its probability given

prob(X, Cond, P) :- !,
    findall((CONDi, Pi), p(X,CONDi,Pi), CPlist),        %Condition on parents
    sum_probs(CPlist, Cond, P).

sum_probs([],_,0).
sum_probs([(COND1,P1) | CondsProbs], COND, P) :-
    prob(COND1, COND, PC1),
    sum_probs(CondsProbs, COND, PRest),
    P is P1 * PC1 + PRest.


predecessor(X, \+ Y) :- !,          %Negated variable Y
    predecessor(X,Y).

predecessor(X,Y) :-
    parent(X,Y).

predecessor(X,Z) :-
    parent(X,Y),
    predecessor(Y,Z).

member(X, [X|_]).
member(X, [_|L]) :-
    member(X,L).

delete(X, [X|L], L).
delete(X, [Y|L], [Y|L2]) :-
    delete(X, L, L2). 
这里还有一些关于在prolog中实现贝叶斯网络信息的例子(我只添加了一些,因为它太长了):

有关完整代码,请参见

不幸的是,当我试图推理一些概率时,我遇到了一个问题,比如:

?- prob(series, [horn], P).
?- prob(series, [brake], P).
?- prob(pantograph, [overhead_line], P).
据说错误是这样的:

ERROR: Arithmetic: evaluation error: `zero_divisor'
ERROR: In:
ERROR:   [27] _43124 is 0.045454539961694*0/0
ERROR:   [25] prob([compressor],[\+brake,traction|...],_43166) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:2
ERROR:   [24] sum_probs([(...,0.026315789),...],[\+brake,traction|...],_43216) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:37
ERROR:   [22] prob([horn,door|...],[\+brake,traction|...],_43278) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:2
ERROR:   [21] prob([\+brake,horn|...],[traction,wiper|...],_43334) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:3
ERROR:   [20] prob([traction,...|...],[wiper,speedometer|...],_43390) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:3

有人能帮我纠正这个错误吗?提前感谢。

在介绍安全测试之后

...
prob(Y, Cond, Py),
Py > 0,
P is Px * PyGivenX / Py.        %Assuming Py > 0
并更正了github代码中的一个输入错误和几个错误,我得到以下结果:

?- prob(series, [horn], P).
false.

?- prob(series, [brake], P).
P = 0.086661842800551.

?- prob(pantograph, [overhead_line], P).
false.

因此,您现在可以试着理解为什么代码会产生
false
而不是
p=0.0

我意识到为什么IntrMeter会产生零除数错误的答案,这是因为当我用:

?- prob(series, [horn], P).
?- prob(series, [brake], P).
?- prob(pantograph, [overhead_line], P)
所有这些都按照规则处理:

prob(X, Cond0, P):-
    delete(Y, Cond0, Cond),
    predecessor(X,Y),!,             %Y is a descendant of X
    prob(X, Cond, Px),
    prob(Y, [X|Cond], PyGivenX),
    prob(Y, Cond, Py),
    P is Px * PyGivenX / Py.        %Assuming Py > 0
然而,应使用下面的规则处理它们:

prob(X, Cond, P) :-
    p(X, P),!.                      % X a root cause - its probability given

prob(X, Cond, P) :- !,
    findall((CONDi, Pi), p(X,CONDi,Pi), CPlist),        %Condition on parents
    sum_probs(CPlist, Cond, P).
因为查询不涉及X的后代

有没有办法区分这两条规则?因为我以后仍然递归地使用这两个规则


我已经尝试在
prob(X,Cond0,p)
中添加条件
parent(X,Cond0)
,但是当我查询条件时涉及到X的后代,答案是错误的

您需要检查您的数学。你在除以零。我不认为有人会通过你所有的离线代码为你找到原因。你做了什么调试?我已经用trace来调试了,但是仍然没有找到代码中哪一部分被零除。没有跟踪结果表明它除以零。如果您只是尝试用测试修补有问题的行,会发生什么
Py>0,P是Px*PyGivenX/Py。
我还没有看过所有的代码,但也许你可以在调用
prob/4
后添加
Py>0
,在那里你计算
Py
。是的,我添加了Py 0,并创建了一个新的谓词prob/4,它可以工作,非常感谢:)非常感谢你的回答,现在我知道我必须在哪里修复代码:)
prob(X, Cond, P) :-
    p(X, P),!.                      % X a root cause - its probability given

prob(X, Cond, P) :- !,
    findall((CONDi, Pi), p(X,CONDi,Pi), CPlist),        %Condition on parents
    sum_probs(CPlist, Cond, P).