def progress(G): S = nx.DiGraph() S.add_edges_from( (x, y) for x, y in S.edges() if S.edge[x][y]["codeblock"] != "fire") scc = len(list(nx.strongly_connected_components(S))) if scc > 0: log.err("found %s SCC without a fire" % scc) else: log.info("no SCC without a fire")
def work (self) : self.retry = False marking = self.trace.last if PRAGMAS["LOGS"] : log.debug(self, ">> flows(%s)" % marking) flows = self.net.getflows(self.name, marking) if PRAGMAS["LOGS"] : log.debug(self, "<< flows(%s) = %s" % (marking, flows)) flows = [f for f in flows if f.sub <= self.trace.last] if PRAGMAS["LOGS"] : log.debug(self, ".. keep %s" % flows) if self.retry and not flows : call(self.work) if PRAGMAS["LOGS"] : log.debug(self, "=> %sretry" % log.YELLOW) if PRAGMAS["STATS"] : self.net.stats["retries"] += 1 return if not flows : self.state = IDLE if PRAGMAS["LOGS"] : log.debug(self, "=> %ssleep" % log.YELLOW) else : flow = random.choice(flows) if PRAGMAS["LOGS"] : log.debug(self, "=> %sfire with %s" % (log.YELLOW, flow)) try : succ = self.trace.last - flow.sub + flow.add except Exception as err : if PRAGMAS["LOGS"] : log.debug(self, "fire failed!") log.err("%s - %s + %s => %s" % (self.trace.last, flow.sub, flow.add, err)) self.net.kill() sys.exit(0) self.trace.fire(self.name, succ) self.state = IDLE for player in random.permutation(list(self.team | self.out)) : if player.state == IDLE : if PRAGMAS["LOGS"] : log.debug(self, "=> call %s.work" % player.name) player.state = BUSY call(player.work) elif player.state == BUSY : if PRAGMAS["LOGS"] : log.debug(self, ".. skip %s (%s)" % (player.name, player.state)) if player in self.out : player.retry = True else : pass if PRAGMAS["LOGS"] : log.debug(self, ".. skip %s (%s)" % (player.name, player.state))
def deadlocks(G): states = G.graph["substates"] count = 0 deadlocks = set() for node in G: if G.node[node]["dead"]: count += 1 mark = G.node[node]["marking"] state = states._state[mark] deadlocks.add(mark) if list(states.successors(state)): log.error("invalid dealock", node, "=> %s=%s" % (state, mark)) if count == 0: log.info("no deadlock found") else: log.info("checked %s deadlock(s)" % count) for state in states: if not list(states.successors()): mark = states.net.get_marking() if mark not in deadlocks: log.err("missing deadlock: %s" % mark) return count
def fire (self, trans, succ) : "Extend the trace with an event" if PRAGMAS["LOGS"] : log.info("fire %s: %s => %s" % (trans, self.last, succ)) if PRAGMAS["CHECKS"] : pred = self.last self.last = succ if PRAGMAS["STATS"] : self.count += 1 if PRAGMAS["FAIR"] : self.trans[trans] += 1 if PRAGMAS["CHECKS"] : self.net.set_marking(pred) for t in self.net.transition() : for m in t.modes() : t.fire(m) if t.name == trans and self.net.get_marking() == succ : return self.net.set_marking(pred) log.err("invalid firing of %s => %s (does not exist)" % (trans, succ)) self.netserver.kill() sys.exit(0)
def correctness(G): def match(a, b): return a == b return nx.is_isomorphic(tau_star_reduce(lts(G.graph["states"])), lts(G.graph["substates"]), node_match=match, edge_match=match) if __name__ == "__main__": log.verbosity = log.ALL for path in glob.glob("nets/*.py"): g = make(path) d = deadlocks(g) progress(g) if nx.is_strongly_connected(g): log.info("strongly connected") elif d: if nx.is_strongly_connected(remove_dead(g)): log.info("strongly connected (except deadlocks)") else: log.err("not strongly connected (even without deadlocks)") else: log.err("not strongly connected but without deadlocks") if correctness(g): log.info("checked tau*-bisimilarity") else: log.err("marking graphs are not tau*-bisimilar") print