Ejemplo n.º 1
0
    def test_complete_when_dfa_is_not_complete(self):
        """Test that when we try to make complete a non-complete SimpleDFA
        then the returned SimpleDFA is complete."""

        dfa = SimpleDFA(
            {"q0", "q1"},
            MapAlphabet({"a", "b"}),
            "q0",
            set(),
            {"q0": {"a": "q0", "b": "q1"}},
        )

        expected_dfa = SimpleDFA(
            {"q0", "q1", "sink"},
            MapAlphabet({"a", "b"}),
            "q0",
            set(),
            {
                "q0": {"a": "q0", "b": "q1"},
                "q1": {"a": "sink", "b": "sink"},
                "sink": {"a": "sink", "b": "sink"},
            },
        )

        actual_dfa = dfa.complete()
        assert actual_dfa == expected_dfa
Ejemplo n.º 2
0
def graph_automata(states, alphabet, initial_state, accepting_states, transition_function, name, minimize = False):
    dfa = SimpleDFA(states, alphabet, initial_state, accepting_states, transition_function)

    if minimize:
        graph = dfa.minimize().trim().to_graphviz()
    else:
        graph = dfa.to_graphviz()
    graph.render(name)
Ejemplo n.º 3
0
 def test_is_complete_when_dfa_is_not_complete(self):
     """Test that the is_complete method return False if the SimpleDFA is not complete."""
     dfa = SimpleDFA(
         {"q0", "q1"},
         MapAlphabet({"a", "b"}),
         "q0",
         set(),
         {"q0": {"a": "q0", "b": "q1"}},
     )
     assert not dfa.is_complete()
Ejemplo n.º 4
0
    def test_complete_when_dfa_is_already_complete(self):
        """Test that when we try to make complete an already complete SimpleDFA
        then the returned SimpleDFA is equal to the previous one."""

        complete_dfa = SimpleDFA(
            {"q"}, MapAlphabet({"a"}), "q", set(), {"q": {"a": "q"}}
        )

        new_dfa = complete_dfa.complete()
        assert complete_dfa == new_dfa
Ejemplo n.º 5
0
    def test_reachable_no_transitions(self):
        """Test that the reachable SimpleDFA of a SimpleDFA without transitions
        is the SimpleDFA with only the initial state."""

        dfa = SimpleDFA({"q0", "q1", "q2"}, MapAlphabet({"a1", "a2"}), "q0", {"q1"}, {})

        actual_reachable_dfa = dfa.reachable()
        expected_reachable_dfa = SimpleDFA(
            {"q0"}, MapAlphabet({"a1", "a2"}), "q0", set(), {}
        )

        assert actual_reachable_dfa == expected_reachable_dfa
Ejemplo n.º 6
0
    def GraphDFA(self):
        states = set(self.trans_func.keys())
        alphabet = set(self.symbols)

        dfa = SimpleDFA(states, alphabet, self.initial_state,
                        self.accepting_states, self.trans_func)

        graph = dfa.trim().to_graphviz()
        graph.attr(rankdir='LR')

        source = graph.source
        WriteToFile('./output/DirectDFA.gv', source)
        graph.render('./output/DirectDFA.gv', format='pdf', view=True)
Ejemplo n.º 7
0
    def test_to_graphviz(self):

        dfa = SimpleDFA(
            {"q0", "q1", "q2", "q3", "q4", "q5"},
            MapAlphabet({"a", "b"}),
            "q0",
            {"q0"},
            {},
        )

        dfa.to_graphviz()

        dfa = SimpleDFA(
            {"q0", "q1", "q2", "q3", "q4", "q5"},
            MapAlphabet({"a", "b"}),
            "q0",
            {"q3"},
            {
                "q0": {"a": "q0", "b": "q1"},
                "q1": {"a": "q0", "b": "q2"},
                "q2": {"a": "q3", "b": "q4"},
                "q3": {"a": "q3", "b": "q4"},
                "q4": {"a": "q3", "b": "q5"},
            },
        )

        dfa.to_graphviz()
Ejemplo n.º 8
0
    def test_coreachable_no_accepting_states_gives_empty_dfa(self):

        dfa = SimpleDFA(
            {"q0", "q1", "q2"},
            MapAlphabet({"a1", "a2"}),
            "q0",
            set(),
            {"q0": {"a1": "q0", "a2": "q1"}},
        )

        actual_coreachable = dfa.coreachable()

        expected_coreachable = EmptyDFA(MapAlphabet({"a1", "a2"}))

        assert actual_coreachable == expected_coreachable
