Пример #1
0
    def _get_desc_is_active(
            self,
            proc_index: int):  # TODO: should not dependent on proc_index!
        #: :type: FuncDescription
        sends_func = self.outvar_desc_by_process[proc_index][
            self._sends_signals[proc_index]]
        assert len(sends_func.inputs) == 1, 'consider easy case for now'
        assert list(
            sends_func.inputs
        )[0][0] == self.state_arg_name, 'consider easy case for now'
        sends_args = sends_func.get_args_list(
            {self.state_arg_name: self.state_arg_name})

        #: :type: QuantifiedSignal
        sends_prev_signal = self._sends_prev_signals[proc_index]

        sched_eq_proc_arg_by_signal = self._get_equal_func_args(
            lmap(str, self._sched_signals), lmap(str, self._proc_signals))

        sched_eq_proc_args = self._get_desc_equal_bools().get_args_list(
            sched_eq_proc_arg_by_signal)

        prev_is_sched_args = map(lambda signal_type: str(signal_type[0]),
                                 self._get_desc_prev_next_is_sched(
                                     True).inputs)  # order is important

        if self.nof_processes > 1:
            body_template = '(or ({equal_bits} {sched_eq_proc_args}) \n' \
                            '    (and {sends_prev} ({prev_is_sched} {prev_is_sched_args}) )' \
                            ')'
        else:
            assert self.nof_processes == 1
            body_template = '(or ({equal_bits} {sched_eq_proc_args}) \n' \
                            '    {sends_prev})'

        body = body_template.format_map({
            'equal_bits':
            self._EQUAL_BITS_NAME,
            'sched_eq_proc_args':
            ' '.join(sched_eq_proc_args),
            'prev_is_sched':
            self._PREV_IS_SCHED_NAME,
            'prev_is_sched_args':
            ' '.join(prev_is_sched_args),
            'sends_prev':
            str(sends_prev_signal),
            'sends':
            sends_func.name,
            'sends_args':
            ' '.join(sends_args),
        })

        type_by_arg = dict([(sends_prev_signal, 'Bool')] +
                           self._sched_arg_type_pairs +
                           self._proc_arg_type_pairs)

        description = FuncDescription(self._IS_ACTIVE_NAME, type_by_arg,
                                      'Bool', body)

        return description
Пример #2
0
def p_unit_data(p):
    """unit_data :    empty
                    | expressions """
    if p[1] is None:
        p[0] = ([],[])
    else:
        assumptions = lmap(lambda e: e.data, filter(lambda e: isinstance(e, Assumption), p[1]))
        guarantees = lmap(lambda e: e.data, filter(lambda e: isinstance(e, Guarantee), p[1]))
        p[0] = (assumptions, guarantees)
Пример #3
0
    def __init__(self,
                 top_formula: Expr,
                 atm_by_p: Dict[Prop, Automaton],
                 UCWs: Iterable[Automaton],
                 tau_desc: FuncDesc,
                 inputs: Iterable[Signal],
                 desc_by_output: Dict[Signal, FuncDesc],
                 all_model_states: Iterable[int],
                 model_init_state: int = 0):

        self.top_formula = top_formula  # type:Expr
        self.atm_by_sig = dict(
            map(lambda p_atm: (p_atm[0].arg1, p_atm[1]),
                atm_by_p.items()))  # type: Dict[Signal, Automaton]
        self.UCWs = set(UCWs)  # type: Set[Automaton]

        assert len(set(map(lambda n: n.name,
                           chain(*lmap(lambda a: a.nodes, chain(atm_by_p.values(),
                                                                self.atm_by_sig.values())))))) \
               == \
               len(set(chain(*lmap(lambda a: a.nodes, chain(atm_by_p.values(),
                                                            self.atm_by_sig.values()))))), \
            'node names are not unique'

        self.inputs = set(inputs)  # type: Set[Signal]
        self.tau_desc = tau_desc  # type: FuncDesc
        self.desc_by_outSig = desc_by_output  # type: Dict[Signal,FuncDesc]
        # we create fake outputs for A/E propositions;
        # they are defined via reach in `encode_headers`:
        #   ( define-fun _prop ((m M)) Bool (__reach q0_prop m) )
        self.desc_by_pSig = dict(
            map(
                lambda sig:
                (sig,
                 FuncDesc(sig.name, {ARG_MODEL_STATE: TYPE_MODEL_STATE}, 'Bool'
                          )), self.atm_by_sig))
        self.desc_by_sig = dict(
            chain(self.desc_by_pSig.items(), self.desc_by_outSig.items()))

        assert set(map(lambda out_func: out_func.name, self.desc_by_outSig.values()))\
            .isdisjoint(set(map(lambda prop_func:prop_func.name, self.desc_by_pSig.values()))),\
            "output and prop func names should not collide"

        self.model_states = list(all_model_states)
        self.model_init_state = model_init_state  # type: int
        self.last_allowed_states = None  # type: List[int]

        reach_args = {
            ARG_A_STATE: TYPE_A_STATE,
            ARG_MODEL_STATE: TYPE_MODEL_STATE
        }

        r_args = reach_args

        self.reach_func_desc = FuncDesc(FUNC_REACH, reach_args, bool_type())
        self.rank_func_desc = FuncDesc(FUNC_R, r_args, real_type())
