def test_constraint_context_sigma(self):
     fsm   = master_be_fsm()
     
     _true = Node.from_ptr(parse_ltl_spec("TRUE"))
     _true = bmcutils.make_nnf_boolean_wff(_true)
     _truen= _true.to_node()
     
     cond  = Wff(parse_ltl_spec("G !(mouse = hover)"))\
                 .to_boolean_wff()\
                 .to_negation_normal_form()
     off_1 = 0
     off_2 = 2
     length= 1
      
     # sigma1
     problem = diagnosability.generate_sat_problem([], (_truen, _truen), length, _true, cond.to_node(), _truen)
     tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(), length, off_1)
     
     canonical_p = tests.canonical_cnf(problem)
     canonical_f = tests.canonical_cnf(tm_cond)
     
     self.assertTrue(all(clause in canonical_p for clause in canonical_f))
     
     # sigma2
     problem = diagnosability.generate_sat_problem([], (_truen, _truen), length, _true, _truen, cond.to_node())
     tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(), length, off_2)
     
     canonical_p = tests.canonical_cnf(problem)
     canonical_f = tests.canonical_cnf(tm_cond)
     
     self.assertTrue(all(clause in canonical_p for clause in canonical_f))
     
def generate_sat_problem(observable_vars, formula_nodes, length, theta, sigma1, sigma2):
    """
    Generates a SAT problem which is satisfiable iff the given `formula` is
    *NOT* diagnosable for the loaded model for traces of length `length`.

    :param observable_vars: the list of the boolean variables that are considered
        visible in the scope of this diagnosability test
    :param formula: the node (NuSMV ast representation) representing the formula
        whose diagnosability is under verification
    :param length: the maximum length of the generated traces.
    :param theta: the initial condition placed on the initial belief state
        (in the form of a :see:`pynusmv.node.Node`)
    :param sigma1: the shape of the traces considered relevant for the first
        member of the critical pair in the ongoing diagnosability test
        (in the form of a :see:`pynusmv.node.Node`)
    :param sigma2: the shape of the traces considered relevant for the second
        member of the critical pair in the ongoing diagnosability test
        (in the form of a :see:`pynusmv.node.Node`)
    :return: a SAT problem which is satisfiable iff the given formula is not
        diagnosable on the loaded model.
    """
    fsm = master_be_fsm()
    offset_1  = 0
    offset_2  = length +1

    problem = generate_path(offset_1, length) & generate_path(offset_2, length) \
            & constraint_same_observations(
                                    observable_vars, offset_1, offset_2, length)\
            & constraint_context_theta_initial(theta, offset_1, offset_2)       \
            & bounded_semantics_at_offset(fsm, sigma1, length, offset_1)        \
            & bounded_semantics_at_offset(fsm, sigma2, length, offset_2)        \
            & constraint_eventually_critical_pair(
                                    formula_nodes, offset_1, offset_2, length)

    return problem
    def test_releases(self):
        with Configure(self, __file__, "/models/flipflops.smv"):
            fsm     = self.befsm
            formula = self.nnf("(a V b)")
            
            # bound 0
            offset  = 0
            bound   = 0
            
            ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
            expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
            self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
            
            # bound 1
            offset  = 0
            bound   = 1
             
            ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
            expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
#             VERIFIED manually, complains only about the CNF clauses literals and that's OK.
#             self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
            
            # ---- other offset ----             
            #  bound 2
            offset  = 2
            bound   = 1
           
            # because of the way the loop condition is encoded !
            ref_expr= ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, bound, offset)\
                    | ( ltlspec.bounded_semantics_with_loop_at_offset(fsm, formula, 0, bound, 0, offset) 
                      & bmcutils.loop_condition(self.enc, offset+bound, offset+0))
                      
            expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
Exemple #4
0
def generate_sat_problem(fsm, fml, length):
    fsm = master_be_fsm()
    offset  = 0
    wff     = bmcutils.make_negated_nnf_boolean_wff(fml).to_node()
    problem = generate_path(offset, length) \
            & ltlspec.bounded_semantics_at_offset(fsm, wff, length, offset)
    return problem
