def modelcheck(kripke, formula, F=None): if not (isinstance(formula, CTLS.A)): raise TypeError('expected a LTL state formula, got %s' % (formula)) if not isinstance(kripke, Kripke): raise TypeError('expected a Kripke structure, got %s' % (kripke)) try: p_formula = LNot( formula.subformula(0)).get_equivalent_restricted_formula() if F != None: kripke = kripke.copy() fair_label = kripke.label_fair_states(F) p_formula = p_formula.get_equivalent_non_fair_formula(fair_label) p_formula = And(fair_label, p_formula) return set(kripke.states()) - checkE_path_formula(kripke, p_formula) except TypeError: raise TypeError('expected a LTL formula, got %s' % (formula))
def get_equivalent_restricted_formula(self): ''' Return a equivalent formula in the restricted syntax. This method returns a formula that avoids "and", "implies", "A", "F", and "R" and that is equivalent to this formula. :param self: this formula :type self: E :returns: a formula that avoids "and", "implies", "A", "F", and "R" and that is equivalent to this formula :rtype: StateFormula ''' p_formula = self.subformula(0) sf0 = p_formula.subformula(0).get_equivalent_restricted_formula() if (isinstance(p_formula, CTLS.X)): return EX(sf0) if (isinstance(p_formula, CTLS.F)): return EU(True, sf0) if (isinstance(p_formula, CTLS.G)): return EG(sf0) sf1 = p_formula.subformula(1).get_equivalent_restricted_formula() if (isinstance(p_formula, CTLS.U)): return EU(sf0, sf1) if (isinstance(p_formula, CTLS.R)): neg_sf1 = LNot(sf1) neg_sf0 = LNot(sf0) return Or(EU(sf1, Not(Or(neg_sf0, neg_sf1))), EG(sf1)) if (isinstance(p_formula, CTLS.W)): return Or(EU(Or(sf0, sf1), sf1), EG(Or(sf0, sf1))) raise TypeError('%s is not a CTL formula' % (self))
def get_closure(formula): closure = set() T = [formula] Lang = sys.modules[formula.__module__] while len(T) > 0: phi = T.pop() if hash(phi) not in [hash(o) for o in closure]: closure.add(phi) T.append(LNot(phi)) if isinstance(phi, CTLS.X): T.append(phi.subformula(0)) else: if (isinstance(phi, CTLS.Not) and isinstance(phi.subformula(0), CTLS.X)): sf = phi.subformula(0).subformula(0) T.append(Lang.X(LNot(sf))) else: if isinstance(phi, CTLS.Or): T.append(phi.subformula(0)) T.append(phi.subformula(1)) else: if isinstance(phi, CTLS.U): T.append(phi.subformula(0)) T.append(phi.subformula(1)) T.append(Lang.X(phi)) else: if not (isinstance(phi, CTLS.Not) or isinstance(phi, CTLS.AtomicProposition) or isinstance(phi, CTLS.Bool)): raise TypeError( 'expected a LTL path formula ' + 'restricted to "or", "not", ' + '"U" and "X", got %s' % (phi)) return closure
def get_equivalent_non_fair_formula(self, fairAP): p_formula = self.subformula(0) sf0 = p_formula.subformula(0).get_equivalent_non_fair_formula(fairAP) if (isinstance(p_formula, CTLS.X)): return EX(And(sf0, fairAP)) if (isinstance(p_formula, CTLS.F)): return EU(True, And(sf0, fairAP)) if (isinstance(p_formula, CTLS.G)): return EG(And(sf0, fairAP)) sf1 = p_formula.subformula(1).get_equivalent_non_fair_formula(fairAP) if (isinstance(p_formula, CTLS.U)): return EU(sf0, And(sf1, fairAP)) if (isinstance(p_formula, CTLS.R)): neg_sf1 = LNot(sf1) neg_sf0 = LNot(sf0) return Or(EU(sf1, And(Not(Or(neg_sf0, neg_sf1))), fairAP), EG(And(sf1, fairAP))) raise TypeError('%s is not a CTL formula' % (self))
def build_atoms(K, closure): A = [] for state in K.states(): A.append(TableuAtom(state)) for phi in sorted(list(closure), key=lambda a: a.height): Lang = sys.modules[phi.__module__] if phi != Lang.Not(True) and phi != Lang.Bool(False): neg_phi = LNot(phi) A_tail = [] if isinstance(phi, CTLS.Bool): for atom in A: atom.add(phi) else: if isinstance(phi, CTLS.AtomicProposition): for atom in A: if phi in K.labels(atom.state): atom.add(phi) else: atom.add(neg_phi) if (isinstance(phi, CTLS.Or)): sf = phi.subformulas() neg_sf = [LNot(p) for p in sf] for atom in A: if (sf[0] in atom or sf[1] in atom): atom.add(phi) else: atom.add(neg_phi) if (isinstance(phi, CTLS.Not) and isinstance(phi.subformula(0), CTLS.X)): sf = phi.subformula(0).subformula(0) for atom in A: if phi.subformula(0) not in atom: if phi not in atom: new_atom = atom | set([phi, Lang.X(LNot(sf))]) A_tail.append(new_atom) atom.add(phi.subformula(0)) else: atom.add(Lang.X(LNot(sf))) if isinstance(phi, CTLS.U): sf = phi.subformulas() neg_sf = [LNot(p) for p in sf] for atom in A: if (sf[1] in atom): atom.add(phi) A_tail.append(atom | set([Lang.X(phi)])) else: if (sf[0] in atom): A_tail.append(atom | set([phi, Lang.X(phi)])) atom.add(neg_phi) atom.add(Lang.Not(Lang.X(phi))) A.extend(A_tail) for atom in A: if phi not in atom and neg_phi not in atom: A.append(atom | set([phi])) atom.add(neg_phi) return A