Esempio n. 1
0
    def test_active_lstar_05(self):
        """
        Try to let L* learn the regular language A.
        A is a language over the alphabet sigma = {a},
        that accepts all strings with an odd number of
        a's.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'a'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q1, q0, 'a')
        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'a'}, teacher)
        dfa = lstar.learn()

        self.assertEqual(2, len(dfa.states))
        self.assertEqual(1, len(dfa.accept_states))

        s_plus = set()
        s_minus = set()
        for i in range(1, 21, 2):
            s_plus.add('a' * i)
            s_minus.add('a' * (i - 1))

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
                self.assertFalse(dfa.parse_string(s)[1])
Esempio n. 2
0
    def test_active_nlstar_11(self):
        """
        try to let NL* learn the regular language L.
        L is a regular language over the alphabet {a, b} where
        for every string in L contains exactly two a's.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q0, 'b')
        expected_dfa.add_transition(q0, q1, 'a')

        expected_dfa.add_transition(q1, q1, 'b')
        expected_dfa.add_transition(q1, q2, 'a')

        expected_dfa.add_transition(q2, q2, 'b')
        expected_dfa.add_transition(q2, q3, 'a')

        expected_dfa.add_transition(q3, q3, 'a')
        expected_dfa.add_transition(q3, q3, 'b')

        expected_dfa.accept_states.add(q2)

        teacher = oracle.ActiveOracle(expected_dfa)
        nlstar = algorithms.NLSTAR({'a', 'b'}, teacher)

        nfa = nlstar.learn()
        dfa = nfa.to_dfa()

        self.assertEqual(expected_dfa, dfa)
Esempio n. 3
0
    def test_active_lstar_06(self):
        """
        try to let L* learn the regular language A.
        A is a regular language over the alphabet {0, 1} where
        each string contains an odd number of 1s
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'0', '1'}, start_state=q0)

        expected_dfa.add_transition(q0, q0, '0')
        expected_dfa.add_transition(q0, q1, '1')

        expected_dfa.add_transition(q1, q1, '0')
        expected_dfa.add_transition(q1, q0, '1')

        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'0', '1'}, teacher)
        dfa = lstar.learn()

        s_plus = set()
        s_minus = {''}
        for i in self._combinations({'0', '1'}, 7):
            if i.count('1') % 2 == 1:
                s_plus.add(i)
            else:
                s_minus.add(i)

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Esempio n. 4
0
    def test_active_nlstar_07(self):
        """
        try to let NL* learn the regular language A.
        A is a regular language over the alphabet {0, 1} where
        each string contains 101 as a substring.
        """
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')
        q4 = automaton.State('4')

        expected_dfa = automaton.DFA({'0', '1'}, start_state=q1)

        expected_dfa.add_transition(q1, q1, '0')
        expected_dfa.add_transition(q1, q2, '1')

        expected_dfa.add_transition(q2, q2, '1')
        expected_dfa.add_transition(q2, q3, '0')

        expected_dfa.add_transition(q3, q1, '0')
        expected_dfa.add_transition(q3, q4, '1')

        expected_dfa.add_transition(q4, q4, '0')
        expected_dfa.add_transition(q4, q4, '1')

        expected_dfa.accept_states.add(q4)

        teacher = oracle.ActiveOracle(expected_dfa)
        nlstar = algorithms.NLSTAR({'0', '1'}, teacher)

        nfa = nlstar.learn()
        dfa = nfa.to_dfa()

        self.assertEqual(expected_dfa.rename_states(), dfa.rename_states())
Esempio n. 5
0
    def test_active_lstar_08(self):
        """
        try to let L* learn the regular language A.
        A is a regular language over the alphabet {0, 1} where
        each string contains an even number of 0's and an even
        number of 1's.
        """
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')
        q4 = automaton.State('4')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q1)

        expected_dfa.add_transition(q1, q2, 'b')
        expected_dfa.add_transition(q1, q4, 'a')

        expected_dfa.add_transition(q2, q1, 'b')
        expected_dfa.add_transition(q2, q3, 'a')

        expected_dfa.add_transition(q3, q2, 'a')
        expected_dfa.add_transition(q3, q4, 'b')

        expected_dfa.add_transition(q4, q3, 'b')
        expected_dfa.add_transition(q4, q1, 'a')

        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)

        lstar = algorithms.LSTAR({'a', 'b'}, teacher)
        dfa = lstar.learn()

        self.assertTrue(expected_dfa, dfa)
Esempio n. 6
0
    def test_active_nlstar_05(self):
        """
        Try to let NL* learn the regular language A.
        A is a language over the alphabet sigma = {a},
        that accepts all strings with an odd number of
        a's.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'a'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q1, q0, 'a')
        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)
        nlstar = algorithms.NLSTAR({'a'}, teacher)

        nfa = nlstar.learn()

        self.assertEqual(2, len(nfa._states))
        self.assertEqual(1, len(nfa._accept_states))

        self.assertEqual(expected_dfa, nfa.to_dfa())
