Exemple #1
0
    def _get_wrapped_prev_expr(self, proc_index, sys_states_vector,
                               value_by_sched: dict) -> str:
        assert self.nof_processes > 1, 'nonsense'

        prev_proc = (proc_index - 1) % self.nof_processes

        prev_proc_state = sys_states_vector[prev_proc]

        #: :type: QuantifiedSignal
        sends_signal = _filter_by_proc(prev_proc, self._sends_signals)[0]
        #: :type: FuncDescription
        sends_func_desc = self.outvar_desc_by_process[prev_proc][sends_signal]

        sends_prev_call = self.underlying_solver.call_func(
            sends_func_desc, {self.state_arg_name: prev_proc_state})

        prev_is_sched_func = self._get_desc_prev_next_is_sched(True)

        curr_proc_index_label = self._build_label_from_proc_index(proc_index)
        prev_is_sched_args = add_dicts(value_by_sched, curr_proc_index_label)

        prev_is_sched_expr = self.underlying_solver.call_func(
            prev_is_sched_func, prev_is_sched_args)

        expr = self.underlying_solver.op_and(
            [sends_prev_call, prev_is_sched_expr])

        return expr
Exemple #2
0
    def _get_wrapped_prev_expr(self, proc_index, sys_states_vector, value_by_sched:dict) -> str:
        assert self.nof_processes > 1, 'nonsense'

        prev_proc = (proc_index - 1) % self.nof_processes

        prev_proc_state = sys_states_vector[prev_proc]

        #: :type: QuantifiedSignal
        sends_signal = _filter_by_proc(prev_proc, self._sends_signals)[0]
        #: :type: FuncDescription
        sends_func_desc = self.outvar_desc_by_process[prev_proc][sends_signal]

        sends_prev_call = self.underlying_solver.call_func(sends_func_desc,
                                                            {self.state_arg_name:prev_proc_state})

        prev_is_sched_func = self._get_desc_prev_next_is_sched(True)

        curr_proc_index_label = self._build_label_from_proc_index(proc_index)
        prev_is_sched_args = add_dicts(value_by_sched, curr_proc_index_label)

        prev_is_sched_expr = self.underlying_solver.call_func(prev_is_sched_func,
                                                               prev_is_sched_args)

        expr = self.underlying_solver.op_and([sends_prev_call, prev_is_sched_expr])

        return expr
Exemple #3
0
    def get_architecture_trans_assumption(self, label,
                                          sys_state_vector) -> str:
        """ It handles 'is_active' and 'tok' variables in the specification. """

        #TODO: here I can add G(tok -> !prev) for the hub abstraction instead of specifying this on LTL level

        active_signals = list(
            filter(lambda s: s in label, self._is_active_signals))
        assert len(active_signals
                   ) <= 1, 'spec cannot contain > 1 is_active as conjunction'

        index_of_prev = index_of(lambda s: s in label,
                                 self._sends_prev_signals)
        assert index_of_prev is None or self.nof_processes == 1, \
            'using prev in the spec is not supported; prev in async hub abstraction works with local properties only'

        if not active_signals and not index_of_prev:
            return ''

        if active_signals:
            #: :type: QuantifiedSignal
            active = active_signals[0]
            proc_index = active.binding_indices[0]
        else:
            proc_index = self._sends_prev_signals[
                index_of_prev].binding_indices[0]
            assert self.nof_processes == 1, 'should come here only in the case of async hub'

        sends_prev_signal = _filter_by_proc(proc_index,
                                            self._sends_prev_signals)[0]

        value_by_sched, _ = build_signals_values(self._sched_signals, label)

        if self.nof_processes > 1:
            sends_prev_value = self._get_wrapped_prev_expr(
                proc_index, sys_state_vector, value_by_sched)
        else:
            #async_hub
            value_by_signal, _ = build_signals_values([sends_prev_signal],
                                                      label)
            sends_prev_value = value_by_signal[sends_prev_signal]

        if not active_signals:
            return sends_prev_value

        value_by_proc = self._build_label_from_proc_index(proc_index)

        value_by_signal = add_dicts(
            value_by_sched, value_by_proc,
            {sends_prev_signal: sends_prev_value},
            {self.state_arg_name: sys_state_vector[proc_index]})

        is_active_func_desc = self._get_desc_is_active(proc_index)

        func = self.underlying_solver.call_func(is_active_func_desc,
                                                value_by_signal)

        return func
