📄 main.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 + -