Esempio n. 7
0
    def test_active_nlstar_06(self):
        """
        try to let NL* learn the regular language A.
        A is a regular language over the alphabet {0, 1} where
        each string contains an odd number of 1s
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'0', '1'}, start_state=q0)

        expected_dfa.add_transition(q0, q0, '0')
        expected_dfa.add_transition(q0, q1, '1')

        expected_dfa.add_transition(q1, q1, '0')
        expected_dfa.add_transition(q1, q0, '1')

        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)
        nlstar = algorithms.NLSTAR({'0', '1'}, teacher)

        nfa = nlstar.learn()

        self.assertEqual(2, len(nfa._states))
        self.assertEqual(1, len(nfa._accept_states))

        self.assertEqual(expected_dfa, nfa.to_dfa())
Esempio n. 8
0
    def test_active_lstar_09(self):
        """
        try to let L* learn the regular language L.
        L is a regular language over the alphabet {a, b, c} where
        every string in L is an even length.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'a', 'b', 'c'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q0, q1, 'b')
        expected_dfa.add_transition(q0, q1, 'c')

        expected_dfa.add_transition(q1, q0, 'a')
        expected_dfa.add_transition(q1, q0, 'b')
        expected_dfa.add_transition(q1, q0, 'c')

        expected_dfa.accept_states.add(q0)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'a', 'b', 'c'}, teacher)
        dfa = lstar.learn()

        self.assertEqual(expected_dfa, dfa.rename_states())
Esempio n. 9
0
    def _build_automaton(self, ot: utils.ObservationTable) -> automaton.DFA:
        """
        Builds an automaton from the observation table.

        :type ot: ObservationTable
        :return: Automaton built from the observation table
        :rtype: Automaton
        """
        dfa = automaton.DFA(self._alphabet)

        states = {automaton.State(i) for i in self._red}

        we = utils.break_strings_in_two(self._red)
        for w, e in we:
            we = w + e
            if we in self._red and ot.entry_exists(w, e):
                val = ot.get(w, e)
                state = automaton.State(we)
                if val == 1:
                    dfa.accept_states.add(state)
                    states.add(state)
                elif val == 0:
                    dfa.reject_states.add(state)
                    states.add(state)

        for w in states:
            for a in self._alphabet:
                for u in self._red:
                    wa = w.name + a
                    if ot.row_exists(u) and ot.row_exists(wa) and \
                            ot.get_row(u) == ot.get_row(wa):
                        dfa.add_transition(w, automaton.State(u), a)

        return dfa
Esempio n. 10
0
    def test_active_lstar_01(self):
        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')
        q4 = automaton.State('4')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q0, q2, 'b')

        expected_dfa.add_transition(q1, q3, 'a')
        expected_dfa.add_transition(q1, q4, 'b')

        expected_dfa.add_transition(q2, q3, 'a')
        expected_dfa.add_transition(q2, q3, 'b')

        expected_dfa.add_transition(q4, q2, 'a')
        expected_dfa.add_transition(q4, q3, 'b')

        expected_dfa.add_transition(q3, q3, 'a')
        expected_dfa.add_transition(q3, q3, 'b')

        expected_dfa.accept_states.update({q0, q1, q2, q4})

        teacher = oracle.ActiveOracle(expected_dfa)

        lstar = algorithms.LSTAR({'a', 'b'}, teacher)
        dfa = lstar.learn()
