#include <iostream>
#include <fstream>
#include "struct.h"
#include <string.h>
using namespace std;

bool verifier_fait(char f_FAV, Regle *f_BaseDeRegles, int f_taille, char* &f_FI, int &f_nb_etat_init)
{
    char cond;
    int i=0;
    bool cond_ok;
    bool init_ok = false;


    for (int cpt_init=0; cpt_init<= f_nb_etat_init-1; cpt_init++)
    {
           if (f_FAV == f_FI[cpt_init])
           {
                       return  true;
           }
    }

    for(int cpt_BR = 0 ; cpt_BR <= f_taille-1 ; cpt_BR++)
    {
        if (f_BaseDeRegles[cpt_BR].conclusion == f_FAV)
        {

           cout<<endl<< "Regle: ";
           cout<<"R"<< f_BaseDeRegles[cpt_BR].n_regle<<": ";


           for(int cpt_c = 0 ; cpt_c <= f_BaseDeRegles[cpt_BR].n_conditions-1; cpt_c++)
           {
                   cout<< f_BaseDeRegles[cpt_BR].conditions[cpt_c];
                   if((f_BaseDeRegles[cpt_BR].n_conditions > 1)&&(cpt_c != f_BaseDeRegles[cpt_BR].n_conditions-1 ))
                   {
                            cout << ".";
                   }
           }
           cout<<"=" << f_BaseDeRegles[cpt_BR].conclusion << endl << "Fais ok: ";
           for(int cpt_i = 0 ; cpt_i <= f_nb_etat_init-1; cpt_i++)
           {
                   cout << f_FI[cpt_i]<<" ";
           }
           cout<<endl;


           for( int cpt_c=0 ; cpt_c <= f_BaseDeRegles[cpt_BR].n_conditions-1; cpt_c++)
           {
                 cond = f_BaseDeRegles[cpt_BR].conditions[cpt_c];
                  cond_ok = verifier_fait (cond, f_BaseDeRegles, f_taille, f_FI, f_nb_etat_init);
            }

             for(int cpt_c = 0 ; cpt_c <= f_BaseDeRegles[cpt_BR].n_conditions-1; cpt_c++)
             {
                   for(int cpt_i = 0 ; cpt_i <= f_nb_etat_init-1; cpt_i++)
                   {
                      if(f_BaseDeRegles[cpt_BR].conditions[cpt_c] == f_FI[cpt_i])
                      {
                                i++;
                      }
                      if(i==f_BaseDeRegles[cpt_BR].n_conditions)
                      {
                           f_FI[f_nb_etat_init]= f_FAV;
                           f_nb_etat_init++ ;
                           return true;
                      }
                  }
              }
      }
    }
      return false;
}

int main()
{
    cout << "Chainage arriere!" << endl;

    char* selection_fichier;
    selection_fichier = "baseregles.txt";
    ifstream fichier(selection_fichier, ios::in);

    int taille=0;
    int nb_etat_init;
    char *etat_init;
    Regle *BaseDeRegles;



    string FE;
    char FAV = '#';
    char t_FAV;

        fichier >> taille; // récupere le nombre de règle du fichier
        BaseDeRegles = new Regle[taille];

        char condition;
        char conclusion;
        char c;
        int cpt_nb_regles=0;


        do
        {

            int cpt_conditions=0;

            BaseDeRegles[cpt_nb_regles].n_regle = cpt_nb_regles + 1;
            fichier >>BaseDeRegles[cpt_nb_regles].n_conditions;
            fichier >> c; // on enleve :
            fichier >> condition;

                while((condition) != '=' )
                {

                        BaseDeRegles[cpt_nb_regles].conditions=BaseDeRegles[cpt_nb_regles].conditions+condition;
                        cpt_conditions++;

                    fichier >> condition;
                };

            if(condition == '=')
            {
                fichier >> conclusion;
                BaseDeRegles[cpt_nb_regles].conclusion = conclusion;
            }

            cpt_nb_regles++;

        }while(cpt_nb_regles<taille);


         char fait;
         int cpt_i=0;
         etat_init = new char[30];

         fichier >> nb_etat_init;
         fichier >> fait;

         while(fait != '#')
         {
               etat_init[cpt_i] = fait;
               fichier >> fait;
               cpt_i++;
         }

        fichier.close();


    cout << endl << "Nombre de regles: "<< taille<<endl;


    for(int cptt=0;cptt<taille;cptt++)
    {
        cout <<"R"<< BaseDeRegles[cptt].n_regle <<": "<< BaseDeRegles[cptt].conditions << " => " << BaseDeRegles[cptt].conclusion << endl;
    }


    string FI=etat_init;

    for(int cpt1=0;cpt1<taille;cpt1++)
    {
        for(int cpt2=0;cpt2<BaseDeRegles[cpt1].conditions.size();cpt2++)
        {

                if(FE.find_first_of(BaseDeRegles[cpt1].conditions[cpt2])==string::npos)
                {
                    FE = FE + BaseDeRegles[cpt1].conditions[cpt2];

                }

                if(FE.find_first_of(BaseDeRegles[cpt1].conclusion)==string::npos)
                {
                    FE = FE + BaseDeRegles[cpt1].conclusion;

                }

        }
    }


    cout <<endl<< "Liste des faits : " << FE << endl;
    cout << "Faits initiaux : " << FI << endl;


    //saisie du fait à vérifier parmis les conclusions

        cout <<endl<<endl<< "Fait a verifier : " ;
        cin >>t_FAV;


        bool verif=false;

        char *c_FI;
        c_FI = new char[26];
        size_t size = FI.size() + 1;
        strncpy( c_FI, FI.c_str(), size );
        cout <<endl<<"****************************************";
        cout <<endl<< "CHAINAGE ARRIERE : " << endl;
        cout <<endl<<"****************************************";
        verif=verifier_fait(t_FAV, BaseDeRegles, taille, etat_init, nb_etat_init);




        if(verif==true)
        {
            cout <<endl<<"****************************************";
            cout <<endl<< "Ce fait est verifie" << endl;
            cout <<endl<<"****************************************";
        }
        else{cout <<endl<< "Ce fait n'est pas verifie" << endl;}



    cout <<endl<<endl;
    system("PAUSE");
    return 0;
}
