#include #include #include #include #include #include using namespace std; typedef vector transitions; typedef vector word; struct Automaton { int states; vector accept; vector delta; int initial; Automaton(int in, int n, const vector &d, const vector &acc) { assert(in < n); assert(d.size() == n); accept = acc; delta.resize(n); for (int i = 0; i < d.size(); i++) { delta[i] = transitions(d[i]); } in = initial; states = n; } int apply(const word &w, int beg) { int crawl = beg; for (auto c: w) { crawl = delta[crawl][c]; } return crawl; } bool check(const word &s) { int q = apply(s, initial); for (auto i: accept) { if (q == i) return true; } return false; } void dump() { cout << "States: " << states << "; accepting: "; for (auto i: accept) cout << i << " "; cout << "\n"; cout << "Transition table:\n"; for (int i = 0; i < states; i++) { cout << i << ":"; for (int j = 0; j < delta[i].size(); j++) { cout << "\t--" << (char)(j + 'a') << "--> " << delta[i][j] << "\n"; } } } }; void fill_accepts(int mask, int states, vector &acc) { acc.clear(); for (int i = 0; i < states; i++) { if (mask & (1< generate_words(int max_len, int alph_sz) { vector result; for (int len = 0; len <= max_len; len++) { word w; for (int i = 0; i < len; i++) w.push_back(0); do { result.push_back(w); } while (next_word(w, alph_sz)); } return result; } void get_transitions(Automaton &aut, word &w, vector &res) { res.clear(); for (int i = 0; i < aut.states; i++) { res.push_back(aut.apply(w, i)); } } int my_power(int a, int b) { if (b == 0) return 1; return a * my_power(a, b-1); } bool check_automaton(vector &words, Automaton &aut) { vector> funcs; for (auto w: words) { vector trans; get_transitions(aut, w, trans); funcs.push_back(trans); } sort(funcs.begin(), funcs.end()); auto it = unique(funcs.begin(), funcs.end()); funcs.erase(it, funcs.end()); cout << funcs.size() << "\n"; if (funcs.size() == my_power(aut.states, aut.states)) { cout << "mamy to!!\n"; aut.dump(); return true; } return false; } vector generate_automatons(int states, int alph_sz, vector &words) { vector result; vector delta; vector accepts; for (int i = 0; i < states; i++) { delta.push_back(transitions()); for (int s = 0; s < alph_sz; s++) { delta[i].push_back(0); } } /* loop over accepting states */ // for (int i = 0; i < (1<> states >> alph_sz; vector accept; vector delta; int initial; fill_accepts(1, states, accept); initial = 0; for (int i = 0; i < states; i++) { cout << i << ":"; delta.push_back(transitions()); for (int j = 0; j < alph_sz; j++) { int x; cout << "\t--" << (char)(j + 'a') << "--> ? "; cin >> x; delta[i].push_back(x); } } return Automaton(0, states, delta, accept); } int main(int argc, char *argv[]) { if (argc != 4) { fprintf(stderr, "Usage: %s states alph_sz word_sz\n", argv[0]); return -1; } int states = atoi(argv[1]); int alph_sz = atoi(argv[2]); int word_sz = atoi(argv[3]); // vector automatons = generate_automatons(states, alph_sz); // for (auto a: automatons) { // a.dump(); // cout << "\n"; // } fprintf(stderr, "Generating words...\n"); vector words = generate_words(word_sz, alph_sz); // for (auto w: words) { // for (auto c: w) { // cout << (char)(c + 'a'); // } // cout << "\n"; // } // fprintf(stderr, "Generating %d automatons...\n", my_power(alph_sz, alph_sz * states)); // generate_automatons(states, alph_sz, words); Automaton aut = automaton_from_input(); check_automaton(words, aut); }