Exemplo n.º 1
0
    def __computesP(self, hypothesis):
        if hypothesis is None:
            raise Exception("Hypothesis cannot be None")
        self._logger.debug("Computing P")

        P = []

        empty_word = Word([EmptyLetter()])
        current_query = OutputQuery(empty_word)
        P.append(current_query)

        open_queries = deque([current_query])
        close_queries = []

        seen_states = set([hypothesis.initial_state])
        while len(open_queries) > 0:
            query = open_queries.popleft()
            tmp_seen_states = set()

            for letter in self.input_letters:
                new_word = query.input_word + Word([letter])
                query_z = OutputQuery(new_word)
                (output_word, visited_states) = hypothesis.play_query(query_z)
                close_queries.append(query_z)

                if visited_states[-1] not in seen_states:
                    tmp_seen_states.add(visited_states[-1])
                    open_queries.append(query_z)

            seen_states.update(tmp_seen_states)

        P.extend(close_queries)

        return P
Exemplo n.º 2
0
 def _initialise_unrolling(self):
     self.cluster_information = {}
     initial_RState, pos = self.whiteboxrnn.get_first_RState()
     self.new_RStates = [
         UnrollingInfo(self.proposed_dfa.initial_state,
                       Word([EmptyLetter()]), initial_RState, pos)
     ]
Exemplo n.º 3
0
 def minimal_diverging_suffix(
         self, state1, state2
 ):  #gets series of letters showing the two states are different,
     # i.e., from which one state reaches accepting state and the other reaches rejecting state
     # assumes of course that the states are in the automaton and actually not equivalent
     res = None
     # just use BFS til you reach an accepting state
     # after experiments: attempting to use symmetric difference on copies with s1,s2 as the starting state, or even
     # just make and minimise copies of this automaton starting from s1 and s2 before starting the BFS,
     # is slower than this basic BFS, so don't
     seen_states = set()
     new_states = {(tuple(), (state1, state2))}
     while len(new_states) > 0:
         prefix, state_pair = new_states.pop()
         s1, s2 = state_pair
         if s1 != s2:  # intersection of self.F and [s1,s2] is exactly one state,
             # meaning s1 and s2 are classified differently
             res = prefix
             break
         seen_states.add(state_pair)
         for a in self.input_letters:
             next_state_pair = (s1.visit(a)[1], s2.visit(a)[1])
             #print("div_suf: next state pair: ", prefix, s1, s2, a, next_state_pair)
             next_tuple = (tuple(list(prefix) + [a]), next_state_pair)
             if not next_tuple in new_states and not next_state_pair in seen_states:
                 new_states.add(next_tuple)
     return Word(res)
Exemplo n.º 4
0
    def find_counterexample(self, hypothesis):
        if hypothesis is None:
            raise Exception("Hypothesis cannot be None")

        self._logger.info(
            "Starting the RandomWalk Algorithm to search for a counter-example"
        )

        i_step = 0
        first_step_after_restart = True
        current_state = hypothesis.initial_state

        input_word = Word()
        hypothesis_output_word = Word()
        force_restart = False
        while i_step < self.max_steps:

            # should we restart
            if not first_step_after_restart:
                if force_restart or random.random() < self.restart_probability:
                    current_state = hypothesis.initial_state
                    first_step_after_restart = True

                    counterexample_query = self.__check_equivalence(
                        input_word, hypothesis_output_word)
                    if counterexample_query is not None:
                        return counterexample_query

                    input_word = Word()
                    hypothesis_output_word = Word()
                    force_restart = False
            else:
                first_step_after_restart = False

            try:
                (new_state, input_letter,
                 output_letter) = self.__walk(current_state)
                current_state = new_state
                input_word.letters.append(input_letter)
                hypothesis_output_word.letters.append(output_letter)

            except Exception as e:
                self._logger.warn(e)
                force_restart = True

            i_step += 1
Exemplo n.º 5
0
 def _counterexample_from_cluster_conflict(self, old_info, new_info):
     q1 = old_info.dfa_state
     q2 = new_info.dfa_state
     prefixes = old_info.paths + new_info.paths
     suffix = self.parent.minimal_diverging_suffix(q1, q2)
     #print(" --- ", prefixes, suffix, prefixes[0] + suffix, type(prefixes[0]), type(suffix))
     return self._get_counterexample_from(
         [Word(p.letters + suffix.letters) for p in prefixes])
Exemplo n.º 6
0
    def __compute_distinguishable_string(self, hypothesis, couple):
        self._logger.debug(
            "Computes the distinguishable string for state couple '{}'".format(
                couple))
        if hypothesis is None:
            raise Exception("Hypothesis cannot be None")
        if couple is None:
            raise Exception("couple cannot be None")

        self._logger.debug(
            "Computing distinguishing strings for states {}".format(couple))
        queries_to_test = deque([])

        empty_word = Word([EmptyLetter()])
        z_query = OutputQuery(empty_word)
        for letter in self.input_letters:
            new_word = z_query.input_word + Word([letter])
            queries_to_test.append(OutputQuery(new_word))

        distinguishable_query = z_query

        done = False
        i = 0
        while not done:
            query = queries_to_test.popleft()
            if i > self.max_states * self.max_states:
                break

            if not self.__is_distinguishable_states(hypothesis, query, couple):
                done = False
                for letter in self.input_letters:
                    new_query = OutputQuery(query.input_word + Word([letter]))
                    queries_to_test.append(new_query)
            else:
                done = True
                distinguishable_query = query

            i = i + 1

        return distinguishable_query
Exemplo n.º 7
0
    def get_output_word(self, input_word):
        if input_word is None:
            raise Exception("Input word cannot be None")

        for root in self.roots:
            try:
                w = Word(root.traverse(input_word.letters))
                self._logger.info("I = {} > O = {}".format(input_word, w))
                return w
            except Exception:
                pass

        raise Exception("No path found")
