def nfa_to_dfa(nfa): dfa = DFA(set(nfa.alphabet)) def e_colsure(state_set): # 能够从NFA状态T开始只通过ε转换到达的NFA状态集合 if not isinstance(state_set, set): raise Exception('state_set must be set') queue = list(state_set) result = set(state_set) while queue: h = queue.pop(0) for state in h.get_transfer(Epsilon): if state not in result: result.add(state) queue.append(state) return result def move(state_set, symbol): result = set() for s in state_set: result = result.union(set(s.get_transfer(symbol))) return result state_set_to_node = {} start = tuple(e_colsure(set([nfa.S]))) state_set_to_node[start] = dfa.S queue = [start] while queue: h = queue.pop(0) for symbol in nfa.alphabet: new_set = tuple(e_colsure(move(set(h), symbol))) if not new_set: continue if new_set not in state_set_to_node: node = dfa.create_node() node.data['token'] = set() state_set_to_node[new_set] = node for state in new_set: # if state in nfa.final_state: if state.data: node.data['token'].add(state.data['token']) queue.append(new_set) dfa.add_transfer(state_set_to_node[h], symbol, state_set_to_node[new_set]) return dfa
def epsilonDFA(sigma=None): """ Returns the minimal DFA for {epsilon} (incomplete) :param sigma: :return: """ d = DFA() if sigma is not None: d.setSigma(sigma) i = d.addState() d.setInitial(i) d.addFinal(i) return d
def emptyDFA(sigma=None): """ Returns the minimal DFA for emptyset (incomplete) :param sigma: :return: """ d = DFA() if sigma is not None: d.setSigma(sigma) i = d.addState() d.setInitial(i) return d
def getAutomata(self): """ deal with the information collected""" isDeterministic = True if len(self.initials) > 1 or "@epsilon" in self.states: isDeterministic = False else: for s in self.transitions: for c in self.transitions[s]: if len(self.transitions[s][c]) > 1: isDeterministic = False break if not isDeterministic: break if isDeterministic: if "l" in self.eq.keys(): fa = DFCA() fa.setLength = self.eq["l"] else: fa = DFA() else: fa = NFA() for s in self.states: fa.addState(s) fa.setFinal(fa.indexList(self.finals)) if isDeterministic: fa.setInitial(fa.stateIndex(common.uSet(self.initials))) for s1 in self.transitions: for c in self.transitions[s1]: fa.addTransition( fa.stateIndex(s1), c, fa.stateIndex(common.uSet(self.transitions[s1][c]))) else: fa.setInitial(fa.indexList(self.initials)) for s1 in self.transitions: for c in self.transitions[s1]: for s2 in fa.indexList(self.transitions[s1][c]): fa.addTransition(fa.stateIndex(s1), c, s2) return fa
def create_lr_dfa(final, syntaxs, vn, vt): if vn.intersection(vt): raise Exception('VN and VT has intersection') else: alptabet = list(vn) + list(vt) productions = {} for syntax in syntaxs: if syntax[0] not in productions: productions[syntax[0]] = [] productions[syntax[0]].append(syntax) # print 'productions:' # print productions items_set_to_node = {} # tuple to Node first = {} nullable = {} getting_nullable = set() def get_nullable(item): # 判断一个非终结符是否可以为Epsilon if not isinstance(item, str): raise Exception('item is not str') if item not in vn: raise Exception('item not in vn') if item in nullable: return nullable[item] if item in getting_nullable: nullable[item] = False return nullable[item] getting_nullable.add(item) nullable[item] = False for production in productions[item]: _nullable = True for t in production[1:]: if t in vt: _nullable = False else: _nullable &= get_nullable(t) nullable[item] |= _nullable getting_nullable.remove(item) return nullable[item] getting_first = set() def get_first(item): # 获取first集,返回set if not isinstance(item, tuple): raise Exception('item is not tuple') if item in first: return first[item] getting_first.add(item) first[item] = set() for t in item: if t in vt: first[item].add(t) break else: for production in productions[t]: if production[0] in vt: first[item].add(production[0]) elif production[1:] not in getting_first: first[item] = first[item].union( get_first(production[1:])) if not get_nullable(t): break getting_first.remove(item) return first[item] def closure(item, item_set): pos, production, ahead = item # print 'pos,production,ahead:' # print pos,production,ahead right_part = production[pos + 1:] # print right_part if not right_part or right_part[0] not in vn: return for production in productions[right_part[0]]: new_set = set() for t in ahead: new_set = new_set.union(get_first(right_part[1:] + (t,))) new_item = (0, production, tuple(new_set)) if new_item not in item_set: item_set.add(new_item) closure(new_item, item_set) # create the start Node init_item = (0, (final + '\'', final), ('#',)) init_set = set() init_set.add(init_item) closure(init_item, init_set) dfa = DFA(set(alptabet)) dfa.S.data = tuple(init_set) items_set_to_node[dfa.S.data] = dfa.S # start to build dfa queue = [dfa.S] while queue: head = queue.pop(0) # print 'head %4d' % head.index for symbol in alptabet: # print symbol new_set = set() for item in head.data: pos, production, ahead = item # print 'production, production[pos + 1: pos + 2]:' # print production, production[pos + 1] if (pos + 1 < len(production) and production[pos + 1] == symbol): new_item = (pos + 1, production, ahead) new_set.add(new_item) closure(new_item, new_set) new_set = tuple(new_set) if not new_set: continue if new_set not in items_set_to_node: node = dfa.create_node() node.data = new_set items_set_to_node[new_set] = node queue.append(node) dfa.add_transfer(head, symbol, items_set_to_node[new_set]) print "%d ----%10s---->%d" % (head.index, symbol, items_set_to_node[new_set].index) # print '-----------items_set--------------' # for item in dfa.states[6].data: # print item # raise Exception('') return dfa
def concatWCT(m=6, n=6): """ @ worst-case family concatenation where @m>=2 and n>=2 and k=3 :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA,DFA)""" if n < 2 or m < 2: raise TestsError("number of states must both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b", "c"]) d1.States = range(m) d1.setInitial(0) d1.addFinal(m - 1) d1.addTransition(0, "a", 1) d1.addTransition(0, "c", 0) for i in range(1, m): d1.addTransition(i, "a", (i + 1) % m) d1.addTransition(i, "b", 0) d1.addTransition(i, "c", i) d2.setSigma(["a", "b", "c"]) d2.States = range(n) d2.setInitial(0) d2.addFinal(n - 1) d2.addTransition(0, "a", 0) d2.addTransition(0, "b", 1) for i in range(1, n): d2.addTransition(i, "b", (i + 1) % n) d2.addTransition(i, "a", i) d2.addTransition(i, "c", 1) return d1, d2
def unionWCTk2(m=6, n=6): """ @ worst-case family union where @m>=2 and n>=2 and k=2 ..seealso:: Gao, Y., Salomaa, K., Yu, S.: Transition complexity of incomplete dfas. Fundam. Inform. 110(1-4), 143–158 (2011) @ the conjecture in this article fails for this family :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA,DFA)""" if n < 2 or m < 2: raise TestsError("number of states must both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b"]) d1.States = range(m) d1.setInitial(0) d1.addFinal(0) d1.addTransition(m - 1, "a", 0) for i in range(0, m - 1): d1.addTransition(i, "b", i + 1) d2.setSigma(["a", "b"]) d2.States = range(n) d2.setInitial(0) d2.addFinal(n - 1) d2.addTransition(n - 1, "b", n - 1) for i in range(0, n - 1): d2.addTransition(i, "a", i + 1) d2.addTransition(i, "b", i) return d1, d2
def starInterBC(m=3, n=3): """Bad case automata for starInter(DFA,DFA) with m,n>1 ..seealso:: Arto Salomaa, Kai Salomaa, and Sheng Yu. 'State complexity of combined operations'. Theor. Comput. Sci., 383(2-3):140–152, 2007. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA,DFA)""" if n < 2 or m < 2: raise TestsError("number of states must be both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b", "c", "d", "e"]) d1.States = range(m) d1.setInitial(0) d1.addFinal(m - 1) for i in range(m): d1.addTransition(i, "a", (i + 1) % m) d1.addTransition(i, "b", i) d1.addTransition(i, "c", i) d1.addTransition(i, "d", i) d1.addTransition(i, "e", i) d2.setSigma(["a", "b", "c", "d", "e"]) d2.States = range(n) d2.setInitial(0) d2.addFinal(n - 1) for i in range(n): d2.addTransition(i, "b", (i + 1) % n) d2.addTransition(i, "a", i) d2.addTransition(i, "c", n - 2) if i == n - 2: d2.addTransition(i, "d", n - 1) elif i == n - 1: d2.addTransition(i, "d", n - 2) else: d2.addTransition(i, "d", i) if i > n - 4: d2.addTransition(i, "e", i) else: d2.addTransition(i, "e", i + 1) return d1, d2
def shuffleWC(m=3, n=3): """Worst case automata for shuffle(DFA,DFA) with m.n>1 ..seealso:: C. Campeanu, K. Salomaa, and S. Yu. Tight lower bound for the state complexity of shuffle of regular languages. Journal of Automata, Languages and Combinatorics, 7(3):303–310, 2002. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA, DFA)""" if n < 2 or m < 2: raise TestsError("number of states must be both greater than 1") d1, d2 = DFA(), DFA() d1.States = range(m) d1.setSigma(["a", "b", "c", "d", "f"]) d1.setInitial(0) d1.addFinal(0) for i in range(m): d1.addTransition(i, "a", (i + 1) % m) if i != m - 1: d1.addTransition(i, "c", i + 1) d1.addTransition(i, "d", i) if i != 0: d1.addTransition(i, "f", i) d2.States = range(n) d2.setSigma(["a", "b", "c", "d", "f"]) d2.setInitial(0) d2.addFinal(0) for i in range(n): d2.addTransition(i, "b", (i + 1) % n) d2.addTransition(i, "c", i) if i != n - 1: d2.addTransition(i, "d", i + 1) if i != 0: d2.addTransition(i, "f", i) return d1, d2
def reversalbinaryWC(m=5): """Worst case automata for reversal(DFA) binary ..seealso:: G. Jir{\'a}skov{\'a} and J. S\v ebej. Note on Reversal of binary regular languages. Proc. DCFS 2011, LNCS 6808, Springer, pp 212-221. @arg m: number of states @type m: integer @returns: a dfa @rtype: DFA""" if m < 2: raise TestsError("number of states must be greater than 1") d = DFA() d.setSigma(["a", "b"]) d.States = range(m) d.setInitial(0) d.addFinal(m - 1) d.addTransition(0, "a", 1) d.addTransition(0, "b", 0) d.addTransition(1, "b", 0) if m == 2: d.addTransition(1, "a", 0) else: d.addTransition(1, "a", 2) d.addTransition(2, "a", 0) if m == 3: d.addTransition(2, "b", 2) else: d.addTransition(2, "b", 3) d.addTransition(3, "b", 2) d.addTransition(3, "a", 4) d.addTransition(m - 1, "a", 3) d.addTransition(m - 1, "b", m - 1) for i in range(4, m - 1): d.addTransition(i, "a", i + 1) d.addTransition(i, "b", i) return d
import sys from fa import NFA, DFA filename = "test2.txt" file = open(filename, 'r') lines = file.readlines() file.close() nfa = NFA() dfa = DFA() nfa.construct_nfa_from_lines(lines) nfa.print_nfa() print() dfa.convert_from_nfa(nfa) dfa.print_dfa()
def disjWC(m=6, n=5): """ Worst case automata for disjunction(DFA,DFA) with m,n >1 ..seealso:: S. Yu, Q. Zhuang, and K. Salomaa. The state complexities of some basic operations on regular languages. Theor. Comput. Sci., 125(2):315–328, 1994. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA, DFA)""" if n < 2 or m < 2: raise TestsError("number of states must be both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b"]) d1.States = range(m) d1.setInitial(0) d1.addTransition(0, "a", 1) d1.addTransition(0, "b", 0) for i in range(1, m): d1.addTransition(i, "a", (i + 1) % m) d1.addTransition(i, "b", i) d1.addFinal(i) d2.setSigma(["a", "b"]) d2.States = range(m) d2.setInitial(0) d2.addTransition(0, "b", 1) d2.addTransition(0, "a", 0) for i in range(n): d2.addTransition(i, "b", (i + 1) % n) d2.addTransition(i, "a", i) d2.addFinal(0) return d1, d2
def suffWCe(m=3): """Witness for suff(L) when L does not have empty as a quotient :rtype: DFA ..seealso: Janusz A. Brzozowski, Galina Jirásková, Chenglong Zou, Quotient Complexity of Closed Languages. Theory Comput. Syst. 54(2): 277-292 (2014) """ if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b"]) f.States = range(m) f.setInitial(0) f.addFinal(0) f.addTransition(0, "a", 1) f.addTransition(1, "a", 2) f.addTransition(0, "b", 0) f.addTransition(1, "b", 0) for i in range(2, m): f.addTransition(i, "a", (i + 1) % m) f.addTransition(i, "b", i) return f
def universal(n, l=None, Finals=None, dialect=False, d=None): """Universal witness for state compelxity :arg int n: number of states :arg [str] l: alphabet :arg [int] Finals: list of final states :arg bool dialect: is it a dialect :returns: dfa :rtype: DFA """ if n < 3: raise TestsError("number of states must be greater than 2") u = DFA() u.States = range(n) if l is None: l = ("a", "b", "c") u.setSigma(list(l)) u.setInitial(0) u.addFinal(n - 1) u.addTransition(0, "b", 1) u.addTransition(1, "b", 0) if "c" in l: u.addTransition(n - 1, "c", 0) for i in range(n): u.addTransition(i, "a", (i + 1) % n) if i >= 2: u.addTransition(i, "b", i) if i != n - 1 and "c" in l: u.addTransition(i, "c", i) return u
def startDFASemRule(self, lst, context=None): """ :param context: :param lst: :param context:""" new = DFA() while self.states: x = self.states.pop() new.addState(x) new.Sigma = self.alphabet x = self.initials.pop() new.setInitial(new.stateIndex(x)) while self.finals: x = self.finals.pop() new.addFinal(new.stateIndex(x)) while self.transitions: (x1, x2, x3) = self.transitions.pop() new.addTransition(new.stateIndex(x1), x2, new.stateIndex(x3)) self.theList.append(new) self.initLocal()
def __init__(self): self.lexs = [] self.lex_dfa = DFA() self.keyword = ['lambda']
def concatWCB(m=4, n=4): """ Worst case automata for catenation(DFA,DFA) with m,n > 1, k=2, ..seealso::Jirásek, J., Jiráaskováa, G., Szabari, A., 2005. State complexity of concatenation and complementation of regular languages. Int. J. Found. Comput. Sci. 16 (3), 511–529. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA, DFA)""" if n < 2 or m < 2: raise TestsError("number of states must be both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b"]) d1.States = range(m) d1.setInitial(0) d1.addFinal(m - 1) d1.addTransition(m - 1, "b", 0) d1.addTransition(m - 1, "a", m - 1) for i in range(m - 1): d1.addTransition(i, "a", i) d1.addTransition(i, "b", i + 1) d2.setSigma(["a", "b"]) d2.States = range(n) d2.setInitial(0) d2.addFinal(n - 1) d2.addTransition(n - 1, "a", 0) d2.addTransition(n - 1, "b", 0) d2.addTransition(0, "a", 0) d2.addTransition(0, "b", 1) d2.addTransition(n - 2, "a", n - 1) for i in range(1, n - 1): d2.addTransition(i, "a", i + 1) d2.addTransition(i, "b", i + 1) return d1, d2
def suffWCd(m=3): """Witness for suff(L) when L has empty as a quotient :rtype: DFA ..seealso: as above """ if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b"]) f.States = range(m) f.setInitial(0) f.addFinal(0) f.addTransition(0, "a", 1) f.addTransition(1, "a", 2) f.addTransition(0, "b", m - 1) f.addTransition(1, "b", 0) f.addTransition(m - 1, "b", m - 1) f.addTransition(m - 1, "a", m - 1) for i in range(2, m - 1): f.addTransition(i, "a", (i + 1) % (m - 1)) f.addTransition(i, "b", i) return f
def reversalWC3L(m=5): """ Worst case automata for reversal(DFA) with m > 2, k=3 ..seealso:: E. L. Leiss. Succinct representation of regular languages by boolean automata ii. Theor. Comput. Sci., 38:133–136, 1985. :arg m: number of states :type m: integer :returns: a dfa :rtype: DFA""" if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b", "c"]) f.States = range(m) f.setInitial(0) f.addFinal(0) f.addTransition(0, "b", 1) f.addTransition(1, "b", 0) f.addTransition(0, "a", 1) f.addTransition(1, "a", 2) f.addTransition(0, "c", m - 1) f.addTransition(1, "c", 1) for i in range(2, m): f.addTransition(i, "a", (i + 1) % m) f.addTransition(i, "b", i) f.addTransition(i, "c", i) return f
def reversalMB(m=8): """Worst case automata for reversal(DFA) ..seealso:: S. Yu, Q. Zhuang, and K. Salomaa. The state complexities of some basic operations on regular languages. Theor. Comput. Sci., 125(2):315–328, 1994. :arg m: number of states :type m: integer :returns: a dfa :rtype: DFA""" if m < 3: raise TestsError("number of states must be greater than 2") d = DFA() d.setSigma(["a", "b"]) d.States = range(m) d.setInitial(0) for i in range(m): if i == m - 1: d.addTransition(m - 1, "a", 0) else: d.addTransition(i, "a", i + 1) if i == 2: d.addTransition(2, "b", 0) elif i == 3: d.addTransition(3, "b", 2) else: d.addTransition(i, "b", i) return d
def suffWCsynt(m=3): """ Worst case witness for synt of suff(L) """ if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b", "c", "d", "e"]) f.States = range(m) f.setInitial(0) f.addFinal(m - 1) f.addTransition(0, "a", 0) f.addTransition(0, "b", 0) f.addTransition(0, "c", 0) f.addTransition(0, "d", 0) f.addTransition(0, "e", 1) f.addTransition(1, "a", 2) f.addTransition(1, "b", 2) f.addTransition(1, "c", 1) f.addTransition(1, "d", 1) f.addTransition(1, "e", 1) f.addTransition(2, "b", 1) f.addTransition(2, "e", 1) f.addTransition(2, "c", 2) f.addTransition(2, "d", 2) f.addTransition(2, "a", 3) for i in range(3, m - 1): f.addTransition(i, "a", (i + 1) % m) f.addTransition(i, "b", i) f.addTransition(i, "c", i) f.addTransition(i, "d", i) f.addTransition(i, "e", 1) f.addTransition(m - 1, "a", 1) f.addTransition(m - 1, "c", 1) f.addTransition(m - 1, "e", 1) f.addTransition(m - 1, "d", 0) return f
def reversalternaryWC(m=5): """Worst case automata for reversal(DFA) ternary alphabet :arg m: number of states :type m: integer :returns: a dfa :rtype: DFA""" if m < 3: raise TestsError("number of states must be greater than 2") d = DFA() d.setSigma(["a", "b", "c"]) d.setInitial(0) d.addFinal(0) d.States = range(m) d.addTransition(0, "a", m - 1) d.addTransition(0, "c", 0) d.addTransition(0, "b", 0) d.addTransition(1, "c", m - 1) d.addTransition(1, "b", 0) d.addTransition(1, "a", 0) for i in range(2, m): d.addTransition(i, "a", i - 1) d.addTransition(i, "c", i - 1) d.addTransition(i, "b", i) return d
def booleanWCSymGrp(m=3): """Witness for symmetric group :rtype: DFA ..seealso: Jason Bell, Janusz A. Brzozowski, Nelma Moreira, Rogério Reis. Symmetric Groups and Quotient Complexity of Boolean Operations. ICALP (2) 2014: 1-12 """ if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b"]) f.States = range(m) f.setInitial(0) f.addFinal(0) f.addFinal(1) f.addTransition(0, "a", 1) f.addTransition(1, "a", 0) f.addTransition(0, "b", 1) f.addTransition(1, "b", 2) for i in range(2, m): f.addTransition(i, "b", (i + 1) % m) f.addTransition(i, "a", i) return f
def suffFreeSyntWC(m=5): """ """ if m < 5: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b", "c", "d", "e"]) f.States = range(m) f.setInitial(0) f.addFinal(1) f.addTransition(0, "a", m - 1) f.addTransition(0, 'b', m - 1) f.addTransition(0, 'c', m - 1) f.addTransition(0, 'd', m - 1) f.addTransition(0, 'e', 1) f.addTransition(1, "a", 2) f.addTransition(1, 'c', 1) f.addTransition(1, 'e', m - 1) f.addTransition(1, 'd', m - 1) f.addTransition(1, 'b', 2) f.addTransition(2, 'b', 1) f.addTransition(2, "a", 3) f.addTransition(2, "c", 2) f.addTransition(2, "e", m - 1) f.addTransition(2, 'd', 2) f.addTransition(1, 'd', m - 1) f.addTransition(m - 2, 'c', 1) f.addTransition(m - 2, 'a', 1) for sym in f.Sigma: f.addTransition(m - 1, sym, m - 1) for i in range(3, m - 1): f.addTransition(i, "b", i) if i != m - 2: f.addTransition(i, "c", i) f.addTransition(i, "a", (i + 1)) f.addTransition(i, "d", i) f.addTransition(i, "e", m - 1) return f
def revFibonnacci(n): a = DFA() a.setSigma(["a", "b"]), for i in range(n): a.addState(i) a.setInitial(0) for i in range(n): if i % 2 != 0: if i < n - 1: a.addTransition(i, 'b', i + 1) if i < n - 2: a.addTransition(i, 'a', i + 2) else: if i < n - 2: a.addTransition(i, 'b', i + 2) if i < n - 1: a.addTransition(i, 'a', i + 1) a.addFinal(n - 1) return a
def starDisjWC(m=6, n=5): """Worst case automata for starDisj(DFA,DFA) with m.n>1 ..seealso: Arto Salomaa, Kai Salomaa, and Sheng Yu. 'State complexity of combined operations'. Theor. Comput. Sci., 383(2-3):140–152, 2007. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA,DFA)""" if n < 2 or m < 2: raise TestsError("number of states must be both greater than 1") d1, d2 = DFA(), DFA() d1.States = range(m) d1.setSigma(["a", "b", "c"]) d1.setInitial(0) d1.addFinal(0) for i in range(m): d1.addTransition(i, "a", (i + 1) % m) d1.addTransition(i, "b", i) if i != 0: d1.addTransition(i, "c", i) d1.addTransition(0, "c", 1) d2.States = range(n) d2.setSigma(["a", "b", "c"]) d2.setInitial(0) d2.addFinal(0) for i in range(n): d2.addTransition(i, "b", (i + 1) % n) d2.addTransition(i, "a", i) if i != 0: d2.addTransition(i, "c", i) d2.addTransition(0, "c", 1) return d1, d2
def starWC(m=5): """ Worst case automata for star(DFA) with m > 2, k=2 ..seealso:: S. Yu, Q. Zhuang, and K. Salomaa. The state complexities of some basic operations on regular languages. Theor. Comput. Sci., 125(2):315–328, 1994. :arg m: number of states :type m: integer :returns: a dfa :rtype: DFA""" if m < 3: raise TestsError("number of states must be greater than 2") # for m=2, L=\{w\in\{a,b\}*| |w|a odd \} f = DFA() f.setSigma(["a", "b"]) f.States = range(m) f.setInitial(0) f.addFinal(m - 1) f.addTransition(0, "a", 1) f.addTransition(0, "b", 0) for i in range(1, m): f.addTransition(i, "a", (i + 1) % m) f.addTransition(i, "b", (i + 1) % m) return f
def disjWStarWC(m=6, n=5): """ ..seealso:: Yuan Gao and Sheng Yu. 'State complexity of union and intersection combined with star and reversal'. CoRR, abs/1006.3755, 2010. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA,DFA)""" if n < 3 or m < 3: raise TestsError("number of states must be greater than 2") f1 = DFA() f1.setSigma(["a", "b", "c"]) f1.States = range(m) f1.setInitial(0) f1.addFinal(m - 1) f1.addTransition(0, "a", 1) f1.addTransition(0, "b", 0) f1.addTransition(0, "c", 0) for i in range(1, m): f1.addTransition(i, "a", (i + 1) % m) f1.addTransition(i, "b", (i + 1) % m) f1.addTransition(i, "c", i) f2 = DFA() f2.setSigma(["a", "b", "c"]) f2.States = range(n) f2.setInitial(0) f2.addFinal(n - 1) for i in range(n): f2.addTransition(i, "a", i) f2.addTransition(i, "b", i) f2.addTransition(i, "c", (i + 1) % n) return f1, f2
def starWCM(m=5): """ Worst case automata for star(DFA) with m > 2, k=2 ..seealso:: A. N. Maslov. Estimates of the number of states of finite automata. Dokllady Akademii Nauk SSSR, 194:1266–1268, 1970. :arg m: number of states :type m: integer :returns: a dfa :rtype: DFA""" if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b"]) f.States = range(m) f.setInitial(0) f.addFinal(m - 1) f.addTransition(m - 1, "a", 0) f.addTransition(m - 1, "b", m - 2) f.addTransition(0, "b", 0) f.addTransition(0, "a", 1) for i in range(1, m - 1): f.addTransition(i, "a", (i + 1)) f.addTransition(i, "b", (i - 1)) return f
def unionWCT2(n=6): """ @ worst-case family union where @m=1 and n>=2 and k=3 @ Note that the same happens to m>=2 and n=1 :arg n: number of states :type n: integer :returns: two dfas :rtype: (DFA,DFA)""" m = 1 if n < 2: raise TestsError("number of states must both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b", "c"]) d1.States = range(m) d1.setInitial(0) d1.addFinal(0) d1.addTransition(0, "b", 0) d1.addTransition(0, "c", 0) d2.setSigma(["a", "b", "c"]) d2.States = range(n) d2.setInitial(0) d2.addFinal(n - 1) d2.addTransition(0, "a", 0) d2.addTransition(0, "b", 1) for i in range(1, n): d2.addTransition(i, "b", (i + 1) % n) d2.addTransition(i, "a", i) d2.addTransition(i, "c", 1) return d1, d2
def concatWCM(m=4, n=4): """ Worst case automata for catenation(DFA,DFA) with m,n > 1, k=2, ..seealso:: A. N. Maslov. Estimates of the number of states of finite automata. Dokllady Akademii Nauk SSSR, 194:1266–1268, 1970. :arg m: number of states :arg n: number of states :type m: integer :type n: integer :returns: two dfas :rtype: (DFA, DFA)""" if n < 2 or m < 2: raise TestsError("number of states must be both greater than 1") d1, d2 = DFA(), DFA() d1.setSigma(["a", "b"]) d1.States = range(m) d1.setInitial(0) d1.addFinal(m - 1) d1.addTransition(m - 1, "b", 0) d1.addTransition(m - 1, "a", m - 1) for i in range(m - 1): d1.addTransition(i, "a", i) d1.addTransition(i, "b", i + 1) d2.setSigma(["a", "b"]) d2.States = range(n) d2.setInitial(0) d2.addFinal(n - 1) d2.addTransition(n - 1, "a", n - 1) d2.addTransition(n - 1, "b", n - 2) d2.addTransition(n - 2, "b", n - 1) d2.addTransition(n - 2, "a", n - 1) for i in range(n - 2): d2.addTransition(i, "a", i + 1) d2.addTransition(i, "b", i) return d1, d2
def starWCT1(m=5): """ @ worst-case family star where @m>=2 and k=2 :arg m: number of states :type m: integer :returns: dfa :rtype: DFA""" if m < 3: raise TestsError("number of states must be greater than 2") f = DFA() f.setSigma(["a", "b"]) f.States = range(m) f.setInitial(0) f.addFinal(m - 1) f.addTransition(0, "b", 0) f.addTransition(0, "a", 1) f.addTransition(m - 2, "a", m - 1) f.addTransition(m - 1, "a", 0) for i in range(1, m - 2): f.addTransition(i, "a", (i + 1) % m) f.addTransition(i, "b", (i + 1) % m) return f
def compile(self): """ 利用 self.grammar 编译出dfa, 并构造分析表 :return: """ self.calc_first() alloc = 0 grammar = self.grammar dfa = DFA() que = Queue() dfa.start = DFANode(id=alloc, lr_items=self.closure(("start", tuple(), tuple(grammar["start"][0]), {'$'}))) self.idx_items = [dfa.start] que.put(dfa.start.lr_items) vis = dict() vis[frozen_items(dfa.start.lr_items)] = dfa.start while not que.empty(): lr_items = que.get() # if frozen_items(lr_items) in vis: # continue dfa_node = vis[frozen_items(lr_items)] # print 'u_items:' # print lr_items tmp = defaultdict(list) for item in lr_items: if item[2]: u_item = (item[0], item[1] + item[2][:1], item[2][1:], item[3]) tmp[item[2][0]].append(u_item) # 可能该状态有两个以上项目可以通过 item[2][0] 转换到新项目, 而新的项目集应该是他们的合集 for l_hand, items in tmp.iteritems(): vitem = defaultdict(set) for item in items: u_items = self.closure(item) for u_item in u_items: vitem[u_item[:-1]].update(u_item[3]) next_items = [core + (head, ) for core, head in vitem.iteritems()] if frozen_items(next_items) not in vis: que.put(next_items) alloc += 1 dfa_node.next[l_hand] = DFANode(id=alloc, lr_items=next_items) self.idx_items.append(dfa_node.next[l_hand]) # 插入新节点 vis[frozen_items(next_items)] = dfa_node.next[l_hand] else: dfa_node.next[l_hand] = vis[frozen_items(next_items)] # dfa.draw("LR", show_meta=["lr_items"], generate_id=False) self.lr_dfa = dfa # DFA 构造完成 # 构造分析表 lr_table = defaultdict(dict) que = Queue() que.put(dfa.start) vis = dict() while not que.empty(): tmp = que.get() if tmp in vis: continue vis[tmp] = 1 for item in tmp.lr_items: if item[2]: # 移进状态 if item[2][0] in lr_table[tmp.id]: if lr_table[tmp.id][item[2][0]]['action'] != 'shift': print(colorful('移近规约冲突', 'Red')) raise LRConflict() elif lr_table[tmp.id][item[2][0]]['next'] != \ tmp.next[item[2][0]].id: print(colorful('移近移近冲突', 'Red')) raise LRConflict() lr_table[tmp.id][item[2][0]] = \ dict(action="shift", next=tmp.next[item[2][0]].id) else: # 规约状态 for a in item[3]: if a in lr_table[tmp.id]: if lr_table[tmp.id][a]['action'] != 'reduce': print(colorful('移近规约冲突', 'Red')) raise LRConflict() elif lr_table[tmp.id][a]['grammar'] != item: print(colorful('规约规约冲突', 'Red')) raise LRConflict() lr_table[tmp.id][a] = dict(action="reduce", grammar=item) for next_node in tmp.next.values(): que.put(next_node) self.lr_table = lr_table return dfa