Esempio n. 11
0
    def test_nfa_01(self):
        nfa = automaton.NFA({'0', '1'})

        q1 = automaton.State('q1')
        q2 = automaton.State('q2')
        q3 = automaton.State('q3')
        q4 = automaton.State('q4')

        nfa.add_state(q1)
        nfa.add_state(q2)
        nfa.add_state(q3)
        nfa.add_state(q4)

        nfa.add_transition(q1, q1, '0')
        nfa.add_transition(q1, q1, '1')
        nfa.add_transition(q1, q2, '1')

        nfa.add_transition(q2, q3, '0')
        nfa.add_transition(q2, q3, '')

        nfa.add_transition(q3, q4, '1')

        nfa.add_transition(q4, q4, '0')
        nfa.add_transition(q4, q4, '1')

        nfa.add_accepting_state(q4)
        nfa.add_start_state(q1)

        state, accepted = nfa.parse_string('010110')
        self.assertTrue(accepted)
        self.assertEqual(state.name, 'q4')
Esempio n. 12
0
    def test_automaton_02(self):
        start_state = automaton.State('')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        dfa = automaton.DFA({'a', 'b'}, start_state)

        dfa.add_transition(start_state, start_state, 'a')
        dfa.add_transition(start_state, q1, 'b')
        dfa.add_transition(q1, q2, 'a')
        dfa.add_transition(q1, q2, 'b')

        self.assertEqual(3, len(dfa.states))
        self.assertEqual(2, len(dfa._transitions.keys()))
        self.assertTrue(dfa.transition_exists(start_state, 'a'))
        self.assertTrue(dfa.transition_exists(start_state, 'b'))
        self.assertTrue(dfa.transition_exists(q1, 'a'))

        self.assertFalse(dfa.transition_exists(q2, 'a'))
        self.assertFalse(dfa.transition_exists(q2, 'b'))

        q, a = dfa.find_transition_to_q(start_state)
        self.assertEqual('a', a)
        self.assertEqual(start_state, q)

        q, a = dfa.find_transition_to_q(q2)
        self.assertEqual('a', a)
        self.assertEqual(q1, q)
Esempio n. 13
0
    def test_nfa_to_dfa_04(self):
        nfa = automaton.NFA({'a', 'b'})

        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')

        nfa.add_state(q0)
        nfa.add_state(q1)
        nfa.add_state(q2)
        nfa.add_state(q3)

        nfa.add_transition(q0, q1, '')

        nfa.add_transition(q1, q2, '')
        nfa.add_transition(q1, q3, 'a')

        nfa.add_transition(q2, q1, 'a')

        nfa.add_transition(q3, q3, 'b')
        nfa.add_transition(q3, q2, 'a')
        nfa.add_transition(q3, q2, 'b')

        nfa.add_accepting_state(q2)

        nfa.add_start_state(q0)
        nfa.add_start_state(q1)

        dfa = nfa.to_dfa().minimize()

        self.assertEqual(4, len(dfa.states))
        self.assertEqual(3, len(dfa.accept_states))
