Loading Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ all : test typecheck : $(PY:%=%.mypy) unit: pytest PYTHONPATH=$$PWD pytest test: typecheck unit Loading demo.py +2 −19 Original line number Diff line number Diff line Loading @@ -122,22 +122,6 @@ def grammar_test(str): #gra.cfg_to_reggrammar() print() def web_eq(str1, type1, str2, type2): try: web = WebChecker(str1, type1) web.compare(str2, type2) if web.ok: print("ok") elif web.eq: if web.eq.left_counterexample is not None: print(web.eq.left_counterexample) if web.eq.right_counterexample is not None: print(web.eq.right_counterexample) print(web.eq.inf) except RecognitionException as re: print(re) def web_conv(str, type, task): try: web = WebChecker(str, task) Loading Loading @@ -362,14 +346,13 @@ def main(): grammar_test("S'->a|aA''|\e;A''->a|bS'|<ab_0>''") grammar_test("S->a;\nS->aA;\nS->\e;\nA->a;\nA->bS;\n") words = dfa_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", words = dfa_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3} $comment#", "init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}") print(words.right_counterexample, words.left_counterexample, words.inf) print() print("Info pro web") web_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", 'DFA', "init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}", 'DFA') #web_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", 'DFA',"init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}", 'DFA') web_conv("S->a|aA;A->a|b", "GRA", "DFA") Loading lib/dfa.py +19 −17 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ class IsEmptyResult: class IsEquivalentResult: def __init__(self, left_counterexample: Optional[str] = None, right_counterexample: Optional[str] = None, def __init__(self, left_counterexample: Optional[str] = None, right_counterexample: Optional[str] = None, inf: Optional[bool] = None): self.left_counterexample = left_counterexample self.right_counterexample = right_counterexample Loading @@ -51,7 +52,7 @@ class DFA: self.final = final self.check() def check(self): def check(self): # this control exists mainly for development reasons assert len(self.states) > 0, "empty automaton" for (state, character) in self.transition: Loading Loading @@ -215,46 +216,47 @@ class DFA: def sorted_characters(self) -> List[Character]: return sorted(self.characters, key=lambda x: x.name) def minimize(self) -> DFA: def minimize(self) -> DFA: # 26-30, section 2.1.5 dfa = self.eliminate_unreachable().total() characters = self.sorted_characters() # bc I want to iterate always in same order characters = self.sorted_characters() # bc I want to iterate always in the same order previous: Dict[State, int] = dict() actual: Dict[State, int] = dict() for state in dfa.states: for state in dfa.states: # first classification: final or non-final if state in dfa.final: actual[state] = 1 else: actual[state] = 0 # how many classes are there now: classes_prev = 0 classes_new = 1 if len(self.final) > 0 else 0 if len(self.states.difference(self.final)) > 0: classes_new = 1 if len(self.final) > 0 else 0 # there exist some final states if len(self.states.difference(self.final)) > 0: # and there exist some non-final states classes_new += 1 while classes_prev != classes_new: while classes_prev != classes_new: # did number of classes change? previous = deepcopy(actual) patterns: Dict[Tuple[int, ...], Set[State]] = dict() actual = dict() for state in dfa.states: pattern = [previous[state]] for character in characters: pattern.append(previous[dfa.transition[state, character]]) for state in dfa.states: # each state gets new pattern consisting of pattern = [previous[state]] # previous class for character in characters: # and for each transition pattern.append(previous[dfa.transition[state, character]]) # previous class of dest_state patterns.setdefault(tuple(pattern), set()).add(state) classes_prev = classes_new classes_new = 0 for states in patterns.values(): for state in states: actual[state] = classes_new for states in patterns.values(): # according to new patterns for state in states: # each state actual[state] = classes_new # gets to new class classes_new += 1 new_transition: DFA.Transition = {} dfa.states = set() dfa.final = set() for state in actual: for state in actual: # according to last classification of states new_state = State("new_" + str(actual[state])) dfa.states.add(new_state) Loading Loading
Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ all : test typecheck : $(PY:%=%.mypy) unit: pytest PYTHONPATH=$$PWD pytest test: typecheck unit Loading
demo.py +2 −19 Original line number Diff line number Diff line Loading @@ -122,22 +122,6 @@ def grammar_test(str): #gra.cfg_to_reggrammar() print() def web_eq(str1, type1, str2, type2): try: web = WebChecker(str1, type1) web.compare(str2, type2) if web.ok: print("ok") elif web.eq: if web.eq.left_counterexample is not None: print(web.eq.left_counterexample) if web.eq.right_counterexample is not None: print(web.eq.right_counterexample) print(web.eq.inf) except RecognitionException as re: print(re) def web_conv(str, type, task): try: web = WebChecker(str, task) Loading Loading @@ -362,14 +346,13 @@ def main(): grammar_test("S'->a|aA''|\e;A''->a|bS'|<ab_0>''") grammar_test("S->a;\nS->aA;\nS->\e;\nA->a;\nA->bS;\n") words = dfa_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", words = dfa_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3} $comment#", "init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}") print(words.right_counterexample, words.left_counterexample, words.inf) print() print("Info pro web") web_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", 'DFA', "init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}", 'DFA') #web_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", 'DFA',"init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}", 'DFA') web_conv("S->a|aA;A->a|b", "GRA", "DFA") Loading
lib/dfa.py +19 −17 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ class IsEmptyResult: class IsEquivalentResult: def __init__(self, left_counterexample: Optional[str] = None, right_counterexample: Optional[str] = None, def __init__(self, left_counterexample: Optional[str] = None, right_counterexample: Optional[str] = None, inf: Optional[bool] = None): self.left_counterexample = left_counterexample self.right_counterexample = right_counterexample Loading @@ -51,7 +52,7 @@ class DFA: self.final = final self.check() def check(self): def check(self): # this control exists mainly for development reasons assert len(self.states) > 0, "empty automaton" for (state, character) in self.transition: Loading Loading @@ -215,46 +216,47 @@ class DFA: def sorted_characters(self) -> List[Character]: return sorted(self.characters, key=lambda x: x.name) def minimize(self) -> DFA: def minimize(self) -> DFA: # 26-30, section 2.1.5 dfa = self.eliminate_unreachable().total() characters = self.sorted_characters() # bc I want to iterate always in same order characters = self.sorted_characters() # bc I want to iterate always in the same order previous: Dict[State, int] = dict() actual: Dict[State, int] = dict() for state in dfa.states: for state in dfa.states: # first classification: final or non-final if state in dfa.final: actual[state] = 1 else: actual[state] = 0 # how many classes are there now: classes_prev = 0 classes_new = 1 if len(self.final) > 0 else 0 if len(self.states.difference(self.final)) > 0: classes_new = 1 if len(self.final) > 0 else 0 # there exist some final states if len(self.states.difference(self.final)) > 0: # and there exist some non-final states classes_new += 1 while classes_prev != classes_new: while classes_prev != classes_new: # did number of classes change? previous = deepcopy(actual) patterns: Dict[Tuple[int, ...], Set[State]] = dict() actual = dict() for state in dfa.states: pattern = [previous[state]] for character in characters: pattern.append(previous[dfa.transition[state, character]]) for state in dfa.states: # each state gets new pattern consisting of pattern = [previous[state]] # previous class for character in characters: # and for each transition pattern.append(previous[dfa.transition[state, character]]) # previous class of dest_state patterns.setdefault(tuple(pattern), set()).add(state) classes_prev = classes_new classes_new = 0 for states in patterns.values(): for state in states: actual[state] = classes_new for states in patterns.values(): # according to new patterns for state in states: # each state actual[state] = classes_new # gets to new class classes_new += 1 new_transition: DFA.Transition = {} dfa.states = set() dfa.final = set() for state in actual: for state in actual: # according to last classification of states new_state = State("new_" + str(actual[state])) dfa.states.add(new_state) Loading