Example #1
0
    def test_closed_and_consistent_01(self):
        ot = ObservationTable({'a', 'b'}, oracle.PassiveOracle(set(), set()))

        row1 = Row('')
        row2 = Row('b')
        row3 = Row('a')

        ot.suffixes = {'', 'aaa', 'aa', 'a'}
        ot.rows = [row1, row2, row3]
        ot.upper_rows = [row1]
        ot.lower_rows = [row2, row3]

        row1.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row2.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row3.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 0}

        ot.update_meta_data()

        self.assertEqual(2, len(ot.primes))

        nlstar = algorithms.NLSTAR({'a', 'b'}, oracle.PassiveOracle(set(), set()))
        nlstar._ot = ot

        self.assertFalse(ot.is_closed()[0])
        self.assertTrue(ot.is_consistent()[0])
Example #2
0
    def test_closed_and_consistent_02(self):
        ot = ObservationTable({'a', 'b'}, oracle.PassiveOracle(set(), set()))

        row1 = Row('')
        row2 = Row('b')
        row3 = Row('a')

        ot.suffixes = {'', 'aaa', 'aa', 'a'}
        ot.rows = {row1, row2, row3}
        ot.upper_rows = {row1}
        ot.lower_rows = {row2, row3}

        row1.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row2.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row3.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 0}

        ot.update_meta_data()

        self.assertEqual(2, len(ot.primes))
        self.assertEqual(1, len(ot.rows.symmetric_difference(ot.primes)))

        nlstar = algorithms.NLSTAR({'a', 'b'}, oracle.PassiveOracle(set(), set()))
        nlstar._ot = ot

        closed_info, consistency_info = ot.is_closed_and_consistent()
        is_closed, unclosed_rows = closed_info
        is_consistent, _, _ = consistency_info

        self.assertFalse(is_closed)
        self.assertTrue(is_consistent)

        nlstar._close_table(unclosed_rows)

        self.assertEqual(5, len(nlstar._ot.rows))
Example #3
0
    def test_passive_lstar_13(self):
        """
        try to let L* learn the regular language L.
        L is a regular language over the alphabet {a, b, c} where
        for every string in L, we have the following property,
        the character at the 3rd position from the end of the string
        should be an a.
        """
        s_plus = set()
        s_minus = set()

        for i in self._combinations({'a', 'b', 'c'}, 6):
            if len(i) < 3:
                s_minus.add(i)
                continue

            cpy_1 = list(i)
            cpy_2 = list(i)
            cpy_3 = list(i)
            cpy_1[-3] = 'a'
            cpy_2[-3] = 'b'
            cpy_3[-3] = 'c'

            s_plus.add(''.join(cpy_1))

            s_minus.add(''.join(cpy_2))
            s_minus.add(''.join(cpy_3))

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'a', 'b', 'c'}, teacher)

        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #4