Esempio n. 14
0
    def test_active_lstar_10(self):
        """
        try to let L* learn the regular language L.
        L is a regular language over the alphabet {a, b} where
        for every string in L, we have the following property,
        the characters at an even position should be a, the
        characters at an odd position can be a or b. The empty
        string is not accepted by the language.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q0, q1, 'b')

        expected_dfa.add_transition(q1, q2, 'b')
        expected_dfa.add_transition(q1, q3, 'a')

        expected_dfa.add_transition(q2, q2, 'a')
        expected_dfa.add_transition(q2, q2, 'b')

        expected_dfa.add_transition(q3, q1, 'a')
        expected_dfa.add_transition(q3, q1, 'b')

        expected_dfa.accept_states.update({q1, q3})

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'a', 'b'}, teacher)

        dfa = lstar.learn()

        s_plus = set()
        s_minus = set()

        for i in self._combinations({'a', 'b'}, 8):
            if i == '':
                s_minus.add(i)
                continue

            cpy = list(i[:])
            for idx in range(len(i)):
                if idx % 2 == 1:
                    cpy[idx] = 'a'

            s_plus.add(''.join(cpy))

            if all([i[q] == 'a' for q in range(1, len(i), 2)]):
                s_plus.add(i)
            else:
                s_minus.add(i)

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Esempio n. 15
0
    def test_rpni_08(self):
        """
        try to let RPNI learn the regular language L.
        L is a regular language over the alphabet {0, 1} where
        each string contains an odd number of 1s
        """
        random.seed(10012)
        s_plus = set()
        s_minus = set()

        for i in range(1, 15, 2):
            positive_example = list('1' * i + '0' * random.randint(0, 6))
            negative_example = list('1' * (i - 1) + '0' * random.randint(0, 6))

            random.shuffle(positive_example)
            random.shuffle(negative_example)

            s_plus.add(''.join(positive_example))
            s_minus.add(''.join(negative_example))

        rpni = algorithms.RPNI(s_plus, s_minus, {'0', '1'})
        dfa = rpni.learn()

        q_lambda = automaton.State('')
        q1 = automaton.State('1')

        self.assertSetEqual({q_lambda, q1}, dfa.states)
        self.assertSetEqual({q1}, dfa.accept_states)
        self.assertSetEqual({q_lambda}, dfa.reject_states)

        expected_transitions = OrderedDict({
            q_lambda:
            OrderedDict({
                '0': q_lambda,
                '1': q1,
            }),
            automaton.State('1'):
            OrderedDict({
                '0': q1,
                '1': q_lambda,
            })
        })
        self.assertSetEqual(set(map(str, expected_transitions.keys())),
                            set(map(str, dfa._transitions.keys())))

        for k in expected_transitions.keys():
            for a in expected_transitions[k].keys():
                self.assertEqual(expected_transitions[k][a],
                                 dfa._transitions[k][a])

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Esempio n. 16
0
    def test_build_automaton_01(self):
        blue = {'b', 'aa', 'ab'}
        red = {'', 'a'}
        ot = utils.ObservationTable(blue, red, {'a', 'b'})

        ot.put('', '', 0)
        ot.put('', 'a', 1)
        ot.put('a', '', 1)
        ot.put('a', 'a', 0)
        ot.put('b', '', 1)
        ot.put('b', 'a', 0)
        ot.put('aa', '', 0)
        ot.put('aa', 'a', 1)
        ot.put('ab', '', 1)
        ot.put('ab', 'a', 0)

        self.assertTrue(ot.is_closed()[0])
        self.assertTrue(ot.is_consistent())
        self.assertEqual((True, True), ot.is_closed_and_consistent())

        gold = algorithms.Gold({'a', 'b'}, set(), {'a', 'b'})
        gold._blue = blue
        gold._red = red
        dfa = gold._build_automaton(ot)

        self.assertSetEqual({'a', 'b'}, dfa.alphabet)
        self.assertTrue(2, len(dfa.states))
        self.assertTrue(1, len(dfa.accept_states))
        self.assertTrue(1, len(dfa.reject_states))

        q1 = automaton.State('')
        q2 = automaton.State('a')
        expected_transitions = OrderedDict({
            q1: OrderedDict({
                'a': q2,
                'b': q2
            }),
            q2: OrderedDict({
                'a': q1,
                'b': q2
            })
        })
        self.assertSetEqual(set(map(str, expected_transitions.keys())),
                            set(map(str, dfa._transitions.keys())))

        for k in expected_transitions.keys():
            for a in expected_transitions[k].keys():
                self.assertEqual(expected_transitions[k][a],
                                 dfa._transitions[k][a])
Esempio n. 17
0
    def _build_automaton(self, ot: utils.ObservationTable) -> automaton.DFA:
        """
        Builds an automaton from the observation table.

        :param ot: The data to build the dfa from.
        :type ot: ObservationTable
        :return: The dfa built from the observation table.
        :rtype: DFA
        """
        self._logger.info('Building DFA from the table.')
        dfa = automaton.DFA(self._alphabet)

        for u in self._red:
            for v in ot.ot.keys():
                if u == v:
                    continue

                if len(v) < len(u) and ot.get_row(v) != ot.get_row(u):
                    dfa.states.add(automaton.State(u))

        for u in dfa.states:
            if ot.entry_exists(u.name, ''):
                if ot.get(u.name, '') == 1:
                    dfa.accept_states.add(u)
                elif ot.get(u.name, '') == 0:
                    dfa.reject_states.add(u)

            for a in self._alphabet:
                for w in dfa.states:
                    if ot.get_row(u.name + a) == ot.get_row(w.name):
                        dfa.add_transition(u, w, a)

        return dfa.rename_states()
Esempio n. 18
0
    def test_renamed_and_eq_01(self):
        alphabet = {'0', '1'}

        qa = automaton.State('a')
        qb = automaton.State('b')
        qc = automaton.State('c')
        qd = automaton.State('d')
        qe = automaton.State('e')
        qf = automaton.State('f')

        dfa = automaton.DFA(alphabet, qa)

        dfa.add_transition(qa, qb, '0')
        dfa.add_transition(qa, qc, '1')

        dfa.add_transition(qb, qa, '0')
        dfa.add_transition(qb, qd, '1')

        dfa.add_transition(qc, qe, '0')
        dfa.add_transition(qc, qf, '1')

        dfa.add_transition(qd, qe, '0')
        dfa.add_transition(qd, qf, '1')

        dfa.add_transition(qe, qe, '0')
        dfa.add_transition(qe, qf, '1')

        dfa.add_transition(qf, qf, '0')
        dfa.add_transition(qf, qf, '1')

        dfa.accept_states.update({qc, qd, qe})

        dfa = dfa.minimize()

        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')

        expected_dfa = automaton.DFA(alphabet, q0)

        expected_dfa.add_transition(q0, q1, '1')
        expected_dfa.add_transition(q0, q0, '0')

        expected_dfa.add_transition(q1, q2, '1')
        expected_dfa.add_transition(q1, q1, '0')

        expected_dfa.add_transition(q2, q2, '1')
        expected_dfa.add_transition(q2, q2, '0')

        expected_dfa.accept_states.add(q1)

        self.assertEqual(expected_dfa, dfa)
Esempio n. 19
0
    def test_nfa_03(self):
        nfa = automaton.NFA({'a', 'b'})

        q1 = automaton.State('q1')
        q2 = automaton.State('q2')
        q3 = automaton.State('q3')

        nfa.add_state(q1)
        nfa.add_state(q2)
        nfa.add_state(q3)

        nfa.add_transition(q1, q2, 'b')
        nfa.add_transition(q1, q3, '')

        nfa.add_transition(q2, q2, 'a')
        nfa.add_transition(q2, q3, 'a')
        nfa.add_transition(q2, q3, 'b')

        nfa.add_transition(q3, q1, 'a')

        nfa.add_accepting_state(q1)
        nfa.add_start_state(q1)

        state, accepted = nfa.parse_string('')
        self.assertTrue(accepted)
        self.assertEqual(state.name, 'q1')

        state, accepted = nfa.parse_string('a')
        self.assertTrue(accepted)
        self.assertEqual(state.name, 'q1')

        state, accepted = nfa.parse_string('baba')
        self.assertTrue(accepted)
        self.assertEqual(state.name, 'q1')

        state, accepted = nfa.parse_string('baa')
        self.assertTrue(accepted)
        self.assertEqual(state.name, 'q1')

        _, accepted = nfa.parse_string('b')
        self.assertFalse(accepted)

        _, accepted = nfa.parse_string('bb')
        self.assertFalse(accepted)

        _, accepted = nfa.parse_string('babba')
        self.assertFalse(accepted)
Esempio n. 20
0
    def test_active_lstar_11(self):
        """
        try to let L* learn the regular language L.
        L is a regular language over the alphabet {a, b} where
        for every string in L contains exactly two a's.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q0, 'b')
        expected_dfa.add_transition(q0, q1, 'a')

        expected_dfa.add_transition(q1, q1, 'b')
        expected_dfa.add_transition(q1, q2, 'a')

        expected_dfa.add_transition(q2, q2, 'b')
        expected_dfa.add_transition(q2, q3, 'a')

        expected_dfa.add_transition(q3, q3, 'a')
        expected_dfa.add_transition(q3, q3, 'b')

        expected_dfa.accept_states.add(q2)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'a', 'b'}, teacher)

        dfa = lstar.learn()

        s_plus = set()
        s_minus = set()

        for i in self._combinations({'a', 'b'}, 11):
            if i.count('a') == 2:
                s_plus.add(i)
            else:
                s_minus.add(i)

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])

        self.assertEqual(expected_dfa, dfa)
