рассуждения в вере сети с прологом - PullRequest
0 голосов
/ 10 июня 2018

У меня проблема в Прологе для моего финального проекта.Я пытаюсь рассуждать о схеме разрушения системы поезда, используя байесовскую сеть и пролог.У меня байесовская сеть выглядит следующим образом: Байесовская сеть Изображение

Я читал книги Пролог для Articial Intellegent 3-е дополнение Ивана Братко, и я нашел, как представлять Байесовскую сеть в Прологе.Вы можете увидеть код Пролога следующим образом:

%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). 

Здесь также представлена ​​реализация информации о байесовской сети в прологе (я только добавляю некоторые из них, потому что она была слишком длинной):

p(static_inverter, [overhead_line], 0.005050505).
p(static_inverter, [\+ overhead_line], 0.000213767).

p(ac, [static_inverter], 0.5).
p(ac, [\+ static_inverter], 0.029749692).

p(door, [compressor], 0.026315789).
p(door, [\+ compressor], 0.006821).

p(horn, [compressor], 0.026315789).
p(horn, [\+ compressor], 0.000206697).

p(brake, [compressor], 0.026315789).
p(brake, [\+ compressor], 0.004340637).

p(switch, [signal, service_table], 0.5).
p(switch, [\+ signal, service_table], 0.346153846).
p(switch, [signal, \+ service_table], 0.054098361).
p(switch, [\+ signal, \+ service_table], 0.041364933).

p(overhead_line, [fire, fallen_tree], 0.5).
p(overhead_line, [fire, \+ fallen_tree], 0.005882353).
p(overhead_line, [\+ fire, fallen_tree], 0.304878049).
p(overhead_line, [\+ fire, \+ fallen_tree], 0.038850284).

p(pantograph, [overhead_line, fallen_tree], 0.038461538).
p(pantograph, [overhead_line, \+ fallen_tree], 0.002702703).
p(pantograph, [\+ overhead_line, fallen_tree], 0.017241379).
p(pantograph, [\+ overhead_line, \+ fallen_tree], 0.00440955).

для полного кода, который вы можете увидеть на здесь

к сожалению, у меня возникает проблема, когда я пытаюсь обосновать некоторые вероятности, такие как:

?- 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

Кто-нибудь может мне помочь исправить эту ошибку?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Я понимаю, почему intrpreter получает ответ с ошибкой zero_divisor, потому что когда я запрашиваю с:

?- 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

Есть идеи отличить оба правила?Потому что я все еще использую оба правила рекурсивно позже?

Я уже пытаюсь добавить условие parent(X, Cond0) в prob(X, Cond0, P), но когда я запрашиваю условие, включающее потомка X, ответ неверен

0 голосов
/ 10 июня 2018

После введения теста безопасности,

...
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 ...

...