sat(true,_E).
sat(false,_E):-fail.
sat(ap(Property),E) :- check_ap(Property,E).
sat(p(Property),E) :- check_ap(Property,E).
sat(and(F,G),E) :- sat(F,E), sat(G,E).
sat(or(F,_G),E) :- sat(F,E).
sat(or(_F,G),E) :- sat(G,E).
sat(implies(F,G),E) :- sat(or(not(F),G),E).
sat(equivalence(F,G),E) :- sat(and(implies(F,G),implies(G,F)),E).
sat(not(F),E) :- probformula(_,_,_)\=F, sat_not(F,E).
sat(probformula(Operator,P,Ctl_formula),E) :-
Ctl_formula = gk(_,_) ->
sat_gk(probformula(Operator,P,Ctl_formula),E)
; Ctl_formula = g(_) ->
sat_g(probformula(Operator,P,Ctl_formula),E)
; (node(Node) ->
New_Node is Node +1,
retract(node(Node)),
assert(node(New_Node)),
sat_node(probformula(Operator,P,Ctl_formula),E,New_Node)
; assert(node(0)),
sat_node(probformula(Operator,P,Ctl_formula),E,0),
retractall(node(_)) /*reinitialize nodes*/
).
sat(not(probformula(Operator,P,Ctl_formula)),E) :-
negate_operator(Operator,NotOp),
sat(probformula(NotOp,P,Ctl_formula),E).
sat(probformula(Operator,P,gk(K,F)),E) :-
ground(P) ->
Q is 1-P,
(Operator = equal ->
sat(probformula(Operator,Q,fk(K,not(F))),E)
; sat(not(probformula(Operator,Q,fk(K,not(F)))),E))
; ((Operator = equal ->
sat(probformula(Operator,Q,fk(K,not(F))),E)
; sat(not(probformula(Operator,Q,fk(K,not(F)))),E)),
P is 1-Q)
.