def test_mc_ltl_true(self): # Initialize the model glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm spec = prop.Spec(parser.parse_ltl_spec("G admin = none")) self.assertEqual(mc.check_ltl_spec(spec), False)
def test_ex(self): glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm alice = mc.eval_simple_expression(fsm, "admin = alice") spec = prop.Spec(parser.parse_ctl_spec("EX admin = alice")) exalice = mc.eval_ctl_spec(fsm, spec) self.assertEqual(mc.ex(fsm, alice), exalice)
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_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_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_au(self): glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm none = mc.eval_simple_expression(fsm, "admin = none") alice = mc.eval_simple_expression(fsm, "admin = alice") spec = prop.Spec( parser.parse_ctl_spec("A[admin = none U admin = alice]")) aunonealice = mc.eval_ctl_spec(fsm, spec) self.assertEqual(mc.au(fsm, none, alice), aunonealice)
def test_mc_explain_ltl_true(self): # Initialize the model glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() spec = prop.Spec( parser.parse_ltl_spec("(F admin = alice) | (F admin = bob)")) result, explanation = mc.check_explain_ltl_spec(spec) self.assertTrue(result) self.assertIsNone(explanation)
def test_get_mod_instance_type(self): glob.load_from_file("tests/pynusmv/models/counters.smv") glob.compute_model() sexp = parse_simple_expression("c1") self.assertIsNotNone(sexp) st = glob.symb_table() tp = nssymb_table.SymbTable_get_type_checker(st._ptr) expr_type = nstype_checking.TypeChecker_get_expression_type( tp, sexp, None) self.assertTrue(nssymb_table.SymbType_is_error(expr_type))
def test_eg(self): glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm alice = mc.eval_simple_expression(fsm, "admin = alice") spec = prop.Spec(parser.parse_ctl_spec("EG admin = alice")) egalice = mc.eval_ctl_spec(fsm, spec) self.assertEqual(mc.eg(fsm, alice), egalice) self.assertEqual( egalice, fixpoint(lambda Z: alice & fsm.pre(Z), BDD.true()) & fsm.reachable_states)
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_mc_explain_ltl_false(self): # Initialize the model glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() spec = prop.Spec(parser.parse_ltl_spec("G admin = none")) result, explanation = mc.check_explain_ltl_spec(spec) self.assertFalse(result) self.assertIsNotNone(explanation) #print(explanation[0]) #for inputs, state in zip(explanation[1::2], explanation[2::2]): # print(inputs) # print(state) self.assertTrue( any(state["admin"] != "none" for state in explanation[::2]))
def test_access_flat_hierarchy(self): glob.load(*self.counters()) glob.compute_model() flat = glob.flat_hierarchy() symb_table = glob.symb_table() self.assertIsNotNone(flat.init) self.assertIsNotNone(flat.trans) self.assertIsNone(flat.invar) self.assertIsNone(flat.justice) self.assertIsNone(flat.compassion) variables = flat.variables for variable in variables: var_type = symb_table.get_variable_type(variable) self.assertEqual(nssymb_table.SymbType_get_tag(var_type), nssymb_table.SYMB_TYPE_ENUM)
def run_model_in_nusmv(filename, get_path=False): init_nusmv() load_from_file(filename) compute_model(keep_single_enum=True) fsm = prop_database().master.bddFsm propDb = prop_database() for prop in propDb: spec = prop.expr status = check_ctl_spec( fsm, spec) if prop.type == propTypes['CTL'] else check_ltl_spec(spec) if status is False: print('Specification', str(spec), 'is', str(status)) if get_path: explanation = explain(fsm, fsm.init, spec) print_specification_explanation(explanation) deinit_nusmv()
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 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 test_no_compute_model(self): with self.assertRaises(NuSMVNoReadModelError): glob.compute_model()
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 test_fsm(self): glob.load_from_file("tests/tools/ctlk/dining-crypto.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm self.assertIsNotNone(fsm)
def load_admin_model(self): glob.load("tests/pynusmv/models/admin.smv") glob.compute_model()
def print_instances(self, filepath): print("----- Instances for", filepath) car = nsnode.car cdr = nsnode.cdr glob.load_from_file(filepath) # Get parsed tree tree = nsparser.cvar.parsed_tree print("--- Main instances") # main module is car(tree) main_vars = self.get_instances_for_module(car(tree)) instances_args = {} for var in main_vars: # var = COLON(ATOM, MODTYPE(ATOM, CONS)) varname = nsnode.sprint_node(car(var)) instances_args[varname] = [] args = cdr(cdr(var)) argslist = [] while args is not None: arg = car(args) instances_args[varname].append(arg) argslist.append(nsnode.sprint_node(arg)) args = cdr(args) print(varname, ":", nsnode.sprint_node(car(cdr(var))), argslist) # Get FSM and stuff glob.compute_model() fsm = glob.prop_database().master.bddFsm self.assertIsNotNone(fsm) flatH = nscompile.cvar.mainFlatHierarchy st = nscompile.Compile_get_global_symb_table() self.assertIsNotNone(flatH) print("--- Check arguments instances") for instance in instances_args: print("INSTANCE", instance) for arg in instances_args[instance]: arg, err = nscompile.FlattenSexp(st, arg, None) self.assertEqual(err, 0) isVar = nssymb_table.SymbTable_is_symbol_var(st, arg) if isVar: print("VAR", nsnode.sprint_node(arg)) else: print("NOT VAR", nsnode.sprint_node(arg)) print("--- All vars") varset = nscompile.FlatHierarchy_get_vars(flatH) self.assertIsNotNone(varset) varlist = nsset.Set_Set2List(varset) self.assertIsNotNone(varlist) ite = nsutils.NodeList_get_first_iter(varlist) while not nsutils.ListIter_is_end(ite): var = nsutils.NodeList_get_elem_at(varlist, ite) isInput = nssymb_table.SymbTable_is_symbol_input_var(st, var) isVar = nssymb_table.SymbTable_is_symbol_var(st, var) if isInput: print("IVAR", "\t", "IN", "'" + nsnode.sprint_node(car(var)) + "'", "\t", nsnode.sprint_node(var)) elif isVar: print("VAR", "\t", "IN", "'" + nsnode.sprint_node(car(var)) + "'", "\t", nsnode.sprint_node(var)) else: print("[ERROR] Unknown type:", nsnode.sprint_node(var)) ite = nsutils.ListIter_get_next(ite) print("------------------------------------------------------")
def test_cdr(self): glob.load(*self.counters()) glob.compute_model() spec = node.Node.from_ptr(parse_ctl_spec("A [x U y]")) self.assertEqual(type(spec.cdr), node.Atom) self.assertEqual(str(spec.cdr), "y")
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_compute_model(self): glob.load_from_file("tests/pynusmv/models/counters.smv") glob.compute_model()
def test_init_deinit_stats(self): init_nusmv() glob.load_from_file("tests/pynusmv/models/counters.smv") glob.compute_model() deinit_nusmv(ddinfo=True) self.assertFalse(is_nusmv_init())
def test_get_flat_hierarchy(self): with self.assertRaises(NuSMVNeedFlatHierarchyError): flat = glob.flat_hierarchy() glob.load_from_file("tests/pynusmv/models/counters.smv") glob.compute_model() flat = glob.flat_hierarchy()
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 inputs_model(self): glob.load_from_file("tests/pynusmv/models/inputs.smv") glob.compute_model() return glob.prop_database().master.bddFsm