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

📄 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>

// 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)
{
	// Erase all the rules those have not a head in v_ListeAtomPositif
	// And put these rules in another CProgLogPos for processing it

	vector<CReglePos*> vSetAllRulesInModel; // 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);
			vSetAllRulesInModel.push_back(rPut);
		}
	}


	//debug
	vector<CReglePos*>::iterator i1 = vSetAllRulesInModel.begin();
	for (; i1 != vSetAllRulesInModel.end(); i1++)
	  {
	    rTmp = *i1;
	    rTmp->WriteInformationPos();
	  }
	//end debug
	

	// At this point we have the reduct of pProg program (in vSetAllRulesInModel)
	CProgReduct vStableModel;
	iterRule = vSetAllRulesInModel.begin();

	for (; iterRule != vSetAllRulesInModel.end(); iterRule++)
	{
		rTmp = *iterRule;
		if (rTmp->IsEmptyBody(BODYPLUS))
		{
		    CProgReduct::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()));
		    }

		    vSetAllRulesInModel.erase(iterRule); // Erase all rules those have got no body atoms
		    iterRule = vSetAllRulesInModel.begin(); // Come back to the beginning
		}
	}

	vector<CAtomPos>::iterator iterAtom;
	int nFirstNewEntry = -1;

	// We have the base tree in vStableModel
	// Computing data
	iterAtom = vStableModel.begin();

	while (iterAtom != vStableModel.end() && vSetAllRulesInModel.size() != 0)
	{
	    CAtomPos aTmp = *iterAtom; // Get the current atom
	    iterRule = vSetAllRulesInModel.begin();
	    
	    // For all the rules leaving
	    for (; iterRule != vSetAllRulesInModel.end(); iterRule++)
	    {
	        rTmp = *iterRule;
		if (rTmp->IsContaining(aTmp.nAtom, BODYPLUS))
		{
		    // if the head isn't referenced in vStableModel
		    // Add the head to the vStableModel with rule degree (by default)
		    if (vStableModel.Find(rTmp->GetHead()) == vStableModel.end())
		    {
		        // The head isn't in the vStableModel
		        vStableModel.push_back(CAtomPos(rTmp->GetHead(), rTmp->GetDegree()));
			if (nFirstNewEntry == -1)
			{
			    nFirstNewEntry = rTmp->GetHead(); // Remember the first new input element
			}
		    }

		    // Look if the rule's degree is min or max than current atom degree
		    // if the current atom's degree < rule's degree, update the head in the 
		    // vStableModel by setting degree to current atom's degree
		    if (rTmp->GetDegree() > aTmp.nDegree)
		    {
		        rTmp->SetDegree(aTmp.nDegree);
		    }

		    vStableModel.UpdateDegree(rTmp->GetHead(), aTmp.nDegree, INFERIOR);

		    // Erase the occurence of iterAtom in iterRule
		    rTmp->EraseElement(aTmp.nAtom, BODYPLUS);
		}
		else
		{
		    // aTmp.nAtom is not referenced in the current rule
		    // Nothing to do
		}
	    }

	    // Erase all the rules those have not body atoms
	    iterRule = vSetAllRulesInModel.begin();
	    while (iterRule != vSetAllRulesInModel.end())
	    {
	        rTmp = *iterRule;
		if (rTmp->IsEmptyBody(BODYPLUS))
		{
		    vStableModel.UpdateDegree(rTmp->GetHead(), rTmp->GetDegree(), SUPERIOR);
		    delete rTmp;
		    vSetAllRulesInModel.erase(iterRule);
		    iterRule = vSetAllRulesInModel.begin();
		    continue;
		}
		iterRule++;
	    }

	    // Take the next atom
	    if (nFirstNewEntry != -1)
	    {
	        iterAtom = vStableModel.Find(nFirstNewEntry);
		nFirstNewEntry = -1;
	    }
	    else
	    {
	        iterAtom++;
	    }
	}

	/*************************************************/

	cout << "\nNEW vStableModel Definite :" << endl;
	CProgReduct::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;
	}
	cout << "\n/*************************************************/\n" << endl;
}

void ConstructSmodels(CProgLogPos* pProg)
{
	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();

	// Generate the stable models
	smodels.init();

	// Compute all stable models
	while (smodels.model ())  // Returns 0 when there are no more models
	{
	        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);
	}
}

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;
    }

    CProgLogPos* pProgLog = ConstructProgLogPos(argv[1]);
    // pProgLog->WriteInformation();

    ConstructSmodels(pProgLog);

    delete pProgLog;

    return 0;
}


⌨️ 快捷键说明

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