Esempio n. 21
0
    def test_active_lstar_07(self):
        """
        try to let L* learn the regular language A.
        A is a regular language over the alphabet {0, 1} where
        each string contains 101 as a substring.
        """
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')
        q4 = automaton.State('4')

        expected_dfa = automaton.DFA({'0', '1'}, start_state=q1)

        expected_dfa.add_transition(q1, q1, '0')
        expected_dfa.add_transition(q1, q2, '1')

        expected_dfa.add_transition(q2, q2, '1')
        expected_dfa.add_transition(q2, q3, '0')

        expected_dfa.add_transition(q3, q1, '0')
        expected_dfa.add_transition(q3, q4, '1')

        expected_dfa.add_transition(q4, q4, '0')
        expected_dfa.add_transition(q4, q4, '1')

        expected_dfa.accept_states.add(q4)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'0', '1'}, teacher)
        dfa = lstar.learn()

        s_plus = set()
        s_minus = {''}
        for i in self._combinations({'0', '1'}, 10):
            if len(i) < 3:
                continue
            if '101' in i:
                s_plus.add(i)
            else:
                s_minus.add(i)

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Esempio n. 22
0
    def test_nfa_02(self):
        nfa = automaton.NFA({'0', '1'})

        q1 = automaton.State('q1')
        q2 = automaton.State('q2')
        q3 = automaton.State('q3')
        q4 = automaton.State('q4')

        nfa.add_state(q1)
        nfa.add_state(q2)
        nfa.add_state(q3)
        nfa.add_state(q4)

        nfa.add_transition(q1, q1, '0')
        nfa.add_transition(q1, q1, '1')
        nfa.add_transition(q1, q2, '1')

        nfa.add_transition(q2, q3, '0')
        nfa.add_transition(q2, q3, '1')

        nfa.add_transition(q3, q4, '0')
        nfa.add_transition(q3, q4, '1')

        nfa.add_accepting_state(q4)
        nfa.add_start_state(q1)

        s_plus = set()
        s_minus = set()
        for comb in self._combinations({'0', '1'}, 8):
            if len(comb) < 3:
                s_minus.add(comb)
            elif comb[-3] == '1':
                s_plus.add(comb)
            else:
                s_minus.add(comb)

        for s in s_plus:
            state, accepted = nfa.parse_string(s)
            self.assertTrue(accepted)
            self.assertEqual(state.name, 'q4')

        for s in s_minus:
            _, accepted = nfa.parse_string(s)
            self.assertFalse(accepted)