Exemplo n.º 8
0
    def submit_word(self, word):
        self._logger.debug(
            "Submiting word '{}' to the fake target".format(word))

        if self.automata is None:
            raise Exception("Automata cannot be None")

        current_state = self.automata.initial_state
        output_letters = []
        for letter in word.letters:
            try:
                (current_state,
                 output_letter) = self._next_state(current_state, letter)
            except Exception:
                output_letter = EmptyLetter()

            output_letters.append(output_letter)

        output_word = Word(output_letters)
        return output_word
Exemplo n.º 9
0
    def _add_children_states(self, cluster):
        state_info = self.cluster_information[cluster]
        if not state_info.explored:
            # we explore a state only the first time we successfully visit and process it, and we store a state's
            # information in self.cluster_information only if we have successfully processed it.
            RState = state_info.RStates[0]
            state_info.explored = True
            for char in self.parent.input_letters:
                next_RState, pos = self.whiteboxrnn.get_next_RState(
                    RState, char)
                path = state_info.paths[0] + Word([
                    char,
                ])
                #XXXjc test
                pos = self.whiteboxrnn.submit_word(path)

                # we only ever explore a state the first
                # time we find it, so, with the first path in its list of reaching paths
                next_dfa_state = state_info.dfa_state.visit(char)[
                    1]  #self.proposed_dfa.delta[state_info.dfa_state][char]
                self.new_RStates.append(
                    UnrollingInfo(next_dfa_state, path, next_RState, pos))
Exemplo n.º 10
0
    def __computesZ(self, hypothesis, W):
        """it follows the formula Z= W U (X^1.W) U .... U (X^(m-1-n).W) U (W^(m-n).W)

        """
        if hypothesis is None:
            raise Exception("Hypothesis cannot be None")
        if W is None:
            raise Exception("W cannot be None")

        self._logger.debug("Computing Z")

        Z = []
        Z.extend(W)

        states = hypothesis.get_states()
        v = self.max_states - len(states)
        if v < 0:
            v = 0
        self._logger.debug("V= {}".format(v))

        output_queries = []
        for input_letter in self.input_letters:
            output_query = OutputQuery(word=Word([input_letter]))
            output_queries.append(output_query)

        X = dict()
        X[0] = W
        for i in range(1, v + 1):
            self._logger.debug("Computing X^{}".format(i))
            X[i] = []
            previous_X = X[i - 1]
            for x in previous_X:
                X[i].extend(x.multiply(output_queries))
            for w in W:
                for xi in X[i]:
                    if not xi in Z:
                        Z.append(xi)

        return Z
Exemplo n.º 11
0
    def play_word(self, input_word, starting_state=None):
        """This method can be used to play the specified word
        accross the current automata.
        It returns a tupple made of the output_word and the visited state
        captured while visiting the automata

        >>> from mylstar.Letter import Letter, EmptyLetter
        >>> from mylstar.Word import Word
        >>> from mylstar.automata.State import State
        >>> from mylstar.automata.Transition import Transition
        >>> from mylstar.automata.Automata import Automata
        >>> l_lambda = EmptyLetter()
        >>> l_a = Letter('a')
        >>> l_b = Letter('b')
        >>> l_0 = Letter(0)
        >>> l_1 = Letter(1)
        >>> s0 = State("S0")
        >>> s1 = State("S1")
        >>> s2 = State("S2")
        >>> s3 = State("S3")
        >>> t1 = Transition("T1", s3, l_a, l_0)
        >>> t2 = Transition("T2", s1, l_b, l_0)        
        >>> s0.transitions = [t1, t2]
        >>> t3 = Transition("T3", s0, l_a, l_1)
        >>> t4 = Transition("T4", s2, l_b, l_1)        
        >>> s1.transitions = [t3, t4]
        >>> t5 = Transition("T5", s3, l_a, l_0)
        >>> t6 = Transition("T6", s0, l_b, l_0)        
        >>> s2.transitions = [t5, t6]        
        >>> t7 = Transition("T7", s3, l_a, l_1)
        >>> t8 = Transition("T8", s3, l_b, l_1)        
        >>> s3.transitions = [t7, t8]
        >>> automata = Automata(s0)
        >>> print(automata.play_word(Word([l_a, l_a, l_a]))[0])
        [Letter(0), Letter(1), Letter(1)]
        >>> print(automata.play_word(Word([l_b, l_b, l_b]))[0])
        [Letter(0), Letter(1), Letter(0)]
        >>> print(automata.play_word(Word([l_b, l_a,  l_b, l_a, l_b]))[0])
        [Letter(0), Letter(1), Letter(0), Letter(1), Letter(0)]
        
        """

        if input_word is None or len(input_word) == 0:
            raise Exception("Input word cannot be None or empty")

        #if input_word == Word([EmptyLetter()]) and starting_state == None:
        #    self._logger.debug("Received Word([EmptyLetter()]), returning initial state")
        #    return (Word([EmptyLetter()]), self.initial_state)

        if starting_state is None:
            current_state = self.initial_state
        else:
            current_state = starting_state

        self._logger.debug("Playing word '{}'".format(input_word))

        output_letters = []
        visited_states = []
        
        for letter in input_word.letters:
            if letter == EmptyLetter():
                output_letters.append(EmptyLetter())
                visited_states.append(current_state)
                output_state = current_state
            else:
                (output_letter, output_state) = current_state.visit(letter)
                output_letters.append(output_letter)
                visited_states.append(output_state)

            current_state = output_state

        output_word = Word(letters=output_letters)
        return (output_word, visited_states)