Exemple #4
0
def _build_srcdst_to_io_labels(lts:LTS, outvars_treated_as_moore) -> dict:
    srcdst_to_io_labels = dict()
    for label, next_state in lts.tau_model.items():
        crt_state = label['state']

        i_label = _get_inputvals(label)
        o_label = _get_outputvals(label, lts, outvars_treated_as_moore)

        io_label = add_dicts(i_label, o_label)

        srcdst_to_io_labels[(crt_state, next_state)] = srcdst_to_io_labels.get((crt_state, next_state), list())
        srcdst_to_io_labels[(crt_state, next_state)].append(io_label)
    return srcdst_to_io_labels
Exemple #5
0
def _build_edge_labels(lts:LTS, state_variable, moore_signals) -> dict:
    edge_labels = dict()
    for label, next_state in lts.tau_model.items():  # TODO: bad: it assumes that label enumerates ALL possible values!
        crt_state = label[state_variable]

        i_label = _get_i_label(label, state_variable)
        o_label = _get_o_label(label, lts, moore_signals)

        io_label = add_dicts(i_label, o_label)

        edge_labels[(crt_state, next_state)] = edge_labels.get((crt_state, next_state), list())
        edge_labels[(crt_state, next_state)].append(io_label)
    return edge_labels
Exemple #6
0
    def get_architecture_trans_assumption(self, label, sys_state_vector) -> str:
        """ It handles 'is_active' and 'tok' variables in the specification. """

        #TODO: here I can add G(tok -> !prev) for the hub abstraction instead of specifying this on LTL level

        active_signals = list(filter(lambda s: s in label, self._is_active_signals))
        assert len(active_signals) <= 1, 'spec cannot contain > 1 is_active as conjunction'

        index_of_prev = index_of(lambda s: s in label, self._sends_prev_signals)
        assert index_of_prev is None or self.nof_processes == 1, \
            'using prev in the spec is not supported; prev in async hub abstraction works with local properties only'

        if not active_signals and not index_of_prev:
            return ''

        if active_signals:
            #: :type: QuantifiedSignal
            active = active_signals[0]
            proc_index = active.binding_indices[0]
        else:
            proc_index = self._sends_prev_signals[index_of_prev].binding_indices[0]
            assert self.nof_processes == 1, 'should come here only in the case of async hub'

        sends_prev_signal = _filter_by_proc(proc_index, self._sends_prev_signals)[0]

        value_by_sched, _ = build_signals_values(self._sched_signals, label)

        if self.nof_processes > 1:
            sends_prev_value = self._get_wrapped_prev_expr(proc_index,
                                                           sys_state_vector,
                                                           value_by_sched)
        else:
            #async_hub
            value_by_signal, _ = build_signals_values([sends_prev_signal], label)
            sends_prev_value = value_by_signal[sends_prev_signal]

        if not active_signals:
            return sends_prev_value

        value_by_proc = self._build_label_from_proc_index(proc_index)

        value_by_signal = add_dicts(value_by_sched,
                                    value_by_proc,
                                    {sends_prev_signal: sends_prev_value},
                                    {self.state_arg_name:sys_state_vector[proc_index]})

        is_active_func_desc = self._get_desc_is_active(proc_index)

        func = self.underlying_solver.call_func(is_active_func_desc, value_by_signal)

        return func
Exemple #7
0
def _build_edge_labels(lts: LTS, state_variable, moore_signals) -> dict:
    edge_labels = dict()
    for label, next_state in lts.tau_model.items(
    ):  # TODO: bad: it assumes that label enumerates ALL possible values!
        crt_state = label[state_variable]

        i_label = _get_i_label(label, state_variable)
        o_label = _get_o_label(label, lts, moore_signals)

        io_label = add_dicts(i_label, o_label)

        edge_labels[(crt_state, next_state)] = edge_labels.get(
            (crt_state, next_state), list())
        edge_labels[(crt_state, next_state)].append(io_label)
    return edge_labels
