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