⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 The subject which is to us propos¨&brvbar is as follows: calculation of the degr¨&brvbar d&iexcl &ma
💻 CPP
字号:

#include "Structure.h"
#include "Lecture.h"
#include <algorithm>
#include "time.h"
#include <unistd.h>
#include <sys/timeb.h>

// SModels Header
#include "smodels.h"
#include "api.h"
#include "atomrule.h"

bool IntersectionNotNil(CSetAtom a, CSetAtom b)
{
  CSetAtom::iterator i = a.begin();
  for (; i != a.end(); i++)
  {
     CSetAtom::iterator j = b.begin();
     for (; j != b.end(); j++)
     {
       if (*j == *i)
	 return false;
     }
  }

  return true;
}

void CalculReduit(CProgLogPos* pProg, CSetAtom v_ListeAtomPositif)
{
        timeb tTimeTake;
	ftime(&tTimeTake);

	// Erase all the rules those have not a head in v_ListeAtomPositif
	// And put these rules in another CProgLogPos for processing it

	vector<CReglePos*> vReductProg; // Set whitch contained all the rules needed for the stable model

	vector<CReglePos*> vSetAllRules = pProg->GetAllPossibilistRules(); // Get all the rules of the program
	vector<CReglePos*>::iterator iterRule = vSetAllRules.begin();

	CReglePos* rTmp;

	// Calcul of the reduct program
	for (; iterRule != vSetAllRules.end(); iterRule++)
	{
		rTmp = *iterRule;
		CSetAtom rSetAtom = rTmp->GetBodyMinus();
		// LE CODE SUIVANT QUI EST MIS EN COMMENTAIRE PROVOQUE UNE ERREUR DE COMPILATION A L'APPEL DE LA FONCTION set_intersection
		// int nHead = rTmp->GetHead();
		// CSetAtom resultDeb;
		// CSetAtom::iterator resultFin;
		/* resultFin = set_intersection(v_ListeAtomPositif.begin(),
					     v_ListeAtomPositif.end(),
					     rSetAtom.begin(),
					     rSetAtom.end(),
					     resultDeb.begin());*/

		// if (resultDeb.begin() == resultFin)
		// Jusqu'ici
		if (IntersectionNotNil(rSetAtom, v_ListeAtomPositif)) // Cette fonction permet de contourner l'erreur de compilation (mais elle n'est pas optimale...)
		{
			CReglePos* rPut = (CReglePos*) rTmp->Copy(BODYPLUS);
			vReductProg.push_back(rPut);
		}
	}

	// At this point we have the reduct of pProg program (in vReductProg)
	// Search the base of the stable model posibilist
	CStableModelPos vStableModel;
	iterRule = vReductProg.begin();

	while (iterRule != vReductProg.end())
	{
		rTmp = *iterRule;
		if (rTmp->IsEmptyBody(BODYPLUS))
		{
		    CStableModelPos::iterator i = vStableModel.Find(rTmp->GetHead());
		    if ( i != vStableModel.end())
		    {
		        // This atom is already in the base so update his degree (only if the current's one is superior)
		        vStableModel.UpdateDegree(rTmp->GetHead(), rTmp->GetDegree(), SUPERIOR);
		    }
		    else
		    {
		        vStableModel.push_back(CAtomPos(rTmp->GetHead(), rTmp->GetDegree()));
		    }

		    vReductProg.erase(iterRule); // Erase all rules those have got no body atoms
		    iterRule = vReductProg.begin(); // Come back to the beginning (we can't know the iterator place)
		    continue;
		}

		iterRule++;
	}

	// Initialisation of nNbrAtom : Give the number of atoms in the body+ for all the rules
	int nNbrRule = vReductProg.size();
	int* nNbrAtom = (int*) malloc (sizeof(int) * (nNbrRule+1));

	for (int i=0; i<nNbrRule; i++)
	{
		rTmp = vReductProg[i];
		nNbrAtom[i] = rTmp->GetBodyPlus().size();
	}

	while (vStableModel.size() < v_ListeAtomPositif.size())
	{
		iterRule = vReductProg.begin();
		int i = 0;
		for (; iterRule != vReductProg.end(); iterRule++)
		{
			rTmp = *iterRule;
			// Retrieved the number of the rule atom those are not in vStableModel
			if (nNbrAtom[i] != -1)
				nNbrAtom[i] = rTmp->UnionWith(vStableModel);
			i++;
		}

		// Update the stable model posibilist
		for (i=0; i<nNbrRule; i++)
		{
		  if (nNbrAtom[i] == 0) // Another rule can be deduce with the current vStableModel
			{
				rTmp = vReductProg[i];
				CStableModelPos::iterator iterStableAtom = vStableModel.Find(rTmp->GetHead());
				if (iterStableAtom == vStableModel.end())
				{
					// Add the head to the stable model posibilist
					int nMinSetAtom = rTmp->MinOfSetAtom(vStableModel);
					vStableModel.push_back(CAtomPos(rTmp->GetHead(), nMinSetAtom));
				}
				else
				{
					// The head is already referenced in the stable model posibilist
					// So look if its degree is superior to the current one
					CAtomPos aPosTmp = *iterStableAtom;
					int nOldDegree = aPosTmp.nDegree;
					int nMinSetAtom = rTmp->MinOfSetAtom(vStableModel);
					vStableModel.UpdateDegree(rTmp->GetHead(), nMinSetAtom, SUPERIOR);
					if (nOldDegree < nMinSetAtom)
					{
						// We have update the stable model posibilist
						// So calcule the others atoms inside (they can change)
						iterRule = vReductProg.begin();
						int nTmp = 0;
						while (iterRule != vReductProg.end())
						{
							rTmp = *iterRule;
							if (nNbrAtom[nTmp] == -1)
							{
								aPosTmp = *vStableModel.Find(rTmp->GetHead());
								nOldDegree = aPosTmp.nDegree;
								nMinSetAtom = rTmp->MinOfSetAtom(vStableModel);
								if (nOldDegree < nMinSetAtom) 
								{
									// We have found a atom posibilist with a better degree in stable model
									vStableModel.UpdateDegree(rTmp->GetHead(), nMinSetAtom, SUPERIOR);

									// The stable model have changed so come back at the begining
									nTmp = 0;
									iterRule = vReductProg.begin();
									continue;
								}
							}

							nTmp++;
							iterRule++;
						}
					}
				}
				nNbrAtom[i] = -1;
			}

		}
	}

	free(nNbrAtom);

	/*************************************************/
	cout << "\nNEW vStableModel Definite :" << endl;
	CStableModelPos::iterator k = vStableModel.begin();
	for (;k != vStableModel.end(); k++)
	{
		CAtomPos z = *k;
		char* nameAtom = pProg->GetDictionnaryEntry(z.nAtom);
		cout << "{ Atom : " << nameAtom << " , Degree : " << z.nDegree << " }" << endl;
	}

	// Print the elapsed time
	timeb tTimeTakeLast;
	ftime(&tTimeTakeLast);

	cout << "\nTime to calculate this possibilist stable model : " << tTimeTakeLast.millitm - tTimeTake.millitm << " ms" << endl;
	cout << "\n/*************************************************/\n" << endl;
}

