def test_eventually(self): parser = self.parser i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab true = self.true false = self.false assert parser("F a").delta(i_a) == PLOr([ true, PLAnd([ true, PLAnd([ PLAtomic(LTLfUntil([LTLfTrue(), LTLfAtomic("a")])), PLAtomic(LTLfUntil([LTLfTrue(), LTLfTrue()])), ]), ]), ]) assert parser("F a").delta(i_) == PLOr([ false, PLAnd([ true, PLAnd([ PLAtomic(LTLfUntil([LTLfTrue(), LTLfAtomic("a")])), PLAtomic(LTLfUntil([LTLfTrue(), LTLfTrue()])), ]), ]), ]) assert parser("F a").delta(i_a, epsilon=True) == false assert parser("F a").delta(i_, epsilon=True) == false
def ltlf_until(self, args): if len(args) == 1: return args[0] elif (len(args) - 1) % 2 == 0: subformulas = args[::2] return LTLfUntil(subformulas) else: raise ParsingError
def p_formula(self, p): """formula : formula EQUIVALENCE formula | formula IMPLIES formula | formula OR formula | formula AND formula | formula UNTIL formula | formula RELEASE formula | EVENTUALLY formula | ALWAYS formula | NEXT formula | WEAK_NEXT formula | NOT formula | TRUE | FALSE | END | ATOM""" if len(p) == 2: if p[1] == Symbols.TRUE.value: p[0] = LTLfTrue() elif p[1] == Symbols.FALSE.value: p[0] = LTLfFalse() elif p[1] == Symbols.END.value: p[0] = LTLfEnd() else: p[0] = LTLfAtomic(p[1]) elif len(p) == 3: if p[1] == Symbols.NEXT.value: p[0] = LTLfNext(p[2]) elif p[1] == Symbols.WEAK_NEXT.value: p[0] = LTLfWeakNext(p[2]) elif p[1] == Symbols.EVENTUALLY.value: p[0] = LTLfEventually(p[2]) elif p[1] == Symbols.ALWAYS.value: p[0] = LTLfAlways(p[2]) elif p[1] == Symbols.NOT.value: p[0] = LTLfNot(p[2]) elif len(p) == 4: l, o, r = p[1:] if o == Symbols.EQUIVALENCE.value: p[0] = LTLfEquivalence([l, r]) elif o == Symbols.IMPLIES.value: p[0] = LTLfImplies([l, r]) elif o == Symbols.OR.value: p[0] = LTLfOr([l, r]) elif o == Symbols.AND.value: p[0] = LTLfAnd([l, r]) elif o == Symbols.UNTIL.value: p[0] = LTLfUntil([l, r]) elif o == Symbols.RELEASE.value: p[0] = LTLfRelease([l, r]) else: raise ValueError else: raise ValueError
def test_until(self): parser = self.parser i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab true = self.true false = self.false assert parser("A U B").delta(i_a) == PLOr([ false, PLAnd([ true, PLAtomic(LTLfUntil([LTLfAtomic("A"), LTLfAtomic("B")])), PLAtomic(LTLfEventually(LTLfTrue()).to_nnf()) ]) ]) assert parser("A U B").delta(i_ab, epsilon=True) == false
def test_parser(): parser = LTLfParser() a, b, c = [LTLfAtomic(c) for c in "abc"] assert parser("!a | b <-> !(a & !b) <-> a->b") == LTLfEquivalence([ LTLfOr([LTLfNot(a), b]), LTLfNot(LTLfAnd([a, LTLfNot(b)])), LTLfImplies([a, b]), ]) assert parser("(X a) & (WX !b)") == LTLfAnd( [LTLfNext(a), LTLfWeakNext(LTLfNot(b))]) assert parser("(F (a&b)) <-> !(G (!a | !b) )") == LTLfEquivalence([ LTLfEventually(LTLfAnd([a, b])), LTLfNot(LTLfAlways(LTLfOr([LTLfNot(a), LTLfNot(b)]))), ]) assert parser("(a U b U c) <-> !(!a R !b R !c)") == LTLfEquivalence([ LTLfUntil([a, b, c]), LTLfNot(LTLfRelease([LTLfNot(a), LTLfNot(b), LTLfNot(c)])), ])
def test_nnf(): parser = LTLfParser() a, b, c = [LTLfAtomic(c) for c in "abc"] f = parser("!(a & !b)") assert f.to_nnf() == LTLfOr([LTLfNot(a), b]) f = parser("!(!a | b)") assert f.to_nnf() == LTLfAnd([a, LTLfNot(b)]) f = parser("!(a <-> b)") assert f.to_nnf() == LTLfAnd( [LTLfOr([LTLfNot(a), LTLfNot(b)]), LTLfOr([a, b])]) # Next and Weak Next f = parser("!(X (a & b))") assert f.to_nnf() == LTLfWeakNext(LTLfOr([LTLfNot(a), LTLfNot(b)])) f = parser("!(WX (a & b))") assert f.to_nnf() == LTLfNext(LTLfOr([LTLfNot(a), LTLfNot(b)])) # Eventually and Always f = parser("!(F (a | b))") assert f.to_nnf() == LTLfAlways(LTLfAnd([LTLfNot(a), LTLfNot(b)])).to_nnf() # Until and Release f = parser("!(a U b)") assert f.to_nnf() == LTLfRelease([LTLfNot(a), LTLfNot(b)]) f = parser("!(a R b)") assert f.to_nnf() == LTLfUntil([LTLfNot(a), LTLfNot(b)]) f = parser("!(F (a | b))") assert f.to_nnf() == LTLfAlways(LTLfAnd([LTLfNot(a), LTLfNot(b)])).to_nnf() f = parser("!(G (a | b))") assert f.to_nnf() == LTLfEventually(LTLfAnd([LTLfNot(a), LTLfNot(b)])).to_nnf()
def test_nnf(): parser = LTLfParser() a, b, c = [LTLfAtomic(c) for c in "ABC"] f = parser("!(A & !B)") assert f.to_nnf() == LTLfOr([LTLfNot(a), b]) f = parser("!(!A | B)") assert f.to_nnf() == LTLfAnd([a, LTLfNot(b)]) f = parser("!( (A->B) <-> (!A | B))") assert f.to_nnf() == LTLfAnd([ LTLfAnd([a, LTLfNot(b)]), LTLfOr([LTLfNot(a), b]), ]) # Next and Weak Next f = parser("!(X (A & B))") assert f.to_nnf() == LTLfWeakNext(LTLfOr([LTLfNot(a), LTLfNot(b)])) f = parser("!(WX (A & B))") assert f.to_nnf() == LTLfNext(LTLfOr([LTLfNot(a), LTLfNot(b)])) # Eventually and Always f = parser("!(F (A | B))") assert f.to_nnf() == LTLfAlways(LTLfAnd([LTLfNot(a), LTLfNot(b)])).to_nnf() f = parser("!(F (A | B))") assert f.to_nnf() == LTLfAlways(LTLfAnd([LTLfNot(a), LTLfNot(b)])).to_nnf() f = parser("!(G (A | B))") assert f.to_nnf() == LTLfEventually(LTLfAnd([LTLfNot(a), LTLfNot(b)])).to_nnf() # Until and Release f = parser("!(A U B)") assert f.to_nnf() == LTLfRelease([LTLfNot(a), LTLfNot(b)]) f = parser("!(A R B)") assert f.to_nnf() == LTLfUntil([LTLfNot(a), LTLfNot(b)])
def test_parser(): parser = LTLfParser() a, b, c = [LTLfAtomic(c) for c in "ABC"] assert parser("!A | B <-> !(A & !B) <-> A->B") == LTLfEquivalence([ LTLfOr([LTLfNot(a), b]), LTLfNot(LTLfAnd([a, LTLfNot(b)])), LTLfImplies([a, b]) ]) assert parser("(X A) & (WX !B)") == LTLfAnd([ LTLfNext(a), LTLfWeakNext(LTLfNot(b)) ]) assert parser("(F (A&B)) <-> !(G (!A | !B) )") == LTLfEquivalence([ LTLfEventually(LTLfAnd([a, b])), LTLfNot(LTLfAlways(LTLfOr([LTLfNot(a), LTLfNot(b)]))) ]) assert parser("(A U B U C) <-> !(!A R !B R !C)") == LTLfEquivalence([ LTLfUntil([a, b, c]), LTLfNot(LTLfRelease([LTLfNot(a), LTLfNot(b), LTLfNot(c)])) ])