Пример #4
0
def p_unit_data(p):
    """unit_data :    empty
                    | expressions """
    if p[1] is None:
        p[0] = ([], [])
    else:
        assumptions = lmap(lambda e: e.data,
                           filter(lambda e: isinstance(e, Assumption), p[1]))
        guarantees = lmap(lambda e: e.data,
                          filter(lambda e: isinstance(e, Guarantee), p[1]))
        p[0] = (assumptions, guarantees)
Пример #5
0
    def _accumulator(self, prev_proc, crt_proc, enum_clauses):
        equals_desc = self._get_desc_equal_bools()

        proc_eq_crt_args_dict = self._get_equal_func_args(lmap(str, self._proc_signals), crt_proc)
        sched_eq_prev_args_dict = self._get_equal_func_args(lmap(str, self._sched_signals), prev_proc)

        proc_eq_crt_args = equals_desc.get_args_list(proc_eq_crt_args_dict)
        sched_eq_prev_args = equals_desc.get_args_list(sched_eq_prev_args_dict)

        enum_clauses.append('(and ({equals} {proc_eq_crt}) ({equals} {sched_eq_prev}))'.format_map(
            {
                'equals': self._EQUAL_BITS_NAME,
                'proc_eq_crt': ' '.join(proc_eq_crt_args),
                'sched_eq_prev': ' '.join(sched_eq_prev_args)
            }))
Пример #6
0
    def __init__(self,
                 automaton: Automaton,
                 tau_desc: FuncDesc,
                 inputs: Iterable[Signal],
                 descr_by_output: Dict[Signal, FuncDesc],
                 all_model_states: Iterable[int],
                 max_k: int,
                 model_init_state: int = 0
                 ):  # the automata alphabet is inputs+outputs
        self.automaton = automaton

        self.inputs = list(inputs)  # type: List[Signal]
        self.descr_by_output = descr_by_output  # type: Dict[Signal,FuncDesc]
        self.tau_desc = tau_desc  # type: FuncDesc
        self.max_model_states = list(all_model_states)

        reach_args_sig = {
            ARG_A_STATE: TYPE_A_STATE,
            ARG_MODEL_STATE: TYPE_MODEL_STATE
        }

        self.reach_func_desc = FuncDesc(FUNC_REACH, reach_args_sig,
                                        bool_type())

        self.model_init_state = model_init_state  # type: int
        self.last_allowed_states = None  # type: List[int]
        self.max_k = max_k
        self.forbidding_atoms = lmap(lambda k: '__forbid%i' % k,
                                     range(self.max_k))  # type: List[str]
