/home/enzo/treballs/fib/pfc/nanocomp/src/simulationManager.cpp

Go to the documentation of this file.
00001 /*
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   This program is distributed in the hope that it will be useful,       *
00009  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00010  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00011  *   GNU General Public License for more details.                          *
00012  *                                                                         *
00013  *   You should have received a copy of the GNU General Public License     *
00014  *   along with this program; if not, write to the                         *
00015  *   Free Software Foundation, Inc.,                                       *
00016  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00017                                                                           */
00018 
00019 // $Revision: 1.12 $
00020 
00021 #include "simulationManager.hpp"
00022 
00024 
00031 SimulationManager::SimulationManager(MainController *controller, TruthTableManager *tableManager, ForbiddenPatternManager *FPManager, RuleManager *ruleManager, LayoutManager *layoutManager)
00032 {
00033     this->tableManager = tableManager;
00034     this->FPManager = FPManager;
00035     this->ruleManager = ruleManager;
00036     this->controller = controller;
00037     this->layoutManager = layoutManager;
00038 }
00039 
00040 
00042 SimulationManager::~SimulationManager()
00043 {
00044 }
00045 
00046 
00048 
00053 void SimulationManager::prepareSimulation()
00054 {
00055     //Get the table, rules and patterns
00056     rules.clear();
00057     patterns.clear();
00058     table = *(layoutManager->getTableSelected());
00059     tableInputs = layoutManager->getTableInput(table.getName());
00060     tableOutputs = layoutManager->getTableOutput(table.getName());
00061     list<Rule> ruleList = layoutManager->getListRuleEnabled();
00062     list<ForbiddenPattern> patternList = layoutManager->getListFPEnabled();
00063     //Get te initial layout
00064     layout = layoutManager->getLayout()->getMatrix();
00065     initialGrid = layoutManager->getLayout()->getGrid();
00066     
00067     //Rotate rules
00068     for (list<Rule>::iterator i = ruleList.begin(); i != ruleList.end(); i++)
00069     {
00070         addRule((*i));
00071     }
00072     
00073     
00074     //Rotate patterns
00075     for (list<ForbiddenPattern>::iterator i = patternList.begin(); i != patternList.end(); i++)
00076     {
00077         addPattern((*i));
00078     }
00079 
00080     //Initialize simulation results data structures    
00081     row = 0;
00082     processedLayouts.resize((int)pow(2, tableInputs.size()));
00083     processedLayouts.clear();
00084     finalLayouts.resize((int)pow(2, tableInputs.size()));
00085     finalLayouts.clear();
00086     forbiddenLayouts.resize((int)pow(2, tableInputs.size()));
00087     cycles.resize((int)pow(2, tableInputs.size()));
00088     forbiddenLayouts.clear();
00089     //Initializes the simulation view and starts
00090     view = new SimulationView(controller->getNanoFrame(), wxID_ANY);
00091     simulation = new Simulation(view, this, layout, &rules, &patterns);
00092     view->setSimulation(simulation);
00093     startSimulation();
00094 }
00095 
00096 
00097 //TODO: mirar què fer si la rotació falla
00099 
00102 void SimulationManager::addRule(Rule newRule)
00103 {
00104     if (!findRule(newRule))
00105     {
00106         rules.push_back(newRule);
00107         
00108         //Rotate only if square and even size
00109         if ((newRule.getWidth() == newRule.getHeight()) && (newRule.getWidth() %2 != 0))
00110         {
00111 
00112             Grid tempInitial = newRule.getInitialGrid();
00113             Grid tempFinal = newRule.getFinalGrid();
00114     
00115             for (int i = 0; i < 5; i++)
00116             {
00117                 Grid initialRotated(tempInitial.getWidth(), tempInitial.getHeight());
00118                 Grid finalRotated(tempInitial.getWidth(), tempInitial.getHeight());
00119                 Rule ruleRotated(newRule.getWidth(), newRule.getHeight());
00120                 if (rotateGrid(tempInitial, &initialRotated) && rotateGrid(tempFinal, &finalRotated))
00121                 {
00122                     ruleRotated.setInitialGrid(initialRotated);
00123                     ruleRotated.setFinalGrid(finalRotated);
00124                     if (!findRule(ruleRotated))
00125                     {
00126                         rules.push_back(ruleRotated);
00127                     }
00128                 }
00129                 else
00130                 {   
00131                     cout << "Error in rotation " << i << endl;
00132                     break;
00133                 }
00134                 tempInitial = ruleRotated.getInitialGrid();
00135                 tempFinal = ruleRotated.getFinalGrid();
00136             }
00137         }
00138     }
00139 }
00140 
00141 
00143 
00146 void SimulationManager::addPattern(ForbiddenPattern newPattern)
00147 {
00148     if (!findPattern(newPattern))
00149     {
00150         patterns.push_back(newPattern);
00151         //Rotate only if square and even size
00152         if ((newPattern.getWidth() == newPattern.getHeight()) && (newPattern.getWidth() %2 != 0))
00153         {
00154             Grid temp = newPattern.getGrid();
00155     
00156             for (int i = 0; i < 5; i++)
00157             {
00158                 Grid rotatedGrid(temp.getWidth(), temp.getHeight());
00159                 ForbiddenPattern patternRotated(newPattern.getWidth(), newPattern.getHeight());
00160                 if (rotateGrid(temp, &rotatedGrid))
00161                 {
00162                     patternRotated.setGrid(rotatedGrid);
00163                     if (!findPattern(patternRotated))
00164                     {
00165                         patterns.push_back(patternRotated);
00166                     }
00167                 }
00168                 else
00169                 {
00170                     break;
00171                 }
00172                 temp= patternRotated.getGrid();
00173             }
00174         }
00175     }
00176 }
00177 
00178 
00180 
00184 bool SimulationManager::findRule(Rule rule)
00185 {
00186     for (list<Rule>::iterator i = rules.begin(); i != rules.end(); i++)
00187     {
00188         if (rule == (*i))
00189         {
00190             return true;
00191         }
00192     }
00193     return false;
00194 }
00195 
00196 
00198 
00202 bool SimulationManager::findPattern(ForbiddenPattern pattern)
00203 {
00204     for (list<ForbiddenPattern>::iterator i = patterns.begin(); i != patterns.end(); i++)
00205     {
00206         if ((*i) == pattern)
00207         {
00208             return true;
00209         }
00210     }
00211     return false;
00212 }
00213 
00214 
00216 
00219 void SimulationManager::printRule(Rule rule)
00220 {
00221     cout << "Initial" << endl;
00222     for (int i = 0; i < rule.getWidth(); i++)
00223     {
00224         for (int k = 0; k < i; k++)
00225         {
00226             cout << "  ";
00227         }
00228         for (int j = 0; j < rule.getHeight(); j++)
00229         {
00230             cout << rule.getInitialGrid()(i, j) << "  ";
00231         }
00232         cout << endl;
00233     }
00234     
00235     cout << endl;
00236     cout << "Final" << endl;
00237     for (int i = 0; i < rule.getWidth(); i++)
00238     {
00239         for (int k = 0; k < i; k++)
00240         {
00241             cout << "  ";
00242         }
00243         for (int j = 0; j < rule.getHeight(); j++)
00244         {
00245             cout << rule.getFinalGrid()(i, j) << "  ";
00246         }
00247         cout << endl;
00248     }
00249 }
00250 
00251 
00253 
00256 void SimulationManager::printPattern(Grid pattern)
00257 {
00258     for (int i = 0; i < pattern.getWidth(); i++)
00259     {
00260         for (int k = 0; k < i; k++)
00261         {
00262             cout << " ";
00263         }
00264         for (int j = 0; j < pattern.getHeight(); j++)
00265         {
00266             cout << pattern(i, j) << " ";
00267         }
00268         cout << endl;
00269     }
00270 }
00271 
00272 
00274 
00279 bool SimulationManager::rotateGrid(Grid originalGrid, Grid *destGrid)
00280 {
00281     int c;
00282     int center;
00283     int i, j;
00284     int ii, jj;
00285     int size = originalGrid.getWidth();
00286 
00287     
00288     center = size/2;
00289 
00290     for (i = 0; i < size; i++) 
00291     {
00292         for (j = 0; j < size; j++) 
00293         {
00294             (*destGrid)(i, j) = nDONTCARE;
00295         }
00296     }
00297 
00298     for (i = 0; i < size; i++) 
00299     {
00300         for (j = 0; j < size; j++) 
00301         {
00302             c = originalGrid(i, j);
00303 
00304             rotateHexCoordinate(center, i, j, &ii, &jj);
00305             
00306             if (0 <= ii && ii < size && 0 <= jj && jj < size) 
00307             {
00308                 (*destGrid)(ii, jj) = c;
00309             }
00310             else if (c == nENABLED || c == nDISABLED)
00311             {
00312                 cout << "Warning: cannot map a transformed site" << endl;
00313                 return false;
00314             }
00315         }
00316     }
00317     return true;
00318 }
00319 
00320 
00322 
00329 void SimulationManager::rotateHexCoordinate(int center, int i, int j, int *ii, int *jj)
00330 {
00331     int x, y;
00332     int xx, yy;
00333 
00334     x = i - center;
00335     y = j - center;
00336 
00337     xx = -y;
00338     yy = x + y;
00339 
00340     *ii = xx + center;
00341     *jj = yy + center;
00342 }
00343 
00344 
00345 //TODO: recorda, ha de ser tot vàlid:
00346 //layout no null
00347 //taula de veritat no nula
00348 //inputs i outputs de la taula de veritat assignats
00349 //això ho ha de controlar el check simulation i el 
00350 //controlador principal habilitant i deshabilitant el botó
00351 //que controla aquesta funció
00352 //A MUST: abans de cridar aquesta funció s'ha de cridar
00353 //prepareSimulation()
00355 
00359 void SimulationManager::startSimulation()
00360 {
00361     simulateRow();
00362 }
00363 
00364 
00366 
00370 bool SimulationManager::nextRow()
00371 {
00372     return (row < pow(2, tableInputs.size()));
00373 }
00374 
00375 
00377 void SimulationManager::simulateRow()
00378 {
00379     if (nextRow())
00380     {
00381         layout = layoutManager->getLayout()->getMatrix();
00382         vector<int> result(tableInputs.size(), nDISABLED);
00383         int j = tableInputs.size() -1 ;
00384         int l = row;
00385         while (l > 0)
00386         {
00387             if ((l % 2) == 1) //1 = True
00388             {
00389                 result[j] = nENABLED;
00390             }  
00391             else
00392             {
00393                 result[j] = nDISABLED;
00394             }
00395             l /= 2;  
00396             j--;
00397     }
00398     list<matrix> finalLayouts;
00399     for (unsigned int k = 0; k < tableInputs.size(); k++)
00400     {
00401         layout[tableInputs[k].x][tableInputs[k].y] = result[k];
00402     }
00403     for (unsigned int k = 0; k < tableOutputs.size(); k++)
00404     {
00405         layout[tableOutputs[k].x][tableOutputs[k].y] = nDISABLED;
00406     }
00407     simulation->resetSimulation(view, this, layout, &rules, &patterns);
00408     view->setBlankLine();
00409     view->setInfo(wxString::Format(_("Simulating row %d"), row));
00410     view->setBlankLine();
00411     }
00412     row++;
00413 }
00414 
00415 
00417 void SimulationManager::finishedRow()
00418 {
00419     view->setInfo(wxString::Format(_("Gathering data from the row: %d"), row - 1));
00420     processedLayouts[row - 1] = simulation->getProcessedLayouts();
00421     finalLayouts[row - 1] = simulation->getStableLayouts();
00422     forbiddenLayouts[row - 1] = simulation->getForbiddenLayouts();
00423     cycles[row - 1] = simulation->getCycles();
00424 }
00425 
00426 
00428 void SimulationManager::results()
00429 {
00430     if (!resultsView)
00431     {
00432         resultsView = new ResultsView(controller->getNanoFrame(), wxID_ANY, this);
00433         resultsView->Show(true);
00434     }
00435     rRow = 0;
00436     rInformation = 0;
00437     rPath = 0;
00438     updateRowList();
00439     updateInformationList();
00440     updatePathList();
00441     updateGrid();
00442     resultsView->updateInitialGrid(initialGrid, true);
00443     resultsView->setTable(table);
00444     resultsView->setInputs(tableInputs);
00445     resultsView->setOutputs(tableOutputs);
00446 }
00447 
00448 
00450 
00453 void SimulationManager::rowSelected(int row)
00454 {
00455     rRow = row;
00456     rInformation = 0;
00457     rPath = 0;
00458     updateRowList();
00459     updateInformationList();
00460     updatePathList();
00461     updateGrid();
00462 }
00463 
00464 
00466 
00469 void SimulationManager::informationSelected(int information)
00470 {
00471     rInformation = information;
00472     rPath = 0;
00473     updateInformationList();
00474     updatePathList();
00475     updateGrid();
00476 }
00477 
00478 
00480 
00483 void SimulationManager::pathSelected(int path)
00484 {
00485     rPath = path;
00486     updatePathList();
00487     updateGrid();
00488 }
00489 
00490 
00492 void SimulationManager::updateRowList()
00493 {
00494     //We must check here if the row verifies the
00495     //table or not
00496     bool verifies = true;
00497     wxArrayString s;
00498     for (int i = 0; i < (int)pow(2, tableInputs.size()); i++)
00499     {
00500         if (verifyRow(i))
00501         {
00502             s.Add(wxString::Format(_("Row %d: OK"), i + 1));
00503         }
00504         else
00505         {
00506             s.Add(wxString::Format(_("Row %d: KO"), i + 1));
00507             verifies = false;
00508         }
00509     }
00510     resultsView->updateRowList(s);
00511     resultsView->selectRow(rRow);
00512     resultsView->setResult(verifies);
00513 }
00514 
00515 
00517 void SimulationManager::updateInformationList()
00518 {
00519     wxArrayString s;
00520     //First we must know if we must update
00521     //forbidden patterns or stable layouts
00522     if (forbiddenLayouts[rRow].size() > 0) //FPs
00523     {
00524         for (unsigned int i = 0; i < forbiddenLayouts[rRow].size(); i++)
00525         {
00526             s.Add(wxString::Format(_("Pattern %d"), i + 1));
00527         }
00528     }
00529     else if (finalLayouts[rRow].size() > 0)
00530     {
00531         for (unsigned int i = 0; i < finalLayouts[rRow].size(); i++)
00532         {
00533             s.Add(wxString::Format(_("Stable %d"), i + 1));
00534         }
00535     }
00536     else
00537     {
00538         for (unsigned int i = 0; i < cycles[rRow].size(); i++)
00539         {
00540             s.Add(wxString::Format(_("Cycle %d"), i + 1));
00541         }
00542     }
00543     resultsView->updateInformationList(s);
00544     resultsView->selectInformation(rInformation);
00545 }
00546 
00547 
00549 void SimulationManager::updatePathList()
00550 {
00551     wxArrayString s;
00552     if (forbiddenLayouts[rRow].size() > 0) //FPs
00553     {
00554         list <simulationStep>::iterator it = forbiddenLayouts[rRow].begin();
00555         for (int i = 0; i < rInformation; i++)
00556         {
00557             it++;
00558         }
00559         simulationStep ss = *it;
00560         //We must know the path length of the FP
00561         for (unsigned int i =0; i < ss.path.size() + 1; i++)
00562         {
00563             s.Add(wxString::Format(_("Step %d"), i + 1));
00564         }
00565     }
00566     else if (finalLayouts[rRow].size() > 0)
00567     {
00568         list <simulationStep>::iterator it = finalLayouts[rRow].begin();
00569         for (int i = 0; i < rInformation; i++)
00570         {
00571             it++;
00572         }
00573         simulationStep ss = *it;
00574         //We must know the path length of the FP
00575         for (unsigned int i =0; i < ss.path.size() + 1; i++)
00576         {
00577             s.Add(wxString::Format(_("Step %d"), i + 1));
00578         }
00579     }
00580     else
00581     {
00582         list <simulationStep>::iterator it = cycles[rRow].begin();
00583         for (int i = 0; i < rInformation; i++)
00584         {
00585             it++;
00586         }
00587         simulationStep ss = *it;
00588         //We must know the path length of the Cycle
00589         for (unsigned int i =0; i < ss.path.size() + 1; i++)
00590         {
00591             s.Add(wxString::Format(_("Step %d"), i + 1));
00592         }
00593     }
00594     resultsView->updatePathList(s);
00595     resultsView->selectPath(rPath);
00596 }
00597 
00598 
00600 void SimulationManager::updateGrid()
00601 {
00602     simulationStep ss;
00603     if (forbiddenLayouts[rRow].size() > 0) //FPs
00604     {
00605         list <simulationStep>::iterator it = forbiddenLayouts[rRow].begin();
00606         for (int i = 0; i < rInformation; i++)
00607         {
00608             it++;
00609         }
00610         ss = *it;
00611     }
00612     else if (finalLayouts[rRow].size() > 0) //Stable Layouts
00613     {
00614         list <simulationStep>::iterator it = finalLayouts[rRow].begin();
00615         for (int i = 0; i < rInformation; i++)
00616         {
00617             it++;
00618         }
00619         ss = *it;
00620     }
00621     
00622     else //Cycle --> to be done
00623     {
00624         list <simulationStep>::iterator it = cycles[rRow].begin();
00625         for (int i = 0; i < rInformation; i++)
00626         {
00627             it++;
00628         }
00629         ss = *it;
00630     }
00631     
00632     //Now we must know if the step is on the path or on the top
00633     if (rPath > (int)ss.path.size() - 1)
00634     {
00635         Grid g = ss.space;
00636         resultsView->updateGrid(g, false);
00637     }
00638     else
00639     {
00640         list<Grid>::iterator it = ss.path.begin();
00641         for (int i = 0; i < rPath; i++)
00642         {
00643             it++;
00644         }
00645         Grid g = (*it);
00646         resultsView->updateGrid(g, false);
00647     }
00648 }
00649 
00650 
00652 
00656 bool SimulationManager::verifyRow(int row)
00657 {
00658     bool result = true;
00659     if (forbiddenLayouts[row].size() > 0)
00660     {
00661         result = false;
00662     }
00663     else if (finalLayouts[row].size() > 0)//Verify all the stable layouts
00664     {
00665         for (list<simulationStep>::iterator  i = finalLayouts[row].begin(); i != finalLayouts[row].end(); i++)
00666         {
00667             result = result && verifyGrid(row, (*i).space);
00668         }        
00669     }
00670     else //Bucles: TODO: comprovar també
00671     {
00672         result = false;
00673     }
00674     return result;
00675 }
00676 
00677 
00679 
00684 bool SimulationManager::verifyGrid(int row, Grid g)
00685 {
00686     //Get the outputs values of the row
00687     vector<bool> result(tableInputs.size(), false);
00688     int j = tableInputs.size() -1 ;
00689     int k = row;
00690     while (k > 0)
00691     {
00692         if ((k % 2) == 1) //1 = True
00693         {
00694             result[j] = true;
00695         }  
00696         else
00697         {
00698             result[j] = false;
00699         }
00700         k /= 2;  
00701         j--;
00702     }
00703     vector<bool> outputs = table.getOutput(result);
00704     
00705     //Check the outputs are ok
00706     for (unsigned int i = 0; i < tableOutputs.size(); i++)
00707     {
00708         if (outputs[i]) //the position must be nENABLED
00709         {
00710             if (g(tableOutputs[i].x, tableOutputs[i].y) != nENABLED)
00711             {
00712                 return false;
00713             }
00714         }
00715         else //the position must be nDISABLED
00716         {
00717             if (g(tableOutputs[i].x, tableOutputs[i].y) != nDISABLED)
00718             {
00719                 return false;
00720             }
00721         }
00722     }
00723     return true;
00724 }

Generated on Fri Sep 1 23:55:14 2006 for NanoComp by  doxygen 1.4.6