Esempio n. 23
0
    def test_active_lstar_04(self):
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q0, q1, 'b')

        expected_dfa.add_transition(q1, q1, 'a')
        expected_dfa.add_transition(q1, q1, 'b')

        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'a', 'b'}, teacher)

        dfa = lstar.learn()

        self.assertEqual(2, len(dfa.states))
        self.assertEqual(1, len(dfa.accept_states))
Esempio n. 24
0
    def test_minimize_01(self):
        alphabet = {'0', '1'}

        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')
        q4 = automaton.State('4')
        q5 = automaton.State('5')

        dfa = automaton.DFA(alphabet, q0)

        dfa.add_transition(q0, q3, '0')
        dfa.add_transition(q0, q1, '1')

        dfa.add_transition(q1, q2, '0')
        dfa.add_transition(q1, q5, '1')

        dfa.add_transition(q2, q2, '0')
        dfa.add_transition(q2, q5, '1')

        dfa.add_transition(q3, q4, '1')
        dfa.add_transition(q3, q0, '0')

        dfa.add_transition(q4, q2, '0')
        dfa.add_transition(q4, q5, '1')

        dfa.add_transition(q5, q5, '0')
        dfa.add_transition(q5, q5, '1')

        dfa.accept_states.update({q1, q2, q4})
        minimized_dfa = dfa.minimize()

        self.assertEqual(3, len(minimized_dfa.states))
        self.assertEqual(1, len(minimized_dfa.accept_states))