Exemple #5
0
def generate_sat_problem(fsm, fml, length):
    fsm = master_be_fsm()
    offset  = 0
    wff     = bmcutils.make_negated_nnf_boolean_wff(fml).to_node()
    problem = generate_path(offset, length) \
            & ltlspec.bounded_semantics_at_offset(fsm, wff, length, offset)
    return problem
 def test_until(self):
     with Configure(self, __file__, "/models/flipflops.smv"):
         fsm     = self.befsm
         formula = self.nnf("(a U !b)")
         
         # bound 0
         offset  = 0
         bound   = 0
         
         ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         # bound 1
         offset  = 0
         bound   = 1
         
         ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         
         # ---- other offset ----             
         #  bound 0
         offset  = 2
         bound   = 0
     
         cdr     = Wff.decorate(ltlspec.cdr(formula)).to_be(fsm.encoding)
         
         ref_expr= self.enc.shift_to_time(cdr, 0+offset)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         #  bound 1
         offset  = 2
         bound   = 1
          
         car     = Wff.decorate(ltlspec.car(formula)).to_be(fsm.encoding)
         cdr     = Wff.decorate(ltlspec.cdr(formula)).to_be(fsm.encoding)
         
         ref_expr= self.enc.shift_to_time(cdr, 0+offset) \
                 | (self.enc.shift_to_time(car, 0+offset) & self.enc.shift_to_time(cdr, 1+offset))
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
 def test_globally(self):
     with Configure(self, __file__, "/models/flipflops.smv"):
         fsm     = self.befsm
         formula = self.nnf("G (a <-> !b)")
         
         # bound 0
         offset  = 0
         bound   = 0
         
         ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         # bound 1
         offset  = 0
         bound   = 1
         
         ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         
         # ---- other offset ----             
         #  bound 0
         offset  = 2
         bound   = 0
         
         ref_expr= Be.false(self.enc.manager)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         #  bound 1
         offset  = 2
         bound   = 1
         
         ref_expr= ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, bound, offset) \
                 |( ltlspec.bounded_semantics_with_loop_at_offset(fsm, formula, 0, bound, 0, offset) \
                 & bmcutils.loop_condition(self.enc, bound+offset, offset))
                 
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
 def test_next(self):
     with Configure(self, __file__, "/models/flipflops.smv"):
         fsm     = self.befsm
         formula = self.nnf("X (a <-> !b)")
         
         # bound 0
         offset  = 0
         bound   = 0
         
         ref_expr= ltlspec.bounded_semantics(fsm, formula, bound)
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
         self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
         
         # bound 1
         offset  = 0
         bound   = 1
         
         # done this way to avoid the depth 1 optimisation
         car     = Wff.decorate(ltlspec.car(formula)).to_be(fsm.encoding)
         ref_expr= self.enc.shift_to_time(car, offset+1) \
                 | (self.enc.shift_to_time(car, offset) & bmcutils.loop_condition(self.enc, bound, 0))
         expr    = ltlspec.bounded_semantics_at_offset(fsm, formula, bound, offset)
    def test_constraint_context_sigma(self):
        fsm = master_be_fsm()

        _true = Node.from_ptr(parse_ltl_spec("TRUE"))
        _true = bmcutils.make_nnf_boolean_wff(_true)
        _truen = _true.to_node()

        cond  = Wff(parse_ltl_spec("G !(mouse = hover)"))\
                    .to_boolean_wff()\
                    .to_negation_normal_form()
        off_1 = 0
        off_2 = 2
        length = 1

        # sigma1
        problem = diagnosability.generate_sat_problem([], (_truen, _truen),
                                                      length, _true,
                                                      cond.to_node(), _truen)
        tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(),
                                                      length, off_1)

        canonical_p = tests.canonical_cnf(problem)
        canonical_f = tests.canonical_cnf(tm_cond)

        self.assertTrue(all(clause in canonical_p for clause in canonical_f))

        # sigma2
        problem = diagnosability.generate_sat_problem([], (_truen, _truen),
                                                      length, _true, _truen,
                                                      cond.to_node())
        tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(),
                                                      length, off_2)

        canonical_p = tests.canonical_cnf(problem)
        canonical_f = tests.canonical_cnf(tm_cond)

        self.assertTrue(all(clause in canonical_p for clause in canonical_f))
Exemple #10
0
def generate_sat_problem(observable_vars, formula_nodes, length, theta, sigma1, sigma2):
    """
    Generates a SAT problem which is satisfiable iff the given `formula` is 
    *NOT* diagnosable for the loaded model for traces of length `length`.
    
    :param observable_vars: the list of the boolean variables that are considered
        visible in the scope of this diagnosability test
    :param formula: the node (NuSMV ast representation) representing the formula
        whose diagnosability is under verification
    :param length: the maximum length of the generated traces.
    :param theta: the initial condition placed on the initial belief state 
        (in the form of a :see:`pynusmv.node.Node`)
    :param sigma1: the shape of the traces considered relevant for the first
        member of the critical pair in the ongoing diagnosability test 
        (in the form of a :see:`pynusmv.node.Node`)
    :param sigma2: the shape of the traces considered relevant for the second
        member of the critical pair in the ongoing diagnosability test 
        (in the form of a :see:`pynusmv.node.Node`)
    :return: a SAT problem which is satisfiable iff the given formula is not
        diagnosable on the loaded model.
    """
    fsm = master_be_fsm()
    offset_1 = 0
    offset_2 = length + 1

    problem = (
        generate_path(offset_1, length)
        & generate_path(offset_2, length)
        & constraint_same_observations(observable_vars, offset_1, offset_2, length)
        & constraint_context_theta_initial(theta, offset_1, offset_2)
        & bounded_semantics_at_offset(fsm, sigma1, length, offset_1)
        & bounded_semantics_at_offset(fsm, sigma2, length, offset_2)
        & constraint_eventually_critical_pair(formula_nodes, offset_1, offset_2, length)
    )

    return problem