예제 #1
0
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))
예제 #2
0
    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))
예제 #3
0
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
예제 #4
0
    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))
예제 #5
0
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