Пример #7
0
    def _get_desc_tau_sched_wrapper(self, proc_index:int, all_models_inputs) -> FuncDescription:
        local_tau_input_signals = _filter_by_proc(proc_index, all_models_inputs)
        local_tau_arg_type_pairs = self._get_desc_local_tau(local_tau_input_signals).inputs

        type_by_signal = dict(local_tau_arg_type_pairs + self._sched_arg_type_pairs + self._proc_arg_type_pairs)

        local_tau_arg_type_pairs = list(map(lambda signal_type: signal_type[0], local_tau_arg_type_pairs))

        is_active_desc = self._get_desc_is_active(proc_index)
        is_active_inputs = lmap(lambda signal: signal[0],
                                is_active_desc.inputs)  # TODO: hack: knowledge: var names are the same

        body = """
        (ite ({is_active} {is_active_inputs}) ({tau} {local_tau_inputs}) {state})
        """.format_map({'tau': self._TAU_NAME,
                        'local_tau_inputs': ' '.join(map(str, local_tau_arg_type_pairs)),
                        'state': self.state_arg_name,
                        'is_active': self._IS_ACTIVE_NAME,
                        'is_active_inputs': ' '.join(map(str, is_active_inputs))})

        description = FuncDescription(self._TAU_SCHED_WRAPPER_NAME, type_by_signal,
                                      self._state_type,
                                      body)

        return description
Пример #8
0
def convert_aiger_model_to_tlsf_model(aiger_model: str, bad_name: str) -> str:
    """ :returns AIGER string with bad output removed and
                 outputs have prefix 'controllable_' removed.
                 The header is adapted.
    """
    aiger_lines = aiger_model.splitlines()
    header_numbers = lmap(int, aiger_lines[0].split()[1:])  # aag M I L O A
    assert len(header_numbers) == 5, 'only old AIGER format is supported'
    new_header = 'aag ' + ' '.join(
        map(str,
            header_numbers[:3] + [header_numbers[3] - 1] + header_numbers[4:]))

    bad_def_line_idx, bad_sym_line_idx, bad_idx = _get_bad_line_indices(
        aiger_lines, bad_name)

    new_aiger_lines = [new_header] + \
                      aiger_lines[1:bad_def_line_idx] + \
                      aiger_lines[bad_def_line_idx+1:bad_sym_line_idx] + \
                      aiger_lines[bad_sym_line_idx+1:]

    symbols_table_start = 1 + sum(header_numbers[1:])
    for i, l in enumerate(new_aiger_lines[symbols_table_start:]):
        if l[0] == 'o':
            cur_idx = int(l.split()[0][1:])
            new_aiger_lines[symbols_table_start +
                            i] = 'o{dec} {wo_prefix}'.format(
                                dec=cur_idx -
                                1 if cur_idx > bad_idx else cur_idx,
                                wo_prefix=' '.join(
                                    l.split()[1:])[len('controllable_'):])
        if l[0] == 'c':
            break
    return '\n'.join(
        new_aiger_lines) + '\n'  # some tools complain about not having this
Пример #9
0
    def _get_desc_is_active(self, proc_index:int):   # TODO: should not dependent on proc_index!
        #: :type: FuncDescription
        sends_func = self.outvar_desc_by_process[proc_index][self._sends_signals[proc_index]]
        assert len(sends_func.inputs) == 1, 'consider easy case for now'
        assert list(sends_func.inputs)[0][0] == self.state_arg_name, 'consider easy case for now'
        sends_args = sends_func.get_args_list({self.state_arg_name: self.state_arg_name})

        #: :type: QuantifiedSignal
        sends_prev_signal = self._sends_prev_signals[proc_index]

        sched_eq_proc_arg_by_signal = self._get_equal_func_args(lmap(str, self._sched_signals),
                                                                lmap(str, self._proc_signals))

        sched_eq_proc_args = self._get_desc_equal_bools().get_args_list(sched_eq_proc_arg_by_signal)

        prev_is_sched_args = map(lambda signal_type: str(signal_type[0]),
                                 self._get_desc_prev_next_is_sched(True).inputs)  # order is important

        if self.nof_processes > 1:
            body_template = '(or ({equal_bits} {sched_eq_proc_args}) \n' \
                            '    (and {sends_prev} ({prev_is_sched} {prev_is_sched_args}) )' \
                            ')'
        else:
            assert self.nof_processes == 1
            body_template = '(or ({equal_bits} {sched_eq_proc_args}) \n' \
                            '    {sends_prev})'

        body = body_template.format_map({'equal_bits': self._EQUAL_BITS_NAME,
                                         'sched_eq_proc_args': ' '.join(sched_eq_proc_args),
                                         'prev_is_sched': self._PREV_IS_SCHED_NAME,
                                         'prev_is_sched_args': ' '.join(prev_is_sched_args),
                                         'sends_prev': str(sends_prev_signal),
                                         'sends': sends_func.name,
                                         'sends_args': ' '.join(sends_args),
                                         })

        type_by_arg = dict([(sends_prev_signal, 'Bool')] +
                           self._sched_arg_type_pairs +
                           self._proc_arg_type_pairs)

        description = FuncDescription(self._IS_ACTIVE_NAME,
                                      type_by_arg,
                                      'Bool',
                                      body)

        return description
