Exemple #1
0
    def test_get_next_states(self):
        state = Node('init')

        sig_r, sig_g = Signal('r'), Signal('g')
        node_r = Node('r')
        node_rg = Node('rg')
        node_nr_g = Node('!rg')

        _ = False
        edge_to_r = {(node_r, _)}
        edge_to_rg = {(node_rg, _)}
        edge_to_not_r_g = {(node_nr_g, _)}

        state.add_transition({sig_r:True}, edge_to_r)
        state.add_transition({sig_r:True, sig_g:True}, edge_to_rg)
        state.add_transition({sig_r:False, sig_g:True}, edge_to_not_r_g)

        next_states = get_next_states(state, Label({sig_r:False, sig_g:False}))
        assert len(next_states) == 0

        next_states = get_next_states(state, Label({sig_r:False, sig_g:True}))
        assert len(next_states) == 1
        self._are_equal_sequences({node_nr_g}, next_states)

        next_states = get_next_states(state, Label({sig_r:True, sig_g:True}))
        assert len(next_states) == 2
        self._are_equal_sequences({node_r, node_rg}, next_states)
Exemple #2
0
    def test_simplify_edge_labels___basic2(self):
        r = Signal('r')
        g = Signal('g')
        edge_labels = dict()

        edge_labels[('t0', 't1')] = [{r: True, g: False}]

        edge_labels[('t0', 't2')] = [{r: False, g: False}]

        simplified_edge_labels = simplify_edge_labels(edge_labels)

        self.assertDictEqual(simplified_edge_labels, edge_labels)
Exemple #3
0
    def test_simplify_edge_labels___complex(self):
        r = Signal('r')
        g = Signal('g')
        x = Signal('x')

        edge_labels = dict()

        edge_labels[('t0', 't1')] = [{r: True, g: False}, {r: True, g: True}]

        edge_labels[('t0', 't2')] = [{r: True, g: False}]

        edge_labels[('t2', 't0')] = [{r: True, g: True}]

        edge_labels[('t0', 't0')] = [{
            r: True,
            g: True
        }, {
            r: True,
            g: False,
            x: False
        }]

        simplified_edge_labels = simplify_edge_labels(edge_labels)

        self.assertDictEqual(
            simplified_edge_labels, {
                ('t0', 't1'): [{
                    r: True
                }],
                ('t0', 't1'): [{
                    r: True
                }],
                ('t0', 't2'): [{
                    r: True,
                    g: False
                }],
                ('t2', 't0'): [{
                    r: True,
                    g: True
                }],
                ('t0', 't0'): [{
                    r: True,
                    g: True
                }, {
                    r: True,
                    x: False
                }],
            })
Exemple #4
0
 def visit_signal(self, signal:Signal):
     dst_form_prop = self.dstFormPropManager.get_dst_form_prop(signal.name)
     # To dualize a proposition, dualize:
     # 1. ext_label
     # 2. dst_name
     # We need (2) since the dual automaton has dualized state names.
     dual_dst_form_prop = DstFormulaProp(dst_form_prop.ext_label.dual(),
                                         _dualize_node(dst_form_prop.dst_state))
     dual_signal = Signal(self.dstFormPropManager.get_add_signal_name(dual_dst_form_prop))
     return dual_signal
Exemple #5
0
    def tests_all(self):
        input_signals, output_signals, data_by_name = parse(
            test_string_ltl, test_string_part)

        exp_input_signals = [
            Signal(n) for n in 'idle request0 request1'.split()
        ]
        assert set(input_signals) == set(exp_input_signals)

        exp_output_signals = [Signal(n) for n in 'grant0 grant1'.split()]
        assert set(output_signals) == set(exp_output_signals)

        for (k, v) in data_by_name.items():
            print(k, v)

        u1_assumptions, u1_guarantees = data_by_name['u1']
        assert len(u1_assumptions) == 1
        assert len(u1_guarantees) == 3

        u2_assumptions, u2_guarantees = data_by_name['u2']
        assert len(u2_assumptions) == 2
        assert len(u2_guarantees) == 3
Exemple #6
0
def _parse_signals_from_lines(signal_lines: list) -> list:
    signals_raw = chain(*[l.split()[1:] for l in signal_lines])

    signals = [Signal(n.strip()) for n in signals_raw]

    return signals
