#include <astl.h>
#include <dfa_map.h>
#include <cursor.h>
#include <language.h>
#include <combinatory.h>
#include <filter.h>
#include <set_operation.h>
#include <astl_tree.h>
#include <iterator>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <ccopy.h>
#include <minimize.h>
#include <debug.h>

typedef DFA_map<plain, minimization_tag> DFA;
typedef forward_cursor<DFA> ForwardCursor;

// compile with:
// g++ -Wall -O3 -I.. -I../.. anagrammes.cpp

// Usage: a.out dico
// dico contains one word per line
// then for each word entered, the program
// displays all permutations of the word which are in the dictionary

int main(int argc, char **argv)
{
  DFA dfa1, dfa2;  
  if (argc > 1) {
    ifstream f1;
    f1.open(argv[1], ios::in);
    if (!f1) exit(2);
    tree_build(dfa1, istream_iterator<string>(f1), istream_iterator<string>());
    f1.close();
  }
  cout << "Q = " << dfa1.state_count() << " T = " << dfa1.trans_count()
       << endl;
  cout << "minimizing...";
  cout.flush();
  acyclic_minimization(dfa1);
  cout << endl << "Q = " << dfa1.state_count() << " T = " << dfa1.trans_count()
       << endl;

  ostream_iterator<char> output(cerr);
  while(1) {
    string w;
    cout << "Ok" << endl;
    cin >> w;
    cout << "language:" << endl;

    // On commence par trier les lettres du mots (nécessaire pour l'intersection):
    sort(w.begin(), w.end());

    // On ajoute une lettre quelconque au début de la chaîne pour que les
    // indices des caractères commencent à 1:
    w.insert(w.begin(), ' ');

    language(output, 
	     dfirstc(intersectionc(filter_outc(permutationc(w.size() - 1), 
					       bind1st(mem_fun_ref(&string::operator[]), w)), forwardc(dfa1))));
  }
  
  cout << "exit." << endl;
  return 0;
}
  
  