Пример #10
0
    def _accumulator(self, prev_proc, crt_proc, enum_clauses):
        equals_desc = self._get_desc_equal_bools()

        proc_eq_crt_args_dict = self._get_equal_func_args(
            lmap(str, self._proc_signals), crt_proc)
        sched_eq_prev_args_dict = self._get_equal_func_args(
            lmap(str, self._sched_signals), prev_proc)

        proc_eq_crt_args = equals_desc.get_args_list(proc_eq_crt_args_dict)
        sched_eq_prev_args = equals_desc.get_args_list(sched_eq_prev_args_dict)

        enum_clauses.append(
            '(and ({equals} {proc_eq_crt}) ({equals} {sched_eq_prev}))'.
            format_map({
                'equals': self._EQUAL_BITS_NAME,
                'proc_eq_crt': ' '.join(proc_eq_crt_args),
                'sched_eq_prev': ' '.join(sched_eq_prev_args)
            }))
Пример #11
0
def to_boolean_nusmv(lts: LTS, specification: SpecProperty) -> str:
    nof_state_bits = int(max(1, math.ceil(math.log(len(lts.states), 2))))
    bits_by_state = dict((state, bin_fixed_list(i, nof_state_bits))
                         for (i, state) in enumerate(sorted(lts.states)))

    state_bits = lmap(_ith_state_bit, range(nof_state_bits))

    _assert_no_intersection(state_bits,
                            list(lts.input_signals) + lts.output_signals)

    dot_lines = StrAwareList()
    dot_lines += 'MODULE main'
    dot_lines += 'IVAR'
    dot_lines += [
        '  {signal} : boolean;'.format(signal=s.name)
        for s in lts.input_signals
    ]

    dot_lines += 'VAR'
    dot_lines += ['  {si} : boolean;'.format(si=si) for si in state_bits]

    dot_lines += 'DEFINE'
    dot_lines += [
        '  {out_name} := {formula} ;'.format(out_name=out_name,
                                             formula=_get_formula(
                                                 out_name, out_model,
                                                 bits_by_state))
        for (out_name, out_model) in lts.model_by_name.items()
    ]

    dot_lines += 'ASSIGN'
    for i, sb in enumerate(state_bits):
        sb_init = str(bits_by_state[list(lts.init_states)[0]][i]).upper()

        dot_lines += '  init({sb}) := {init_sb};'.format(sb=sb,
                                                         init_sb=sb_init)

        dot_lines += '  next({sb}) := '.format(sb=sb)
        dot_lines += '    case'

        for (label, next_state) in lts.tau_model.items():
            sb_next = str(bits_by_state[next_state][i]).upper()
            dot_lines += '      {formula} : {next_state};'.format(
                formula=_clause_to_formula(label, bits_by_state),
                next_state=sb_next)

        dot_lines += '    TRUE : FALSE;'  # default: unreachable states, don't care
        dot_lines += '    esac;'

    expr = BinOp('->', and_expressions(specification.assumptions),
                 and_expressions(specification.guarantees))
    expr = WeakToUntilConverterVisitor().dispatch(
        expr)  # SMV does not have Weak until

    dot_lines += 'LTLSPEC ' + AstToSmvProperty().dispatch(expr)

    return '\n'.join(dot_lines)