0
    def test_passive_nlstar_10(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 even number of 0's and an even
        number of 1's.
        """
        random.seed(10012)
        s_plus = set()
        s_minus = set()

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

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        nlstar = algorithms.NLSTAR({'0', '1'}, teacher)
        nfa = nlstar.learn()

        for s in s_plus:
            self.assertTrue(nfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(nfa.parse_string(s)[1])
Example #5
0
    def test_passive_nlstar_01(self):
        s_plus = {'a' * i for i in range(25)}

        teacher = oracle.PassiveOracle(s_plus, set())
        nlstar = algorithms.NLSTAR({'a'}, teacher)
        nfa = nlstar.learn()

        self.assertEqual(1, len(nfa._states))
        self.assertEqual(1, len(nfa._accept_states))
        self.assertTrue(nfa.parse_string('a' * 1000)[1])
Example #6
0
    def test_passive_lstar_01(self):
        s_plus = {'', 'a', 'b', 'ab', 'aba'}
        s_minus = {'abb'}
        teacher = oracle.PassiveOracle(s_plus, s_minus)

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

        self.assertEqual(5, len(dfa.states))
        self.assertEqual(4, len(dfa.accept_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])
Example #7
0
    def test_passive_lstar_17(self):
        s_plus = set()
        s_minus = set()

        for i in self._combinations({'a', '1', '#'}, 8):
            if 'a' in i and '1' in i and '#' in i:
                s_plus.add(i)
            else:
                s_minus.add(i)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'a', '1', '#'}, teacher)
        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #8
0
    def test_passive_nlstar_02(self):
        """
        Try to let NL* learn Kleene plus.
        The alphabet is sigma = {a} and the
        language accepts every string with 1
        or more a's.
        """
        s_plus = {'a', 'aa', 'aaa', 'aaaa', 'aaaaaaaa'}
        s_minus = {''}

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        nlstar = algorithms.NLSTAR({'a'}, teacher)
        nfa = nlstar.learn()

        self.assertEqual(2, len(nfa._states))
        self.assertEqual(1, len(nfa._accept_states))
    def test_ot_02(self):
        ot = ObservationTable({'a', 'b'}, oracle.PassiveOracle(set(), set()))
        row1 = Row('')
        row2 = Row('a')
        row3 = Row('ab')
        row4 = Row('abb')
        row5 = Row('b')
        row6 = Row('aa')

        row7 = Row('aba')
        row8 = Row('abbb')
        row9 = Row('abba')

        ot.suffixes = {'', 'aaa', 'aa', 'a'}

        ot.rows = {row1, row2, row3, row4, row5, row6, row7, row8, row9}

        ot.upper_rows = {row1, row2, row3, row4}
        ot.lower_rows = {row5, row6, row7, row8, row9}

        row1.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row2.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 0}

        row3.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 1}
        row4.columns = {'': 1, 'aaa': 1, 'aa': 0, 'a': 0}

        row5.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row6.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 1}
        row7.columns = {'': 1, 'aaa': 1, 'aa': 1, 'a': 0}
        row8.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row9.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 0}

        ot.update_meta_data()

        composed_rows = ot.primes.symmetric_difference(ot.rows)

        self.assertEqual(7, len(ot.primes))
        self.assertEqual(2, len(composed_rows))

        for i in ['', 'a', 'ab', 'abb', 'b', 'abbb', 'abba']:
            self.assertTrue(i in map(lambda r: r.prefix, ot.primes))

        for i in ['aa', 'aba']:
            self.assertTrue(i in map(lambda r: r.prefix, composed_rows))
Example #10
0
    def test_passive_lstar_16(self):
        s_plus = set()
        s_minus = set()

        reps = set('a' * i for i in range(1, 9))
        for i in reps:
            for j in reps:
                s_plus.add('{}@{}'.format(i, j))

        reps_with_empty = set('a' * i for i in range(9))
        s_minus.add('@')
        for i in reps_with_empty:
            s_minus.add('{}@'.format(i))
            s_minus.add('@{}'.format(i))
            s_minus.add('@{}@'.format(i))
            s_minus.add('@{}@@'.format(i))
            s_minus.add('@{}@@@'.format(i))
            for j in reps_with_empty:
                s_minus.add('@{}@{}'.format(i, j))
                s_minus.add('{}@{}@'.format(i, j))
                s_minus.add('{}@{}@@'.format(i, j))
                s_minus.add('{}@{}@@@'.format(i, j))
                s_minus.add('{}@{}@@@@'.format(i, j))

                s_minus.add('{}@{}@@{}'.format(i, j, i))
                s_minus.add('{}@{}@@@{}'.format(i, j, i))
                s_minus.add('{}@{}@@@@{}'.format(i, j, i))

        s_minus.update(reps_with_empty)

        s_minus.update({
            'a@a@a@a', 'aa@aa@', 'aaaa@aaaaa@aaaaa', 'a@@a@a'
            'aa@@a@a'
            'aa@@aaa@a'
        })

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'a', '@'}, teacher)
        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #11
0
    def test_passive_lstar_09(self):
        """
        try to let L* learn the regular language A.
        A is a regular language over the alphabet {0, 1} where
        each string does not contain 101 as a substring.
        """
        s_plus = {''}
        s_minus = set()
        for i in self._combinations({'0', '1'}, 6):
            if '101' in i:
                s_minus.add(i)
            else:
                s_plus.add(i)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'0', '1'}, teacher)
        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #12
0
    def test_passive_lstar_05(self):
        s_plus = set()
        s_minus = set()
        for i in self._combinations({'a', 'b'}, 4):
            if i == '':
                s_minus.add(i)
            else:
                s_plus.add(i)

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

        self.assertEqual(2, len(dfa.states))
        self.assertEqual(1, len(dfa.accept_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])
Example #13
0
    def test_passive_lstar_02(self):
        s_plus = {'', 'a', 'b', 'ab', 'aa', 'aba', 'aab', 'abab'}
        s_minus = {'abb'}

        teacher = oracle.PassiveOracle(s_plus, s_minus)

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

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

        expected_transitions = OrderedDict({
            automaton.State('0'):
            OrderedDict({
                'a': automaton.State('0'),
                'b': automaton.State('1'),
            }),
            automaton.State('1'):
            OrderedDict({
                'a': automaton.State('0'),
                'b': automaton.State('2'),
            }),
            automaton.State('2'):
            OrderedDict({
                'a': automaton.State('2'),
                'b': automaton.State('2'),
            })
        })
        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])
Example #14
0
    def test_passive_lstar_14(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.
        """
        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)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'a', 'b'}, teacher)

        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #15