Exemple #7
0
def convert(spec: Spec, nof_IDs: int or None,
            ltl_to_atm: LTLToAutomaton) -> Spec:
    # (E.g. EG¬g ∧ AGEF¬g ∧ EFg)
    # The algorithm is:
    #   collect all E-subformulas
    #   for each unique E-subformula:
    #     introduce new v-variable if not yet introduced
    #   if nof_IDs is not given:
    #     nof_IDs = the number of states in all existential automata
    #     # nof_IDs defines the range of every v-variable
    #   introduce nof_IDs d-variables (each is a valuation of all inputs)
    #   for each unique A-subformula:
    #     introduce p-variable
    #   for each unique A-subformula:
    #     create an LTL formula         (0)
    #   for each unique E-subformula:
    #     create an LTL formula         (1)
    #   create the top-level formula    (2)
    #   create the conjunction (0) & (1) & (2)
    #   //(nope, we don't do this) inline back A-subformulas (replace their p by the path formulas (without 'A'))
    #   replace existential propositions by 'v != 0'
    #   return the result

    spec = Spec(spec.inputs, spec.outputs,
                NNFNormalizer().dispatch(spec.formula))

    atomizer = CTLAtomizerVisitor('__p')
    top_formula = atomizer.dispatch(spec.formula)

    exist_props = [p for (p, f) in atomizer.f_by_p.items() if f.name == 'E']

    if nof_IDs is None:
        atm_by_exist_p = dict(
            (p,
             ltl_to_atm.convert(atomizer.f_by_p[p].arg, '__q_' + p.arg1.name))
            for p in exist_props)
        nof_IDs = sum(len(atm.nodes) for atm in atm_by_exist_p.values())

    logging.info("k = %i", nof_IDs)

    v_bits_by_exist_p = dict((
        p,
        tuple(
            reversed([
                Signal('__v%s_%i' % (p.arg1.name.replace('_', ''), i))
                for i in range(ceil(log(nof_IDs + 1, 2)) or 1)
            ]))  # NB: +1 to account for 0
    ) for p in exist_props)  # type: Dict[BinOp, SignalsTuple]
    ordered_inputs = tuple(spec.inputs)  # type: SignalsTuple
    dTuple_by_id = dict(
        (j, tuple(Signal('__d%i_%s' % (j, i)) for i in ordered_inputs))
        for j in range(1, nof_IDs + 1))  # type: Dict[int, SignalsTuple]

    univ_props_to_inline = set(atomizer.f_by_p.keys()) - \
                           _calc_nested_props(atomizer.f_by_p) - \
                           set(exist_props)

    ltl_formula = top_formula
    # such props can only be mentioned in the top_formula
    ltl_formula = _inline_univ_p(
        ltl_formula, dict(
            (p, atomizer.f_by_p[p]) for p in univ_props_to_inline))
    ltl_formula &= _conjunction(
        _create_LTL_for_A_formula(p, atomizer.f_by_p[p].arg)
        for p in set(atomizer.f_by_p) - set(exist_props) -
        univ_props_to_inline)
    ltl_formula &= _conjunction(
        _create_LTL_for_E_formula(v_bits_by_exist_p[p], atomizer.f_by_p[p].arg,
                                  dTuple_by_id, ordered_inputs)
        for p in exist_props)

    ltl_formula = _replace_exist_propositions(ltl_formula, v_bits_by_exist_p,
                                              nof_IDs)

    logging.debug("exist propositions: \n%s",
                  pformat([ep.arg1 for ep in v_bits_by_exist_p]))

    new_outputs = list(chain(*v_bits_by_exist_p.values())) + \
                  list(chain(*dTuple_by_id.values())) + \
                  list(p.arg1 for p in set(atomizer.f_by_p) - set(exist_props) - univ_props_to_inline)

    spec = Spec(spec.inputs, set(new_outputs) | spec.outputs, ltl_formula)
    return spec
Exemple #8
0
def sig_prop(name:str) -> Tuple[Signal, BinOp]:
    return Signal(name),\
           BinOp('=', Signal(name), Number(1))
Exemple #9
0
    def test_simplify_edge_labels___bug(self):
        # ('t2', 't5') :
        #[{prev_0: True, mlocked_0: True, sready_0: True, mbusreq_0: True},
        # {prev_0: True, mlocked_0: True, sready_0: False, mbusreq_0: True},
        # {prev_0: True, mlocked_0: False, sready_0: True, mbusreq_0: False},
        # {prev_0: True, mlocked_0: True, sready_0: True, mbusreq_0: False},
        # {prev_0: True, mlocked_0: True, sready_0: False, mbusreq_0: False},
        # {prev_0: True, mlocked_0: False, sready_0: False, mbusreq_0: False},
        # {prev_0: True, mlocked_0: False, sready_0: False, mbusreq_0: True},
        # {prev_0: True, mlocked_0: False, sready_0: True, mbusreq_0: True}]
        # was simplified into:
        #[{prev_0: True, sready_0: True},
        # {prev_0: True, mbusreq_0: True},
        # {prev_0: True, mlocked_0: False}]
        # but the right solution is:
        # [{prev_0: True}]
        # ------------------------------------------------
        edge_labels = dict()
        edge_labels[('t2', 't5')] = [{
            Signal('prev'): True,
            Signal('mlocked'): True,
            Signal('sready'): True,
            Signal('mbusreq'): True
        }, {
            Signal('prev'): True,
            Signal('mlocked'): True,
            Signal('sready'): False,
            Signal('mbusreq'): True
        }, {
            Signal('prev'): True,
            Signal('mlocked'): False,
            Signal('sready'): True,
            Signal('mbusreq'): False
        }, {
            Signal('prev'): True,
            Signal('mlocked'): True,
            Signal('sready'): True,
            Signal('mbusreq'): False
        }, {
            Signal('prev'): True,
            Signal('mlocked'): True,
            Signal('sready'): False,
            Signal('mbusreq'): False
        }, {
            Signal('prev'): True,
            Signal('mlocked'): False,
            Signal('sready'): False,
            Signal('mbusreq'): False
        }, {
            Signal('prev'): True,
            Signal('mlocked'): False,
            Signal('sready'): False,
            Signal('mbusreq'): True
        }, {
            Signal('prev'): True,
            Signal('mlocked'): False,
            Signal('sready'): True,
            Signal('mbusreq'): True
        }]

        simplified_edge_labels = simplify_edge_labels(edge_labels)

        # kinda hack - returns strings instead of Signals..
        self.assertDictEqual(simplified_edge_labels,
                             {('t2', 't5'): [{
                                  Signal('prev'): True
                              }]})