Пример #12
0
    def _encode_state(self, q: Node, m: int) -> List[str]:
        q_transitions = lfilter(lambda t: t.src == q, self.aht_transitions)

        # Encoding:
        # - if q is existential, then one of the transitions must fire:
        #
        #     reach(q,t) ->
        #                OR{state_label \in q_transitions}: sys_out=state_label & reach(q',t')
        #
        # - if q is universal, then all transitions of that system output should fire
        #
        #     reach(q,t) ->
        #                AND{state_label \in q_transitions}: sys_out=state_label -> reach(q',t')
        #

        # build s_premise `reach(q,t)`
        s_m = smt_name_m(m)
        s_q = smt_name_q(q)
        s_premise = call_func(self.reach_func_desc, {
            ARG_MODEL_STATE: s_m,
            ARG_A_STATE: s_q
        })

        # build s_conclusion `exists`
        s_conclusion_out_sExpr_pairs = set()  # type: Set[Tuple[str, str]]
        for t in q_transitions:  # type: Transition
            s_t_state_label = smt_out(s_m, t.state_label, self.inputs,
                                      self.descr_by_output)
            s_dst_expr = self._translate_dst_expr_into_smt(t.dst_expr, q, m)
            s_conclusion_out_sExpr_pairs.add((s_t_state_label, s_dst_expr))

        if q.is_existential:
            s_conclusion_elements = lmap(lambda sce: op_and(sce),
                                         s_conclusion_out_sExpr_pairs)
        else:
            s_conclusion_elements = lmap(
                lambda sce: op_implies(sce[0], sce[1]),
                s_conclusion_out_sExpr_pairs)

        s_conclusion = (op_and, op_or)[q.is_existential](s_conclusion_elements)

        s_assertion = op_implies(s_premise, s_conclusion)

        return [assertion(s_assertion)]
Пример #13
0
def lts_to_verilog(lts:LTS, module_name:str) -> str:
    s = StrAwareList()

    s += 'module {module}({inputs}, {outputs});'.format(
        inputs=', '.join(map(lambda sig: sig.name, lts.input_signals)),
        outputs=', '.join(map(lambda sig: sig.name, lts.output_signals)),
        module=module_name)
    s.newline()

    s += '\n'.join(['input {sig};'.format(sig=sig.name) for sig in lts.input_signals])
    s.newline()

    s += '\n'.join(['output {sig};'.format(sig=sig.name) for sig in lts.output_signals])
    s.newline()

    # TODO: don't use latches for state-less models
    nof_state_bits = math.ceil(math.log2(len(lts.states)))
    s += 'reg [{max_bit}:0] {state};'.format(max_bit=int(max(0., nof_state_bits-1)),  # max_bit is at least 0
                                                         state=lts.state_name)
    s.newline()

    s += '\n'.join(['wire {out};'.format(out=sig.name) for sig in lts.output_signals])
    s.newline()

    for out_sig, value_tuples in lts.output_models.items():
        labels_true = lmap(lambda x: x[0],
                           filter(lambda label_value: label_value[1],
                                  value_tuples.items()))
        assign = 'assign {sig} = {true_expr};'.format(sig=out_sig.name,
                                                      true_expr=' || '.join(map(_label_to_verilog, labels_true))
                                                                if labels_true else '0')
        s += assign
    s.newline()

    s += 'initial begin'
    s += '{state} = 0;'.format(state=lts.state_name)
    s += 'end'
    s.newline()

    s += 'always@($global_clock)'
    s += 'begin'

    # you can also use '=' instead of '<=' here, but we will be strict
    tau_items = tuple(lts.tau_model.items())
    s += 'if ({expr}) {state} <= {next_val};'.format(expr=_label_to_verilog(tau_items[0][0]),
                                                     state=lts.state_name,
                                                     next_val=tau_items[0][1])
    for lbl, val in tau_items[1:]:
        s += 'else if ({expr}) {state} <= {next_val};'.format(expr=_label_to_verilog(lbl),
                                                              state=lts.state_name,
                                                              next_val=val)
    s += 'end'
    s += 'endmodule'
    return s.to_str()
