def test_imply(self): impspec = imply(sptrue(), spfalse()) self.assertEqual(impspec.type, parser.IMPLIES) self.assertIsNotNone(impspec.car) self.assertIsNotNone(impspec.cdr) with self.assertRaises(ValueError): impspec = imply(sptrue(), None)
def test_iff(self): iffspec = iff(sptrue(), spfalse()) self.assertEqual(iffspec.type, parser.IFF) self.assertIsNotNone(iffspec.car) self.assertIsNotNone(iffspec.cdr) with self.assertRaises(ValueError): iffspec = iff(sptrue(), None)
def test_not(self): notspec = ~(sptrue()) self.assertEqual(notspec.type, parser.NOT) self.assertIsNotNone(notspec.car) self.assertIsNone(notspec.cdr) self.assertEqual(notspec, not_(sptrue())) with self.assertRaises(ValueError): notspec = not_(None)
def test_or(self): orspec = sptrue() | spfalse() self.assertEqual(orspec.type, parser.OR) self.assertIsNotNone(orspec.car) self.assertIsNotNone(orspec.cdr) self.assertEqual(orspec, or_(sptrue(), spfalse())) with self.assertRaises(ValueError): orspec = sptrue() | None with self.assertRaises(ValueError): orspec = or_(None, None)
def test_and(self): andspec = sptrue() & spfalse() self.assertEqual(andspec.type, parser.AND) self.assertIsNotNone(andspec.car) self.assertIsNotNone(andspec.cdr) self.assertEqual(andspec, and_(sptrue(), spfalse())) with self.assertRaises(ValueError): andspec = sptrue() & None with self.assertRaises(ValueError): andspec = and_(None, None)
def test_gg(self): gspec = g(sptrue()) self.assertEqual(gspec.type, parser.OP_GLOBAL) self.assertIsNotNone(gspec.car) self.assertIsNone(gspec.cdr) with self.assertRaises(ValueError): gspec = g(None)
def test_types(self): spec = au(ex(sptrue()), ag(spfalse() & sptrue())) self.assertEqual(spec.type, parser.AU) exspec = spec.car self.assertEqual(exspec.type, parser.EX) self.assertIsNone(exspec.cdr) self.assertEqual(exspec.car.type, parser.TRUEEXP) agspec = spec.cdr self.assertEqual(agspec.type, parser.AG) self.assertIsNone(agspec.cdr) andspec = agspec.car self.assertEqual(andspec.type, parser.AND) self.assertEqual(andspec.car.type, parser.FALSEEXP) self.assertEqual(andspec.cdr.type, parser.TRUEEXP)
def test_u(self): uspec = u(sptrue(), spfalse()) self.assertEqual(uspec.type, parser.UNTIL) self.assertIsNotNone(uspec.car) self.assertIsNotNone(uspec.cdr) with self.assertRaises(ValueError): uspec = u(None, None)
def test_x(self): xspec = x(sptrue()) self.assertEqual(xspec.type, parser.OP_NEXT) self.assertIsNotNone(xspec.car) self.assertIsNone(xspec.cdr) with self.assertRaises(ValueError): xspec = x(None)
def test_aw(self): awspec = aw(sptrue(), spfalse()) self.assertEqual(awspec.type, parser.AW) self.assertIsNotNone(awspec.car) self.assertIsNotNone(awspec.cdr) with self.assertRaises(ValueError): awspec = aw(None, None)
def test_ew(self): ewspec = ew(sptrue(), spfalse()) self.assertEqual(ewspec.type, parser.EW) self.assertIsNotNone(ewspec.car) self.assertIsNotNone(ewspec.cdr) with self.assertRaises(ValueError): ewspec = ew(None, None)
def test_ag(self): agspec = ag(sptrue()) self.assertEqual(agspec.type, parser.AG) self.assertIsNotNone(agspec.car) self.assertIsNone(agspec.cdr) with self.assertRaises(ValueError): agspec = ag(None)
def test_eg(self): egspec = eg(sptrue()) self.assertEqual(egspec.type, parser.EG) self.assertIsNotNone(egspec.car) self.assertIsNone(egspec.cdr) with self.assertRaises(ValueError): egspec = eg(None)
def test_f(self): fspec = f(sptrue()) self.assertEqual(fspec.type, parser.OP_FUTURE) self.assertIsNotNone(fspec.car) self.assertIsNone(fspec.cdr) with self.assertRaises(ValueError): fspec = f(None)
def test_true(self): true = sptrue() self.assertEqual(true.type, parser.TRUEEXP) self.assertIsNone(true.car) self.assertIsNone(true.cdr)
def test_ag(self): agspec = ag(sptrue()) self.assertEqual(agspec.type, parser.AG) self.assertIsNotNone(agspec.car) self.assertIsNone(agspec.cdr)
def test_au(self): auspec = au(sptrue(), spfalse()) self.assertEqual(auspec.type, parser.AU) self.assertIsNotNone(auspec.car) self.assertIsNotNone(auspec.cdr)
def test_iff(self): iffspec = iff(sptrue(), spfalse()) self.assertEqual(iffspec.type, parser.IFF) self.assertIsNotNone(iffspec.car) self.assertIsNotNone(iffspec.cdr)
def test_imply(self): impspec = imply(sptrue(), spfalse()) self.assertEqual(impspec.type, parser.IMPLIES) self.assertIsNotNone(impspec.car) self.assertIsNotNone(impspec.cdr)
def test_or(self): orspec = sptrue() | spfalse() self.assertEqual(orspec.type, parser.OR) self.assertIsNotNone(orspec.car) self.assertIsNotNone(orspec.cdr)
def test_and(self): andspec = sptrue() & spfalse() self.assertEqual(andspec.type, parser.AND) self.assertIsNotNone(andspec.car) self.assertIsNotNone(andspec.cdr)
def test_not(self): notspec = ~(sptrue()) self.assertEqual(notspec.type, parser.NOT) self.assertIsNotNone(notspec.car) self.assertIsNone(notspec.cdr)
def test_ex(self): exspec = ex(sptrue()) self.assertEqual(exspec.type, parser.EX) self.assertIsNotNone(exspec.car) self.assertIsNone(exspec.cdr)
def test_aw(self): awspec = aw(sptrue(), spfalse()) self.assertEqual(awspec.type, parser.AW) self.assertIsNotNone(awspec.car) self.assertIsNotNone(awspec.cdr)
def test_ax(self): axspec = ax(sptrue()) self.assertEqual(axspec.type, parser.AX) self.assertIsNotNone(axspec.car) self.assertIsNone(axspec.cdr)
def witness_branch(fsm, state, spec, context, originalspec): """ Return a TLACE branch explaining why state of fsm satisfies spec. fsm -- a pynusmv.fsm.BddFsm representing the system. state -- a pynusmv.dd.BDD representing a state of fsm. spec -- a pynusmv.spec.spec.Spec node representing the specification. context -- a pynusmv.spec.spec.Spec representing the context of spec in fsm. originalspec -- a pynusmv.spec.spec.Spec representing the original spec; used to annotate the produced branch, despite updated specs. Return a tlacebranch.Tlacebranch explaining why state of fsm satisfies spec. Throw a NonExistentialSpecError if spec is not existential. """ if spec.type == parser.EX: f = eval_ctl_spec(fsm, spec.car, context) path = explainEX(fsm, state, f) branch = (Tlacenode(path[0]), path[1], witness(fsm, path[2], spec.car, context)) return Tlacebranch(originalspec, branch) elif spec.type == parser.EF: newspec = eu(sptrue(), spec.car) return witness_branch(fsm, state, newspec, context, originalspec) elif spec.type == parser.EG: f = eval_ctl_spec(fsm, spec.car, context) (path, (inloop, loopstate)) = explainEG(fsm, state, f) branch = [] # intermediate states for s, i in zip(path[::2], path[1::2]): wit = witness(fsm, s, spec.car, context) branch.append(wit) branch.append(i) # manage the loop if s == loopstate: loop = wit # last state branch.append(witness(fsm, path[-1], spec.car, context)) return Tlacebranch(originalspec, tuple(branch), (inloop, loop)) elif spec.type == parser.EU: f = eval_ctl_spec(fsm, spec.car, context) g = eval_ctl_spec(fsm, spec.cdr, context) path = explainEU(fsm, state, f, g) branch = [] # intermediate states for s, i in zip(path[::2], path[1::2]): branch.append(witness(fsm, s, spec.car, context)) branch.append(i) # last state branch.append(witness(fsm, path[-1], spec.cdr, context)) return Tlacebranch(originalspec, tuple(branch)) elif spec.type == parser.EW: euspec = eu(spec.car, spec.cdr) egspec = eg(spec.car) if state.entailed(eval_ctl_spec(fsm, euspec, context)): return witness_branch(fsm, state, euspec, context, originalspec) else: return witness_branch(fsm, state, egspec, context, originalspec) else: # Default case, throw an exception because spec is not existential raise NonExistentialSpecError()
def test_ew(self): ewspec = ew(sptrue(), spfalse()) self.assertEqual(ewspec.type, parser.EW) self.assertIsNotNone(ewspec.car) self.assertIsNotNone(ewspec.cdr)
def test_eu(self): euspec = eu(sptrue(), spfalse()) self.assertEqual(euspec.type, parser.EU) self.assertIsNotNone(euspec.car) self.assertIsNotNone(euspec.cdr)
def test_ef(self): efspec = ef(sptrue()) self.assertEqual(efspec.type, parser.EF) self.assertIsNotNone(efspec.car) self.assertIsNone(efspec.cdr)
def test_af(self): afspec = af(sptrue()) self.assertEqual(afspec.type, parser.AF) self.assertIsNotNone(afspec.car) self.assertIsNone(afspec.cdr)
def countex(fsm, state, spec, context): """ Return a TLACE node explaining why state of fsm violates spec. fsm -- a pynusmv.fsm.BddFsm representing the system. state -- a pynusmv.dd.BDD representing a state of fsm. spec -- a pynusmv.spec.spec.Spec node representing the specification. context -- a pynusmv.spec.spec.Spec representing the context of spec in fsm. Return a tlacenode.Tlacenode explaining why state of fsm violates spec. """ if spec.type == parser.CONTEXT: return countex(fsm, state, spec.cdr, spec.car) elif spec.type == parser.FALSEEXP: newspec = sptrue() elif spec.type == parser.NOT: newspec = spec.car elif spec.type == parser.OR: newspec = (~spec.car) & (~spec.cdr) elif spec.type == parser.AND: newspec = (~spec.car) | (~spec.cdr) elif spec.type == parser.IMPLIES: newspec = spec.car & (~spec.cdr) elif spec.type == parser.IFF: newspec = (spec.car & (~spec.cdr)) | ((~spec.car) & spec.cdr) elif spec.type == parser.EX: newspec = ax(~spec.car) elif spec.type == parser.EF: newspec = ag(~spec.car) elif spec.type == parser.EG: newspec = af(~spec.car) elif spec.type == parser.EU: newspec = aw(~spec.cdr, (~spec.car) & (~spec.cdr)) elif spec.type == parser.EW: newspec = au(~spec.cdr, (~spec.car) & (~spec.cdr)) elif spec.type == parser.AX: newspec = ex(~spec.car) elif spec.type == parser.AF: newspec = eg(~spec.car) elif spec.type == parser.AG: newspec = ef(~spec.car) elif spec.type == parser.AU: newspec = ew(~spec.cdr, (~spec.car) & (~spec.cdr)) elif spec.type == parser.AW: newspec = eu(~spec.cdr, (~spec.car) & (~spec.cdr)) else: if spec.type == parser.NOT: newspec = spec.car else: newspec = ~spec return Tlacenode(state, (newspec, ), None, None) return witness(fsm, state, newspec, context)
def countex(fsm, state, spec, context): """ Return a TLACE node explaining why state of fsm violates spec. fsm -- a pynusmv.fsm.BddFsm representing the system. state -- a pynusmv.dd.BDD representing a state of fsm. spec -- a pynusmv.spec.spec.Spec node representing the specification. context -- a pynusmv.spec.spec.Spec representing the context of spec in fsm. Return a tlacenode.Tlacenode explaining why state of fsm violates spec. """ if spec.type == parser.CONTEXT: return countex(fsm, state, spec.cdr, spec.car) elif spec.type == parser.FALSEEXP: newspec = sptrue() elif spec.type == parser.NOT: newspec = spec.car elif spec.type == parser.OR: newspec = (~spec.car) & (~spec.cdr) elif spec.type == parser.AND: newspec = (~spec.car) | (~spec.cdr) elif spec.type == parser.IMPLIES: newspec = spec.car & (~spec.cdr) elif spec.type == parser.IFF: newspec = (spec.car & (~spec.cdr)) | ((~spec.car) & spec.cdr) elif spec.type == parser.EX: newspec = ax(~spec.car) elif spec.type == parser.EF: newspec = ag(~spec.car) elif spec.type == parser.EG: newspec = af(~spec.car) elif spec.type == parser.EU: newspec = aw(~spec.cdr, (~spec.car) & (~spec.cdr)) elif spec.type == parser.EW: newspec = au(~spec.cdr, (~spec.car) & (~spec.cdr)) elif spec.type == parser.AX: newspec = ex(~spec.car) elif spec.type == parser.AF: newspec = eg(~spec.car) elif spec.type == parser.AG: newspec = ef(~spec.car) elif spec.type == parser.AU: newspec = ew(~spec.cdr, (~spec.car) & (~spec.cdr)) elif spec.type == parser.AW: newspec = eu(~spec.cdr, (~spec.car) & (~spec.cdr)) else: if spec.type == parser.NOT: newspec = spec.car else: newspec = ~spec return Tlacenode(state, (newspec,), None, None) return witness(fsm, state, newspec, context)
def test_eg(self): egspec = eg(sptrue()) self.assertEqual(egspec.type, parser.EG) self.assertIsNotNone(egspec.car) self.assertIsNone(egspec.cdr)