Example #1
0
 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())
Example #2
0
    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())
Example #3
0
 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))
Example #4
0
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))
Example #5
0
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()
Example #6
0
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))