Пример #14
0
def declare_fun(func_desc:FuncDescription) -> str:
    input_types = lmap(lambda i_t: i_t[1], func_desc.inputs)
    smt_str = '(declare-fun '
    smt_str += func_desc.name + ' ('

    for var in input_types:
        smt_str += var + ' '
    if len(input_types):
        smt_str = smt_str[:-1]

    smt_str += ') ' + str(func_desc.output) + ')\n'
    return smt_str
Пример #15
0
def declare_fun(func_desc: FuncDescription) -> str:
    input_types = lmap(lambda i_t: i_t[1], func_desc.inputs)
    smt_str = '(declare-fun '
    smt_str += func_desc.name + ' ('

    for var in input_types:
        smt_str += var + ' '
    if len(input_types):
        smt_str = smt_str[:-1]

    smt_str += ') ' + str(func_desc.output) + ')\n'
    return smt_str
Пример #16
0
    def declare_fun(self) -> str:
        input_types = lmap(lambda i_t: i_t[1], self.inputs)
        smt_str = '(declare-fun '
        smt_str += self.name + ' ('

        for var in input_types:
            smt_str += var + ' '
        if len(input_types):
            smt_str = smt_str[:-1]

        smt_str += ') ' + str(self.output_ty) + ')\n'
        return smt_str
Пример #17
0
def lts_to_verilog(lts:LTS) -> str:
    s = StrAwareList()

    s += 'module model(i_clk, \n{inputs}, \n{outputs});'.format(inputs=', '.join(map(lambda sig: sig.name,
                                                                                     lts.input_signals)),
                                                                outputs=', '.join(map(lambda sig: sig.name,
                                                                                      lts.output_signals)))
    s.newline()

    s += 'input i_clk;'
    s += '\n'.join(['input {sig};'.format(sig=sig.name) for sig in lts.input_signals])
    s.newline()

    s += '\n'.join(['output {sig};'.format(sig=sig.name) for sig in lts.output_signals])
    s.newline()

    nof_state_bits = max(1, math.ceil(math.log2(len(lts.states))))
    s += 'reg [{max_bit}:0] {state};'.format(max_bit=nof_state_bits-1, state=lts.state_name)
    s.newline()

    s += '\n'.join(['wire {out};'.format(out=sig.name) for sig in lts.output_signals])
    s.newline()

    for out_sig, value_tuples in lts.output_models.items():
        labels_true = lmap(lambda x: x[0],
                           filter(lambda label_value: label_value[1],
                                  value_tuples.items()))
        assign = 'assign {sig} = {true_expr};'.format(sig=out_sig.name,
                                                      true_expr=' || '.join(map(_label_to_verilog,
                                                                                labels_true))
                                                                if labels_true else '0')
        s += assign
    s.newline()

    s += 'initial begin'
    s += '{state} = 0;'.format(state=lts.state_name)
    s += 'end'
    s.newline()

    s += 'always@(posedge i_clk)'
    s += 'begin'

    tau_items = tuple(lts.tau_model.items())
    s += 'if ({expr}) {state} = {next_val};'.format(expr=_label_to_verilog(tau_items[0][0]),
                                                    state=lts.state_name,
                                                    next_val=tau_items[0][1])
    for lbl, val in tau_items[1:]:
        s += 'else if ({expr}) {state} = {next_val};'.format(expr=_label_to_verilog(lbl),
                                                             state=lts.state_name,
                                                             next_val=val)
    s += 'end'
    s += 'endmodule'
    return s.to_str()
Пример #18
0
    def _define_declare_functions(self, func_descs):
        #should preserve the order: some functions may depend on others
        desc_by_name = dict((desc.name, (i, desc)) for (i, desc) in enumerate(func_descs))
        # TODO: cannot use set of func descriptions due to hack in FuncDescription

        unique_index_descs_sorted = sorted(desc_by_name.values(), key=lambda i_d: i_d[0])
        unique_descs = lmap(lambda i_d: i_d[1], unique_index_descs_sorted)

        for desc in unique_descs:
            if desc.definition is not None:
                self._underlying_solver.define_fun(desc)
            else:
                self._underlying_solver.declare_fun(desc)