0
    def test_passive_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 an odd number of 1s
        """
        random.seed(10012)
        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)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'0', '1'}, teacher)
        dfa = lstar.learn()

        for s in s_plus:
            self.assertTrue(dfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #16
0
    def test_passive_nlstar_09(self):
        """
        try to let NL* learn the regular language L.
        L is a regular language over the alphabet {a, b} where
        every string in L is an odd length.
        """
        s_plus = set()
        s_minus = set()

        for i in self._combinations({'a', 'b'}, 6):
            if len(i) % 2 == 1:
                s_plus.add(i)
            else:
                s_minus.add(i)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        nlstar = algorithms.NLSTAR({'a', 'b'}, teacher)
        nfa = nlstar.learn()

        for s in s_plus:
            self.assertTrue(nfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(nfa.parse_string(s)[1])
Example #17
0
    def test_passive_nlstar_05(self):
        """
        try to let NL* learn the regular language A.
        A is a regular language over the alphabet {a, b, c} where
        each string contains an even number of a's
        """
        random.seed(10012)
        s_plus = set()
        s_minus = set()
        for i in self._combinations({'a', 'b', 'c'}, 6):
            if i == '':
                continue
            if i.count('a') % 2 == 0:
                s_plus.add(i)
            else:
                s_minus.add(i)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        nlstar = algorithms.NLSTAR({'a', 'b', 'c'}, teacher)
        nfa = nlstar.learn()

        for s in s_minus:
            self.assertFalse(nfa.parse_string(s)[1])
Example #18
0
    def test_passive_lstar_12(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.
        """
        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)

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'a', 'b'}, teacher)

        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #19
