def print_vars_and_trans(self, modelpath): fsm = BddFsm.from_filename(modelpath) self.assertIsNotNone(fsm) propDb = glob.prop_database() master = propDb.master print("MODEL:", modelpath) print("============================================================") sexpfsm_ptr = nsprop.Prop_get_scalar_sexp_fsm(master._ptr) var_list = nssexp.SexpFsm_get_vars_list(sexpfsm_ptr) var_list_length = nsutils.NodeList_get_length(var_list) print("var_list length:", var_list_length) var_list_iter = nsutils.NodeList_get_first_iter(var_list) while var_list_iter is not None: item = nsutils.NodeList_get_elem_at(var_list, var_list_iter) print(nsnode.sprint_node(item)) print("--------------------------") var_init = nssexp.SexpFsm_get_var_init(sexpfsm_ptr, item) print(nsnode.sprint_node(var_init)) print("--------------------------") var_trans = nssexp.SexpFsm_get_var_trans(sexpfsm_ptr, item) print(nsnode.sprint_node(var_trans)) print("--------------------------") print() var_list_iter = nsutils.ListIter_get_next(var_list_iter)
def test_check_invar_incrementally_dual(self): for prop in prop_database(): with self.assertRaises(ValueError): invarspec.check_invar_incrementally_dual(prop,-1, invarspec.InvarClosureStrategy.FORWARD) invarspec.check_invar_incrementally_dual(prop, 2, invarspec.InvarClosureStrategy.FORWARD) invarspec.check_invar_incrementally_dual(prop, 2, invarspec.InvarClosureStrategy.BACKWARD)
def test_check_invar_incrementally_falsification(self): for prop in prop_database(): with self.assertRaises(ValueError): invarspec.check_invar_incrementally_falsification(prop,-1) invarspec.check_invar_incrementally_falsification(prop, 2) invarspec.check_invar_incrementally_falsification(prop, 2)
def test_force_reordering(self): glob.load("tests/pynusmv/models/admin.smv") glob.compute_model(variables_ordering="tests/pynusmv/models/admin.ord") fsm = glob.prop_database().master.bddFsm self.assertTupleEqual(("admin", "state"), fsm.bddEnc.get_variables_ordering()) reorder(fsm.bddEnc.DDmanager) self.assertTupleEqual(("state", "admin"), fsm.bddEnc.get_variables_ordering())
def test_check_invar_induction(self): for prop in prop_database(): # consistency of fname and dump type with self.assertRaises(ValueError): invarspec.check_invar_induction(prop, fname_template="coucou") with self.assertRaises(ValueError): invarspec.check_invar_induction(prop, dump_type=DumpType.DIMACS) # must perform the verif invarspec.check_invar_induction(prop)
def test_generate_invar_problem(self): # PROBLEM = BASE STEP & INDUCTION for prop in prop_database(): expr = utils.make_nnf_boolean_wff(prop.expr) problem = invarspec.generate_invar_problem(self.fsm, expr) manual = (invarspec.generate_base_step(self.fsm, expr) & invarspec.generate_inductive_step(self.fsm, expr)) self.assertEqual(problem.to_cnf().vars_list, manual.to_cnf().vars_list)
def test_variables_ordering_compute(self): glob.load_from_file("tests/pynusmv/models/constraints.smv") glob.compute_model(variables_ordering= "tests/pynusmv/models/constraints.ord") fsm = glob.prop_database().master.bddFsm with open("tests/pynusmv/models/constraints.ord", "r") as f: order = f.read().split("\n") self.assertListEqual(order, list(fsm.bddEnc.get_variables_ordering()))
def test_propDb(self): propDb = glob.prop_database() self.assertTrue(propDb.get_size() >= 1, "propDb misses some props") prop = propDb.get_prop_at_index(0) self.assertIsNotNone(prop, "prop should not be None") self.assertEqual(len(propDb), propDb.get_size()) self.assertEqual(propDb[0]._ptr, propDb.get_prop_at_index(0)._ptr) for prop in propDb: self.assertIsNotNone(prop, "prop should not be None")
def init_model(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i" "tests/pynusmv/models/admin.smv") self.assertEqual(ret, 0, "cannot read the model") ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0, "cannot build the model") propDb = glob.prop_database() master = propDb.master fsm = propDb.master.bddFsm return fsm
def test_check_invar_een_sorensson(self): for prop in prop_database(): # consistency of fname and dump type with self.assertRaises(ValueError): invarspec.check_invar_een_sorensson(prop, 2, fname_template="coucou") with self.assertRaises(ValueError): invarspec.check_invar_een_sorensson(prop, 2, dump_type=DumpType.DIMACS) # with self.assertRaises(ValueError): invarspec.check_invar_een_sorensson(prop,-1) invarspec.check_invar_een_sorensson(prop, 2)
def test_decorate(self): for prop in glob.prop_database(): # can decorate a property dec = Wff.decorate(prop.exprcore) self.assertEqual(str(dec), str(prop.exprcore)) # can decorate a plain node x = self.enc.by_name["x"] _x = Wff.decorate(x.name) self.assertEqual("x", str(_x)) # combination possible between plain nodes and specs self.assertEqual(str(dec | _x), '('+str(prop.exprcore)+" | x)")
def test_generate_base_step(self): # BASE STEP = (I0 -> P0 ) for prop in prop_database(): expr = utils.make_nnf_boolean_wff(prop.expr) gen = invarspec.generate_base_step(self.fsm, expr) # model = BmcModel() i0 = model.init[0] & model.invar[0] # recall: the prop has to be shifted to time 0 p0 = self.fsm.encoding.shift_to_time(expr.to_be(self.fsm.encoding), 0) manual= i0.imply(p0) self.assertEqual(gen.to_cnf().vars_list, manual.to_cnf().vars_list)
def test_check_ltl_incrementally(self): for prop in prop_database(): # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.check_ltl_incrementally(prop, bound=-1) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.check_ltl_incrementally(prop, bound=5, loop=6) ######### Verified manually (because of the E2E nature) ########### # it can perform simple end to end verification ltlspec.check_ltl_incrementally(prop) # it can perform verif for one single problem ltlspec.check_ltl_incrementally(prop, one_problem=True)
def test_generate_inductive_step(self): # INDUCT = (P0 and R01) -> P1 for prop in prop_database(): expr = utils.make_nnf_boolean_wff(prop.expr) gen = invarspec.generate_inductive_step(self.fsm, expr) # model = BmcModel() r01 = model.unrolling(0, 1) # recall: the prop has to be shifted to time 0 p = expr.to_be(self.fsm.encoding) p0 = self.fsm.encoding.shift_to_time(p, 0) p1 = self.fsm.encoding.shift_to_time(p, 1) manual= (p0 & r01).imply(p1) self.assertEqual(gen.to_cnf().vars_list, manual.to_cnf().vars_list)
def test_precedences(self): ret = cmd.Cmd_SecureCommandExecute("read_model -i" " tests/pynusmv/models/admin.smv") self.assertEqual(ret, 0) ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0) propDb = glob.prop_database() self.assertTrue(len(propDb) >= 2) prop = propDb[1] spec = prop.exprcore.cdr # Ignoring NULL context self.assertEqual(spec.type, nsparser.AND) self.assertEqual(spec.car.type, nsparser.EF) self.assertEqual(spec.cdr.type, nsparser.EF)
def test_change_trans_of_flat(self): glob.load(*self.counters()) glob.flatten_hierarchy() flat = glob.flat_hierarchy() self.assertIsNotNone(flat) trans = flat.trans choose_run = node.Expression.from_string("run = rc1") flat.trans = flat.trans & choose_run glob.compute_model() fsm = glob.prop_database().master.bddFsm self.assertEqual(fsm.count_states(fsm.reachable_states), 3)
def test_check_violated_spec(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i " "tests/tools/tlace/admin.smv") self.assertEqual(ret, 0, "cannot read the model") ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0, "cannot build the model") propDb = glob.prop_database() master = propDb.master fsm = propDb.master.bddFsm self.assertTrue(propDb.get_size() >= 1, "propDb has no properties") prop = propDb.get_prop_at_index(0) spec = prop.exprcore res = check(fsm, spec) self.assertFalse(res[0], "spec should be violated") self.assertIsNotNone(res[1], "TLACE should be given")
def test_mc(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i" " tests/pynusmv/models/admin.smv") self.assertEqual(ret, 0) ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0) ret = {"(EF admin = alice -> AG (admin != none -> admin = alice))": False, "(EF admin = alice & EF admin = bob)": True} propDb = glob.prop_database() fsm = propDb.master.bddFsm for p in propDb: if p.type == prop.propTypes["CTL"]: spec = p.expr self.assertEqual(mc.check_ctl_spec(fsm, spec), ret[str(spec)])
def test_check_satisfied_spec(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i" "tests/tools/tlace/admin.smv") self.assertEqual(ret, 0, "cannot read the model") ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0, "cannot build the model") propDb = glob.prop_database() master = propDb.master fsm = propDb.master.bddFsm self.assertTrue(propDb.get_size() >= 3, "propDb misses some props") prop = propDb.get_prop_at_index(2) self.assertIsNotNone(prop, "prop should not be None") spec = prop.exprcore res = check(fsm, spec) self.assertTrue(res[0], "spec should be satisfied") self.assertIsNone(res[1], "TLACE should not exist")
def test_elements(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i" "tests/pynusmv/models/admin.smv") self.assertEqual(ret, 0, "cannot read the model") ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0, "cannot build the model") propDb = glob.prop_database() master = propDb.master fsm = propDb.master.bddFsm init = fsm.init ln = BDDList.from_tuple((init, BDD.true(init._manager), init)) self.assertEqual(len(ln), 3) self.assertSequenceEqual((init, BDD.true(init._manager), init), ln.to_tuple()) del ln
def test_print_violated_spec_admin_ax(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i " "tests/tools/tlace/admin.smv") self.assertEqual(ret, 0, "cannot read the model") ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0, "cannot build the model") propDb = glob.prop_database() master = propDb.master fsm = propDb.master.bddFsm self.assertTrue(len(propDb) >= 6, "propDb has no properties") prop = propDb[5] spec = prop.exprcore res = check(fsm, spec) self.assertFalse(res[0], "spec should be violated") self.assertIsNotNone(res[1], "TLACE should be given") print(xml_representation(fsm, res[1], spec))
def test_check_ltl(self): for prop in prop_database(): # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.check_ltl(prop, bound=-1) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.check_ltl(prop, bound=5, loop=6) # it must raise exception when dump_type and fname_template are not # consistent with self.assertRaises(ValueError): ltlspec.check_ltl(prop, dump_type=DumpType.DIMACS) with self.assertRaises(ValueError): ltlspec.check_ltl(prop, fname_template="should_fail") ######### Verified manually (because of the E2E nature) ########### # it can perform simple end to end verification ltlspec.check_ltl(prop) # it can perform verif for one single problem ltlspec.check_ltl(prop, one_problem=True) # it can do everything but solving the problem ltlspec.check_ltl(prop, solve=False)
def process(allargs): """ Process program arguments and dump the model. Write on standard output the DOT format of the dumped model. allargs -- a sys.args-like arguments list, without script name. """ # Parse arguments parser = argparse.ArgumentParser(description="SMV model DOT dumper.") # Populate arguments: for now, only the model parser.add_argument("model", help="the SMV model") args = parser.parse_args(allargs) # Initialize the model glob.load_from_file(args.model) glob.compute_model() fsm = glob.prop_database().master.bddFsm try: print(dumpDot(fsm)) except PyNuSMVError as e: print("[ERROR]", str(e), file=sys.stderr)
def check_and_explain(allargs): """ Check specs on the given NuSMV model and compute TLACEs when needed. Build the model from a given file, check every CTL spec in it and compute and store TLACEs when needed. allargs -- a sys.args-like arguments list, without script name. """ # Parse arguments parser = argparse.ArgumentParser(description='CTL model checker ' 'with TLACE generation.') # Populate arguments: for now, only the model parser.add_argument('model', help='the NuSMV model with specifications') args = parser.parse_args(allargs) # Initialize the model fsm = BddFsm.from_filename(args.model) propDb = glob.prop_database() # Check all CTL properties for prop in propDb: # Check type if prop.type == propTypes['CTL']: spec = prop.exprcore (satisfied, cntex) = check_ctl_spec(fsm, spec) # Print the result and the TLACE if any print('Specification',str(spec), 'is', str(satisfied), file=sys.stderr) if not satisfied: print(xml_representation(fsm, cntex, spec)) print()
def cli(model_path, query, order): """Solve QUERY that belongs to fragment CTLQx for model in MODEL_PATH.""" try: # Parse `query` and transform it in NNF. ast = negation_normal_form(parse_ctlq(query)) # Check that `query` belongs to fragment CTLQx. if not check_ctlqx(ast): click.echo("Error: {query} does not belong to CTLQx".format(query=query)) # Quit PyTLQ. sys.exit() # Initialize NuSMV. with init_nusmv(): # Load model from `model_path`. load(model_path) # Enable dynamic reordering of the variables. enable_dynamic_reordering() # Check if an order file is given. if order: # Build model with pre-calculated variable ordering. compute_model(variables_ordering=order) else: # Build model. compute_model() # Retrieve FSM of the model. fsm = prop_database().master.bddFsm # Solve `query` in `fsm`. solution = solve_ctlqx(fsm, ast) # Display solution. click.echo("Solution states:") if not solution: click.echo("No solution") # Quit PyTLQ. sys.exit() elif solution.is_false(): click.echo("False") # Quit PyTLQ. sys.exit() else: size = fsm.count_states(solution) if size > 100: if click.confirm( "The number of states is too large" " ({size}). Do you still want to print" " them?".format(size=size) ): pprint(bdd_to_set(fsm, solution)) else: pprint(bdd_to_set(fsm, solution)) # Ask for further manipulations. while True: command = click.prompt( "\nWhat do you want to do?" "\n 1. Project the solution on a" " subset of the variables" "\n 2. Simplify the solution according" " to Chan's approximate conjunctive" " decomposition" "\n 3. Quit PyTLQ" "\nYour choice", type=click.IntRange(1, 3), default=3, ) # Check if solution must be projected or simplified. if command == 1 or command == 2: # Gather more information. click.echo("") if command == 2: maximum = click.prompt( "Please enter the maximum" " number of variables that must" " appear in the conjuncts of" " the simplification", type=int, default=1, ) variables = click.prompt( "Please enter the list of" " variables of interest," " separated by commas", type=str, default="all the variables", ) # Format `variables`. if variables == "all the variables": variables = None else: variables = variables.replace(" ", "").split(",") if command == 1: # Project solution and display projection. click.echo("\nProjection:") click.echo(project(fsm, solution, variables)) else: # Simplify solution and display simplification. click.echo("\nApproximate conjunctive decomposition:") click.echo(simplify(fsm, solution, maximum, variables)) # No further manipulations are needed. else: break except Exception as error: click.echo("Error: {msg}".format(msg=error))
def model(self): glob.load_from_file("tests/pynusmv/models/inputs.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm self.assertIsNotNone(fsm) return fsm
def test_dump_dimacs_filename(self): for prop in prop_database(): expr = utils.make_nnf_boolean_wff(prop.expr) problem = invarspec.generate_invar_problem(self.fsm, expr) invarspec.dump_dimacs_filename(self.fsm.encoding, problem.to_cnf(), "testit")
def test_flat_command_allow_prop_db(self): glob.load_from_file("tests/pynusmv/models/counters.smv") ret = nscmd.Cmd_SecureCommandExecute("flatten_hierarchy") self.assertEqual(ret, 0) pd = glob.prop_database() self.assertIsNotNone(pd)
def test_no_prop_database(self): with self.assertRaises(NuSMVNeedFlatHierarchyError): glob.prop_database() with self.assertRaises(NuSMVNeedFlatHierarchyError): glob.load_from_file("tests/pynusmv/models/counters.smv") glob.prop_database()
def test_prop_database(self): glob.load_from_file("tests/pynusmv/models/counters.smv") glob.flatten_hierarchy() pd = glob.prop_database() self.assertIsNotNone(pd)