Пример #19
0
    def _define_declare_functions(self, func_descs):
        # should preserve the order: some functions may depend on others
        desc_by_name = dict((desc.name, (i, desc)) for (i, desc) in enumerate(func_descs))
        # TODO: cannot use set of func descriptions due to hack in FuncDescription

        unique_index_descs_sorted = sorted(desc_by_name.values(), key=lambda i_d: i_d[0])
        unique_descs = lmap(lambda i_d: i_d[1], unique_index_descs_sorted)

        for desc in unique_descs:
            if desc.definition is not None:
                self._underlying_solver.define_fun(desc)
            else:
                self._underlying_solver.declare_fun(desc)
Пример #20
0
def _get_bad_line_indices(aiger_lines: List[str],
                          bad_name: str) -> (int, int, int):
    """ :returns line_of_def, line_of_symbol, id """
    header_numbers = lmap(int, aiger_lines[0].split()[1:])  # aag M I L O A
    symbols_table_start = 1 + sum(header_numbers[1:])
    for i, l in enumerate(aiger_lines[symbols_table_start:]):
        if l == 'c':
            assert 0, 'name of the bad output was not found'
        if l[0] == 'o':  # example: "o0 g_0"
            names = l.split()[1:]
            if bad_name in names:
                idx = int(l.split()[0][1:])
                return (1 + header_numbers[1] + header_numbers[2] +
                        idx), symbols_table_start + i, idx
    assert 0, 'name of the bad output was not found'
Пример #21
0
def to_boolean_nusmv(lts:LTS, specification:SpecProperty) -> str:
    nof_state_bits = int(max(1, math.ceil(math.log(len(lts.states), 2))))
    bits_by_state = dict((state, bin_fixed_list(i, nof_state_bits))
                         for (i,state) in enumerate(sorted(lts.states)))

    state_bits = lmap(_ith_state_bit, range(nof_state_bits))

    _assert_no_intersection(state_bits, list(lts.input_signals) + lts.output_signals)

    dot_lines = StrAwareList()
    dot_lines += 'MODULE main'
    dot_lines += 'IVAR'
    dot_lines += ['  {signal} : boolean;'.format(signal=s.name) for s in lts.input_signals]

    dot_lines += 'VAR'
    dot_lines += ['  {si} : boolean;'.format(si=si) for si in state_bits]

    dot_lines += 'DEFINE'
    dot_lines += ['  {out_name} := {formula} ;'.format(out_name=out_name,
                                                       formula=_get_formula(out_name, out_model, bits_by_state))
                  for (out_name,out_model) in lts.model_by_name.items()]

    dot_lines += 'ASSIGN'
    for i,sb in enumerate(state_bits):
        sb_init = str(bits_by_state[list(lts.init_states)[0]][i]).upper()

        dot_lines += '  init({sb}) := {init_sb};'.format(sb=sb, init_sb=sb_init)

        dot_lines += '  next({sb}) := '.format(sb=sb)
        dot_lines += '    case'

        for (label,next_state) in lts.tau_model.items():
            sb_next = str(bits_by_state[next_state][i]).upper()
            dot_lines += '      {formula} : {next_state};'.format(formula=_clause_to_formula(label, bits_by_state),
                                                                  next_state=sb_next)

        dot_lines += '    TRUE : FALSE;'  # default: unreachable states, don't care
        dot_lines += '    esac;'

    expr = BinOp('->', and_expressions(specification.assumptions), and_expressions(specification.guarantees))
    expr = WeakToUntilConverterVisitor().dispatch(expr)  # SMV does not have Weak until

    dot_lines += 'LTLSPEC ' + AstToSmvProperty().dispatch(expr)

    return '\n'.join(dot_lines)