Ejemplo n.º 9
0
    def test_coreachable_simple_case(self):

        dfa = SimpleDFA(
            {"q0", "q1", "q2"},
            MapAlphabet({"a1", "a2"}),
            "q0",
            {"q0"},
            {"q0": {"a1": "q0", "a2": "q1"}},
        )

        actual_coreachable = dfa.coreachable()

        expected_coreachable = SimpleDFA(
            {"q0"}, MapAlphabet({"a1", "a2"}), "q0", {"q0"}, {"q0": {"a1": "q0"}}
        )

        assert actual_coreachable == expected_coreachable
Ejemplo n.º 10
0
 def setup_class(cls):
     """Set the test up."""
     cls.dfa = SimpleDFA(
         {0, 1, 2},
         MapAlphabet(["a", "b", "c"]),
         0,
         {2},
         {0: {"a": 0, "b": 1}, 1: {"b": 1, "c": 2}, 2: {"c": 2}},
     )
Ejemplo n.º 11
0
def test_dfa_from_transitions():
    """Test that the constructor "from_transitions" works correctly."""

    states = {"q0", "q1", "q2"}
    actions = MapAlphabet({"a0", "a1"})
    initial_state = "q0"
    final_states = {"q2"}
    transition_function = {"q0": {"a0": "q1"}, "q1": {"a1": "q2"}}

    expected_dfa = SimpleDFA(
        states, actions, initial_state, final_states, transition_function
    )

    actual_dfa = SimpleDFA.from_transitions(
        initial_state, final_states, transition_function
    )

    assert expected_dfa == actual_dfa
Ejemplo n.º 12
0
 def setup_class(cls):
     """Set the test up."""
     cls.dfa = SimpleDFA(
         {0, 1, 2},
         ["a", "b", "c"],
         0,
         {2},
         {
             0: {"a": 0, "b": 1, "c": 2},
             1: {"a": 0, "b": 1, "c": 2},
             2: {"a": 0, "b": 1, "c": 2},
         },
     )
Ejemplo n.º 13
0
 def test_transition_function_with_invalid_symbols_raises_error(self):
     """Test that if a symbol of some transitions is invalid we raise an error."""
     with pytest.raises(
         ValueError,
         match="Transition function not valid: symbols .* are not in the alphabet.",
     ):
         SimpleDFA(
             {"q0", "q1"},
             MapAlphabet({"a"}),
             "q0",
             set(),
             {"q0": {"a": "q1"}, "q1": {"b": "q1"}},
         )
Ejemplo n.º 14
0
    def test_minimize(self):

        dfa = SimpleDFA(
            {"q0", "q1", "q2", "q3", "q4"},
            MapAlphabet({"a", "b", "c"}),
            "q0",
            {"q3", "q4"},
            {
                "q0": {"a": "q1", "b": "q2"},
                "q1": {"c": "q3"},
                "q2": {"c": "q3"},
                "q3": {"c": "q4"},
                "q4": {"c": "q4"},
            },
        )

        actual_minimized_dfa = dfa.minimize()

        # the renaming of the states is non deterministic, so we need to compare every substructure.
        assert len(actual_minimized_dfa._states) == 4
        assert actual_minimized_dfa._alphabet == ArrayAlphabet(["a", "b", "c"])
        assert actual_minimized_dfa.is_complete()
Ejemplo n.º 15
0
    def test_level_to_accepting_states(self):
        dfa = SimpleDFA(
            {"q0", "q1", "q2", "q3", "q4", "q5"},
            MapAlphabet({"a", "b"}),
            "q0",
            {"q3"},
            {
                "q0": {"a": "q0", "b": "q1"},
                "q1": {"a": "q0", "b": "q2"},
                "q2": {"a": "q3", "b": "q4"},
                "q3": {"a": "q3", "b": "q4"},
                "q4": {"a": "q3", "b": "q5"},
            },
        )

        assert dfa.levels_to_accepting_states() == {
            "q0": 3,
            "q1": 2,
            "q2": 1,
            "q3": 0,
            "q4": 1,
            "q5": -1,
        }