void ConstructSmodels(CProgLogPos* pProg)
{
        timeb tTimeTake, tTimeTakeLast; // Used to calcul elapsed time
	ftime(&tTimeTake);

	Smodels smodels;
        Api api(&smodels.program);

        Atom *aTmp;

	// Keep track of atom names
	api.remember();

	vector<CRegle*> m_vSetOfRules = pProg->GetAllLogicRules();
	vector<CRegle*>::iterator iterRule = m_vSetOfRules.begin();

	for (; iterRule != m_vSetOfRules.end(); iterRule++)
	{
		// Creation of a new rule in smodels
		api.begin_rule(BASICRULE);
		CRegle* rTmp = *iterRule;

		// Head
		char* nameAtom = pProg->GetDictionnaryEntry(rTmp->GetHead());

		if (!(aTmp = api.get_atom(nameAtom))) // Check if the atom doesn't exist
		{
			// It is not referenced so we create a new atom
			aTmp = api.new_atom();
			api.set_name(aTmp, nameAtom);
		}
		else
		{
		        // we've got the head reference in aTmp // Nothing to do
		}

		api.add_head(aTmp);

		// Definition of the body's rule
		// Body Plus
		CSetAtom bodyPlus = rTmp->GetBodyPlus();
		CSetAtom::iterator iter;
		for (iter = bodyPlus.begin(); iter != bodyPlus.end(); iter++)
		{
			int nAtom = *iter;
			nameAtom = pProg->GetDictionnaryEntry(nAtom);

			if (!(aTmp = api.get_atom(nameAtom)))
			{
				aTmp = api.new_atom();
				api.set_name(aTmp, nameAtom);
			}

			api.add_body(aTmp, true);
		}

		// Body Minus
		CSetAtom bodyMinus = rTmp->GetBodyMinus();
		for (iter = bodyMinus.begin(); iter != bodyMinus.end(); iter++)
		{
			int nAtom = *iter;
			nameAtom = pProg->GetDictionnaryEntry(nAtom);

			if (!(aTmp = api.get_atom(nameAtom)))
			{
				aTmp = api.new_atom();
				api.set_name(aTmp, nameAtom);
			}

			api.add_body(aTmp, false);
		}

		// Definition of the rule finished
		api.end_rule();
	}

	// Definition of the program finished
	api.done();
	ftime(&tTimeTakeLast);
	cout << "Creation of the program in Smodels takes : " << tTimeTakeLast.millitm -  tTimeTake.millitm << " ms" << endl;

	// Generate the stable models
	ftime(&tTimeTake);

	smodels.init();

	ftime(&tTimeTakeLast);
	cout << "Generation Of Stable Models takes : " << tTimeTakeLast.millitm -  tTimeTake.millitm << " ms" << endl;

	bool bIsAtLeastOneModel = false;
	// Compute all stable models
	while (smodels.model ())  // Returns 0 when there are no more models
	{
	        bIsAtLeastOneModel = true;
	        cout << "\n/*************************************************/\n" << endl;

		// We've got one model more
		smodels.printAnswer ();  // Prints the answer

		CSetAtom vectAtomPositif;

		Node* nd = smodels.program.atoms.head();
		for (; nd; nd = nd->next)
		{
		    if (nd->atom->Bpos)
		    {
		        vectAtomPositif.insert(pProg->FindPlaceInDictionnary((char*)nd->atom->atom_name()));
		    }
		    else if (nd->atom->Bneg)
		    {
		        // Nothing to do ! (The atom is not in the a stable model
		    }
		}

		CalculReduit(pProg, vectAtomPositif);
	}

	if (!bIsAtLeastOneModel)
	{
	    cout << "\nCannot found stable model with Smodels\n" << endl;
	}
}

int main(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Il manque le fichier d'entree contenant un programme logique - deterministe\n");
        system("PAUSE");
        return -1;
    }

    timeb tTimeTake, tTimeTakeLast; // Used to calcul elapsed time
    ftime(&tTimeTake);

    CProgLogPos* pProgLog = ConstructProgLogPos(argv[1]);

    ftime(&tTimeTakeLast);
    cout << "Construction of Application ressources takes : " << tTimeTakeLast.millitm -  tTimeTake.millitm << " ms" << endl;

    // pProgLog->WriteInformation();

    ConstructSmodels(pProgLog);

    delete pProgLog;

    return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -