def encodeCntTimeout(src, symbol, dst, encoding, discardDelim): '''encodeCntTimeout(src, symbol, dst, encoding, discardDelim) -> [Transition] Encodes a counter timeout in the place of the transition. ''' newTransitions = [] if encoding in { CounterEncoding.unary, CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian }: zeroState = dst + "Y0" endState = zeroState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, zeroState)) newTransitions.append( Automaton.makeTrans(zeroState, SYMBOL_ZERO, zeroState)) newTransitions.append( Automaton.makeTrans(zeroState, SYMBOL_ZERO, endState)) else: raise Exception("Invalid encoding: " + str(encoding)) if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append( Automaton.makeTrans(endState, SYMBOL_ENABLED, dst)) return newTransitions
def test_nfa_nfa_1(self): """Convertion from NFA to DFA.""" q1, q2, q3 = map(State, ['q1', 'q2', 'q3']) q1.add_transition('b', q2) q1.add_transition('$', q3) q2.add_transition('a', [q2, q3]) q2.add_transition('b', q3) q3.add_transition('a', q1) M = Automaton('M', [q1, q2, q3], ['a', 'b'], q1, q1) D = M.to_dfa() self.assertTrue('q1' in D.Q[0].ready) self.assertTrue('q3' in D.Q[0].ready) self.assertEqual(len(D.Q[0].ready), 2) self.assertTrue('q2' in D.Q[1].ready) self.assertEqual(len(D.Q[1].ready), 1) self.assertTrue('q2' in D.Q[2].ready) self.assertTrue('q3' in D.Q[2].ready) self.assertEqual(len(D.Q[2].ready), 2) self.assertTrue('q3' in D.Q[3].ready) self.assertEqual(len(D.Q[3].ready), 1) self.assertTrue('q1' in D.Q[4].ready) self.assertTrue('q2' in D.Q[4].ready) self.assertTrue('q3' in D.Q[4].ready) self.assertEqual(len(D.Q[4].ready), 3) self.assertEqual(len(D.Q[5].ready), 0)
def convert_graph_fmt(filename, fmt, output_dir=None): automaton = Automaton(fromfile=filename) filename_dir, filename_name = os.path.split(filename) if output_dir: filename_dir = output_dir new_filename = os.path.join(filename_dir, ".".join([filename_name.split('.')[0], fmt])) automaton.export(filename=new_filename)
def create_word_wfsa(corpus): wfsa = Automaton() for word in corpus: prob = corpus[word] state = "".join(word) + "_0" wfsa.emissions[state] = word wfsa.m_emittors[word].add(state) wfsa.m["^"][state] = math.log(prob) wfsa.m[state]["$"] = 0 # log(1) return wfsa
def eliminate_e_trans( automate: Automaton ): # methode pour enlever les espsilon transitions d'un automate for l in range(len(automate.transitions)): while "%" in automate.transitions[l][1]: list_of_ep_trans = stock_of_trans(automate, "%") for i in range(len(list_of_ep_trans)): etatq = list_of_ep_trans[i][0] etatk = list_of_ep_trans[i][2] list_des_trans = [] for k in range(len(automate.transitions)): if automate.transitions[k][0] == etatk: list_des_trans.append(automate.transitions[k]) for j in range(len(list_des_trans)): automate.add_transition(etatq, list_des_trans[j][1], list_des_trans[j][2]) automate.remove_transition(etatq, "%", etatk) if etatk in automate.acceptstates: automate.make_accept(etatq) for state in automate.statesdict.values(): while function_de_transition(automate, state, "%") is not None: eliminate_e_trans(automate) automate.remove_unreachable() automate.name = automate.name + " sans e trans" return automate
def intersect(automaton1: Automaton, automaton2: Automaton) -> Automaton: automaton1 = automaton1.as_DFA() automaton2 = automaton2.as_DFA() states = get_states_cross_product(automaton1, automaton2) initial = automaton1.initial + automaton2.initial accept = set() for a1 in automaton1.accept: for a2 in automaton2.accept: accept.add(a1+a2) alphabet = automaton1.alphabet | automaton2.alphabet return Automaton(states, initial, accept, alphabet)
def add_transitions(automaton: Automaton, og_state: State, character: str, dest_state: State): if character == EPSILON: if dest_state.name in automaton.acceptstates: automaton.make_accept(og_state.name) for char in dest_state.transitions: for dest in dest_state.transitions.get(char).keys(): add_transitions(automaton, og_state, char, dest) elif (og_state.name, character, dest_state.name) not in a.transitions: a.add_transition(og_state.name, character, dest_state.name) return
def check(rules, tests, parser_args={}): print "-" * 70 g = Grammar(rules) a = Automaton(g) fd = open(join(testdir, "tmp.py"), "w") a.write_parser(fd) fd.close() del a, g import tmp reload(tmp) p = tmp.Parser(**parser_args) EOF.set_real_eof(p.EOF) for input, e_tree, e_err in tests: e_err = [(x[0], frozenset(x[1])) for x in e_err] print "input: " + repr(input) try: tree = p.parse((x, k) for k, x in enumerate(input)) err = [] except p.ParseErrors, e: tree = e.tree err = e.errors err = [(x[0], frozenset(x[1])) for x in err] success = True for e in e_err: if e not in err: print " missed error: " + repr(e) success = False for e in err: if e not in e_err: print " unexpected error: " + repr(e) success = False if e_tree != ignore and tree != e_tree: print " unexpected result:" print " expected: " + repr(e_tree) print " got: " + repr(tree) success = False if success: print " success" else: print " failure" global errors errors += 1
def union_to_automaton(self, first_aut, second_aut): """ Converte uma expressao de uniao em seu respectivo automato """ final_state = self.create_state() finals = {final_state} initial = self.create_state() states = first_aut.states.union(second_aut.states).union( {initial, final_state}) alphabet = first_aut.alphabet.union(second_aut.alphabet) resulting_function = {} resulting_function.update(first_aut.function) resulting_function.update(second_aut.function) resulting_function[initial] = { '&': {initial, first_aut.initial, second_aut.initial} } resulting_function[final_state] = {'&': finals} for final in first_aut.finals.union(second_aut.finals): resulting_function[final]['&'].add(final_state) # print(f"resulting_function = {resulting_function}") return Automaton(states, alphabet, resulting_function, finals, initial)
def parseAut(problem, it): '''parseAut(problem, it) -> Automaton Parses an automaton (resp. transducer) representation into an instance of the Automaton class. Modifies problem, it. ''' # initialize aut = Automaton() for line in it: if (line == "}"): # end of automaton return aut elif (line[0:2] == "//"): # comments pass elif (line == ""): # empty string pass elif (reStartStates.match(line)): # start states Parser.parseStartStates(aut, line) elif (reAcceptStates.match(line)): # accepting states Parser.parseAcceptStates(aut, line) elif (reEpsTrans.match(line)): # epsilon transition Parser.parseEpsTrans(aut, line) elif (reAutTrans.match(line)) or (reTransdTrans.match(line)): Parser.parseTrans(problem, aut, line) else: raise Exception("Syntax error: " + line)
def closure_to_automaton(self, automaton): """ Converte o fechamento para um automato """ final_state = self.create_state() finals = {final_state} initial = self.create_state() states = automaton.states.union({initial, final_state}) alphabet = automaton.alphabet resulting_function = {} resulting_function.update(automaton.function) resulting_function[initial] = { '&': {initial, automaton.initial, final_state} } resulting_function[final_state] = {'&': finals} finals_copy = automaton.finals.copy() for final in finals_copy: resulting_function[final]['&'].add(automaton.initial) resulting_function[final]['&'].add(final_state) # print(f"resulting_function = {resulting_function}") return Automaton(states, alphabet, resulting_function, finals, initial)
def main(): args = parser.parse_args() automaton = Automaton.from_file(args.path_to_automaton) automaton = automaton_to_buchi(automaton) formulas = get_formulas_from_file(args.path_to_ltl) for formula in formulas: neg = formula.normal_form(negation=True) closure = neg.get_closure() if any(map(lambda x: isinstance(x, UntilFormula), closure)): ltl_automaton = LabeledGeneralisedBuchiAutomaton.from_formula(neg, aps=automaton.aps) ltl_automaton = BuchiAutomaton.from_labeled(ltl_automaton) results = verification(automaton, ltl_automaton) if not results[0]: print("Formula \"{}\" is valid\n---".format(formula.get_text())) else: print("Formula \"{}\" is invalid, here goes the counter example :\nStart:\n{};\nCycle:\n{};\n---".format( formula.get_text(), "\n".join(map(lambda x: "\t" + " ".join(sorted(map(lambda y: y.name, x))), results[1])), "\n".join(map(lambda x: "\t" + " ".join(sorted(map(lambda y: y.name, x))), results[2])) )) else: print("Formula \"{}\" has not temporal operator from (U, F, G, R). \n" "So nothing to verify really\n---".format(formula.get_text()))
def run_uniform_exp(self, quantizer, distance, emissions, state_bits, entropy): exp_name = "{0}-{1}-{2}-{3}-{4}".format( quantizer.levels, abs(quantizer.neg_cutoff), 'm', emissions, distance[0]) logging.info("Running {0}".format(exp_name)) learnt_wfsa_filename = "{0}/{1}".format(self.workdir, "learnt_{0}.wfsa".format(exp_name)) corpus = (self.morpheme_corpus if emissions == "m" else self.unigram_corpus) # read Automaton or learn it and dump it finally if os.path.exists(learnt_wfsa_filename): # read already learnt automaton learnt_wfsa = Automaton.create_from_dump(open(learnt_wfsa_filename)) learnt_wfsa.quantizer = quantizer learnt_wfsa.round_and_normalize() else: # create and learn new automaton alphabet = get_alphabet(corpus) numbers_per_letters = dict([(letter, 1) for letter in alphabet]) #print numbers_per_letters wfsa = Automaton.create_uniform_automaton(numbers_per_letters) wfsa.finalize() wfsa.quantizer = quantizer wfsa.round_and_normalize() cp = lambda *x: checkpoint_dump(wfsa, "{0}/cp_{1}".format(self.workdir, exp_name), *x) logging.info('learning starts here') learnt_wfsa = learn_wfsa(wfsa, corpus, distance, cp) # dump with open(learnt_wfsa_filename, "w") as of: learnt_wfsa.dump(of) # encode automaton encoder = Encoder(entropy) bits_a, bits_e, bits_t, err, hq, tc = encode_wfsa( learnt_wfsa, corpus, encoder) return [exp_name, bits_a, bits_e, bits_t, err, hq, tc]
def determinise(automate: Automaton): automateDet = Automaton("deterministe") automateDet.initial = automate.initial listeEtats = [] listeEtats.append(set([automate.initial.name])) listeEtatsNew = listeEtats print(listeEtats) while len(listeEtats) != 0: elt1 = listeEtats[0] listeEtats = listeEtats[1:] for elt11 in elt1: for x in automate.alphabet: EtatDest = [] for (source, symbol, destination) in automate.transitions: if source == str(elt11) and symbol == x: EtatDest.append(destination) if (len(EtatDest) != 0) and EtatDest not in listeEtatsNew: listeEtats.append(EtatDest) listeEtatsNew.append(EtatDest) automateDet.add_transition(str(elt1), x, str(EtatDest)) for etat in automate.acceptstates: for elt1 in listeEtatsNew: if etat in elt1: automateDet.make_accept(str(elt1)) return automateDet
def enabledToFair(autEnabled): '''enabledToFair(autEnabled) -> Automaton Encodes fairness into the Enabled automaton, thus obtaining the language of all possible configurations with enabledness encoded. ''' result = Automaton() return result
def test_app(): passwords = [ ("x", "", "1"), ("want", "a", "epuu7Aeja9"), ("emerge", "bamboo", "zexae2Moo2"), ("question", "predict", "dahTho9Thai5yiasie1c"), ("quick fiber estate ripple phrase", "topic", "huu4aeju2gooth1iS6ai") ] auto = Automaton() client = Client(auto) # Test password insertion assert client.get_size() == 0 for i, (name, login, password) in enumerate(passwords): auto.actions = "rb" client.add(name, login, password) assert client.get_size() == i+1 subtest_password_list(client, passwords) subtest_has_name(client, passwords) subtest_password_retrieval(client, auto, passwords) # Export in plain text and also in encrypted form # Do this before password removal testing auto.actions = "brb" export_plain = client.export(encrypt=False) auto.actions = "b" export_encrypted = client.export() # Test password removal removal_order = [name for name, _, _ in passwords] random.shuffle(removal_order) names = set(removal_order) for name in removal_order: auto.actions = "rb" client.delete_by_name(name) names.remove(name) assert set(client.get_names()) == names assert client.get_size() == 0 # Test import plain subtest_clear(client, auto, passwords) auto.actions = ";b" client.import_("1.1.0", export_plain, encrypted=False) subtest_password_list(client, passwords) subtest_password_retrieval(client, auto, passwords) # Test import encrypted subtest_clear(client, auto, passwords) auto.actions = ";b" client.import_("1.1.0", export_encrypted, encrypted=True) subtest_password_list(client, passwords) subtest_password_retrieval(client, auto, passwords)
def createPlayer1(autEnabled): '''createPlayer1(autEnabled) -> Automaton Synthesises a transducer for Player 1 from the Enabled automaton autEnabled. Player 1 nondeterministically chooses one enabled transition (if such exists). ''' enabledTransd = autEnabled.toTransducer() # the transducer for "no transition enabled" noEnabledTransTransd = enabledTransd.renameStates(lambda s: s + '_noEn') noEnabledTransTransd = noEnabledTransTransd.filterTrans( lambda trans: (trans[1], trans[2]) != (SYMBOL_ENABLED, SYMBOL_ENABLED)) noEnabledTransTransd = noEnabledTransTransd.removeUseless() rename1 = lambda state: state + "_en1" rename2 = lambda state: state + "_en2" # the transducer for chosing one enabled transition oneChosenTransTransd1 = enabledTransd.renameStates(rename1) oneChosenTransTransd2 = enabledTransd.renameStates(rename2) oneChosenTransTransd1 = oneChosenTransTransd1.clearAcceptStates() oneChosenTransTransd2 = oneChosenTransTransd2.clearStartStates() oneChosenTransTransdMerged = Automaton.autUnion(oneChosenTransTransd1, oneChosenTransTransd2) for trans in enabledTransd.transitions: fstSymb = Automaton.getSymbol1(trans) sndSymb = Automaton.getSymbol2(trans) if (fstSymb, sndSymb) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneChosenTransTransdMerged.addTransTransd( rename1(Automaton.getSrcState(trans)), SYMBOL_ENABLED, SYMBOL_CHOSEN, rename2(Automaton.getTgtState(trans))) # result = Automaton.autUnion(oneChosenTransTransdMerged, noEnabledTransTransd) result = oneChosenTransTransdMerged result = result.singleStartState(PLAYER1_START_STATE) return result
def kleene(a1: Automaton) -> Automaton: a2 = a1.deepcopy() for state in a2.acceptstates: a2.add_transition(state, "%", a2.initial.name) new_initial_state = nouvel_etat(a1) a2.add_transition(new_initial_state, EPSILON, a1.initial.name) a2.initial = a2.statesdict[new_initial_state] a2.make_accept(new_initial_state) a2.name = "kleen" return a2
def compute_entropy(probs, quantizer): dist = 0.0 modeled_sum = sum([math.exp(quantizer.representer(math.log(prob))) for prob in probs]) for prob in probs: prob_q = math.exp(quantizer.representer(math.log(prob))) if prob_q == 0.0: prob_q = Automaton.eps prob_q /= modeled_sum dist += Automaton.kullback(prob, prob_q) #print prob, prob_q, Automaton.kullback(prob, prob_q) return dist
def main(): wfsa = Automaton.create_from_dump(open(sys.argv[1])) if len(sys.argv) > 2: remaining = float(sys.argv[2]) lang = wfsa.language(remaining) else: lang = wfsa.language() for w in lang: di = wfsa.state_indices["$"] prob = math.exp(lang[w][di]) print "{0} {1}".format("".join(w), prob)
def concat(a1: Automaton, a2: Automaton) -> Automaton: a1star_a2 = a1.deepcopy() a1star_a2.name = "a1star_a2" nom_nouvel_etat = nouvel_etat(a1star_a2) for s in a2.states: if s in a1star_a2.states: # l'état de a2 existe dans la copie de a1star a2.rename_state( s, nom_nouvel_etat) # ici on modifie a2 directement -> à éviter nom_nouvel_etat = str(int(nom_nouvel_etat) + 1) # incrémente le compteur for (s, a, d) in a2.transitions: a1star_a2.add_transition(s, a, d) a1star_a2.make_accept(a2.acceptstates) for ac in a1.acceptstates: a1star_a2.add_transition(ac, EPSILON, a2.initial.name) a1star_a2.make_accept(a1.acceptstates, accepts=False) # transforme en états non acceptants return a1star_a2
def kleene_star(automaton1: Automaton) -> Automaton: states = automaton1.states newInitial = State("kleen_initial") states.add(newInitial) for state in automaton1.states: if state.name in automaton1.accept: state.add_transition(newInitial.name, EPSILON_SYMBOL) automaton1.accept.add(newInitial.name) newInitial.add_transition(automaton1.initial, EPSILON_SYMBOL) return Automaton(states, newInitial.name, automaton1.accept, automaton1.alphabet)
def main(): # read automaton wfsa = Automaton.create_from_dump(open(sys.argv[1])) # read corpus corpus = read_corpus(open(sys.argv[2]), separator=sys.argv[3], skip=[sys.argv[4]]) normalize_corpus(corpus) # call distance_from_corpus distances = {} dist = wfsa.distance_from_corpus(corpus, Automaton.kullback, distances=distances) # print out result for k, v in distances.iteritems(): print k, v
def main(): path = 'entrada.txt' input_file = open_input(path) transitions_raw = get_transitions(input_file) intial_or_final = initial_and_final(input_file) states_dict = get_states(transitions_raw, intial_or_final) word = get_word(input_file) states = load_states(states_dict) transitions = load_transitions(states, transitions_raw) a = Automaton('Automato Finito', word, transitions) inicial = a.get_initials_list() for i in inicial: a.start_reach(word, i) word = get_word(input_file) #print(a.get_steps()) gif = 1 for s in a.get_steps(): save_dot_and_png(a, s) save_gif(gif) gif += 1
def concat(a1: Automaton, a2: Automaton) -> Automaton: """ Concatenate 2 automaton and return the result """ a1a2 = a1.deepcopy() a1a2.name = a1.name + a2.name new_state_name = nouvel_etat(a1a2) for s in a2.states: if s in a1a2.states: while new_state_name in a2.states: new_state_name = str(int(new_state_name) + 1) a2.rename_state(s, new_state_name) new_state_name = str(int(new_state_name) + 1) for (s, a, d) in a2.transitions: a1a2.add_transition(s, a, d) a1a2.make_accept(a2.acceptstates) for ac in a1.acceptstates: a1a2.add_transition(ac, EPSILON, a2.initial.name) a1a2.make_accept(a1.acceptstates, accepts=False) return a1a2
def main(): automaton = Automaton.create_from_dump(open(sys.argv[1])) corpus = read_corpus(open(sys.argv[2])) normalize_corpus(corpus) entropy = float(sys.argv[3]) string_bits = "u" if len(sys.argv) > 4: string_bits = sys.argv[4] q = LogLinQuantizer(10, -20) automaton.quantizer = q encoder = Encoder(entropy, string_bits) print encoder.encode(automaton, corpus)
def encodeCntTimeout(src, symbol, dst, encoding, discardDelim): '''encodeCntTimeout(src, symbol, dst, encoding, discardDelim) -> [Transition] Encodes a counter timeout in the place of the transition. ''' newTransitions = [] if encoding in {CounterEncoding.unary, CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian}: zeroState = dst + "Y0" endState = zeroState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, zeroState)) newTransitions.append(Automaton.makeTrans(zeroState, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTrans(zeroState, SYMBOL_ZERO, endState)) else: raise Exception("Invalid encoding: " + str(encoding)) if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTrans(endState, SYMBOL_ENABLED, dst)) return newTransitions
def main(): parser = argparse.ArgumentParser( description="Operation for automatons" ) parser.add_argument("--automaton1", "-a", dest="automaton1", type=str, required=True, help="File of the first automaton description") parser.add_argument("--automaton2", "-b", dest="automaton2", type=str, help="File of the second automaton description. Not required for operation kleene_star") parser.add_argument("--operation", "-o", dest="operation", type=str, required=True, choices=OPS, help="Operation to execute") args = parser.parse_args() automaton1 = Automaton(from_file=args.automaton1) check_errors(automaton1.errors) if args.operation != "kleene_star": automaton2 = None if args.automaton2: automaton2 = Automaton(from_file=args.automaton2) else: print("Need to define --automaton2") sys.exit(1) check_errors(automaton2.errors) result = getattr(operations, args.operation)(automaton1, automaton2) else: result = operations.kleene_star(automaton1) print(result.render())
def get_rule_30(steps=None): """for get rule 30 Args: steps (int): number of steps to run the rule 30 Returns: cell_json(list): python object notation of """ # cells = [[0,0,0,0,1,0,0,0,0], # [0,0,0,1,1,1,0,0,0], # [0,0,1,1,0,0,1,0,0], # [0,1,1,0,1,1,1,1,0], # [1,1,0,0,1,0,0,0,1]] cells = Automaton(steps, rule=30).string() cell_json = [{"z": cells, "y": list(range(1, steps))}] # cell_json = [{"z":cells}] logging.info("\n" + str(Automaton(20, rule=30).string())) return cell_json
def union(a1: Automaton, a2: Automaton) -> Automaton: """ Unite 2 automaton and return the result """ a1ora2 = a1.deepcopy() a1ora2.name = a1.name + "+" + a2.name new_state_name = nouvel_etat(a1ora2) for s in a2.states: if s in a1ora2.states: while new_state_name in a2.states: new_state_name = str(int(new_state_name) + 1) a2.rename_state(s, new_state_name) new_state_name = str(int(new_state_name) + 1) for (s, a, d) in a2.transitions: a1ora2.add_transition(s, a, d) a1ora2.make_accept(a2.acceptstates) new_state_name = nouvel_etat(a1ora2) a1ora2.add_transition(new_state_name, EPSILON, a1ora2.initial.name) a1ora2.add_transition(new_state_name, EPSILON, a2.initial.name) a1ora2.initial = a1ora2.statesdict[new_state_name] return a1ora2
def kleene(a1: Automaton) -> Automaton: """ Return kleene star of the automaton passed in the argument """ a1star = a1.deepcopy() a1star.name = "a1star" for state in a1star.acceptstates: a1star.add_transition(state, EPSILON, a1star.initial.name) new_state_name = nouvel_etat(a1star) a1star.add_transition(new_state_name, EPSILON, a1star.initial.name) a1star.initial = a1star.statesdict[new_state_name] a1star.make_accept(new_state_name) return a1star
def __init__(self, examples=None, automaton=None): """ :args: automaton - (optional) instance of Automaton class examples - list of strings, this can include the empty string ('') """ self.A = automaton if automaton else Automaton() self.S = sorted(set(examples)) self.Σ = {char for s in self.S for char in s} # If empty string is accepted, make root accepting state self.root = self.A.add_node( is_initial=True, is_final=True if self.S[0] == '' else False) # Drop empty string from list of examples if self.S[0] == '': self.S = self.S[1:] self.verbose = False
def run_3state_exp(self, quantizer, distance, harant, emissions, state_bits): aut_name = "{0}-{1}-{2}-{3}-{4}".format( quantizer.levels, abs(quantizer.neg_cutoff), "_".join(("@".join(h) if type(h) == tuple else h) for h in harant), emissions, distance[0]) exp_name = "{0}-{1}".format(aut_name, state_bits) logging.info("Running {0}".format(exp_name)) learnt_wfsa_filename = "{0}/{1}".format(self.workdir, "learnt_{0}.wfsa".format(aut_name)) corpus = (self.morpheme_corpus if emissions == "m" else self.unigram_corpus) # read Automaton or learn it and dump it finally if os.path.exists(learnt_wfsa_filename): # read already learnt automaton learnt_wfsa = Automaton.create_from_dump(open(learnt_wfsa_filename)) learnt_wfsa.quantizer = quantizer learnt_wfsa.round_and_normalize() else: # create and learn new automaton wfsa = create_new_three_state_fsa(self.morpheme_corpus, harant, emissions) wfsa.finalize() wfsa.quantizer = quantizer wfsa.round_and_normalize() cp = lambda *x: checkpoint_dump(wfsa, "{0}/cp_{1}".format(self.workdir, aut_name), *x) learnt_wfsa = learn_wfsa(wfsa, corpus, distance, cp) # dump with open(learnt_wfsa_filename, "w") as of: learnt_wfsa.dump(of) # encode automaton encoder = (self.morpheme_encoder if emissions=="m" else self.unigram_encoder) encoder.state_bits = state_bits bits_a, bits_e, bits_t, err, hq, tc = encode_wfsa( learnt_wfsa, corpus, encoder) return [exp_name, bits_a, bits_e, bits_t, err, hq, tc]
def concatenation_to_automaton(self, first_aut, second_aut): #pylint: disable=R0201 """ Converte uma expressao de concatenacao em seu respectivo automato """ states = first_aut.states.union(second_aut.states) finals = second_aut.finals initial = first_aut.initial alphabet = first_aut.alphabet.union(second_aut.alphabet) resulting_function = {} resulting_function.update(first_aut.function) resulting_function.update(second_aut.function) finals_copy = first_aut.finals.copy() for final in finals_copy: resulting_function[final]['&'].add(second_aut.initial) return Automaton(states, alphabet, resulting_function, finals, initial)
def union(a1: Automaton, a2: Automaton) -> Automaton: Union = a1.deepcopy() nom_nouvel_etat = nouvel_etat(a2) for s in a2.states: if s in Union.states: Union.rename_state( s, nouvel_etat(a2)) # ici on modifie a3 directement -> à éviter nom_nouvel_etat = str(int(nom_nouvel_etat) + 1) for (s, a, d) in a2.transitions: Union.add_transition(s, a, d) Union.make_accept(a2.acceptstates) Union.add_transition(nom_nouvel_etat, EPSILON, a1.initial.name) Union.add_transition(nom_nouvel_etat, EPSILON, a2.initial.name) Union.initial.name = nom_nouvel_etat Union.remove_transition(Union.initial.name, EPSILON, Union.initial.name) return Union
def concat(automaton1: Automaton, automaton2: Automaton) -> Automaton: states = set() for state in sorted(automaton1.states): new_state = State(f"A1{state.name}") for trans in state.transitions: new_state.add_transition(f"A1{trans.target}", trans.symbol) if state.name in automaton1.accept: new_state.add_transition(f"A2{automaton2.initial}", EPSILON_SYMBOL) states.add(new_state) for state in sorted(automaton2.states): new_state = State(f"A2{state.name}") for trans in state.transitions: new_state.add_transition(f"A2{trans.target}", trans.symbol) states.add(new_state) initial = f"A1{automaton1.initial}" accept = set() for state_name in automaton2.accept: accept.add(f"A2{state_name}") alphabet = automaton1.alphabet | automaton2.alphabet return Automaton(states, initial, accept, alphabet)
def create_automaton(self, current_node=None): """ Cria o automato que corresponde a expressao """ if current_node is None: current_node = self.expression_tree # print(f"Current node is {current_node.get_value()}") if current_node.get_left_child( ) is None and current_node.get_right_child() is None: state = self.create_state() final = self.create_state() function = { state: { '&': {state}, current_node.get_value(): {final} }, final: { '&': {final} } } aut = Automaton({state, final}, {current_node.get_value()}, function, {final}, state) return aut if current_node.get_left_child() is not None: left_aut = self.create_automaton(current_node.get_left_child()) if current_node.get_right_child() is not None: right_aut = self.create_automaton(current_node.get_right_child()) if current_node.get_value() == '.': return self.concatenation_to_automaton(left_aut, right_aut) if current_node.get_value() == '+': return self.union_to_automaton(left_aut, right_aut) # O valor eh * if current_node.get_left_child() is not None: return self.closure_to_automaton(left_aut) return self.closure_to_automaton(right_aut)
def main(): parser = argparse.ArgumentParser( description='display 1-D cellular automaton') parser.add_argument('rule', type=int, help='wolframe rule (0-255)') parser.add_argument('steps', type=int, help='number of steps') parser.add_argument('seed', help='bin(seed) -> first line') parser.add_argument('--debug', action='store_true', help='for debug purpose') parser.add_argument('--raw', action='store_true', help='display with 0,1') args = parser.parse_args() if args.debug: logging.basicConfig(level=logging.DEBUG) automaton = Automaton(args.rule, args.seed) automaton.display() automaton.print_steps(args.steps, args.raw)
def createPlayer2(autPlay2, autEnabled): '''createPlayer2(autPlay2, autEnabled) -> Automaton Encode enabledness into the transducer autPlay2 for transitions of Player 2 using autEnabled defining enabledness. ''' ############################################################################# def matchDelimChosenToEnDis(lhs, rhs): # if lhs == SYMBOL_DELIM and rhs in {SYMBOL_ENABLED, SYMBOL_DISABLED}: # return True # elif lhs == SYMBOL_CHOSEN and rhs == SYMBOL_ENABLED: # return True # else: # return lhs == rhs # ############################################################################# ############################################################################# def matchDelimEnDis(lhs, rhs): # if lhs == SYMBOL_DELIM and rhs in {SYMBOL_ENABLED, SYMBOL_DISABLED}: # return True # else: # return lhs == rhs # ############################################################################# ##################################### def pickChosenOrRight(lhs, rhs): # if lhs == SYMBOL_CHOSEN: # return lhs # else: # return rhs # ##################################### result = Automaton.transdAutAutProd( autPlay2, autEnabled, matchDelimChosenToEnDis, pickChosenOrRight, autEnabled, matchDelimEnDis, lambda x, y: y ) return result
def main(options): if not options.automaton_file: raise Exception("Automaton \"option\" (-a) is mandatory") automaton = Automaton.create_from_dump(open(options.automaton_file)) if options.quantizer: automaton.quantizer = AbstractQuantizer.read(open(options.quantizer)) automaton.round_and_normalize() input_ = sys.stdin if options.corpus: input_ = open(options.corpus) corpus = read_corpus(input_, options.separator) corpus = normalize_corpus(corpus) learner = Learner.create_from_options(automaton, corpus, options) learner.main() output = sys.stdout if options.output: output = open(options.output, "w") learner.automaton.dump(output)
def encodeEnablednessAut(aut, autEnabled): '''encodeEnablednessAut(aut, autEnabled) -> Automaton Encodes enabledness (given by autEnabled) into an automaton aut. This is done by performing a product of aut and autEnabled, while treating 'delim' as {'enabled', 'disabled'}. ''' def funDelimMatchEnDis(lhs, rhs): if ((lhs == SYMBOL_DELIM) and ((rhs == SYMBOL_ENABLED) or (rhs == SYMBOL_DISABLED))): return True else: return lhs == rhs def funTakeRhs(lhs, rhs): return rhs aut2 = aut.removeEpsilon() result = Automaton.generalIntersection(aut2, autEnabled, funDelimMatchEnDis, funTakeRhs) return result
def create_three_state_fsa(corpus): prefixes, suffixes = get_morpheme_frequencies(corpus) fsa = Automaton() for morpheme in prefixes.keys()+suffixes.keys()+['@', 'O']: state = morpheme+'_0' fsa.emissions[state] = morpheme fsa.m_emittors[morpheme].add(state) total_prefix_freq = sum(prefixes.values()) total_suffix_freq = sum(suffixes.values()) for prefix, p_freq in prefixes.iteritems(): fsa.m['^'][prefix+'_0'] = math.log(p_freq/total_prefix_freq) fsa.m[prefix+'_0']['@_0'] = 0.0 for suffix, s_freq in suffixes.iteritems(): fsa.m['@_0'][suffix+'_0'] = math.log(s_freq/total_suffix_freq) fsa.m[suffix+'_0']['$'] = 0.0 return fsa
def regexp_to_automaton(re: str) -> Automaton: """ Moore's algorithm: regular expression `re` -> non-deterministic automaton """ postfix = RegExpReader(re).to_postfix() stack: List[Automaton] = [] for c in postfix: if c in (".", "+", "*"): right = stack.pop() left = None if c != "*": left = stack.pop() result = operation(left, right, c) stack.append(result) else: automate = Automaton(c) automate.add_transition("0", c, "1") automate.make_accept("1") stack.append(automate) return stack[0]
def check(g, params): a = Automaton(g, params) a.check() return a
def main(): automaton = Automaton.create_from_dump(open(sys.argv[1])) corpus = read_corpus(open(sys.argv[2]), "#") dc = DistanceCache(automaton, corpus) dc.build_paths()
def autPlay1ToFair(aut): '''autPlay1ToFair(aut) -> Automaton Encodes fairness into aut for Player 1. ''' ########################################### def encodeCntChooseTrans(src, symb1, symb2, dst, encoding, discardDelim): '''encodeCntChooseTrans(src, symb1, symb2, dst, encoding, discardDelim) -> [Transition] Encodes a transition for choosing process. ''' cntState = dst + "_" + symb1 + "_" + symb2 newTransitions = [] newTransitions.append(Automaton.makeEpsTrans(src, cntState)) if encoding == CounterEncoding.unary: endState = cntState + "_end" if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, endState)) elif (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_CHOSEN): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, endState)) else: raise Exception("Invalid delimiter symbol \'" + symb1 + "/" + symb2 + "\' (only 'enabled' and 'chosen' are allowed)") elif encoding in {CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian}: cntState2 = cntState + "_2" endState = cntState2 if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ZERO, SYMBOL_ZERO, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ONE, SYMBOL_ONE, cntState2)) elif (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_CHOSEN): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ZERO, SYMBOL_ONE, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ONE, SYMBOL_ONE, cntState2)) else: raise Exception("Invalid delimiter symbol \'" + symb1 + "/" + symb2 + "\' (only 'enabled' and 'chosen' are allowed)") else: raise Exception("Invalid encoding: " + str(encoding)) # transition from endState if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTransTransd(endState, symb1, symb2, dst)) return newTransitions ###################################################### output = Automaton() output.startStates = aut.startStates[:] output.acceptStates = aut.acceptStates[:] # for trans in aut.transitions: # if Automaton.isEpsilonTrans(trans): # # epsilon transitions # output.addTrans(transition = trans) # elif (Automaton.getSymbol1(trans) in ENCODING_ALPHABET): # # delimiters # (src, symb1, symb2, tgt) = trans # cntState = tgt + "_" + symb1 + "_" + symb2 # output.addTrans(transition = (src, cntState)) # output.addTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, cntState) # output.addTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState) # output.addTransTransd(cntState, symb1, symb2, tgt) # else: # # other transitions # output.addTrans(transition = trans) for trans in aut.transitions: if Automaton.isEpsilonTrans(trans): # epsilon transitions output.addTrans(transition = trans) elif (Automaton.getSymbol1(trans) in ENCODING_ALPHABET): # delimiters (src, symb1, symb2, tgt) = trans counterTransitions = encodeCntChooseTrans( src, symb1, symb2, tgt, options.encoding, options.discardDelimiter) output.addTransitions(counterTransitions) # cntState = tgt + "_" + symb1 + "_" + symb2 # endState = cntState + "_end" # output.addTrans(transition = (src, cntState)) # if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): # # TODO: these are bad # output.addTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, cntState) # output.addTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState) # output.addTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, endState) # elif (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_CHOSEN): # # TODO: these are bad # output.addTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, cntState) # output.addTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState) # output.addTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, endState) # else: # raise Exception("Invalid delimiter symbol \'" + symb1 + "/" + # symb2 + "\' (only 'enabled' and 'chosen' are allowed)") # # # transition from endState # if options.discardDelimiter: # output.addTrans(transition = # Automaton.makeEpsTrans(endState, tgt)) # else: # output.addTransTransd(endState, symb1, symb2, tgt) else: # other transitions output.addTrans(transition = trans) output.transitions = list(set(output.transitions)) # kill duplicates return output
def encodeCntTrans(src, dst, symbol, encoding, discardDelim, allowZero): newTransitions = [] if encoding == CounterEncoding.unary: oneState = dst + "_" + symbol + "_" + SYMBOL_ONE zeroState = dst + "_" + symbol + "_" + SYMBOL_ZERO symbState = dst + "_" + symbol newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTrans(oneState, SYMBOL_ONE, oneState)) if allowZero: newTransitions.append( Automaton.makeEpsTrans(oneState, zeroState)) else: newTransitions.append( Automaton.makeTrans(oneState, SYMBOL_ONE, zeroState)) newTransitions.append( Automaton.makeTrans(zeroState, SYMBOL_ZERO, zeroState)) newTransitions.append( Automaton.makeTrans(zeroState, SYMBOL_ZERO, symbState)) if discardDelim: newTransitions.append(Automaton.makeEpsTrans(symbState, dst)) else: newTransitions.append(Automaton.makeTrans(symbState, symbol, dst)) elif encoding in {CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian}: cntState = dst + "_cnt" newTransitions.append(Automaton.makeEpsTrans(src, cntState)) newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ZERO, cntState)) newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ONE, cntState)) if allowZero: endState = cntState else: cntState2 = cntState + "2" endState = cntState2 newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ZERO, cntState2)) # newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ONE, cntState2)) newTransitions.append(Automaton.makeTrans(cntState2, SYMBOL_ZERO, cntState2)) newTransitions.append(Automaton.makeTrans(cntState2, SYMBOL_ONE, cntState2)) # how to treat the delimiter if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTrans(endState, symbol, dst)) pass else: raise Exception("Invalid type of counter encoding") return newTransitions
def encodeCounter(aut, encoding, discardDelim, allowZero): '''encodeCounter(aut, encoding, discardDelim, allowZero) -> Automaton Encode counters using a given encoding into aut, yielding a new automaton. In particular, every delimiter 'D' is substituted with a sub-automaton accepting the language of all valid counter configurations (depending on the encoding). Depending on discardDelim, 'D' is kept or discarded. The allowZero parameter is a Boolean flag that when set to True allows the value of the counter to be zero. ''' ########################################################## def encodeCntTrans(src, dst, symbol, encoding, discardDelim, allowZero): newTransitions = [] if encoding == CounterEncoding.unary: oneState = dst + "_" + symbol + "_" + SYMBOL_ONE zeroState = dst + "_" + symbol + "_" + SYMBOL_ZERO symbState = dst + "_" + symbol newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTrans(oneState, SYMBOL_ONE, oneState)) if allowZero: newTransitions.append( Automaton.makeEpsTrans(oneState, zeroState)) else: newTransitions.append( Automaton.makeTrans(oneState, SYMBOL_ONE, zeroState)) newTransitions.append( Automaton.makeTrans(zeroState, SYMBOL_ZERO, zeroState)) newTransitions.append( Automaton.makeTrans(zeroState, SYMBOL_ZERO, symbState)) if discardDelim: newTransitions.append(Automaton.makeEpsTrans(symbState, dst)) else: newTransitions.append(Automaton.makeTrans(symbState, symbol, dst)) elif encoding in {CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian}: cntState = dst + "_cnt" newTransitions.append(Automaton.makeEpsTrans(src, cntState)) newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ZERO, cntState)) newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ONE, cntState)) if allowZero: endState = cntState else: cntState2 = cntState + "2" endState = cntState2 newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ZERO, cntState2)) # newTransitions.append(Automaton.makeTrans(cntState, SYMBOL_ONE, cntState2)) newTransitions.append(Automaton.makeTrans(cntState2, SYMBOL_ZERO, cntState2)) newTransitions.append(Automaton.makeTrans(cntState2, SYMBOL_ONE, cntState2)) # how to treat the delimiter if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTrans(endState, symbol, dst)) pass else: raise Exception("Invalid type of counter encoding") return newTransitions ############################################################## result = Automaton() result.startStates = aut.startStates[:] result.acceptStates = aut.acceptStates[:] for trans in aut.transitions: (src, symb, tgt) = trans assert symb != SYMBOL_DISABLED if symb == SYMBOL_ENABLED: # for end-of-subword transitions counterTransitions = encodeCntTrans( src, tgt, symb, encoding, discardDelim, allowZero) result.addTransitions(counterTransitions) else: # for ordinary transitions result.addTrans(transition = trans) result.transitions = list(set(result.transitions)) # kill duplicates return result.removeUseless()
def encodeCntDecTrans(src, symb1, symb2, dst, encoding, discardDelim): '''encodeCntDecTrans(src, symb1, symb2, dst, encoding, discardDelim) -> [Transition] Encodes the counter decrement transitions. ''' newTransitions = [] if encoding == CounterEncoding.unary: if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneState = dst + "_enXenX1" zeroState = dst + "_enXenX0" endState = zeroState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, endState)) elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): chEnOneState = dst + "_chXenX1" endState = chEnOneState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, chEnOneState)) newTransitions.append(Automaton.makeTransTransd(chEnOneState, SYMBOL_ONE, SYMBOL_ONE, chEnOneState)) newTransitions.append(Automaton.makeTransTransd(chEnOneState, SYMBOL_ONE, SYMBOL_ZERO, endState)) else: raise Exception("Unexpected symbols: (" + symb1 + ", " + symb2 + ")") elif encoding == CounterEncoding.binaryLittleEndian: if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneState = dst + "_enXenX1" zeroState = dst + "_enXenX0" endState = zeroState # binary decrement newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ZERO, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ONE, SYMBOL_ONE, zeroState)) elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): oneState = dst + "_chXenX1" zeroState = dst + "_chXenX0" endState = zeroState newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ONE, SYMBOL_ONE, zeroState)) else: raise Exception("Unexpected symbols: (" + symb1 + ", " + symb2 + ")") elif encoding == CounterEncoding.binaryBigEndian: if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneState = dst + "_enXenX1" zeroState = dst + "_enXenX0" endState = zeroState # binary decrement newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ZERO, SYMBOL_ZERO, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ONE, zeroState)) elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): oneState = dst + "_chXenX1" zeroState = dst + "_chXenX0" endState = zeroState newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) else: raise Exception("Unexpected symbols: (" + symb1 + ", " + symb2 + ")") else: raise Exception("Invalid encoding: " + str(encoding)) # deal with the delimiter if options.discardDelimiter: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTransTransd(endState, symb1, symb2, dst)) return newTransitions
def encodeCntChooseTrans(src, symb1, symb2, dst, encoding, discardDelim): '''encodeCntChooseTrans(src, symb1, symb2, dst, encoding, discardDelim) -> [Transition] Encodes a transition for choosing process. ''' cntState = dst + "_" + symb1 + "_" + symb2 newTransitions = [] newTransitions.append(Automaton.makeEpsTrans(src, cntState)) if encoding == CounterEncoding.unary: endState = cntState + "_end" if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, endState)) elif (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_CHOSEN): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, endState)) else: raise Exception("Invalid delimiter symbol \'" + symb1 + "/" + symb2 + "\' (only 'enabled' and 'chosen' are allowed)") elif encoding in {CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian}: cntState2 = cntState + "_2" endState = cntState2 if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ZERO, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ZERO, SYMBOL_ZERO, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ONE, SYMBOL_ONE, cntState2)) elif (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_CHOSEN): newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ONE, SYMBOL_ONE, cntState)) newTransitions.append(Automaton.makeTransTransd(cntState, SYMBOL_ZERO, SYMBOL_ONE, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ZERO, SYMBOL_ONE, cntState2)) newTransitions.append(Automaton.makeTransTransd(cntState2, SYMBOL_ONE, SYMBOL_ONE, cntState2)) else: raise Exception("Invalid delimiter symbol \'" + symb1 + "/" + symb2 + "\' (only 'enabled' and 'chosen' are allowed)") else: raise Exception("Invalid encoding: " + str(encoding)) # transition from endState if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTransTransd(endState, symb1, symb2, dst)) return newTransitions
def create_new_three_state_fsa(corpus, harant="a", emissions="m"): """This fsa will not make use of an "O" state and will have edges from the start state to all word-final morphemes @harant - transitions to the second level - "a": for all suffix morphemes - list: morphemes and morpheme igrams that will be harant'ed - else: No transitions here @emissions - morpheme or character emissions - "m": morpheme - "c": character """ prefixes, suffixes = get_morpheme_frequencies(corpus) fsa = Automaton() morphemes_with_index = zip(len(prefixes) * [0], prefixes.keys()) morphemes_with_index += zip(len(suffixes) * [2], suffixes.keys()) for index, morpheme in morphemes_with_index: state = "{0}_{1}".format(morpheme, index) if emissions == "m": fsa.emissions[state] = (morpheme,) fsa.m_emittors[morpheme].add(state) elif emissions == "c": fsa.emissions[state] = tuple(morpheme) fsa.m_emittors[tuple(morpheme)].add(state) total_suffix_freq = sum(suffixes.values())*0.5 total_prefix_freq = sum(prefixes.values())+total_suffix_freq #half of suffix frequencies should appear on edges from the epsilon state, #the other half on edges from the starting state for prefix, p_freq in prefixes.iteritems(): fsa.m['^'][prefix+'_0'] = math.log(p_freq/total_prefix_freq) fsa.m[prefix+'_0']['EPSILON_1'] = 0.0 fsa.m['^']['EPSILON_0'] = -5.0 fsa.m['EPSILON_0']['EPSILON_1'] = 0.0 for suffix, s_freq in suffixes.iteritems(): fsa.m['EPSILON_1'][suffix+'_2'] = math.log( (0.5*s_freq)/total_suffix_freq) #the two 0.5s cancel each other out, which reflects that once #we got as far as the epsilon state, it doesn't matter anymore #whether we allowed suffixes to follow the start state or not if harant == "a": fsa.m['^'][suffix+'_2'] = math.log((0.5*s_freq)/total_prefix_freq) elif type(harant) == list and suffix in harant: fsa.m['^'][suffix+'_2'] = math.log((0.5*s_freq)/total_prefix_freq) fsa.m[suffix+'_2']['$'] = 0.0 for prefix, _ in prefixes.iteritems(): for suffix, _ in suffixes.iteritems(): if type(harant) == list and (prefix, suffix) in harant: state_name = "".join(prefix) + "".join(suffix) + "_3" fsa.m["^"][state_name] = -20.0 fsa.m[state_name]["$"] = 0.0 fsa.emissions[state_name] = (prefix,suffix) fsa.m_emittors[(prefix,suffix)].add(state_name) fsa.round_and_normalize() return fsa
def autPlay2ToFair(aut): '''autPlay2ToFair(aut) -> Automaton Encodes fairness into aut for Player 2. ''' ########################################### def encodeCntDecTrans(src, symb1, symb2, dst, encoding, discardDelim): '''encodeCntDecTrans(src, symb1, symb2, dst, encoding, discardDelim) -> [Transition] Encodes the counter decrement transitions. ''' newTransitions = [] if encoding == CounterEncoding.unary: if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneState = dst + "_enXenX1" zeroState = dst + "_enXenX0" endState = zeroState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, endState)) elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): chEnOneState = dst + "_chXenX1" endState = chEnOneState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, chEnOneState)) newTransitions.append(Automaton.makeTransTransd(chEnOneState, SYMBOL_ONE, SYMBOL_ONE, chEnOneState)) newTransitions.append(Automaton.makeTransTransd(chEnOneState, SYMBOL_ONE, SYMBOL_ZERO, endState)) else: raise Exception("Unexpected symbols: (" + symb1 + ", " + symb2 + ")") elif encoding == CounterEncoding.binaryLittleEndian: if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneState = dst + "_enXenX1" zeroState = dst + "_enXenX0" endState = zeroState # binary decrement newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ZERO, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ONE, SYMBOL_ONE, zeroState)) elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): oneState = dst + "_chXenX1" zeroState = dst + "_chXenX0" endState = zeroState newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ONE, SYMBOL_ONE, zeroState)) else: raise Exception("Unexpected symbols: (" + symb1 + ", " + symb2 + ")") elif encoding == CounterEncoding.binaryBigEndian: if (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): oneState = dst + "_enXenX1" zeroState = dst + "_enXenX0" endState = zeroState # binary decrement newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ZERO, SYMBOL_ZERO, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ONE, zeroState)) elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): oneState = dst + "_chXenX1" zeroState = dst + "_chXenX0" endState = zeroState newTransitions.append(Automaton.makeEpsTrans(src, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState)) newTransitions.append(Automaton.makeTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState)) else: raise Exception("Unexpected symbols: (" + symb1 + ", " + symb2 + ")") else: raise Exception("Invalid encoding: " + str(encoding)) # deal with the delimiter if options.discardDelimiter: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTransTransd(endState, symb1, symb2, dst)) return newTransitions ################################################# output = Automaton() output.startStates = aut.startStates[:] output.acceptStates = aut.acceptStates[:] for trans in aut.transitions: if Automaton.isEpsilonTrans(trans): output.addTrans(transition = trans) else: (src, symb1, symb2, tgt) = trans # if (symb1, symb2) == (SYMBOL_DISABLED, SYMBOL_DISABLED): # disState = tgt + "_disXdis" # output.addTrans(transition = (src, disState)) # output.addTransTransd(disState, SYMBOL_ZERO, SYMBOL_ZERO, disState) # output.addTransTransd(disState, SYMBOL_ONE, SYMBOL_ONE, disState) # output.addTransTransd(disState, SYMBOL_DISABLED, SYMBOL_DISABLED, tgt) # elif (symb1, symb2) == (SYMBOL_ENABLED, SYMBOL_ENABLED): # oneState = tgt + "_enXenX1" # zeroState = tgt + "_enXenX0" # output.addTrans(transition = (src, oneState)) # output.addTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState) # output.addTransTransd(oneState, SYMBOL_ONE, SYMBOL_ZERO, zeroState) # output.addTransTransd(zeroState, SYMBOL_ZERO, SYMBOL_ZERO, zeroState) # output.addTransTransd(zeroState, SYMBOL_ENABLED, SYMBOL_ENABLED, tgt) # elif (symb1, symb2) == (SYMBOL_DISABLED, SYMBOL_ENABLED): # # NOTE: this case determines the particular notion of fairness, right? # oneState = tgt + "_starXenX1" # disEnState = tgt + "_disXen" # output.addTrans(transition = (src, oneState)) # output.addTransTransd(oneState, SYMBOL_ZERO, SYMBOL_ONE, oneState) # output.addTransTransd(oneState, SYMBOL_ONE, SYMBOL_ONE, oneState) # output.addTransTransd(oneState, SYMBOL_ZERO, SYMBOL_ZERO, disEnState) # output.addTransTransd(disEnState, SYMBOL_DISABLED, SYMBOL_ENABLED, tgt) # elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_DISABLED): # chDisState = tgt + "_chXdis" # output.addTrans(transition = (src, chDisState)) # output.addTransTransd(chDisState, SYMBOL_ZERO, SYMBOL_ZERO, chDisState) # output.addTransTransd(chDisState, SYMBOL_ONE, SYMBOL_ONE, chDisState) # output.addTransTransd(chDisState, SYMBOL_CHOSEN, SYMBOL_DISABLED, tgt) # elif (symb1, symb2) == (SYMBOL_CHOSEN, SYMBOL_ENABLED): # chEnOneState = tgt + "_chXenX1" # chEnState = tgt + "_chXen" # output.addTrans(transition = (src, chEnOneState)) # output.addTransTransd(chEnOneState, SYMBOL_ZERO, SYMBOL_ONE, chEnOneState) # output.addTransTransd(chEnOneState, SYMBOL_ONE, SYMBOL_ONE, chEnOneState) # output.addTransTransd(chEnOneState, SYMBOL_ZERO, SYMBOL_ZERO, chEnState) # output.addTransTransd(chEnState, SYMBOL_CHOSEN, SYMBOL_ENABLED, tgt) # else: # assert symb1 not in FAIR_ENCODING_ALPHABET # assert symb2 not in FAIR_ENCODING_ALPHABET # # output.addTrans(transition = trans) if symb1 in FAIR_ENCODING_ALPHABET and symb2 in FAIR_ENCODING_ALPHABET: counterTransitions = encodeCntDecTrans(src, symb1, symb2, tgt, options.encoding, options.discardDelimiter,) output.addTransitions(counterTransitions) else: assert symb1 not in FAIR_ENCODING_ALPHABET assert symb2 not in FAIR_ENCODING_ALPHABET output.addTrans(transition = trans) output.transitions = list(set(output.transitions)) # kill duplicates return output
def autFinalToFair(aut, autEnabled, options): '''autFinalToFair(aut, autEnabled, options) -> Automaton Encodes fairness into an automaton representing final configurations of a system, w.r.t. enabled transitions given by autEnabled. The final states are states given by aut with fairness encoded, or states corresponding to one enabled process's counter reaching zero. The options parameter contains command line arguments. ''' ########################################### def encodeCntTimeout(src, symbol, dst, encoding, discardDelim): '''encodeCntTimeout(src, symbol, dst, encoding, discardDelim) -> [Transition] Encodes a counter timeout in the place of the transition. ''' newTransitions = [] if encoding in {CounterEncoding.unary, CounterEncoding.binaryLittleEndian, CounterEncoding.binaryBigEndian}: zeroState = dst + "Y0" endState = zeroState + "_end" newTransitions.append(Automaton.makeEpsTrans(src, zeroState)) newTransitions.append(Automaton.makeTrans(zeroState, SYMBOL_ZERO, zeroState)) newTransitions.append(Automaton.makeTrans(zeroState, SYMBOL_ZERO, endState)) else: raise Exception("Invalid encoding: " + str(encoding)) if discardDelim: newTransitions.append(Automaton.makeEpsTrans(endState, dst)) else: newTransitions.append(Automaton.makeTrans(endState, SYMBOL_ENABLED, dst)) return newTransitions ############################################# aut1 = autEnabled.renameStates(lambda x: x + "Y1") aut1 = aut1.clearAcceptStates() aut2 = autEnabled.renameStates(lambda x: x + "Y2") aut2 = aut2.clearStartStates() aut3 = Automaton.autUnion(aut1, aut2) for (src, symb, tgt) in autEnabled.transitions: if symb == SYMBOL_ENABLED: aut3.addTrans(src + "Y1", SYMBOL_ENABLED_TIMEOUT, tgt + "Y2") aut4 = encodeCounter(aut3, encoding = options.encoding, discardDelim = options.discardDelimiter, allowZero = True ) aut5 = Automaton() aut5.startStates = aut4.startStates[:] aut5.acceptStates = aut4.acceptStates[:] # encode the timeout condition for trans in aut4.transitions: if (not Automaton.isEpsilonTrans(trans) and Automaton.getSymbol(trans) == SYMBOL_ENABLED_TIMEOUT): (src, symb, tgt) = trans # zeroState = tgt + "Y0" # aut5.addTrans(transition = (src, zeroState)) # aut5.addTrans(zeroState, SYMBOL_ZERO, zeroState) # aut5.addTrans(zeroState, SYMBOL_ZERO, tgt) # for the special timeout symbol counterTransitions = encodeCntTimeout(src, symb, tgt, options.encoding, options.discardDelimiter) aut5.addTransitions(counterTransitions) else: # for other symbols aut5.addTrans(transition = trans) autB = encodeCounter(aut, encoding = options.encoding, discardDelim = options.discardDelimiter, allowZero = True ) output = Automaton.autUnion(aut5, autB) output = output.singleStartState(FINAL_START_STATE) output.transitions = list(set(output.transitions)) # kill duplicates return output.removeUseless()