Ejemplo n.º 16
0
def problem_dfa():
    """
    Create DFA for problem domain.
    :return: SimpleDFA object
    """
    alphabet = {
        "wait,s0", "wait,s1", "wait,s2", "wait,s3", "wait,s4", "wait,s5",
        "wait,s6", "mov_hw1,s5", "mov_hw2,s6", "mov_w1w2,s3", "mov_w1h,s1",
        "mov_w2h,s2", "mov_w2w1,s3", "mov_w12h,s4", "start,s0"
    }
    states = {"s0", "s1", "s2", "s3", "s4", "s5", "s6", 's_init'}
    initial_state = "s_init"
    accepting_states = {"s0", "s1", "s2", "s3", "s4", "s5", "s6"}
    transition_function = {
        "s_init": {
            "start,s0": "s0",
        },
        "s0": {
            "mov_hw1,s5": "s5",
            "mov_hw2,s6": "s6",
            "wait,s0": "s0"
        },
        "s5": {
            "mov_w1w2,s3": "s3",
            "mov_w1h,s1": "s1",
            "wait,s5": "s5"
        },
        "s6": {
            "mov_w2w1,s3": "s3",
            "mov_w2h,s2": "s2",
            "wait,s6": "s6"
        },
        "s3": {
            "mov_w12h,s4": "s4",
            "wait,s3": "s3"
        },
        "s1": {
            "wait,s1": "s1"
        },
        "s2": {
            "wait,s2": "s2"
        },
        "s4": {
            "wait,s4": "s4"
        }
    }
    dfa = SimpleDFA(states, alphabet, initial_state, accepting_states,
                    transition_function)
    return dfa
Ejemplo n.º 17
0
def intersection(prb_dfa, ltl_dfa):
    """
    Build the intersection DFA automaton between
    problem DFA and LTL DFA.
    :param prb_dfa: problem DFA
    :param ltl_dfa: LTL formula DFA
    :return: SimpleDFA object
    """
    parser = LTLfParser()
    alphabet = prb_dfa.alphabet
    states = set({})
    initial_state = "[" + prb_dfa.initial_state + "," + str(
        ltl_dfa.initial_state) + "]"
    accepting_states = set({})
    transition_function = {}
    explore = {(prb_dfa.initial_state, str(ltl_dfa.initial_state))}

    while len(explore) is not 0:
        state = explore.pop()
        state_intersection = "[" + state[0] + "," + state[1] + "]"
        states.add(state_intersection)
        if prb_dfa.is_accepting(state[0]) and ltl_dfa.is_accepting(
                int(state[1])):
            accepting_states.add(state_intersection)
        for letter in alphabet:
            successor = prb_dfa.get_successors(state[0], letter)
            if len(successor) is not 0:
                prob_state = successor.pop()
                ltl_state = state[1]
                props = [propositions[prob_state]]
                transitions = ltl_dfa.get_transitions_from(int(state[1]))
                for transition in transitions:
                    formula = ltl_extract_formula(transition)
                    if parser(str(formula).replace("~", "!")).truth(props, 0):
                        ltl_state = str(ltl_extract_next_state(transition))
                        break
                new_state_intersection = "[" + prob_state + "," + ltl_state + "]"
                if new_state_intersection not in states:
                    explore.add((prob_state, ltl_state))
                if state_intersection not in transition_function:
                    transition_function[state_intersection] = {
                        letter: new_state_intersection
                    }
                else:
                    transition_function[state_intersection][
                        letter] = new_state_intersection

    return SimpleDFA(states, alphabet, initial_state, accepting_states,
                     transition_function)
Ejemplo n.º 18
0
    def test_trim_simple_case(self):
        dfa = SimpleDFA(
            {"q0", "q1", "q2", "sink"},
            MapAlphabet({"a", "b"}),
            "q0",
            {"q1"},
            {
                "q0": {"a": "q0", "b": "q1"},
                "q1": {"a": "sink", "b": "sink"},
                "sink": {"a": "sink", "b": "sink"},
            },
        )

        actual_trimmed_dfa = dfa.trim()

        expected_trimmed_dfa = SimpleDFA(
            {"q0", "q1"},
            MapAlphabet({"a", "b"}),
            "q0",
            {"q1"},
            {"q0": {"a": "q0", "b": "q1"}},
        )

        assert actual_trimmed_dfa == expected_trimmed_dfa
Ejemplo n.º 19
0
def serverGateway(alphabet, states, initialState, acceptingState,
                  transitionList):
    transitionFunction = _getTransitionFunction(states, transitionList)
    alphabet = set(alphabet)
    states = set(states)
    acceptingState = set(acceptingState)

    dfa = SimpleDFA(states, alphabet, initialState, acceptingState,
                    transitionFunction)

    initialDFAGraph = dfa.to_graphviz()
    initialDFAGraph.render("initial", view=False, format='png')

    minimizedDFA = dfa.minimize()
    graph = minimizedDFA.trim().to_graphviz()
    graph.render("graph", view=False, format='png')

    with open("initial.png", "rb") as image_file:
        initialGraphEncoded = base64.b64encode(image_file.read())

    with open("graph.png", "rb") as image_file:
        finalGraphEncoded = base64.b64encode(image_file.read())

    return [initialGraphEncoded, finalGraphEncoded]
