def test_reordering(self): fsm, enc, manager = self.init_model() self.assertFalse(dynamic_reordering_enabled()) enable_dynamic_reordering() self.assertTrue(dynamic_reordering_enabled()) disable_dynamic_reordering() self.assertFalse(dynamic_reordering_enabled())
def test_dymanic_reordering(self): fsm = self.counters_model() bddEnc = fsm.bddEnc ddmanager = bddEnc.DDmanager enable_dynamic_reordering() enable_dynamic_reordering(ddmanager) self.assertTrue(dynamic_reordering_enabled(ddmanager)) reorder() disable_dynamic_reordering() disable_dynamic_reordering(ddmanager) self.assertFalse(dynamic_reordering_enabled(ddmanager))
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 main(): """ Process specs on the given NuSMV model. Build the model from a given file and check the given ATLK_irF specifiation. """ sys.setrecursionlimit(100000) # Parse arguments parser = argparse.ArgumentParser(description='ATLK_irF model checker.') # Populate arguments: # size of the model, property, variant parser.add_argument('-m', dest='model', help='the module to generate models ' '(an SMV text model, ' 'or a python module with a "model()" function, ' 'and an optional "agents()" function)', required=True) parser.add_argument('-p', dest='property', help='the property to check', required=True) parser.add_argument('-i', dest='implementation', help='the implementation to use ' '(naive, partial, early, symbolic, backward)' ' (default: naive)', default="naive") parser.add_argument('-pf', dest='filtering', help='activate pre-filtering (default: deactivated)', action='store_true', default=False) # Variables-order-related arguments parser.add_argument('-rbdd-order', dest="initial_ordering", help="specify an initial variables order file", default=None) parser.add_argument('-no-rbdd', dest="reordering", help='deactivate BDD variables reordering ' '(default: activated)', action='store_false', default=True) parser.add_argument('-rbdd-method', dest="reordering_method", help='choose BDD variables reordering method ' '(default: sift)', default="sift") args = parser.parse_args(sys.argv[1:]) check = lambda mas, formula: checkATLK(mas, formula, implementation=args.implementation, pre_filtering=args.filtering) # Check with tempfile.NamedTemporaryFile(suffix=".smv") as tmp: # Generate the model try: mod = importlib.import_module(args.model) tmp.write(mod.model().encode("UTF-8")) except ImportError: mod = None with open(args.model, "r") as f: tmp.write(f.read().encode("UTF-8")) tmp.flush() MODELFILE = tmp.name # Load the file in PyNuSMV with init_nusmv(): # Set dynamic reordering on if args.reordering: enable_dynamic_reordering(method=args.reordering_method) glob.load_from_file(MODELFILE) # Build the model if mod is not None and hasattr(mod, "agents"): agents = mod.agents() else: agents = None mas = glob.mas(agents=agents, initial_ordering=args.initial_ordering) # Check the property spec = parseATLK(args.property)[0] # Measure execution time and save it print(str(spec) + ' is ' + str(check(mas, spec))) # Close PyNuSMV glob.reset_globals()
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))