Exemple #8
0
    def _get_tok_rings_safety_props(self) -> StrAwareList:  # TODO: should be able to specify states!
        """
        Return (in SMT form, constraints on non-wrapped tau function):
         G(tok & !sends -> Xtok(tau(!prev)))
         G(sends -> tok)
         G(sends -> X!tok(!prev))
         G(Xtok(prev))
         G(!tok -> !Xtok(!prev))
        """
        smt_lines = StrAwareList()

        tau_desc = self.taus_descs[0]
        tau_signals = self.orig_inputs[0]

        tok_func_desc = self.outvar_desc_by_process[0][self._has_tok_signal]
        sends_func_desc = self.outvar_desc_by_process[0][self._sends_signal]

        prev_is_false_label = Label({self._sends_prev_signal: False})
        prev_is_true_label = Label({self._sends_prev_signal: True})

        states = self.states_by_process[0]
        for state in states:
            state_arg = {self.state_arg_name: state}

            has_tok_expr = call_func(tok_func_desc, state_arg)
            sends_tok_expr = call_func(sends_func_desc, state_arg)

            _, free_vars = build_signals_values(tau_signals, prev_is_false_label)

            nprev_arg, _ = build_signals_values(tau_signals, prev_is_false_label)
            nprev_state_arg = add_dicts(nprev_arg, state_arg)

            prev_arg, _ = build_signals_values(tau_signals, prev_is_true_label)
            prev_state_arg = add_dicts(prev_arg, state_arg)

            tau_nprev_expr = call_func(tau_desc, nprev_state_arg)
            tok_of_tau_nprev_expr = call_func(tok_func_desc, {self.state_arg_name: tau_nprev_expr})

            tau_prev_expr = call_func(tau_desc, prev_state_arg)
            tok_of_tau_prev_expr = call_func(tok_func_desc, {self.state_arg_name: tau_prev_expr})

            #
            tok_dont_disappear = forall_bool(free_vars,
                                             op_implies(op_and([has_tok_expr, op_not(sends_tok_expr)]),
                                                        tok_of_tau_nprev_expr))

            sends_with_token_only = forall_bool(free_vars,
                                                op_implies(sends_tok_expr, has_tok_expr))

            sends_means_release = forall_bool(free_vars,
                                              op_implies(sends_tok_expr, op_not(tok_of_tau_nprev_expr)))

            sends_prev_means_acquire = forall_bool(free_vars,
                                                   tok_of_tau_prev_expr)

            no_sends_prev_no_tok_means_no_next_tok = forall_bool(free_vars,
                                                                 op_implies(op_not(has_tok_expr),
                                                                            op_not(tok_of_tau_nprev_expr)))

            smt_lines += [tok_dont_disappear,
                          sends_with_token_only,
                          sends_means_release,
                          sends_prev_means_acquire,
                          no_sends_prev_no_tok_means_no_next_tok]

        return smt_lines
PAR_INPUT_VARIABLES = 'INPUT_VARIABLES'
PAR_OUTPUT_VARIABLES = 'OUTPUT_VARIABLES'
PAR_ASSUMPTIONS = 'ASSUMPTIONS'
PAR_GUARANTEES = 'GUARANTEES'

PAR_GENERAL_TEMPLATE_COUNT = "templates"


PAR_SECTIONS = (PAR_GENERAL, PAR_INPUT_VARIABLES, PAR_OUTPUT_VARIABLES, PAR_ASSUMPTIONS, PAR_GUARANTEES)

#reserved words: syntactic sugar to help to match exactly reserved word
reserved_section_names = dict((s, s) for s in PAR_SECTIONS)
reserved_bools = dict((s, s) for s in ('TRUE', 'FALSE'))
reserved_quantifiers = {'Forall': 'QUANTIFIER'}

reserved_all = add_dicts(reserved_bools, reserved_quantifiers, reserved_section_names)

#states = (
#    ('quantified', 'inclusive'),
#)

tokens = ['COMMA', 'SIGNAL_NAME', 'NUMBER', 'BOOL',
          'TEMPORAL_UNARY', 'NEG', 'TEMPORAL_BINARY',
          'OR', 'AND', 'IMPLIES', 'EQUIV', 'EQUALS',
          'LPAREN', 'RPAREN', 'LBRACKET', 'RBRACKET',
          'SEP'
         ] +\
         list(reserved_section_names.values()) + \
         list(set(reserved_quantifiers.values()))
#             list(reserved_bools.values()) #i use BOOL currently
Exemple #10
0
from helpers.python_ext import add_dicts

