// ---------------------------------------------------------------------- // definition of propositions: // atomic propositions // ap : type. // // ctl propositions // ctl : type. // ctl_ap : ap -> ctl. // ctl_not : ctl -> ctl. // ctl_true : ctl. // ctl_and : ctl -> ctl -> ctl. // ctl_or : ctl -> ctl -> ctl. // ctl_ex : ctl -> ctl. // ctl_eg : ctl -> ctl. // ctl_ef : ctl -> ctl. // ctl_ax : ctl -> ctl. // ctl_ag : ctl -> ctl. // ctl_af : ctl -> ctl. // ok : ctl -> type // means A is a subformula of the input formula that you // want to check ok(?a) :- ok(ctl_not(?a)). ok(?a) :- ok(ctl_and(?a,?b)). ok(?b) :- ok(ctl_and(?a,?b)). ok(?a) :- ok(ctl_or(?a,?b)). ok(?b) :- ok(ctl_or(?a,?b)). ok(?a) :- ok(ctl_ex(?a)). ok(?a) :- ok(ctl_eg(?a)). ok(?a) :- ok(ctl_ef(?a)). ok(ctl_not(ctl_ex(ctl_not(?a)))) :- ok(ctl_ax(?a)). ok(ctl_not(ctl_ef(ctl_not(?a)))) :- ok(ctl_ag(?a)). ok(ctl_not(ctl_eg(ctl_not(?a)))) :- ok(ctl_af(?a)). // ---------------------------------------------------------------------- // models : state -> ctl -> type // invariant: if models(s,a) then state(s) and ok(a) models(?s,ctl_true()). models(?s,ctl_ap(?a)) :- ok(ctl_ap(?a)), apmodels(?s,?a). models(?s,ctl_not(?a)) :- ok(ctl_not(?a)), state(?s), not models(?s,?a). models(?s,ctl_and(?a1,?a2)) :- ok(ctl_and(?a1,?a2)), models(?s,?a1), models(?s,?a2). models(?s, ctl_or(?a1, ?a2)) :- ok(ctl_or(?a1, ?a2)), models(?s, ?a1). models(?s, ctl_or(?a1, ?a2)) :- ok(ctl_or(?a1, ?a2)), models(?s, ?a2). models(?s, ctl_ex(?a)) :- ok(ctl_ex(?a)), edge(?s,?s1), models(?s1, ?a). models(?s, ctl_eg(?a)) :- ok(ctl_eg(?a)), pathallmodel(?s, ?s1, ?a), pathallmodel(?s1, ?s1, ?a). models(?s, ctl_ef(?a)) :- ok(ctl_ef(?a)), path(?s,?s1), models(?s1,?a). models(?s, ctl_ax(?a)) :- ok(ctl_ax(?a)), models(?s, ctl_not(ctl_ex(ctl_not(?a)))). models(?s, ctl_af(?a)) :- ok(ctl_af(?a)), models(?s, ctl_not(ctl_eg(ctl_not(?a)))). models(?s, ctl_ag(?a)) :- ok(ctl_ag(?a)), models(?s, ctl_not(ctl_ef(ctl_not(?a)))). // path : state -> state -> type // invariant: if path(s1,s2) then state(s1) and state(s2) path(?s,?s) :- state(?s). path(?s1,?s3) :- edge(?s1,?s2), path(?s2,?s3). // path all model // invariant: if pathallmodel(s1,s2,a) then state(s1) and state(s2) and ok(a) pathallmodel(?s1, ?s3, ?a) :- edge(?s1, ?s2), models(?s1, ?a), pathallmodel(?s2, ?s3, ?a). pathallmodel(?s1, ?s2, ?a) :- edge(?s1, ?s2), models(?s1, ?a), models(?s2, ?a). // ---------------------------------------------------------------------- // INPUT-SPECIFIC // states for microwave state('a'). // cooking, door closed state('b'). // not cooking, door closed state('c'). // not cooking, door open state('d'). // cooking, door open // edge : state -> state -> type // invariant: if edge(s1,s2) then state(s1) and state(s2) edge('a','b'). edge('b','a'). edge('b','c'). edge('c','b'). edge('d','d'). // atomic propositions models : state -> string -> type // invariant: if apmodels(s,ap) then state(s) apmodels('a','cooking'). // not apmodels('a','open'). // not apmodels('b','open'). // not apmodels('b','cooking'). apmodels('c','open'). // not apmodels('c','cooking'). apmodels('d','open'). apmodels('d','cooking'). // the queries // radiation leak: door is open but microwave is cooking (d) ok(ctl_and(ctl_ap('open'),ctl_ap('cooking'))). ?- models(?a,ctl_and(ctl_ap('open'),ctl_ap('cooking'))). // safe states: can never reach an error state (a b c) ok(ctl_ag(ctl_not(ctl_and(ctl_ap('open'),ctl_ap('cooking'))))). ?- models(?a,ctl_ag(ctl_not(ctl_and(ctl_ap('open'),ctl_ap('cooking'))))). // can eventually make dinner (all) ok(ctl_ef(ctl_ap('cooking'))). ?- models(?a,ctl_ef(ctl_ap('cooking'))). // (b d) ok(ctl_ex(ctl_or(ctl_ap('cooking'),ctl_ap('open')))). ?- models(?a,ctl_ex(ctl_or(ctl_ap('cooking'),ctl_ap('open')))). // (b d) ok(ctl_ax(ctl_or(ctl_ap('cooking'),ctl_ap('open')))). ?- models(?a,ctl_ax(ctl_or(ctl_ap('cooking'),ctl_ap('open')))). // (a c d) ok(ctl_ex(ctl_ex(ctl_or(ctl_ap('cooking'),ctl_ap('open'))))). ?- models(?a,ctl_ex(ctl_ex(ctl_or(ctl_ap('cooking'),ctl_ap('open'))))). // (a b c) ok(ctl_af(ctl_not(ctl_ap('open')))). ?- models(?a,ctl_af(ctl_not(ctl_ap('open')))).