Exemplo n.º 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])
Exemplo n.º 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))
Exemplo n.º 3
0
 def add_columns_to_row(self, row: Row):
     """
     Adds all of the suffixes that are
     currently in the observation table
     to the given row.
     :param row: Row to whom the suffixes
                 should be added for.
     :type row: Row
     """
     for suffix in self.suffixes:
         mq = self._oracle.membership_query(row.prefix + suffix)
         row.columns[suffix] = mq
Exemplo n.º 4
0
    def initialize(self):
        """
        Initializes the observation table.
        The prefix-closed set is initialized
        with the empty string and all of the
        symbols in the alphabet of the regular
        language we are trying to infer.
        The suffix-closed set is initialized
        with the empty string.
        """
        row = Row('')
        self.rows.add(row)
        self.upper_rows.add(row)
        self.prefix_to_row[row.prefix] = row

        for symbol in self._alphabet:
            row = Row(symbol)
            self.rows.add(row)
            self.lower_rows.add(row)
            self.prefix_to_row[row.prefix] = row

        self.add_suffix('')

        self.update_meta_data()
Exemplo n.º 5
0
    def is_closed(self) -> Tuple[bool, Row]:
        """
        An observation table is closed if and only if
        any prime row of the lower part is a prime row
        of the upper part.

        :return: Whether the table is closed, along with
                 the unclosed row if there is one.
        :rtype: Tuple[bool, Row]
        """
        for row in self.lower_rows:
            covered = [r_prime for r_prime in self.upper_primes if r_prime.covered_by(row)]

            if len(covered) == 0 or \
                    not Row.join(covered).columns_are_equal(row):
                return False, row

        return True, None
Exemplo n.º 6
0
    def _close_table(self, unclosed_row):
        """
        Attempts to close the observation table
        by adding a new row to the table.
        """
        self._logger.info('Attempting to close the table by adding a new row.')

        self._ot.upper_rows.add(unclosed_row)
        self._ot.lower_rows.remove(unclosed_row)
        self._ot.upper_primes.add(unclosed_row)

        for symbol in self._alphabet:
            new_row = Row(unclosed_row.prefix + symbol)

            self._ot.rows.add(new_row)
            self._ot.lower_rows.add(new_row)
            self._ot.prefix_to_row[new_row.prefix] = new_row

            self._ot.add_columns_to_row(new_row)

        self._ot.update_meta_data()
Exemplo n.º 7
0
    def test_ot_01(self):
        ot = ObservationTable({'a', 'b'}, oracle.PassiveOracle(set(), set()))
        row1 = Row('')
        row2 = Row('a')
        row3 = Row('ab')
        row4 = Row('b')
        row5 = Row('aa')
        row6 = Row('abb')
        row7 = Row('aba')

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

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

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

        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 = {'': 0, 'aaa': 1, 'aa': 0, 'a': 0}

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

        ot.update_meta_data()

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

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

        for i in ['', 'a', 'ab', 'b', 'abb']:
            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))
Exemplo n.º 8
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])