PAR_INPUT_VARIABLES = 'INPUT_VARIABLES'
PAR_OUTPUT_VARIABLES = 'OUTPUT_VARIABLES'
PAR_ASSUMPTIONS = 'ASSUMPTIONS'
PAR_GUARANTEES = 'GUARANTEES'

PAR_SECTIONS = (PAR_INPUT_VARIABLES, PAR_OUTPUT_VARIABLES, PAR_ASSUMPTIONS, PAR_GUARANTEES)

#reserved words: syntactic sugar to help to match exactly reserved word
reserved_section_names = dict((s, s) for s in PAR_SECTIONS)
reserved_bools = dict((s, s) for s in ('TRUE', 'FALSE'))
reserved_quantifiers = {'Forall': 'QUANTIFIER'}

reserved_all = add_dicts(reserved_bools, reserved_quantifiers, reserved_section_names)

#states = (
#    ('quantified', 'inclusive'),
#)

tokens = ['COMMA', 'SIGNAL_NAME', 'NUMBER', 'BOOL',
          'TEMPORAL_UNARY', 'NEG', 'TEMPORAL_BINARY',
          'OR', 'AND', 'IMPLIES', 'EQUIV', 'EQUALS',
          'LPAREN', 'RPAREN', 'LBRACKET', 'RBRACKET',
          'SEP'
         ] +\
         list(reserved_section_names.values()) + \
         list(set(reserved_quantifiers.values()))
#             list(reserved_bools.values()) #i use BOOL currently

#constant to ensure consistency of the code
Exemple #11
0
    def _get_tok_rings_safety_props(
            self) -> StrAwareList:  # TODO: should be able to specify states!
        """
        Return (in SMT form, constraints on non-wrapped tau function):
         G(tok & !sends -> Xtok(tau(!prev)))
         G(sends -> tok)
         G(sends -> X!tok(!prev))
         G(Xtok(prev))
         G(!tok -> !Xtok(!prev))
        """
        smt_lines = StrAwareList()

        tau_desc = self.taus_descs[0]
        tau_signals = self.orig_inputs[0]

        tok_func_desc = self.outvar_desc_by_process[0][self._has_tok_signal]
        sends_func_desc = self.outvar_desc_by_process[0][self._sends_signal]

        prev_is_false_label = Label({self._sends_prev_signal: False})
        prev_is_true_label = Label({self._sends_prev_signal: True})

        states = self.states_by_process[0]
        for state in states:
            state_arg = {self.state_arg_name: state}

            has_tok_expr = call_func(tok_func_desc, state_arg)
            sends_tok_expr = call_func(sends_func_desc, state_arg)

            _, free_vars = build_signals_values(tau_signals,
                                                prev_is_false_label)

            nprev_arg, _ = build_signals_values(tau_signals,
                                                prev_is_false_label)
            nprev_state_arg = add_dicts(nprev_arg, state_arg)

            prev_arg, _ = build_signals_values(tau_signals, prev_is_true_label)
            prev_state_arg = add_dicts(prev_arg, state_arg)

            tau_nprev_expr = call_func(tau_desc, nprev_state_arg)
            tok_of_tau_nprev_expr = call_func(
                tok_func_desc, {self.state_arg_name: tau_nprev_expr})

            tau_prev_expr = call_func(tau_desc, prev_state_arg)
            tok_of_tau_prev_expr = call_func(
                tok_func_desc, {self.state_arg_name: tau_prev_expr})

            #
            tok_dont_disappear = forall_bool(
                free_vars,
                op_implies(op_and([has_tok_expr,
                                   op_not(sends_tok_expr)]),
                           tok_of_tau_nprev_expr))

            sends_with_token_only = forall_bool(
                free_vars, op_implies(sends_tok_expr, has_tok_expr))

            sends_means_release = forall_bool(
                free_vars,
                op_implies(sends_tok_expr, op_not(tok_of_tau_nprev_expr)))

            sends_prev_means_acquire = forall_bool(free_vars,
                                                   tok_of_tau_prev_expr)

            no_sends_prev_no_tok_means_no_next_tok = forall_bool(
                free_vars,
                op_implies(op_not(has_tok_expr),
                           op_not(tok_of_tau_nprev_expr)))

            smt_lines += [
                tok_dont_disappear, sends_with_token_only, sends_means_release,
                sends_prev_means_acquire,
                no_sends_prev_no_tok_means_no_next_tok
            ]

        return smt_lines