Ejemplo n.º 20
0
 def test_transition_function_with_invalid_end_states_raises_error(self):
     """Test that if some of the ending states of the transitions is not in
      the set of states we raise an error."""
     with pytest.raises(
         ValueError,
         match="Transition function not valid: states .* "
         "are not in the set of states.",
     ):
         SimpleDFA(
             {"q0", "q1"},
             MapAlphabet({"a"}),
             "q0",
             set(),
             {"q0": {"a": "q1"}, "q1": {"a": "q2"}},
         )
Ejemplo n.º 21
0
    def test_equality(self):
        """Test that the equality between two SimpleDFA works correctly."""
        assert self.dfa == self.dfa

        another_dfa = SimpleDFA(
            {0, 1, 2},
            MapAlphabet(["a", "b", "c"]),
            0,
            {2},
            {
                0: {"a": 0, "b": 1, "c": 2},
                1: {"a": 0, "b": 1, "c": 2},
                2: {"a": 0, "b": 1, "c": 2},
            },
        )
        assert self.dfa == another_dfa
Ejemplo n.º 22
0
    def test_accepts(self):

        dfa = SimpleDFA(
            {"q0", "q1"},
            MapAlphabet({"a", "b"}),
            "q0",
            {"q1"},
            {"q0": {"a": "q0", "b": "q1"}},
        )

        assert not dfa.accepts([])
        assert not dfa.accepts(["a"])
        assert not dfa.accepts(["a"])
        assert dfa.accepts(["b"])
        assert dfa.accepts(["a", "b"])
        assert not dfa.accepts(["a", "a"])
        assert not dfa.accepts(["b", "b"])
Ejemplo n.º 23
0
def test_even_01_automaton():
    """Test the even-01 automaton in the documentation."""

    states = {"q0", "q1", "q2", "q3"}
    alphabet = {"0", "1"}
    initial_state = "q0"
    accepting_states = {"q0"}
    transition_function = {
        "q0": {
            "0": "q2",
            "1": "q1"
        },
        "q1": {
            "0": "q3",
            "1": "q0"
        },
        "q2": {
            "0": "q0",
            "1": "q3"
        },
        "q3": {
            "0": "q1",
            "1": "q2"
        },
    }
    automaton = SimpleDFA(
        states=states,
        alphabet=alphabet,
        initial_state=initial_state,
        accepting_states=accepting_states,
        transition_function=transition_function,
    )

    assert automaton.is_complete()

    assert automaton.accepts("")  # True
    assert not automaton.accepts("0")  # False - only one '0'
    assert not automaton.accepts("1")  # False - only one '1'
    assert automaton.accepts("00")  # True
    assert automaton.accepts("11")  # True
    assert automaton.accepts("01" * 42)  # True
Ejemplo n.º 24
0
 def test_is_complete_when_dfa_is_complete(self):
     """Test that the is_complete method return True if the SimpleDFA is complete."""
     dfa = SimpleDFA({"q"}, MapAlphabet({"a"}), "q", set(), {"q": {"a": "q"}})
     assert dfa.is_complete()
Ejemplo n.º 25
0
 def test_initial_state_not_in_states_raises_error(self):
     """Test that if the initial state is not in the set of states we raise an error."""
     with pytest.raises(
         ValueError, match="Initial state .* not in the set of states."
     ):
         SimpleDFA(set("q1"), MapAlphabet({"a"}), "q0", set(), {})
Ejemplo n.º 26
0
 def test_empty_set_of_states_raises_error(self):
     """Test that when we try to instantiate a DFA with an empty set of states we raise an error."""
     with pytest.raises(ValueError, match="The set of states cannot be empty."):
         SimpleDFA(set(), MapAlphabet({"a"}), "q0", set(), {})
Ejemplo n.º 27
0
 def test_some_accepting_states_not_in_states_raises_error(self):
     """Test that if some accepting states are not in the set of states we raise an error."""
     with pytest.raises(
         ValueError, match="Accepting states .* not in the set of states."
     ):
         SimpleDFA({"q0", "q1"}, MapAlphabet({"a"}), "q0", {"q2", "q3"}, {})