Esempio n. 25
0
    def test_rpni_09(self):
        """
        try to let RPNI learn the regular language L.
        L is a regular language over the alphabet {0, 1} where
        each string contains an odd number of 1s.
        This is for the same regular language as the test above,
        but with different example strings.
        """
        random.seed(10012)
        s_plus = set()
        s_minus = set()

        for i in range(1, 15, 2):
            s_plus.add('1' * i + '0' * random.randint(0, 6))
            s_minus.add('1' * (i - 1) + '0' * random.randint(0, 6))

        rpni = algorithms.RPNI(s_plus, s_minus, {'0', '1'})
        dfa = rpni.learn()

        self.assertEqual(10, len(dfa.states))
        self.assertSetEqual(
            {automaton.State(''),
             automaton.State('111111111')}, dfa.accept_states)
        self.assertSetEqual(
            {
                automaton.State('1'),
                automaton.State('11'),
                automaton.State('111111'),
                automaton.State('1111')
            }, dfa.reject_states)

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Esempio n. 26
0
    def test_active_nlstar_01(self):
        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')
        q4 = automaton.State('4')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q0, q2, 'b')

        expected_dfa.add_transition(q1, q3, 'a')
        expected_dfa.add_transition(q1, q4, 'b')

        expected_dfa.add_transition(q2, q3, 'a')
        expected_dfa.add_transition(q2, q3, 'b')

        expected_dfa.add_transition(q4, q2, 'a')
        expected_dfa.add_transition(q4, q3, 'b')

        expected_dfa.add_transition(q3, q3, 'a')
        expected_dfa.add_transition(q3, q3, 'b')

        expected_dfa.accept_states.update({q0, q1, q2, q4})

        teacher = oracle.ActiveOracle(expected_dfa)
        nlstar = algorithms.NLSTAR({'a', 'b'}, teacher)

        nfa = nlstar.learn()

        self.assertTrue(nfa.parse_string('')[1])
        self.assertTrue(nfa.parse_string('a')[1])
        self.assertTrue(nfa.parse_string('ab')[1])
        self.assertTrue(nfa.parse_string('aba')[1])

        self.assertFalse(nfa.parse_string('aa')[1])
        self.assertFalse(nfa.parse_string('abb')[1])
        self.assertFalse(nfa.parse_string('ba')[1])
        self.assertFalse(nfa.parse_string('bb')[1])
