#program initial. switch(s1;s2). component(relay;bulb). fluent(relay;light;b_prot). fluent(S):-switch(S). fluent(ab(C)) :- component(C). value(relay,(on;off)). value(light,(on;off)). value(S,(open;closed)) :- switch(S). hasvalue(F) :- value(F,V). % Fluents are boolean by default domain(F,(true;false)) :- fluent(F), not hasvalue(F). % otherwise, they take the specified values domain(F,V) :- value(F,V). agent(close(s1)). exog(break;surge). action(Y):-exog(Y). action(Y):-agent(Y). #program dynamic. % Inertia h(F,V) :- 'h(F,V), not c(F). % Direct effects c(s1,closed) :- o(close(s1)). #program always. % Axioms for caused h(F,V) :- c(F,V). c(F) :- c(F,V). % Indirect effects c(relay,on) :- h(s1,closed), h(ab(relay),false). c(relay,off) :- h(s1,open). c(relay,off) :- h(ab(relay),true). c(s2,closed) :- h(relay,on). c(light,on) :- h(s2,closed), h(ab(bulb),false). c(light,off) :- h(s2,open). c(light,off) :- h(ab(bulb),true). #program dynamic. % Executability :- o(close(S)), 'h(S,closed). % Malfunctioning c(ab(bulb),true) :- o(break). c(ab(relay),true) :- o(surge). c(ab(bulb),true) :- o(surge), not 'h(b_prot,true). % Observed actions actually occur o(A) :- obs_o(A). #program always. % Check that observations hold :- obs_h(F,V), not h(F,V). #program initial. % Completing the initial state 1 {h(F,V):_domain(F,V)} 1 :- _fluent(F). % A history &tel { obs_h(s1,open) & obs_h(s2,open) & obs_h(b_prot,true) & obs_h(ab(bulb),false) & obs_h(ab(relay),false) ;> obs_o(close(s1)) & obs_h(light,off) }. #program dynamic. % Generate exogenous actions { o(Z): _exog(Z) }. cause(X) :- o(X), _exog(X). #show cause/1. numcauses(N) :- #count{X:cause(X)}=N. #minimize {N:numcauses(N)}.