예제 #1
0
    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(semantics=UppaalCLanguageSemantics())
예제 #2
0
class Declaration(ASTCodeElement):
    """A declaration class.

    In the declaration, all functions, types and data variables used by the system are defined.
    """

    def __init__(self, decl_data):
        """Initializes Declaration.

        Args:
            decl_data: The declaration string or AST data.
        """
        super().__init__(decl_data)
        self._identify_clocks()

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

        Returns:
            None
        """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Declaration instance.

        Returns:
            The copied Declaration instance.
        """
        copy_decl = Declaration(copy.deepcopy(self.ast))
        return copy_decl

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='UppaalDeclaration', trace=False)

    def __str__(self):
        return f'Declaration(\n{self.text}\n)'

    def _identify_clocks(self):
        _, clocks = apply_func_to_ast(self.ast, _get_clock)
        self.clocks = clocks
예제 #3
0
class Reset(ASTCodeElement):
    """An edge clock reset class.

    Via a clock reset, a clock variable is re-assigned.
    """
    def __init__(self, rst_data, autom=None):
        """Initializes Reset.

        Args:
            rst_data: The edge clock reset string or AST data.
        """
        super().__init__(rst_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Reset instance.

        Returns:
            The copied Reset instance.
        """
        copy_reset = Reset(copy.deepcopy(self.ast))
        return copy_reset

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Update')

    def __str__(self):
        return f'Reset({self.text})'
예제 #4
0
class Update(ASTCodeElement):
    """An edge update class.

    Via an update, a non-clock variable is re-assigned.
    """
    def __init__(self, updt_data, autom=None):
        """Initializes Update.

        Args:
            updt_data: The edge update string or AST data.
        """
        super().__init__(updt_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Update instance.

        Returns:
            The copied Update instance.
        """
        copy_updt = Update(copy.deepcopy(self.ast))
        return copy_updt

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Update')

    def __str__(self):
        return f'Update({self.text})'
예제 #5
0
class Parameter(ASTCodeElement):
    """A template parameter class.

    The template parameters are used to assign individual values to the instance automata derived from a template.
    """
    def __init__(self, param_data, autom=None):
        """Initializes Parameter.

        Args:
            param_data: The parameter string or AST data.
        """
        super().__init__(param_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Parameter instance.

        Returns:
            The copied Parameter instance.
        """
        copy_param = Parameter(copy.deepcopy(self.ast))
        return copy_param

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Parameter')

    def __str__(self):
        return f'Parameter({self.text})'
예제 #6
0
class Invariant(ASTCodeElement):
    """A location invariant class.

    Via an invariant, a condition on a clock variable is enforced.
    """
    def __init__(self, inv_data, autom=None):
        """Initializes Invariant.

        Args:
            inv_data: The location invariant string or AST data.
        """
        super().__init__(inv_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Invariant instance.

        Returns:
            The copied Invariant instance.
        """
        copy_inv = Invariant(copy.deepcopy(self.ast))
        return copy_inv

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Invariant')

    def __str__(self):
        return f'Invariant({self.text})'
예제 #7
0
class Synchronization(ASTCodeElement):
    """An edge channel synchronization class.

    Via a channel synchronization, multiple edge can be synchronized and triggered simultaneously.
    """
    def __init__(self, sync_data, autom=None):
        """Initializes Synchronization.

        Args:
            sync_data: The edge channel synchronization string or AST data.
        """
        super().__init__(sync_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Synchronization instance.

        Returns:
            The copied Synchronization instance.
        """
        copy_sync = Synchronization(copy.deepcopy(self.ast))
        return copy_sync

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Sync')

    def __str__(self):
        return f'Sync({self.text})'
예제 #8
0
class Select(ASTCodeElement):
    """An edge select statement class.

    Via a select, a transition is split into individual transitions for each possible select value assignment.
    """

    def __init__(self, sel_data, autom=None):
        """Initializes Select.

        Args:
            sel_data: The edge select statement string or AST data.
        """
        super().__init__(sel_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the Select instance.

        Returns:
            The copied Select instance.
        """
        copy_sync = Select(copy.deepcopy(self.ast))
        return copy_sync

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Select')

    def __str__(self):
        return f'Select({self.text})'
예제 #9
0
class ClockGuard(ASTCodeElement):
    """An edge variable guard class.

    Via a clock guard, a condition on a clock variable is enforced.
    """
    def __init__(self, grd_data, autom=None):
        """Initializes ClockGuard.

        Args:
            grd_data: The edge clock guard string or AST data.
        """
        super().__init__(grd_data)
        self.autom = autom

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

         Returns:
             None
         """
        self.printer = UppaalCPrinter()

    def copy(self):
        """Copies the ClockGuard instance.

        Returns:
            The copied ClockGuard instance.
        """
        copy_grd = ClockGuard(copy.deepcopy(self.ast))
        return copy_grd

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text, rule_name='Guard')

    def __str__(self):
        return f'ClockGuard({self.text})'
예제 #10
0
class QueryFormula(ASTCodeElement):
    """A representation of Uppaal query formula."""
    def __init__(self, formula_data):
        """Initializes QueryFormula.

        Args:
            formula_data: The formula data string or AST dict.
        """
        super().__init__(formula_data)

    def init_parser(self):
        """Initializes the AST code parser.

        Returns:
            None
        """
        self.parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())

    def init_printer(self):
        """Initializes the AST code printer.

        Returns:
            None
        """
        self.printer = UppaalQueryPrinter()

    def copy(self):
        """Copies the QueryFormula instance.

        Returns:
            The copied QueryFormula instance.
        """
        copy_query = QueryFormula(copy.deepcopy(self.ast))
        return copy_query

    def update_ast(self):
        """Updates the AST dict from the AST text string.

        Returns:
            None
        """
        self.ast = self.parser.parse(self.text,
                                     rule_name='UppaalProp',
                                     trace=False)

    def __str__(self):
        return f'QueryFormula(\n{self.text}\n)'
예제 #11
0
    def __init__(self):
        """Initializes UppaalSimulator."""
        self.init_system_state = None
        self.system_state = None
        self.transitions = None
        self.recent_transition = None

        self.transition_trace = []
        self.dbm_op_sequence = DBMOperationSequence()
        self.transition_counts = {
            "potential": None,
            "enabled": None,
            "valid": None
        }

        self.system = None

        self.c_language_parser = UppaalCLanguageParser(
            semantics=UppaalCLanguageSemantics())
        self.c_evaluator = UppaalCEvaluator(do_log_details=False)
예제 #12
0
def uppaal_dict_to_system(system_data):
    """Transforms the data dictionary of a Uppaal system into a system object.

    Args:
        system_data: The Uppaal system data dictionary.

    Returns:
        The Uppaal system object.
    """

    system = nta.System()
    uppaal_c_parser = UppaalCLanguageParser(
        semantics=UppaalCLanguageSemantics())

    system.set_declaration(system_data["global_declaration"])
    system.set_system_declaration(system_data["system_declaration"])

    ###################
    # Parse templates #
    ###################
    for template_data in system_data["templates"]:
        id_ = template_data["id"] if ("id" in template_data) else None
        name = template_data["name"] if ("name" in template_data) else ""

        template = system.new_template(name, id_)

        if template_data["parameters"] != "":
            parameter_asts = uppaal_c_parser.parse(template_data["parameters"],
                                                   rule_name='Parameters')
            for parameter_ast in parameter_asts:
                template.new_parameter(parameter_ast)

        template.set_declaration(template_data["declaration"])

        # Clock check function
        template_scope_clocks = system.declaration.clocks + template.declaration.clocks

        def get_clocks(ast,
                       acc):  # TODO: Handle clocks among template parameters
            """Adds the ast to acc if it is a clock variable.

            Args:
                ast: The AST dict.
                acc: A list of values accumulated during search.

            Returns:
                The original AST dict.
            """
            if ast["astType"] == "Variable":
                if ast["name"] in template_scope_clocks:
                    acc.append(ast["name"])
            return ast

        ###################
        # Parse locations #
        ###################
        for location_data in template_data["locations"]:
            id_ = location_data["id"] if ("id" in location_data) else ""
            name = location_data["name"] if ("name" in location_data) else ""

            location = template.new_location(name, id_)
            location.view["self"] = {"pos": location_data["pos"].copy()}

            if location_data["name_label"]:
                location.view["name_label"] = location_data["name_label"].copy(
                )

            if location_data["invariant"]:
                invariants = uppaal_c_parser.parse(location_data["invariant"],
                                                   rule_name='Invariants')
                for inv in invariants:
                    location.new_invariant(inv)
            if location_data["invariant_label"]:
                location.view["invariant_label"] = location_data[
                    "invariant_label"].copy()

            if location_data["urgent"]:
                location.set_urgent(True)

            if location_data["committed"]:
                location.set_committed(True)

        # Parse initial location
        template.set_init_location_by_id(template_data["init_loc_id"])

        ###############
        # Parse edges #
        ###############
        for edge_data in template_data["edges"]:
            id_ = edge_data["id"] if ("id" in edge_data) else ""
            source_loc_id = edge_data["source_loc_id"]
            target_loc_id = edge_data["target_loc_id"]

            edge = template.new_edge_by_loc_ids(source_loc_id, target_loc_id,
                                                id_)

            # Add guards
            if edge_data["guard"]:
                guards = uppaal_c_parser.parse(edge_data["guard"],
                                               rule_name='Guards')
                for guard in guards:
                    if len(apply_func_to_ast(guard, get_clocks)[1]) > 0:
                        edge.new_clock_guard(guard)
                    else:
                        edge.new_variable_guard(guard)
            if edge_data["guard_label"]:
                edge.view["guard_label"] = edge_data["guard_label"].copy()

            # Add updates
            if edge_data["update"]:
                updates = uppaal_c_parser.parse(edge_data["update"],
                                                rule_name='Updates')
                for update in updates:
                    if len(apply_func_to_ast(update, get_clocks)[1]) > 0:
                        edge.new_reset(update)
                    else:
                        edge.new_update(update)
            if edge_data["update_label"]:
                edge.view["update_label"] = edge_data["update_label"].copy()

            # Add synchronization
            if edge_data["synchronisation"]:
                edge.set_sync(edge_data["synchronisation"])
            if edge_data["sync_label"]:
                edge.view["sync_label"] = edge_data["sync_label"].copy()

            # Add selects
            if edge_data["select"]:
                edge.new_select(edge_data["select"])
            if edge_data["select_label"]:
                edge.view["select_label"] = edge_data["select_label"].copy()

            edge.view["nails"] = deepcopy(edge_data["nails"])

    #################
    # Parse queries #
    #################
    for query_data in system_data["queries"]:
        formula = query_data["formula"]
        comment = query_data["comment"]
        query = Query(formula, comment)
        system.add_query(query)

    # # print(json.dumps(system, indent=2))
    return system
예제 #13
0
def parser():
    return UppaalCLanguageParser(semantics=UppaalCLanguageSemantics())