Esempio n. 27
0
    def learn(self) -> automaton.DFA:
        """
        Learns the grammar from the sets of positive and negative
        example strings. This method returns a DFA that is
        consistent with the sample.

        :return: DFA
        :rtype: Automaton
        """
        self._logger.info('Start learning with alphabet = {}\n'
                          'positive samples = {}\n'
                          'negative samples = {}'.format(
                              self._alphabet, self._pos_examples,
                              self._neg_examples))

        self._logger.info('Building PTA')
        dfa = automaton.build_pta(self._pos_examples)

        pref_set = utils.prefix_set(self._pos_examples)
        self._blue = {
            automaton.State(i)
            for i in self._alphabet.intersection(pref_set)
        }

        while len(self._blue) != 0:
            qb = _choose(self._blue)
            self._blue.remove(qb)

            found = False
            for qr in sorted(self._red, key=functools.cmp_to_key(_cmp)):
                if self._compatible(self._merge(dfa.copy(), qr, qb)):
                    dfa = self._merge(dfa, qr, qb)
                    new_blue_states = set()
                    for q in self._red:
                        for a in self._alphabet:
                            if dfa.transition_exists(q, a) and \
                                    dfa.transition(q, a) not in self._red:
                                new_blue_states.add(dfa.transition(q, a))

                    self._blue.update(new_blue_states)
                    found = True

            if not found:
                dfa = self._promote(qb, dfa)

        for s in self._neg_examples:
            q, accepted = dfa.parse_string(s)
            if not accepted:
                dfa.reject_states.add(q)

        return dfa.remove_dead_states()
Esempio n. 28
0
    def test_dfa_01(self):
        dfa = automaton.DFA({'a', 'b'})

        self.assertTrue(automaton.State('') in dfa.states)
        dfa.add_transition(automaton.State(''), automaton.State('a'), 'a')
        self.assertTrue(dfa.transition_exists(automaton.State(''), 'a'))
        self.assertEqual(automaton.State('a'),
                         dfa.transition(automaton.State(''), 'a'))

        try:
            dfa.add_transition(automaton.State(''), automaton.State('a'), 'c')
            self.fail('Automaton should throw ValueError when trying to add'
                      'transition with letter that is not in the alphabet!')
        except ValueError:
            self.assertTrue(True)
Esempio n. 29
0
    def test_active_lstar_03(self):
        """
        Try to let L* learn Kleene plus.
        The alphabet is sigma = {a} and the
        language accepts every string with 1
        or more a's.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')

        expected_dfa = automaton.DFA({'a'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q1, q1, 'a')

        expected_dfa.accept_states.add(q1)

        teacher = oracle.ActiveOracle(expected_dfa)
        lstar = algorithms.LSTAR({'a'}, teacher)
        dfa = lstar.learn()

        self.assertEqual(2, len(dfa.states))
        self.assertEqual(1, len(dfa.accept_states))
Esempio n. 30
0
    def test_active_nlstar_10(self):
        """
        try to let NL* learn the regular language L.
        L is a regular language over the alphabet {a, b} where
        for every string in L, we have the following property,
        the characters at an even position should be a, the
        characters at an odd position can be a or b. The empty
        string is not accepted by the language.
        """
        q0 = automaton.State('0')
        q1 = automaton.State('1')
        q2 = automaton.State('2')
        q3 = automaton.State('3')

        expected_dfa = automaton.DFA({'a', 'b'}, start_state=q0)

        expected_dfa.add_transition(q0, q1, 'a')
        expected_dfa.add_transition(q0, q1, 'b')

        expected_dfa.add_transition(q1, q2, 'b')
        expected_dfa.add_transition(q1, q3, 'a')

        expected_dfa.add_transition(q2, q2, 'a')
        expected_dfa.add_transition(q2, q2, 'b')

        expected_dfa.add_transition(q3, q1, 'a')
        expected_dfa.add_transition(q3, q1, 'b')

        expected_dfa.accept_states.update({q1, q3})

        teacher = oracle.ActiveOracle(expected_dfa)
        nlstar = algorithms.NLSTAR({'a', 'b'}, teacher)
        nfa = nlstar.learn()
        dfa = nfa.to_dfa()

        self.assertEqual(expected_dfa.rename_states(), dfa.rename_states())