/home/enzo/treballs/fib/pfc/nanocomp/src/simulation.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.13 $
00020 
00021 #include "simulation.hpp"
00022 #include <iostream>
00023 #include <map>
00024 
00025 using namespace std;
00026 
00028 
00035 Simulation::Simulation(SimulationView *view, SimulationManager *controller, Grid initialLayout, list<Rule> *rules, list<ForbiddenPattern> *patterns)
00036 {
00037     finalLayouts = new list<simulationStep>;
00038     patternsSimulated = new list<Grid>;
00039     patternsToSimulate = new list<simulationStep>;
00040     forbiddenPatternsFound = new list<simulationStep>;
00041     cycles = new list<simulationStep>;
00042     simulationStep s;
00043     s.space = initialLayout;
00044     patternsToSimulate->push_back(s);
00045     this->rules = rules;
00046     this->patterns = patterns;
00047     this->view = view;
00048     this->controller = controller;
00049     view->setGrid(initialLayout, true);
00050     view->Show(true);
00051     finished = false;
00052     simulating = false;
00053     stillRows = true;
00054 }
00055 
00056 
00058 Simulation::~Simulation()
00059 {
00060 }
00061 
00062 
00064 
00070 list<coordinate> Simulation::findRule(Grid layout, Rule rule)
00071 {
00072     list<coordinate> result;
00073     for (int i = 0; i < layout.getWidth(); i++)
00074     {
00075         for (int j = 0; j < layout.getHeight(); j++)
00076         {
00077             coordinate c;
00078             c.x = i;
00079             c.y = j;
00080             if (ruleApplicable(layout, c, rule))
00081             {
00082                 result.push_back(c);
00083                 //cout << "Applies!!!!" << endl;
00084             }
00085         }
00086     }
00087     return result;
00088 }
00089 
00090 
00092 
00098 list<coordinate> Simulation::findPattern(Grid layout, ForbiddenPattern pattern)
00099 {
00100     list<coordinate> result;
00101     for (int i = 0; i < layout.getWidth(); i++)
00102     {
00103         for (int j = 0; j < layout.getHeight(); j++)
00104         {
00105             coordinate c;
00106             c.x = i;
00107             c.y = j;
00108             if (patternApplicable(layout, c, pattern))
00109             {
00110                 result.push_back(c);
00111                 //cout << "Applies!!!!" << endl;
00112             }
00113         }
00114     }
00115     return result;
00116 }
00117 
00118 
00120 
00126 Grid Simulation::applyRule(Grid layout, Rule rule, coordinate position)
00127 {
00128     //TODO: check the nDONTCARE match with nDISABLED thing
00129     Grid result(layout);
00130     for (int i = 0; i < rule.getWidth(); i++)
00131     {
00132         for (int j = 0; j < rule.getHeight(); j++)
00133         {
00134             if (rule.getFinalGrid()(i, j) != nDONTCARE) //if it's don't care the actual value should stay unchanged
00135             {
00136                                 //HERE HERE HERE HERE HERE HERE
00137                 if ((rule.getInitialGrid()(i, j) == nDISABLED) && (layout(position.x + i, position.y + j) == nDONTCARE))
00138                 {
00139                     result(position.x + i, position.y + j) = nDONTCARE;
00140                 }
00141                 else
00142                 {
00143                     result(position.x + i, position.y + j) = rule.getFinalGrid()(i, j);
00144                 }
00145             }
00146         }
00147     } 
00148     return result;
00149 }
00150 
00151 
00153 
00160 bool Simulation::ruleApplicable(Grid layout, coordinate position, Rule rule)
00161 {
00162     if (rule.getWidth() > layout.getWidth() - position.x)
00163     {
00164         return false;
00165     }
00166     if (rule.getHeight() > layout.getHeight() - position.y)
00167     {
00168         return false;
00169     }
00170     //First we check if left side of the rule applies
00171     //Careful, if nDISABLED on rule and nDONTCARE in SPACE
00172     //we return YES
00173     //TODO ask jcarmona if this is really what he wants
00174     //TODO if this is the case modify the rule apply because
00175     //it will add nDISABLED where there should be
00176     //nDONTCARE
00177     for (int i = 0; i < rule.getWidth(); i++)
00178     {
00179         for (int j = 0; j < rule.getHeight(); j++)
00180         {
00181             //cout << "Comparing (r) " << rule.initial[i][j] << " to (p) " << layout[position.x + i][position.y + j] << endl;
00182             if (rule.getInitialGrid()(i, j) == nENABLED)
00183             {
00184                 if (layout(position.x + i, position.y + j) != nENABLED)
00185                 {
00186                     return false;
00187                 }
00188             }
00189             else if (rule.getInitialGrid()(i, j) == nDISABLED)
00190             {
00191                 //HERE HERE HERE HERE HERE
00192                 if ((layout(position.x + i, position.y + j) != nDISABLED) && (layout(position.x + i, position.y + j) != nDONTCARE))
00193                 {
00194                     return false;
00195                 }
00196             }
00197         }
00198     }
00199     return true;
00200 }
00201 
00202 
00204 
00208 void Simulation::printRule(Rule rule)
00209 {
00210     cout << "Initial" << endl;
00211     for (int i = 0; i < rule.getWidth(); i++)
00212     {
00213         for (int k = 0; k < i; k++)
00214         {
00215             cout << "  ";
00216         }
00217         for (int j = 0; j < rule.getHeight(); j++)
00218         {
00219             cout << rule.getInitialGrid()(i, j) << "  ";
00220         }
00221         cout << endl;
00222     }
00223     
00224     cout << endl;
00225     cout << "Final" << endl;
00226     for (int i = 0; i < rule.getWidth(); i++)
00227     {
00228         for (int k = 0; k < i; k++)
00229         {
00230             cout << "  ";
00231         }
00232         for (int j = 0; j < rule.getHeight(); j++)
00233         {
00234             cout << rule.getFinalGrid()(i, j) << "  ";
00235         }
00236         cout << endl;
00237     }
00238 }
00239 
00240 
00242 
00246 void Simulation::printLayout(Grid layout)
00247 {
00248     for (int i = 0; i < layout.getWidth(); i++)
00249     {
00250         for (int k = 0; k < i; k++)
00251         {
00252             cout << " ";
00253         }
00254         for (int j = 0; j < layout.getHeight(); j++)
00255         {
00256             cout << layout(i, j) << " ";
00257         }
00258         cout << endl;
00259     }
00260 }
00261 
00262 
00264 
00269 bool Simulation::find(Grid initialLayout, list<Grid> *processedLayouts)
00270 {
00271     for (list<Grid>::iterator i = processedLayouts->begin(); i != processedLayouts->end(); i++)
00272     {
00273         if (initialLayout == (*i))
00274         {
00275             return true;
00276         }
00277     }
00278     return false;
00279 }
00280 
00281 
00283 
00289 bool Simulation::patternApplicable(Grid layout, coordinate position, ForbiddenPattern pattern)
00290 {
00291     if (pattern.getWidth() > layout.getWidth() - position.x)
00292     {
00293         return false;
00294     }
00295     if (pattern.getHeight() > layout.getHeight() - position.y)
00296     {
00297         return false;
00298     }
00299 
00300     for (int i = 0; i < pattern.getWidth(); i++)
00301     {
00302         for (int j = 0; j < pattern.getHeight(); j++)
00303         {
00304             if (pattern.getGrid()(i, j) == nENABLED)
00305             {
00306                 if (layout(position.x + i, position.y + j) != nENABLED)
00307                 {
00308                     return false;
00309                 }
00310             }
00311             else if (pattern.getGrid()(i, j) == nDISABLED)
00312             {
00313                 if (layout(position.x + i, position.y + j) != nDISABLED)
00314                 {
00315                     return false;
00316                 }
00317             }
00318             else //DON'T CARE
00319             {
00320                 if (layout(position.x + i, position.y + j) == nNOSPACE)
00321                 {
00322                     return false;
00323                 }
00324             }
00325         }
00326     }
00327     return true;
00328 }
00329 
00330 
00332 
00335 bool Simulation::isFinished()
00336 {
00337     return finished;
00338 }
00339 
00340 
00341 //IMPORTANT: this function must NOT BE CALLED
00342 //if the stack is empty
00343 //TODO: check cicles
00345 
00355 bool Simulation::nextStep(bool gui)
00356 {
00357     //"Semaphore" for not calling this method reentrant
00358     if (simulating)
00359     {
00360         return true;
00361     }
00362     simulating = true;
00363     wxStopWatch sw;
00364     bool result = true;
00365     bool stable = false;
00366     if (!finished)
00367     {
00368         //We take the layout we have to process from
00369         //the queue
00370         simulationStep s = patternsToSimulate->back();
00371         Grid layout = s.space;
00372         //Then we eliminate it because it's considered already processed
00373         //by this step ofc and add it to the processed list
00374         patternsToSimulate->pop_back();
00375         patternsSimulated->push_back(layout);
00376         if (gui)
00377         {
00378             view->setGrid(layout, false);
00379         }
00380         
00381         //Time to process: find forbidden patterns
00382         for (list<ForbiddenPattern>::iterator i = patterns->begin(); i != patterns->end(); i++)
00383         {
00384             list<coordinate> tempCoordinates;
00385             wxStopWatch swPattern;
00386             tempCoordinates = findPattern(layout, (*i));
00387             if (gui)
00388             {
00389                 view->setInfo(wxString::Format(_("The pattern finding took %ldms to execute"), swPattern.Time()));
00390             }
00391             if (tempCoordinates.size() > 0) //Found a forbidden pattern
00392             {
00393                 if (gui)
00394                 {
00395                     view->setInfo(wxString::Format(_("Forbidden pattern found at %d, %d"), tempCoordinates.front().x, tempCoordinates.front().y));
00396                 }
00397                 finished = true;
00398                 result = false;
00399                 if (gui)
00400                 {
00401                     updateView();
00402                 }
00403             }
00404         }
00405         
00406         if (result)
00407         {
00408             //Time to find rules to apply
00409             list<ruleApplying> rulesToApply;
00410             for (list<Rule>::iterator i = rules->begin(); i != rules->end(); i++)
00411             {
00412                 list<coordinate> tempCoordinates;
00413                 wxStopWatch swRule;
00414                 tempCoordinates = findRule(layout, (*i));
00415                 if (gui)
00416                 {
00417                     view->setInfo(wxString::Format(_("The rule finding took %ldms to execute"), swRule.Time()));
00418                 }
00419                 if (tempCoordinates.size() > 0)
00420                 {
00421                     for (list<coordinate>::iterator j = tempCoordinates.begin(); j != tempCoordinates.end(); j++)
00422                     {
00423                         ruleApplying ruleToApply;
00424                         ruleToApply.rule = &(*i);
00425                         ruleToApply.c = (*j);
00426                         rulesToApply.push_back(ruleToApply);
00427                     }
00428                 }
00429             }
00430             
00431             //Stable layout
00432             if (gui)
00433             {
00434                 view->setInfo(wxString::Format(_("Number or applicable rules found: %d"), rulesToApply.size()));
00435             }
00436 
00437             if (rulesToApply.size() == 0)
00438             {
00439                 //Stable configuration, we return yes and the stable layout
00440                 finalLayouts->push_back(s);
00441                 if (gui)
00442                 {
00443                     view->setInfo(_("Reached stable layout"));
00444                 }
00445                 result = true;
00446                 stable = true;
00447             }
00448             else
00449             {
00450                 result = true;
00451                 //We apply the rules we can and add the resulting
00452                 //layout to the queue to be processed
00453                 for(list<ruleApplying>::iterator i = rulesToApply.begin(); i != rulesToApply.end(); i++)
00454                 {
00455                     //Apply the rule
00456                     if (gui)
00457                     {
00458                         view->setInfo(wxString::Format(_("Applying rule at %d, %d"), (*i).c.x, (*i).c.y));
00459                     }
00460                     Grid changedLayout = applyRule(layout, *(*i).rule, (*i).c);
00461                     
00462                     //If the resulting layout is in the processed queue
00463                     //we don't have to simulate it again
00464                     //TODO: check correctness and cycles here
00465                     //Cycles
00466                     //We must try to find the simulated pattern in the 
00467                     //current path
00468                     if (find(changedLayout, &(s.path)))
00469                     {
00470                         list<Grid> newList = s.path;
00471                         newList.push_back(layout);
00472                         simulationStep newStep;
00473                         newStep.path = newList;
00474                         newStep.space = changedLayout;
00475                         cycles->push_back(newStep);
00476                         if (gui)
00477                         {
00478                             view->setInfo(_("Cycle found"));
00479                         }
00480                     }
00481                     if (!find(changedLayout, patternsSimulated))
00482                     {
00483                         if (gui)
00484                         {
00485                             view->setInfo(_("Adding the resulting space to the queue to be simulated"));
00486                         }
00487                         list<Grid> newList = s.path;
00488                         newList.push_back(layout);
00489                         simulationStep newStep;
00490                         newStep.path = newList;
00491                         newStep.space = changedLayout;
00492                         patternsToSimulate->push_back(newStep);
00493                     }
00494                     else
00495                     {
00496                         if (gui)
00497                         {
00498                             view->setInfo(_("The resulting space has been already simulated"));
00499                         }
00500                     }
00501                 }
00502                 result = true;
00503             }
00504         }
00505         else
00506         {
00507             forbiddenPatternsFound->push_back(s);
00508             controller->finishedRow();
00509         }
00510         //Aqui entrem tan si hem trobat patrons prohibits com si no?
00511         //Si trobem patrons prohibits hauriem de plegar
00512         //però de moment per fer debugging ja va bé
00513         //We are finished if there are no more
00514         //layouts to process
00515         if (patternsToSimulate->empty())
00516         {
00517             if (gui)
00518             {
00519                 view->setInfo(_("No more spaces to simulate"));
00520             }
00521             finished = true;
00522             result = true;
00523             controller->finishedRow();
00524             if (gui)
00525             {
00526                 updateView();
00527             }
00528         }
00529         else
00530         {
00531             if (stable)
00532             {
00533                 if (gui)
00534                 {
00535                     view->setInfo(_("Backtracking to a previous applied rule"));
00536                 }
00537             }
00538         }
00539     }
00540     else
00541     {
00542         result = true;
00543     }
00544     if (gui)
00545     {
00546         view->setInfo(wxString::Format(_("The simulation step took %ldms to execute"), sw.Time()));
00547     }
00548     simulating = false;
00549     return result;
00550 }
00551 
00552 
00554 
00558 void Simulation::updateView()
00559 {
00560     if (finished)
00561     {
00562         if (controller->nextRow())
00563         {
00564             view->setResults(false);
00565             view->setNextRow(true);
00566             view->enableSimulation(false);
00567         }
00568         else
00569         {
00570             view->setResults(true);
00571             view->setNextRow(false);
00572             view->enableSimulation(false);
00573         }
00574     }
00575 }
00576 
00577 
00579 void Simulation::nextRow()
00580 {
00581     if (controller->nextRow())
00582     {
00583         controller->simulateRow();
00584         view->setResults(false);
00585         view->setNextRow(false);
00586         view->enableSimulation(true);
00587     }
00588     else
00589     {
00590         view->setResults(true);
00591         view->setNextRow(false);
00592         view->enableSimulation(true);
00593     }
00594 }
00595 
00596 
00598 void Simulation::results()
00599 {
00600     controller->results();
00601 }
00602 
00603 
00605 
00610 list<simulationStep> Simulation::getStableLayouts()
00611 {
00612     list<simulationStep> result;
00613     for (list<simulationStep>::iterator i = finalLayouts->begin(); i != finalLayouts->end(); i++)
00614     {
00615         result.push_back((*i));
00616     }
00617     return result;
00618 }
00619 
00620 
00622 
00625 list<Grid> Simulation::getProcessedLayouts()
00626 {
00627     list<Grid> result;
00628     for (list<Grid>::iterator i = patternsSimulated->begin(); i != patternsSimulated->end(); i++)
00629     {
00630         result.push_back((*i));
00631     }
00632     return result;
00633 }
00634 
00635 
00637 
00643 list<simulationStep> Simulation::getForbiddenLayouts()
00644 {
00645     list<simulationStep> result;
00646     for (list<simulationStep>::iterator i = forbiddenPatternsFound->begin(); i != forbiddenPatternsFound->end(); i++)
00647     {
00648         result.push_back((*i));
00649     }
00650     return result;
00651 }
00652 
00653 
00655 
00660 list<simulationStep> Simulation::getCycles()
00661 {
00662     list<simulationStep> result;
00663     for (list<simulationStep>::iterator i = cycles->begin(); i != cycles->end(); i++)
00664     {
00665         result.push_back((*i));
00666     }
00667     return result;
00668 }
00669 
00670 
00672 
00679 void Simulation::resetSimulation(SimulationView *view, SimulationManager *controller, Grid initialLayout, list<Rule> *rules, list<ForbiddenPattern> *patterns)
00680 {
00681     //cout << "Resetting simulation" << endl;
00682     finalLayouts->clear();
00683     patternsSimulated->clear();
00684     patternsToSimulate->clear();
00685     forbiddenPatternsFound->clear();
00686     cycles->clear();
00687     simulationStep s;
00688     s.space = initialLayout;
00689     patternsToSimulate->push_back(s);
00690     this->rules = rules;
00691     this->patterns = patterns;
00692     this->view = view;
00693     this->controller = controller;
00694     view->setGrid(initialLayout, true);
00695     view->Show(true);
00696     finished = false;
00697     stillRows = true;
00698     view->Enable(true);
00699     view->stopSimulation();
00700 }
00701 
00702 
00703 
00705 
00709 void Simulation::simulateAll()
00710 {
00711     view->enableSimulation(false);
00712     view->setNextRow(false);
00713     view->setResults(false);
00714     while (stillRows)
00715     {
00716         while (!finished)
00717         {
00718             nextStep(false);
00719         }
00720         if (controller->nextRow())
00721         {
00722             controller->simulateRow();
00723         }
00724         else
00725         {
00726             stillRows = false;
00727         }
00728     }
00729     view->setResults(true);
00730 }

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