Пример #22
0
def _get_all_possible_inputs(func_desc: FuncDesc, last_allowed_states):
    arg_type_pairs = func_desc.ordered_argname_type_pairs

    get_values = lambda t: {
        bool_type(): (true(), false()),
        TYPE_MODEL_STATE: [smt_name_m(m) for m in last_allowed_states],
    }[t]

    records = product(*[get_values(t) for (_, t) in arg_type_pairs])

    args = lmap(lambda a_t: a_t[0], arg_type_pairs)

    dicts = []
    for record in records:
        assert len(args) == len(record)

        arg_value_pairs = zip(args, record)
        dicts.append(dict(arg_value_pairs))

    return dicts
Пример #23
0
    def _get_desc_tau_sched_wrapper(self, proc_index: int,
                                    all_models_inputs) -> FuncDescription:
        local_tau_input_signals = _filter_by_proc(proc_index,
                                                  all_models_inputs)
        local_tau_arg_type_pairs = self._get_desc_local_tau(
            local_tau_input_signals).inputs

        type_by_signal = dict(local_tau_arg_type_pairs +
                              self._sched_arg_type_pairs +
                              self._proc_arg_type_pairs)

        local_tau_arg_type_pairs = list(
            map(lambda signal_type: signal_type[0], local_tau_arg_type_pairs))

        is_active_desc = self._get_desc_is_active(proc_index)
        is_active_inputs = lmap(
            lambda signal: signal[0], is_active_desc.inputs
        )  # TODO: hack: knowledge: var names are the same

        body = """
        (ite ({is_active} {is_active_inputs}) ({tau} {local_tau_inputs}) {state})
        """.format_map({
            'tau':
            self._TAU_NAME,
            'local_tau_inputs':
            ' '.join(map(str, local_tau_arg_type_pairs)),
            'state':
            self.state_arg_name,
            'is_active':
            self._IS_ACTIVE_NAME,
            'is_active_inputs':
            ' '.join(map(str, is_active_inputs))
        })

        description = FuncDescription(self._TAU_SCHED_WRAPPER_NAME,
                                      type_by_signal, self._state_type, body)

        return description
Пример #24
0
    def _build_func_model_from_smt(self, func_smt_lines, func_desc:FuncDesc) -> dict:
        """
        Return graph for the transition (or output) function: {label:output}.
        For label's keys are used:
        - for inputs/outputs: original signals
        - for LTS states: ARG_MODEL_STATE
        """
        func_model = {}
        signals = set(list(self.inputs) + list(self.descr_by_output.keys()))

        for l in func_smt_lines:
            #            (get-value ((tau t0 true true)))
            l = l.replace('get-value', '').replace('(', '').replace(')', '')
            tokens = l.split()

            func_name = tokens[0]
            arg_values_raw = lmap(self._parse_value, tokens[1:-1])
            return_value_raw = tokens[-1]

            if func_name != func_desc.name:
                continue

            smt_args = func_desc.get_args_dict(arg_values_raw)

            args_label = Label(dict((smt_unname_if_signal(var, signals), val)
                                    for var, val in smt_args.items()))

            if func_desc.output_ty == TYPE_MODEL_STATE:
                return_value = smt_unname_m(return_value_raw)
            else:
                assert func_desc.output_ty == self.solver.TYPE_BOOL(), func_desc.output_ty
                assert return_value_raw.strip() == return_value_raw  # TODO: remove after debugging phase
                return_value = (return_value_raw == self.solver.get_true())

            func_model[args_label] = return_value

        return func_model
Пример #25
0
 def _encode_automata_functions(self) -> List[str]:
     atm_states = chain(*lmap(lambda a: a.nodes, self.atm_by_sig.values()))
     return [declare_enum(TYPE_A_STATE, map(smt_name_q, atm_states))]
Пример #26
0
 def _declare_forbidding_atoms(self) -> List[str]:
     return lmap(lambda a: declare_const(a, bool_type()),
                 self.forbidding_atoms)
Пример #27
0
 def encode_assumption_forbid_k(self, k: int) -> List[str]:
     # forbid states with counter being k or lower
     return self.forbidding_atoms[0:k + 1] + lmap(
         lambda e: op_not(e), self.forbidding_atoms[k + 1:])