0
    def test_passive_nlstar_04(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.
        """
        s_plus = set()
        s_minus = set()
        for i in range(1, 21, 2):
            s_plus.add('a' * i)
            s_minus.add('a' * (i - 1))

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        nlstar = algorithms.NLSTAR({'a'}, teacher)
        nfa = nlstar.learn()

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

        for s in s_plus:
            self.assertTrue(nfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(nfa.parse_string(s)[1])
Example #20
0
    def test_passive_lstar_15(self):
        """
        try to let L* learn the regular language L.
        L is a regular language over the alphabet {0, 1, .} where
        for every string in L represent a made up IP address format.
        X.X.X where X is either 0 or 1 and the length of X is 1, 2 or 3.
        """
        s_plus = set()
        s_minus = set()

        valid_length = list(
            filter(lambda st: st != '', self._combinations({'0', '1'}, 3)))
        invalid_lengths = list(
            filter(lambda st: len(st) == 0 or len(st) > 3,
                   self._combinations({'0', '1'}, 6)))

        random.seed(10012)
        s_minus.update(random.sample(invalid_lengths, 35))

        random.seed(132)
        first_part = random.sample(invalid_lengths, 15)
        random.seed(1001)
        for i in first_part:
            s_minus.add('{}.'.format(i))
            s_minus.add('{}..'.format(i))
            s_minus.add('{}...'.format(i))
            s_minus.add('{}.{}'.format(i,
                                       random.sample(invalid_lengths, 1)[0]))

        random.seed(54328)
        second_part = random.sample(invalid_lengths, 15)
        random.seed(2212)
        for i in second_part:
            s_minus.add('{}.'.format(i))
            s_minus.add('{}.{}'.format(i,
                                       random.sample(invalid_lengths, 1)[0]))
            s_minus.add('{}.{}.'.format(i,
                                        random.sample(invalid_lengths, 1)[0]))

        first = valid_length[:]
        second = []
        for i in first:
            for j in valid_length:
                second.append('{}.{}'.format(i, j))

        for i in second:
            for j in valid_length:
                s_plus.add('{}.{}'.format(i, j))

        random.seed(90432)

        s_minus.update({
            '10.10', '1.0', '1.1', '0.0', '101.001', '101.001..10', '0.10.10.',
            '0.10.10..', '0.10.10...', '0.10.10....', '0.10..10....',
            '0.10...10....', '1..', '0..', '0...', '1...', '10...101.10',
            '10...01.10', '10.01..10', '0.1..10', '01.101..10', '01...'
            '101..101', '.', '101..1.01'
        })

        teacher = oracle.PassiveOracle(s_plus, s_minus)
        lstar = algorithms.LSTAR({'0', '1', '.'}, teacher)
        dfa = lstar.learn()

        for s in s_minus:
            self.assertFalse(dfa.parse_string(s)[1])
Example #21
0
    def test_build_hypothesis_01(self):
        ot = ObservationTable({'a', 'b'}, oracle.PassiveOracle(set(), set()))
        row1 = Row('')
        row2 = Row('a')
        row3 = Row('ab')
        row4 = Row('abb')
        row5 = Row('b')
        row6 = Row('aa')

        row7 = Row('aba')
        row8 = Row('abbb')
        row9 = Row('abba')

        ot.suffixes = {'', 'aaa', 'aa', 'a'}

        ot.rows = {row1, row2, row3, row4, row5, row6, row7, row8, row9}

        ot.upper_rows = {row1, row2, row3, row4}
        ot.lower_rows = {row5, row6, row7, row8, row9}

        row1.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row2.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 0}

        row3.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 1}
        row4.columns = {'': 1, 'aaa': 1, 'aa': 0, 'a': 0}

        row5.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row6.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 1}
        row7.columns = {'': 1, 'aaa': 1, 'aa': 1, 'a': 0}
        row8.columns = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}
        row9.columns = {'': 0, 'aaa': 1, 'aa': 1, 'a': 0}

        ot.prefix_to_row = {r.prefix: r for r in ot.rows}

        ot.update_meta_data()

        nlstar = algorithms.NLSTAR({'a', 'b'}, oracle.PassiveOracle(set(), set()))
        nlstar._ot = ot

        nfa = nlstar._build_hypothesis()
        self.assertEqual(4, len(nfa._states))
        self.assertEqual(1, len(nfa._accept_states))

        s_plus = set()
        s_minus = set()

        so_long = []

        for i in self._combinations({'a', 'b'}, 6):
            so_long.append(i)

        for i in self._combinations({'a', 'b'}, 2):
            if len(i) != 2:
                continue

            for pre in so_long:
                s_plus.add('{}a{}'.format(pre, i))
                s_minus.add('{}b{}'.format(pre, i))

        for s in s_plus:
            self.assertTrue(nfa.parse_string(s)[1])
        for s in s_minus:
            self.assertFalse(nfa.parse_string(s)[1])