diff --git a/formrsctlk.cc b/formrsctlk.cc index 6921548..9260769 100644 --- a/formrsctlk.cc +++ b/formrsctlk.cc @@ -7,6 +7,7 @@ */ #include "formrsctlk.hh" +#include "rs.hh" std::string FormRSCTLK::toStr(void) const { @@ -250,3 +251,13 @@ void FormRSCTLK::encodeActions(const SymRS *srs) arg[1]->encodeActions(srs); } } + +ProcSet FormRSCTLK::getAgentsAsProcSet(RctSys *rs) const +{ + ProcSet processes; + for (auto &a : agents) + { + processes.insert(rs->getProcessID(a)); + } + return processes; +} diff --git a/formrsctlk.hh b/formrsctlk.hh index 474ea5f..add62c7 100644 --- a/formrsctlk.hh +++ b/formrsctlk.hh @@ -43,9 +43,13 @@ #define RSCTLK_TF 50 // true/false #define RSCTLK_NK 61 // Epistemic operators +#define RSCTLK_NE 62 +#define RSCTLK_NC 63 #define RSCTLK_UK 71 +#define RSCTLK_UE 72 +#define RSCTLK_UC 73 -#define RSCTLK_COND_1ARG(a) ((a) == RSCTLK_NOT || (a) == RSCTLK_EG || (a) == RSCTLK_EF || (a) == RSCTLK_EX || (a) == RSCTLK_AG || (a) == RSCTLK_AF || (a) == RSCTLK_AX || (a) == RSCTLK_EG_ACT || (a) == RSCTLK_EF_ACT || (a) == RSCTLK_EX_ACT || (a) == RSCTLK_AG_ACT || (a) == RSCTLK_AF_ACT || (a) == RSCTLK_AX_ACT || (a) == RSCTLK_UK || (a) == RSCTLK_NK) +#define RSCTLK_COND_1ARG(a) ((a) == RSCTLK_NOT || (a) == RSCTLK_EG || (a) == RSCTLK_EF || (a) == RSCTLK_EX || (a) == RSCTLK_AG || (a) == RSCTLK_AF || (a) == RSCTLK_AX || (a) == RSCTLK_EG_ACT || (a) == RSCTLK_EF_ACT || (a) == RSCTLK_EX_ACT || (a) == RSCTLK_AG_ACT || (a) == RSCTLK_AF_ACT || (a) == RSCTLK_AX_ACT || (a) == RSCTLK_UK || (a) == RSCTLK_NK || (a) == RSCTLK_UE || (a) == RSCTLK_NE || (a) == RSCTLK_UC || (a) == RSCTLK_NC) #define RSCTLK_COND_2ARG(a) ((a) == RSCTLK_AND || (a) == RSCTLK_OR || (a) == RSCTLK_XOR || (a) == RSCTLK_IMPL || (a) == RSCTLK_EU || (a) == RSCTLK_AU || (a) == RSCTLK_EU_ACT || (a) == RSCTLK_AU_ACT) #define RSCTLK_COND_ACT(a) ((a) > 30 && (a) < 45) #define RSCTLK_IS_VALID(a) (RSCTLK_COND_1ARG(a) || RSCTLK_COND_2ARG(a) || (a) == RSCTLK_PV || (a) == RSCTLK_TF) @@ -288,6 +292,7 @@ class FormRSCTLK assert(oper == RSCTLK_NK || oper == RSCTLK_UK); return *(agents.begin()); } + ProcSet getAgentsAsProcSet(RctSys *rs) const; }; #endif diff --git a/mc.cc b/mc.cc index 4d20649..1f443cf 100644 --- a/mc.cc +++ b/mc.cc @@ -359,6 +359,16 @@ BDD ModelChecker::getStatesRSCTLK(const FormRSCTLK *form) auto proc_id = srs->rs->getProcessID(form->getSingleAgent()); return *reach - (statesNK(*reach - getStatesRSCTLK(form->getLeftSF()), proc_id) * *reach); } + else if (oper == RSCTLK_NC) + { + auto proc_set = form->getAgentsAsProcSet(srs->rs); + return statesNC(getStatesRSCTLK(form->getLeftSF()) * *reach, proc_set) * *reach; + } + else if (oper == RSCTLK_UC) + { + auto proc_set = form->getAgentsAsProcSet(srs->rs); + return *reach - (statesNC(*reach - getStatesRSCTLK(form->getLeftSF()), proc_set) * *reach); + } assert(0); // Should never happen return BDD_FALSE; @@ -453,6 +463,25 @@ BDD ModelChecker::statesNK(const BDD &states, Process proc_id) return x; } +BDD ModelChecker::statesNC(const BDD &states, ProcSet processes) +{ + BDD x = BDD_FALSE; + BDD x_p = *reach; + + while (x != x_p) + { + x_p = x; + BDD t = BDD_FALSE; + for (auto const &proc_id : processes) + { + t += x.ExistAbstract(getIthOnly(proc_id)); + } + x = t; + } + + return x; +} + BDD ModelChecker::getIthOnly(Process proc_id) { /* if possible, we return the BDD from cache */ diff --git a/mc.hh b/mc.hh index 663d3bd..1274f61 100644 --- a/mc.hh +++ b/mc.hh @@ -61,13 +61,14 @@ class ModelChecker BDD statesEUctx(const BDD *contexts, const BDD &statesA, const BDD &statesB); BDD statesEFctx(const BDD *contexts, const BDD &states); BDD statesNK(const BDD &states, Process proc_id); + BDD statesNC(const BDD &states, ProcSet processes); BDD getIthOnly(Process proc_id); void cleanup(void); void reorder(void); - + public: ModelChecker(SymRS *srs, Options *opts); diff --git a/rsin_parser.yy b/rsin_parser.yy index 3d1f688..ebece8b 100644 --- a/rsin_parser.yy +++ b/rsin_parser.yy @@ -39,7 +39,8 @@ class rsin_driver; // Entity_f *ent; // Action_f *act; // ActionsVec_f *actionsVec; - StateConstr *fstc; + StateConstr *fstc; + Agents_f *agents; }; %code { @@ -67,6 +68,7 @@ class rsin_driver; // %type action // %type actions %type state_constr +%type agents; //%printer { yyoutput << *$$; } "identifier" %destructor { delete $$; } "identifier" @@ -330,6 +332,19 @@ state_constr: IDENTIFIER DOT IDENTIFIER { // } // ; +agents: + IDENTIFIER { + Agents_f *ag = new Agents_f; + ag->insert(*$1); + free($1); + $$ = ag; + } + | agents COMMA IDENTIFIER { + $1->insert(*$3); + free($3); + $$ = $1; + } + rsctlk_form: IDENTIFIER DOT IDENTIFIER { $$ = new FormRSCTLK(*$1, *$3); @@ -378,16 +393,20 @@ rsctlk_form: | AG rsctlk_form { $$ = new FormRSCTLK(RSCTLK_AG, $2); } - | UK LSB IDENTIFIER RSB LRB rsctlk_form RRB { - Agents_f agents; - agents.insert(*$3); - $$ = new FormRSCTLK(RSCTLK_UK, agents, $6); + | UK LSB agents RSB LRB rsctlk_form RRB { + $$ = new FormRSCTLK(RSCTLK_UK, *$3, $6); free($3); } - | NK LSB IDENTIFIER RSB LRB rsctlk_form RRB { - Agents_f agents; - agents.insert(*$3); - $$ = new FormRSCTLK(RSCTLK_NK, agents, $6); + | NK LSB agents RSB LRB rsctlk_form RRB { + $$ = new FormRSCTLK(RSCTLK_NK, *$3, $6); + free($3); + } + | UE LSB agents RSB LRB rsctlk_form RRB { + $$ = new FormRSCTLK(RSCTLK_UE, *$3, $6); + free($3); + } + | NE LSB agents RSB LRB rsctlk_form RRB { + $$ = new FormRSCTLK(RSCTLK_NE, *$3, $6); free($3); } diff --git a/types.hh b/types.hh index b49eb62..9d69bf7 100644 --- a/types.hh +++ b/types.hh @@ -30,6 +30,7 @@ struct Reaction { typedef unsigned int Process; typedef std::vector ProcessesById; typedef std::map ProcessesByName; +typedef std::set ProcSet; typedef std::vector Reactions; typedef std::map ReactionsForProc;