Main Page | Modules | Alphabetical List | Compound List | File List | Compound Members | Related Pages

non_halt_detection.hpp

00001 #ifndef kellett_non_halt_detection_header
00002 #define kellett_non_halt_detection_header
00003 
00004 /*Authored 2003    by  Owen Kellett,  UnderGraduate Research
00005 (Advisor: Professor Bram van Heuveln)
00006 
00007 
00008 This  file is part of the   "Generic Turing Machine Implementation for
00009 Use in the Exploration of the Busy Beaver Problem".
00010 
00011 The "Generic Turing Machine Implementation for  Use in the Exploration
00012 of the Busy Beaver Problem" is free  software; you can redistribute it
00013 and/or modify it under the terms of the  GNU General Public License as
00014 published   by the Free Software Foundation;   either version 2 of the
00015 License, or (at your option) any later version.
00016 
00017 This programme is distributed in the hope that it  will be useful, but
00018 WITHOUT    ANY  WARRANTY;  without   even  the    implied warranty  of
00019 MERCHANTABILITY or FITNESS FOR  A  PARTICULAR  PURPOSE.  See  the  GNU
00020 General Public License for more details.
00021 
00022 You should have received   a copy of  the  GNU General Public  License
00023 along  with  this   programme; if  not,  write   to the Free  Software
00024 Foundation, Inc., 59  Temple Place, Suite  330, Boston, MA  02111-1307
00025 USA (or visit http://www.fsf.org/licenses/licenses.html)
00026 
00027 Created as part of the Busy Beaver Project:
00028 Bram van Heuveln <heuveb@rpi.edu>
00029 Boleshaw Szymanski <szymansk@cs.rpi.edu>
00030 Selmer Bringsjord <selmer@rpi.edu>
00031 Carlos Varela <cvarela@cs.rpi.edu>
00032 Owen Kellett <kelleo@rpi.edu>
00033 Shailesh Kelkar <kelkas@rpi.edu>
00034 Kyle Ross <rossk2@rpi.edu>
00035 Rensselaer Reasoning Group
00036 Department of Cognitive Science
00037 Department of Computer Science
00038 Rensselaer Polytechnic Institute
00039 Troy, New York 12180
00040 U.S.A.
00041 */
00042 
00043 #include <fstream>
00044 #include <iostream>
00045 #include <iterator>
00046 #include <list>
00047 #include <vector>
00048 #include <map>
00049 
00050 #include "infinite_tape.hpp"
00051 #include "state.hpp"
00052 #include "turing_machine.hpp"
00053 #include "non_halt_data_structures.hpp"
00054 
00055 typedef unsigned short d_type;
00056 
00070 bool simpleLoopCheck(turing_machine<d_type> &machine, unsigned int transition_limit)
00071 {
00072         machine.resetMachine();
00073 
00074         std::map<stateSymbolPair<d_type>, std::vector<tapeBoundsTriple<d_type> > > loopChecksMap;
00075 
00076         unsigned int step_counter = 0;
00077         while(step_counter < transition_limit && machine.run_one()!=turing_machine<d_type>::halt && !machine.blank_tape())
00078         {
00079                 ++step_counter;
00080                 std::map<stateSymbolPair<d_type>, std::vector<tapeBoundsTriple<d_type> > >::iterator checkBounds = loopChecksMap.begin();
00081                 for(; checkBounds != loopChecksMap.end(); checkBounds++)
00082                 {
00083                         for(int i = 0; i < (*checkBounds).second.size(); i++)
00084                         {
00085                                 (*checkBounds).second[i].tape.checkIteratorLeft((*checkBounds).second[i].leftBound);
00086                                 (*checkBounds).second[i].tape.checkIteratorRight((*checkBounds).second[i].rightBound);
00087                                 machine.access_tape_read_write().checkIteratorLeft((*checkBounds).second[i].leftBoundOriginal);
00088                                 machine.access_tape_read_write().checkIteratorRight((*checkBounds).second[i].rightBoundOriginal);
00089 
00090                                 if(machine.access_tape_read_write().currentLocation() != --((*checkBounds).second[i].leftBoundOriginal))
00091                                         (*checkBounds).second[i].leftBoundOriginal++;
00092                                 else
00093                                         (*checkBounds).second[i].leftBound--;
00094                                 if(machine.access_tape_read_write().currentLocation() != ++((*checkBounds).second[i].rightBoundOriginal))
00095                                         (*checkBounds).second[i].rightBoundOriginal--;
00096                                 else
00097                                         (*checkBounds).second[i].rightBound++;
00098                         }
00099                 }
00100 
00101                 stateSymbolPair<d_type> tempPair(machine.get_current_state(), machine.access_tape().read());
00102 
00103                 int size = loopChecksMap[tempPair].size();
00104                 for(int i = 0; i < size; i++)
00105                 {
00106                         if(loopChecksMap[tempPair][i].tape.repeatConfigRight(machine.access_tape_read_write(), loopChecksMap[tempPair][i].leftBound))
00107                         {
00108                                 return true;
00109                         }
00110                         if(loopChecksMap[tempPair][i].tape.repeatConfigLeft(machine.access_tape_read_write(), loopChecksMap[tempPair][i].rightBound))
00111                         {
00112                                 return true;
00113                         }
00114                 }
00115                 tapeBoundsTriple<d_type> newTapeTriple(machine.access_tape_read_write(),
00116                                                         machine.access_tape_read_write().currentLocation(),
00117                                                         machine.access_tape_read_write().currentLocation());
00118                 loopChecksMap[tempPair].push_back(newTapeTriple);
00119         }
00120         return false;
00121 
00122 }
00123 
00136 bool isInfinite(std::vector<state<d_type> > &stateSet, localTape<d_type>& tape, std::vector<state<d_type> >::size_type stateIndex, int limitSeed, int backTrackLimit)
00137 {
00138         if(limitSeed == backTrackLimit || (stateIndex == 0 && tape.allOneValue(0)))
00139         {
00140                 return false;
00141         }
00142 
00143         d_type write;
00144         infinite_tape<d_type>::direction move;
00145         std::vector<state<d_type> >::size_type nextState;
00146 
00147         std::vector<owenTransition<d_type> > possibleTransitions;
00148         std::vector<localTape<d_type> > requiredTapes;
00149 
00150         for(int j = 0; j < stateSet.size(); j++)
00151         {
00152                 if(stateSet[j].simulate_transition(0, write, move, nextState) == state<d_type>::run && nextState == stateIndex)
00153                         possibleTransitions.push_back(owenTransition<d_type>(0, write, nextState, j, move));
00154                 if(stateSet[j].simulate_transition(1, write, move, nextState) == state<d_type>::run && nextState == stateIndex)
00155                         possibleTransitions.push_back(owenTransition<d_type>(1, write, nextState, j, move));
00156         }
00157         for(int j = 0; j < possibleTransitions.size(); j++)
00158         {
00159                 requiredTapes.push_back(localTape<d_type>(tape.tapeConfig[tape.currentPosition], possibleTransitions[j]));
00160                 if(requiredTapes[j].simulateTransition(tape, possibleTransitions[j]))
00161                 {
00162                         if(!isInfinite(stateSet, requiredTapes[j], possibleTransitions[j].originalState, limitSeed+1, backTrackLimit))
00163                                 return false;
00164                 }
00165         }
00166         return true;
00167 }
00168 
00175 bool backTrack(turing_machine<d_type> &machine, unsigned int transition_limit)
00176 {
00177         std::vector<state<d_type> > stateSet = machine.stateSet();
00178 
00179         d_type write;
00180         infinite_tape<d_type>::direction move;
00181         std::vector<state<d_type> >::size_type nextState;
00182         std::vector<owenTransition<d_type> > possibleTransitions;
00183 
00184         for(int j = 0; j < stateSet.size(); j++)
00185         {
00186                 if(stateSet[j].simulate_transition(0, write, move, nextState) == state<d_type>::run)
00187                 {
00188                         if(nextState == machine.haltState())
00189                                 possibleTransitions.push_back(owenTransition<d_type>(0, write, nextState, j, move));
00190                 }
00191                 else
00192                 {
00193                         possibleTransitions.push_back(owenTransition<d_type>(0, 0, machine.haltState(), j, infinite_tape<d_type>::do_nothing));
00194                 }
00195                 if(stateSet[j].simulate_transition(1, write, move, nextState) == state<d_type>::run)
00196                 {
00197                         if(nextState == machine.haltState())
00198                                 possibleTransitions.push_back(owenTransition<d_type>(1, write, nextState, j, move));
00199                 }
00200                 else
00201                 {
00202                         possibleTransitions.push_back(owenTransition<d_type>(1, 1, machine.haltState(), j, infinite_tape<d_type>::do_nothing));
00203                 }
00204         }
00205         for(int j = 0; j < possibleTransitions.size(); j++)
00206         {
00207                 localTape<d_type> requiredTape(possibleTransitions[j].read);
00208                 if(!isInfinite(stateSet, requiredTape, possibleTransitions[j].originalState, 0, transition_limit))
00209                         return false;
00210         }
00211         return true;
00212 }
00213 
00221 bool isIn(std::vector<state<d_type> >::size_type element,
00222           std::vector<std::vector<state<d_type> >::size_type> set)
00223 {
00224         for(int j = 0; j < set.size(); j++)
00225                 if(set[j] == element)
00226                         return true;
00227         return false;
00228 }
00229 
00239 bool subsetLoop(std::vector<state<d_type> >::size_type seed,
00240                 std::vector<state<d_type> >::size_type haltState,
00241                 std::vector<state<d_type> > &stateSet)
00242 {
00243         std::vector<std::vector<state<d_type> >::size_type> subset;
00244 
00245         d_type write;
00246         infinite_tape<d_type>::direction move;
00247         std::vector<state<d_type> >::size_type nextState;
00248         std::vector<std::vector<state<d_type> >::size_type>::size_type j;
00249 
00250         subset.push_back(seed);
00251         for(j = 0; j < subset.size(); j++)
00252         {
00253                 if(stateSet[subset[j]].simulate_transition(0, write, move, nextState) == state<d_type>::halt || nextState == haltState)
00254                         return false;
00255                 else if(!isIn(nextState, subset))
00256                         subset.push_back(nextState);
00257 
00258                 if(stateSet[subset[j]].simulate_transition(1, write, move, nextState) == state<d_type>::halt || nextState == haltState)
00259                         return false;
00260                 else if(!isIn(nextState, subset))
00261                         subset.push_back(nextState);
00262         }
00263         return true;
00264 }
00265 
00273 bool loopStates(turing_machine<d_type> &machine)
00274 {
00275         std::vector<state<d_type> > stateSet = machine.stateSet();
00276         std::vector<state<d_type> >::size_type j;
00277 
00278         for(j = 0; j < stateSet.size(); j++)
00279                 if(subsetLoop(j, machine.haltState(), stateSet))
00280                         return true;
00281 
00282         return false;
00283 }
00284 
00285 
00286 //begin christmasTree routines
00287 
00300 unsigned int getNextRightBound(turing_machine<d_type> &machine,
00301                                                            std::list<d_type>::iterator &rightBound,
00302                                                            std::list<d_type>::iterator &leftBound,
00303                                                            unsigned int &step_counter,
00304                                                            unsigned int transition_limit)
00305 {
00306         bool rightBoundPushed = false;
00307         unsigned int rightBoundStepCounter = 0;
00308 
00309         for(step_counter; step_counter < transition_limit; step_counter++)
00310         {
00311                 if(machine.access_tape_read_write().currentLocation() == rightBound)
00312                 {
00313                         rightBoundPushed = true;
00314                         rightBoundStepCounter = step_counter-1;
00315                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
00316                         {
00317                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
00318                                 rightBound++;
00319                                 rightBoundPushed = true;
00320                                 rightBoundStepCounter = step_counter;
00321                         }
00322                 }
00323                 if(machine.access_tape_read_write().currentLocation() == leftBound)
00324                 {
00325                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
00326                         {
00327                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
00328                                 leftBound--;
00329                                 if(rightBoundPushed)
00330                                 {
00331                                         return rightBoundStepCounter;
00332                                 }
00333                         }
00334                         if(rightBoundPushed)
00335                         {
00336                                 return rightBoundStepCounter;
00337                         }
00338                 }
00339                 if(machine.run_one()==turing_machine<d_type>::halt)
00340                         return 0;
00341         }
00342         return 0;
00343 }
00344 
00349 unsigned int getNextLeftBound(turing_machine<d_type> &machine,
00350                                                            std::list<d_type>::iterator &rightBound,
00351                                                            std::list<d_type>::iterator &leftBound,
00352                                                            unsigned int &step_counter,
00353                                                            unsigned int transition_limit)
00354 {
00355         bool leftBoundPushed = false;
00356         unsigned int leftBoundStepCounter;
00357 
00358         for(step_counter; step_counter < transition_limit; step_counter++)
00359         {
00360                 if(machine.access_tape_read_write().currentLocation() == rightBound)
00361                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
00362                         {
00363                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
00364                                 rightBound++;
00365                                 if(leftBoundPushed)
00366                                 {
00367                                         return leftBoundStepCounter;
00368                                 }
00369                         }
00370                 if(machine.access_tape_read_write().currentLocation() == leftBound)
00371                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
00372                         {
00373                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
00374                                 leftBound--;
00375                                 leftBoundPushed = true;
00376                                 leftBoundStepCounter = step_counter;
00377                         }
00378                 if(machine.run_one()==turing_machine<d_type>::halt)
00379                         return 0;
00380         }
00381         return 0;
00382 }
00383 
00396 bool findMidSection(tapeChunk<d_type> &before, tapeChunk<d_type> &after, tapeChunk<d_type> &midSection, tapeChunk<d_type> &leftSection, tapeChunk<d_type> &rightSection)
00397 {
00398         int j, k;
00399         for(j = 0; j < before.tapeConfig.size()/2; j++)
00400         {
00401                 if(before.tapeConfig[j] != after.tapeConfig[j])
00402                         return false;
00403         }
00404         for(j = before.tapeConfig.size()-1, k = after.tapeConfig.size()-1; j >= before.tapeConfig.size()/2; j--, k--)
00405         {
00406                 if(before.tapeConfig[j] != after.tapeConfig[k])
00407                         return false;
00408         }
00409         midSection.fillTape(after, before.tapeConfig.size()/2, k);
00410         leftSection.fillTape(before, 0, before.tapeConfig.size()/2 - 1);
00411         rightSection.fillTape(before, before.tapeConfig.size()/2, before.tapeConfig.size()-1);
00412         return true;
00413 }
00414 
00437 tapeChunk<d_type> getNextChunk(turing_machine<d_type> &machine,
00438                                                            std::list<d_type>::iterator leftBound,
00439                                                            std::list<d_type>::iterator rightBound,
00440                                                            unsigned int stopPointCounter,
00441                                                            unsigned int &step_counter,
00442                                                            unsigned int transition_limit,
00443                                                            bool stopAtLeftBound,
00444                                                            bool stopAtRightBound,
00445                                                            bool inclusiveLeft,
00446                                                            bool inclusiveRight,
00447                                                            bool pushLeftBound,
00448                                                            bool pushRightBound)
00449 {
00450         if(stopAtLeftBound)
00451         {
00452                 while(machine.access_tape_read_write().currentLocation() != leftBound)
00453                 {
00454                         if(machine.access_tape_read_write().currentLocation() == rightBound)
00455                         {
00456                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
00457                                 {
00458                                         if(pushRightBound)
00459                                         {
00460                                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
00461                                                 rightBound++;
00462                                         }
00463                                         else
00464                                                 return tapeChunk<d_type>();
00465                                 }
00466                         }
00467                         machine.run_one();
00468                         step_counter++;
00469                         if(step_counter == transition_limit)
00470                                 return tapeChunk<d_type>();
00471                 }
00472         }
00473         else if(stopAtRightBound)
00474         {
00475                 while(machine.access_tape_read_write().currentLocation() != rightBound)
00476                 {
00477                         if(machine.access_tape_read_write().currentLocation() == leftBound)
00478                         {
00479                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
00480                                 {
00481                                         if(pushLeftBound)
00482                                         {
00483                                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
00484                                                 leftBound--;
00485                                         }
00486                                         else
00487                                                 return tapeChunk<d_type>();
00488                                 }
00489                         }
00490                         machine.run_one();
00491                         step_counter++;
00492                         if(step_counter == transition_limit)
00493                                 return tapeChunk<d_type>();
00494                 }
00495         }
00496         else
00497         {
00498                 for(step_counter; step_counter <= stopPointCounter; step_counter++)
00499                 {
00500                         if(machine.access_tape_read_write().currentLocation() == rightBound)
00501                         {
00502                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
00503                                 {
00504                                         if(pushRightBound)
00505                                         {
00506                                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
00507                                                 rightBound++;
00508                                         }
00509                                         else
00510                                                 return tapeChunk<d_type>();
00511                                 }
00512                         }
00513                         if(machine.access_tape_read_write().currentLocation() == leftBound)
00514                         {
00515                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
00516                                 {
00517                                         if(pushLeftBound)
00518                                         {
00519                                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
00520                                                 leftBound--;
00521                                         }
00522                                         else
00523                                                 return tapeChunk<d_type>();
00524                                 }
00525                         }
00526                         machine.run_one();
00527                         if(step_counter == transition_limit)
00528                                 return tapeChunk<d_type>();
00529                 }
00530         }
00531 
00532         if(!inclusiveLeft)
00533                 leftBound++;
00534         if(!inclusiveRight)
00535                 rightBound--;
00536         tapeChunk<d_type> returnValue;
00537         returnValue.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
00538 
00539         return returnValue;
00540 }
00541 
00542 bool checkChristmasTreeGrammar(turing_machine<d_type> &machine,
00543                                                            unsigned int firstRightBound,
00544                                                            unsigned int secondRightBound,
00545                                                            unsigned int thirdRightBound,
00546                                                            unsigned int transition_limit,
00547                                                            tapeChunk<d_type> &U,
00548                                                            tapeChunk<d_type> &X,
00549                                                            tapeChunk<d_type> &V,
00550                                                            std::vector<state<d_type> >::size_type s)
00551 {
00552         machine.resetMachine();
00553         unsigned int step_counter = 0;
00554         tapeChunk<d_type> Xp, Y, Yp, Z, Vp, Vpp, Up, temp;
00555         std::vector<state<d_type> >::size_type q, r;
00556 
00557         for(step_counter; step_counter <= firstRightBound; step_counter++)
00558                 machine.run_one();
00559 
00560         std::list<d_type>::iterator leftBound, rightBound;
00561 
00562         //XVs0* -> qX'V'0*
00563         leftBound = machine.access_tape_read_write().currentLocation();
00564         rightBound = machine.access_tape_read_write().currentLocation();
00565         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
00566                 leftBound--;
00567         temp = getNextChunk(machine,
00568                                                 leftBound,
00569                                                 rightBound,
00570                                                 secondRightBound,
00571                                                 step_counter,
00572                                                 transition_limit,
00573                                                 true,                           //stop at left
00574                                                 false,                          //stop at right
00575                                                 false,                          //inclusive left
00576                                                 true,                           //inclusive right
00577                                                 false,                          //push left
00578                                                 false);                         //push right
00579         if(temp.isEmpty()) return false;
00580         q = machine.get_current_state();
00581         Xp.fillTape(temp, 0, X.tapeConfig.size()-1);
00582         Vp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
00583 
00584         //0*UqX' -> 0*U'Y'r
00585         leftBound = machine.access_tape_read_write().currentLocation();
00586         rightBound = machine.access_tape_read_write().currentLocation();
00587         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
00588                 rightBound++;
00589         temp = getNextChunk(machine,
00590                                                 leftBound,
00591                                                 rightBound,
00592                                                 secondRightBound,
00593                                                 step_counter,
00594                                                 transition_limit,
00595                                                 false,                          //stop at left
00596                                                 true,                           //stop at right
00597                                                 true,                           //inclusive left
00598                                                 false,                          //inclusive right
00599                                                 true,                           //push left
00600                                                 false);                         //push right
00601         if(temp.isEmpty()) return false;
00602         r = machine.get_current_state();
00603         Up.fillTape(temp, 0, temp.tapeConfig.size()-X.tapeConfig.size()-1);
00604         Yp.fillTape(temp, temp.tapeConfig.size()-X.tapeConfig.size(), temp.tapeConfig.size()-1);
00605 
00606         //Y'rV' -> ZVs''
00607         leftBound = machine.access_tape_read_write().currentLocation();
00608         rightBound = machine.access_tape_read_write().currentLocation();
00609         for(int j = 0; j < Yp.tapeConfig.size(); j++)
00610                 leftBound--;
00611         temp = getNextChunk(machine,
00612                                                 leftBound,
00613                                                 rightBound,
00614                                                 secondRightBound,
00615                                                 step_counter,
00616                                                 transition_limit,
00617                                                 false,                          //stop at left
00618                                                 false,                          //stop at right
00619                                                 true,                           //inclusive left
00620                                                 true,                           //inclusive right
00621                                                 false,                          //push left
00622                                                 true);                          //push right
00623         if(temp.isEmpty()) return false;
00624         Z.fillTape(temp, 0, X.tapeConfig.size()-1);
00625         Vpp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
00626         if(machine.get_current_state() != s)
00627                 return false;
00628 
00629         /*std::cout << "Up : "; Up.print();
00630         std::cout << "Z  : "; Z.print();
00631         std::cout << "Vpp: "; Vpp.print();
00632         std::cout << "U :  "; U.print();
00633         std::cout << "X :  "; X.print();
00634         std::cout << "V :  "; V.print();*/
00635 
00636         if(Up + Z + Vpp != U + X + X + V)
00637                 return false;
00638 
00639         //XVs0* -> qX'V'0*
00640         leftBound = machine.access_tape_read_write().currentLocation();
00641         rightBound = machine.access_tape_read_write().currentLocation();
00642         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
00643                 leftBound--;
00644         temp = getNextChunk(machine,
00645                                                 leftBound,
00646                                                 rightBound,
00647                                                 secondRightBound,
00648                                                 step_counter,
00649                                                 transition_limit,
00650                                                 true,                           //stop at left
00651                                                 false,                          //stop at right
00652                                                 false,                          //inclusive left
00653                                                 true,                           //inclusive right
00654                                                 false,                          //push left
00655                                                 false);                         //push right
00656         if(temp.isEmpty()) return false;
00657         if(temp != Xp + Vp || machine.get_current_state() != q)
00658                 return false;
00659 
00660         //XqX' -> qX'Y
00661         leftBound = machine.access_tape_read_write().currentLocation();
00662         rightBound = machine.access_tape_read_write().currentLocation();
00663         for(int j = 0; j < X.tapeConfig.size(); j++)
00664                 leftBound--;
00665         for(int j = 0; j < Xp.tapeConfig.size(); j++)
00666                 rightBound++;
00667         temp = getNextChunk(machine,
00668                                                 leftBound,
00669                                                 rightBound,
00670                                                 secondRightBound,
00671                                                 step_counter,
00672                                                 transition_limit,
00673                                                 true,                           //stop at left
00674                                                 false,                          //stop at right
00675                                                 false,                          //inclusive left
00676                                                 true,                           //inclusive right
00677                                                 false,                          //push left
00678                                                 false);                         //push right
00679         if(temp.isEmpty()) return false;
00680         Y.fillTape(temp, Xp.tapeConfig.size(), temp.tapeConfig.size()-1);
00681         if(temp != Xp+Y || machine.get_current_state() != q)
00682                 return false;
00683 
00684         //0*UqX' -> 0*U'Y'r
00685         leftBound = machine.access_tape_read_write().currentLocation();
00686         rightBound = machine.access_tape_read_write().currentLocation();
00687         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
00688                 rightBound++;
00689         temp = getNextChunk(machine,
00690                                                 leftBound,
00691                                                 rightBound,
00692                                                 secondRightBound,
00693                                                 step_counter,
00694                                                 transition_limit,
00695                                                 false,                          //stop at left
00696                                                 true,                           //stop at right
00697                                                 true,                           //inclusive left
00698                                                 false,                          //inclusive right
00699                                                 true,                           //push left
00700                                                 false);                         //push right
00701         if(temp.isEmpty()) return false;
00702         if(temp != Up+Yp || machine.get_current_state() != r)
00703                 return false;
00704 
00705         //Y'rY -> ZY'r
00706         leftBound = machine.access_tape_read_write().currentLocation();
00707         rightBound = machine.access_tape_read_write().currentLocation();
00708         for(int j = 0; j < Yp.tapeConfig.size(); j++)
00709                 leftBound--;
00710         for(int j = 0; j < Y.tapeConfig.size(); j++)
00711                 rightBound++;
00712         temp = getNextChunk(machine,
00713                                                 leftBound,
00714                                                 rightBound,
00715                                                 secondRightBound,
00716                                                 step_counter,
00717                                                 transition_limit,
00718                                                 false,                          //stop at left
00719                                                 true,                           //stop at right
00720                                                 true,                           //inclusive left
00721                                                 false,                          //inclusive right
00722                                                 false,                          //push left
00723                                                 false);                         //push right
00724         if(temp.isEmpty()) return false;
00725         if(temp != Z+Yp || machine.get_current_state() != r)
00726                 return false;
00727 
00728         //Y'rV' -> ZVs''
00729         leftBound = machine.access_tape_read_write().currentLocation();
00730         rightBound = machine.access_tape_read_write().currentLocation();
00731         for(int j = 0; j < Yp.tapeConfig.size(); j++)
00732                 leftBound--;
00733         temp = getNextChunk(machine,
00734                                                 leftBound,
00735                                                 rightBound,
00736                                                 thirdRightBound,
00737                                                 step_counter,
00738                                                 transition_limit,
00739                                                 false,                          //stop at left
00740                                                 false,                          //stop at right
00741                                                 true,                           //inclusive left
00742                                                 true,                           //inclusive right
00743                                                 false,                          //push left
00744                                                 true);                          //push right
00745         if(temp.isEmpty()) return false;
00746         if(temp != Z+Vpp || machine.get_current_state() != s)
00747                 return false;
00748         if(Up + Z + Z + Vpp != U + X + X + X + V)
00749                 return false;
00750         return true;
00751 }
00752 
00753 bool checkChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
00754 {
00755         machine.resetMachine();
00756         unsigned int step_counter = 0;
00757 
00758         std::list<d_type>::iterator leftBound;
00759         std::list<d_type>::iterator rightBound;
00760 
00761         //last bound push
00762         //0 = left
00763         //1 = right
00764         int lastPush = 0;
00765 
00766         //run for a bit to establish sweeping motion
00767         for(step_counter = 0; step_counter < transition_limit &&
00768                                                   step_counter < 150; step_counter++)
00769         {
00770                 if(step_counter == 50)
00771                 {
00772                         leftBound = machine.access_tape_read_write().currentLocation();
00773                         rightBound = machine.access_tape_read_write().currentLocation();
00774                 }
00775                 if(step_counter >= 50)
00776                 {
00777                         if(machine.access_tape_read_write().currentLocation() == rightBound)
00778                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
00779                                 {
00780                                         machine.access_tape_read_write().checkIteratorRight(rightBound);
00781                                         rightBound++;
00782                                 }
00783                         if(machine.access_tape_read_write().currentLocation() == leftBound)
00784                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
00785                                 {
00786                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
00787                                         leftBound--;
00788                                 }
00789                 }
00790                 if(machine.run_one()==turing_machine<d_type>::halt)
00791                         return false;
00792 
00793         }
00794 
00795         //get the step counters of the left and right bounds
00796         unsigned int firstRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
00797         if(firstRightBound == 0)
00798                 return false;
00799 
00800         unsigned int secondRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
00801         if(secondRightBound == 0)
00802                 return false;
00803 
00804         unsigned int thirdRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
00805         if(thirdRightBound == 0)
00806                 return false;
00807 
00808         unsigned int fourthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
00809         if(fourthRightBound == 0)
00810                 return false;
00811 
00812         //reset the machine and use step counters to get tape configuration at each point
00813         machine.resetMachine();
00814         tapeChunk<d_type> beforeSweep, afterSweep;
00815 
00816         std::vector<state<d_type> >::size_type stateS;
00817 
00818         for(unsigned int j = 0; j <= secondRightBound; j++)
00819         {
00820                 if(j < 50)
00821                         machine.run_one();
00822                 if(j == 50)
00823                         leftBound = machine.access_tape_read_write().currentLocation();
00824                 if(j >= 50)
00825                 {
00826                         if(machine.access_tape_read_write().currentLocation() == leftBound)
00827                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
00828                                 {
00829                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
00830                                         leftBound--;
00831                                 }
00832                         machine.run_one();
00833 
00834                         if(j == firstRightBound)
00835                         {
00836                                 rightBound = machine.access_tape_read_write().currentLocation();
00837                                 beforeSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
00838                                 stateS = machine.get_current_state();
00839                         }
00840 
00841                         if(j == secondRightBound)
00842                         {
00843                                 rightBound = machine.access_tape_read_write().currentLocation();
00844                                 afterSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
00845                                 if(machine.get_current_state() != stateS)
00846                                         return false;
00847                         }
00848                 }
00849         }
00850 
00851 
00852         tapeChunk<d_type> chunkX, chunkU, chunkV;
00853 
00854         if(!findMidSection(beforeSweep, afterSweep, chunkX, chunkU, chunkV))
00855                 return false;
00856 
00857         /*chunkX.print();
00858         chunkU.print();
00859         chunkV.print();*/
00860 
00861         if(!checkChristmasTreeGrammar(machine, secondRightBound, thirdRightBound, fourthRightBound, transition_limit, chunkU, chunkX, chunkV, stateS))
00862                 return false;
00863 
00864 
00865 
00866         return true;
00867 }
00868 
00869 bool christmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
00870 {
00871         if(checkChristmasTree(machine, transition_limit))
00872                 return true;
00873         else
00874         {
00875                 turing_machine<d_type> reverse = machine.reverseMachine();
00876                 if(checkChristmasTree(reverse, transition_limit))
00877                         return true;
00878         }
00879         return false;
00880 }
00881 
00882 //end christmasTree routines
00883 
00884 //begin alternateChristmasTree routines
00885 
00911 tapeChunk<d_type> getNextChunkUnevenCheck(turing_machine<d_type> &machine,
00912                                                            std::list<d_type>::iterator leftBoundCheck,
00913                                                            std::list<d_type>::iterator leftBound,
00914                                                            std::list<d_type>::iterator rightBound,
00915                                                            unsigned int stopPointCounter,
00916                                                            unsigned int &step_counter,
00917                                                            unsigned int transition_limit,
00918                                                            bool stopAtLeftBound,
00919                                                            bool stopAtRightBound,
00920                                                            bool inclusiveLeft,
00921                                                            bool inclusiveRight,
00922                                                            bool pushLeftBound,
00923                                                            bool pushRightBound)
00924 {
00925         if(stopAtLeftBound)
00926         {
00927                 while(machine.access_tape_read_write().currentLocation() != leftBound)
00928                 {
00929                         if(pushRightBound)
00930                                 if(machine.access_tape_read_write().currentLocation() == rightBound)
00931                                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
00932                                         {
00933                                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
00934                                                 rightBound++;
00935                                         }
00936                         machine.run_one();
00937                         step_counter++;
00938                         if(step_counter == transition_limit)
00939                                 return tapeChunk<d_type>();
00940                 }
00941         }
00942         else if(stopAtRightBound)
00943         {
00944                 while(machine.access_tape_read_write().currentLocation() != rightBound || leftBoundCheck != leftBound)
00945                 {
00946                         if(pushLeftBound)
00947                                 if(machine.access_tape_read_write().currentLocation() == leftBound)
00948                                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
00949                                         {
00950                                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
00951                                                 leftBound--;
00952                                         }
00953                         machine.run_one();
00954                         step_counter++;
00955                         if(step_counter == transition_limit)
00956                                 return tapeChunk<d_type>();
00957                 }
00958         }
00959         else
00960         {
00961                 for(step_counter; step_counter <= stopPointCounter; step_counter++)
00962                 {
00963                         if(pushRightBound)
00964                                 if(machine.access_tape_read_write().currentLocation() == rightBound)
00965                                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
00966                                         {
00967                                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
00968                                                 rightBound++;
00969                                         }
00970                         if(pushLeftBound)
00971                                 if(machine.access_tape_read_write().currentLocation() == leftBound)
00972                                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
00973                                         {
00974                                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
00975                                                 leftBound--;
00976                                         }
00977                         machine.run_one();
00978                         if(step_counter == transition_limit)
00979                                 return tapeChunk<d_type>();
00980                 }
00981         }
00982 
00983         if(!inclusiveLeft)
00984                 leftBound++;
00985         if(!inclusiveRight)
00986                 rightBound--;
00987         tapeChunk<d_type> returnValue;
00988         returnValue.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
00989 
00990         return returnValue;
00991 }
00992 
00993 bool checkAlternateChristmasTreeGrammar(turing_machine<d_type> &machine,
00994                                                                                 unsigned int firstRightBound,
00995                                                                                 unsigned int secondRightBound,
00996                                                                                 unsigned int thirdRightBound,
00997                                                                                 unsigned int fourthRightBound,
00998                                                                                 unsigned int fifthRightBound,
00999                                                                                 std::list<d_type>::iterator firstLeftBound,
01000                                                                                 std::list<d_type>::iterator secondLeftBound,
01001                                                                                 std::list<d_type>::iterator thirdLeftBound,
01002                                                                                 std::list<d_type>::iterator fourthLeftBound,
01003                                                                                 unsigned int transition_limit,
01004                                                                                 tapeChunk<d_type> &U,
01005                                                                                 tapeChunk<d_type> &X,
01006                                                                                 tapeChunk<d_type> &V,
01007                                                                                 std::vector<state<d_type> >::size_type s)
01008 {
01009         machine.resetMachine();
01010         unsigned int step_counter = 0;
01011         tapeChunk<d_type> Up, Upp, Vp, Vpp, Vppp, Vpppp, Xp, Y, Yp, Z, Zp, M, Mp, N, temp;
01012         std::vector<state<d_type> >::size_type q, r, t, u, v;
01013 
01014         for(step_counter; step_counter <= firstRightBound; step_counter++)
01015                 machine.run_one();
01016 
01017         std::list<d_type>::iterator leftBound, rightBound;
01018 
01019         //XVs0* -> qX'V'0*
01020         leftBound = machine.access_tape_read_write().currentLocation();
01021         rightBound = machine.access_tape_read_write().currentLocation();
01022         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
01023                 leftBound--;
01024         temp = getNextChunk(machine,
01025                                                 leftBound,
01026                                                 rightBound,
01027                                                 secondRightBound,
01028                                                 step_counter,
01029                                                 transition_limit,
01030                                                 true,                           //stop at left
01031                                                 false,                          //stop at right
01032                                                 false,                          //inclusive left
01033                                                 true,                           //inclusive right
01034                                                 false,                          //push left
01035                                                 false);                         //push right
01036         if(temp.isEmpty()) return false;
01037         q = machine.get_current_state();
01038         Xp.fillTape(temp, 0, X.tapeConfig.size()-1);
01039         Vp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
01040 
01041         //std::cout << "here1" << std::endl;
01042 
01043         //0*UqX' -> 0*U'Y'r
01044         leftBound = machine.access_tape_read_write().currentLocation();
01045         rightBound = machine.access_tape_read_write().currentLocation();
01046         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
01047                 rightBound++;
01048         temp = getNextChunkUnevenCheck(machine,
01049                                                 firstLeftBound,
01050                                                 leftBound,
01051                                                 rightBound,
01052                                                 secondRightBound,
01053                                                 step_counter,
01054                                                 transition_limit,
01055                                                 false,                          //stop at left
01056                                                 true,                           //stop at right
01057                                                 true,                           //inclusive left
01058                                                 false,                          //inclusive right
01059                                                 true,                           //push left
01060                                                 false);                         //push right
01061         if(temp.isEmpty()) return false;
01062         r = machine.get_current_state();
01063         Up.fillTape(temp, 0, temp.tapeConfig.size()-X.tapeConfig.size()-1);
01064         Yp.fillTape(temp, temp.tapeConfig.size()-X.tapeConfig.size(), temp.tapeConfig.size()-1);
01065 
01066         //std::cout << "here2" << std::endl;
01067 
01068         //Y'rV' -> ZVt''
01069         leftBound = machine.access_tape_read_write().currentLocation();
01070         rightBound = machine.access_tape_read_write().currentLocation();
01071         for(int j = 0; j < Yp.tapeConfig.size(); j++)
01072                 leftBound--;
01073         temp = getNextChunk(machine,
01074                                                 leftBound,
01075                                                 rightBound,
01076                                                 secondRightBound,
01077                                                 step_counter,
01078                                                 transition_limit,
01079                                                 false,                          //stop at left
01080                                                 false,                          //stop at right
01081                                                 true,                           //inclusive left
01082                                                 true,                           //inclusive right
01083                                                 false,                          //push left
01084                                                 true);                          //push right
01085         if(temp.isEmpty()) return false;
01086         t = machine.get_current_state();
01087         Z.fillTape(temp, 0, X.tapeConfig.size()-1);
01088         Vpp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
01089 
01090         //std::cout << "here3" << std::endl;
01091 
01092         //--------------------------------------------------------------------------
01093         //ZVt''0* -> uZ'V'''0*
01094         leftBound = machine.access_tape_read_write().currentLocation();
01095         rightBound = machine.access_tape_read_write().currentLocation();
01096         for(int j = 0; j < Vpp.tapeConfig.size() + Z.tapeConfig.size(); j++)
01097                 leftBound--;
01098         temp = getNextChunk(machine,
01099                                                 leftBound,
01100                                                 rightBound,
01101                                                 secondRightBound,
01102                                                 step_counter,
01103                                                 transition_limit,
01104                                                 true,                           //stop at left
01105                                                 false,                          //stop at right
01106                                                 false,                          //inclusive left
01107                                                 true,                           //inclusive right
01108                                                 false,                          //push left
01109                                                 false);                         //push right
01110         if(temp.isEmpty()) return false;
01111         u = machine.get_current_state();
01112         Zp.fillTape(temp, 0, Z.tapeConfig.size()-1);
01113         Vppp.fillTape(temp, Z.tapeConfig.size(), temp.tapeConfig.size()-1);
01114 
01115         //std::cout << "here4" << std::endl;
01116 
01117         //0*Uu'Z' ->  U''Mv'
01118         leftBound = machine.access_tape_read_write().currentLocation();
01119         rightBound = machine.access_tape_read_write().currentLocation();
01120         for(int j = 0; j < Zp.tapeConfig.size()+1; j++)
01121                 rightBound++;
01122         temp = getNextChunkUnevenCheck(machine,
01123                                                 secondLeftBound,
01124                                                 leftBound,
01125                                                 rightBound,
01126                                                 secondRightBound,
01127                                                 step_counter,
01128                                                 transition_limit,
01129                                                 false,                          //stop at left
01130                                                 true,                           //stop at right
01131                                                 true,                           //inclusive left
01132                                                 false,                          //inclusive right
01133                                                 true,                           //push left
01134                                                 false);                         //push right
01135         if(temp.isEmpty()) return false;
01136         Upp.fillTape(temp, 0, temp.tapeConfig.size()-Zp.tapeConfig.size()-1);
01137         Mp.fillTape(temp, temp.tapeConfig.size()-Zp.tapeConfig.size(), temp.tapeConfig.size()-1);
01138         v = machine.get_current_state();
01139 
01140         //std::cout << "here5" << std::endl;
01141 
01142 
01143         //M'vV''' -> NVs''''
01144         leftBound = machine.access_tape_read_write().currentLocation();
01145         rightBound = machine.access_tape_read_write().currentLocation();
01146         for(int j = 0; j < Mp.tapeConfig.size(); j++)
01147                 leftBound--;
01148         temp = getNextChunk(machine,
01149                                                 leftBound,
01150                                                 rightBound,
01151                                                 thirdRightBound,
01152                                                 step_counter,
01153                                                 transition_limit,
01154                                                 false,                          //stop at left
01155                                                 false,                          //stop at right
01156                                                 true,                           //inclusive left
01157                                                 true,                           //inclusive right
01158                                                 false,                          //push left
01159                                                 true);                          //push right
01160         if(temp.isEmpty()) return false;
01161         N.fillTape(temp, 0, Zp.tapeConfig.size()-1);
01162         Vpppp.fillTape(temp, Zp.tapeConfig.size(), temp.tapeConfig.size()-1);
01163         if(machine.get_current_state() != s)
01164                 return false;
01165 
01166         /*std::cout << "here6" << std::endl;
01167 
01168         tapeChunk<d_type> one, two, three, four, five;
01169         one = U+V;
01170         two = U+X+V;
01171         three = Up+Z+Vpp;
01172         four = Upp+N+Vpppp;
01173         five = U+X+X+V;
01174         one.print();
01175         two.print();
01176         three.print();
01177         four.print();
01178         five.print();
01179         std::cout << "U    : ";
01180         U.print();
01181         std::cout << "Up   : ";
01182         Up.print();
01183         std::cout << "Upp  : ";
01184         Upp.print();
01185         std::cout << "V    : ";
01186         V.print();
01187         std::cout << "Vp   : ";
01188         Vp.print();
01189         std::cout << "Vpp  : ";
01190         Vpp.print();
01191         std::cout << "Vppp : ";
01192         Vppp.print();
01193         std::cout << "Vpppp: ";
01194         Vpppp.print();
01195         std::cout << "X    : ";
01196         X.print();
01197         std::cout << "N    : ";
01198         N.print();*/
01199 
01200         if(Upp + N + Vpppp != U + X + X + V)
01201                 return false;
01202 
01203         //std::cout << "here7" << std::endl;
01204 
01205         //-----------------------------------------------------------------
01206         //XVs0* -> qX'V'0*
01207         leftBound = machine.access_tape_read_write().currentLocation();
01208         rightBound = machine.access_tape_read_write().currentLocation();
01209         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
01210                 leftBound--;
01211         temp = getNextChunk(machine,
01212                                                 leftBound,
01213                                                 rightBound,
01214                                                 secondRightBound,
01215                                                 step_counter,
01216                                                 transition_limit,
01217                                                 true,                           //stop at left
01218                                                 false,                          //stop at right
01219                                                 false,                          //inclusive left
01220                                                 true,                           //inclusive right
01221                                                 false,                          //push left
01222                                                 false);                         //push right
01223         if(temp.isEmpty()) return false;
01224         if(temp != Xp + Vp || machine.get_current_state() != q)
01225                 return false;
01226 
01227         //std::cout << "here8" << std::endl;
01228 
01229         //XqX' -> qX'Y
01230         leftBound = machine.access_tape_read_write().currentLocation();
01231         rightBound = machine.access_tape_read_write().currentLocation();
01232         for(int j = 0; j < X.tapeConfig.size(); j++)
01233                 leftBound--;
01234         for(int j = 0; j < Xp.tapeConfig.size(); j++)
01235                 rightBound++;
01236         temp = getNextChunk(machine,
01237                                                 leftBound,
01238                                                 rightBound,
01239                                                 secondRightBound,
01240                                                 step_counter,
01241                                                 transition_limit,
01242                                                 true,                           //stop at left
01243                                                 false,                          //stop at right
01244                                                 false,                          //inclusive left
01245                                                 true,                           //inclusive right
01246                                                 false,                          //push left
01247                                                 false);                         //push right
01248         if(temp.isEmpty()) return false;
01249         Y.fillTape(temp, Xp.tapeConfig.size(), temp.tapeConfig.size()-1);
01250         if(temp != Xp+Y || machine.get_current_state() != q)
01251                 return false;
01252 
01253         //std::cout << "here9" << std::endl;
01254 
01255         //0*UqX' -> 0*U'Y'r
01256         leftBound = machine.access_tape_read_write().currentLocation();
01257         rightBound = machine.access_tape_read_write().currentLocation();
01258         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
01259                 rightBound++;
01260         temp = getNextChunkUnevenCheck(machine,
01261                                                 thirdLeftBound,
01262                                                 leftBound,
01263                                                 rightBound,
01264                                                 secondRightBound,
01265                                                 step_counter,
01266                                                 transition_limit,
01267                                                 false,                          //stop at left
01268                                                 true,                           //stop at right
01269                                                 true,                           //inclusive left
01270                                                 false,                          //inclusive right
01271                                                 true,                           //push left
01272                                                 false);                         //push right
01273         if(temp.isEmpty()) return false;
01274         if(temp != Up+Yp || machine.get_current_state() != r)
01275                 return false;
01276 
01277         //std::cout << "here10" << std::endl;
01278 
01279         //Y'rY -> ZY'r
01280         leftBound = machine.access_tape_read_write().currentLocation();
01281         rightBound = machine.access_tape_read_write().currentLocation();
01282         for(int j = 0; j < Yp.tapeConfig.size(); j++)
01283                 leftBound--;
01284         for(int j = 0; j < Y.tapeConfig.size(); j++)
01285                 rightBound++;
01286         temp = getNextChunk(machine,
01287                                                 leftBound,
01288                                                 rightBound,
01289                                                 secondRightBound,
01290                                                 step_counter,
01291                                                 transition_limit,
01292                                                 false,                          //stop at left
01293                                                 true,                           //stop at right
01294                                                 true,                           //inclusive left
01295                                                 false,                          //inclusive right
01296                                                 false,                          //push left
01297                                                 false);                         //push right
01298         if(temp.isEmpty()) return false;
01299         if(temp != Z+Yp || machine.get_current_state() != r)
01300                 return false;
01301 
01302         //std::cout << "here11" << std::endl;
01303 
01304         //Y'rV' -> ZVt''
01305         leftBound = machine.access_tape_read_write().currentLocation();
01306         rightBound = machine.access_tape_read_write().currentLocation();
01307         for(int j = 0; j < Yp.tapeConfig.size(); j++)
01308                 leftBound--;
01309         temp = getNextChunk(machine,
01310                                                 leftBound,
01311                                                 rightBound,
01312                                                 fourthRightBound,
01313                                                 step_counter,
01314                                                 transition_limit,
01315                                                 false,                          //stop at left
01316                                                 false,                          //stop at right
01317                                                 true,                           //inclusive left
01318                                                 true,                           //inclusive right
01319                                                 false,                          //push left
01320                                                 true);                          //push right
01321         if(temp.isEmpty()) return false;
01322         if(temp != Z+Vpp || machine.get_current_state() != t)
01323                 return false;
01324 
01325         //std::cout << "here12" << std::endl;
01326 
01327         //---------------------------------------------------------------------------
01328         //ZVt''0* -> uZ'V'''0*
01329         leftBound = machine.access_tape_read_write().currentLocation();
01330         rightBound = machine.access_tape_read_write().currentLocation();
01331         for(int j = 0; j < Vpp.tapeConfig.size() + Z.tapeConfig.size(); j++)
01332                 leftBound--;
01333         temp = getNextChunk(machine,
01334                                                 leftBound,
01335                                                 rightBound,
01336                                                 secondRightBound,
01337                                                 step_counter,
01338                                                 transition_limit,
01339                                                 true,                           //stop at left
01340                                                 false,                          //stop at right
01341                                                 false,                          //inclusive left
01342                                                 true,                           //inclusive right
01343                                                 false,                          //push left
01344                                                 false);                         //push right
01345         if(temp.isEmpty()) return false;
01346         if(temp != Zp+Vppp || machine.get_current_state() != u)
01347                 return false;
01348 
01349         //std::cout << "here13" << std::endl;
01350 
01351         //ZuZ' -> uZ'M
01352         leftBound = machine.access_tape_read_write().currentLocation();
01353         rightBound = machine.access_tape_read_write().currentLocation();
01354         for(int j = 0; j < Z.tapeConfig.size(); j++)
01355                 leftBound--;
01356         for(int j = 0; j < Zp.tapeConfig.size(); j++)
01357                 rightBound++;
01358         temp = getNextChunk(machine,
01359                                                 leftBound,
01360                                                 rightBound,
01361                                                 secondRightBound,
01362                                                 step_counter,
01363                                                 transition_limit,
01364                                                 true,                           //stop at left
01365                                                 false,                          //stop at right
01366                                                 false,                          //inclusive left
01367                                                 true,                           //inclusive right
01368                                                 false,                          //push left
01369                                                 false);                         //push right
01370         if(temp.isEmpty()) return false;
01371         M.fillTape(temp, Zp.tapeConfig.size(), temp.tapeConfig.size()-1);
01372         if(temp != Zp+M || machine.get_current_state() != u)
01373                 return false;
01374 
01375         //std::cout << "here14" << std::endl;
01376 
01377         //0*Uu'Z' ->  U''Mv'
01378         leftBound = machine.access_tape_read_write().currentLocation();
01379         rightBound = machine.access_tape_read_write().currentLocation();
01380         for(int j = 0; j < Zp.tapeConfig.size()+1; j++)
01381                 rightBound++;
01382         temp = getNextChunkUnevenCheck(machine,
01383                                                 fourthLeftBound,
01384                                                 leftBound,
01385                                                 rightBound,
01386                                                 secondRightBound,
01387                                                 step_counter,
01388                                                 transition_limit,
01389                                                 false,                          //stop at left
01390                                                 true,                           //stop at right
01391                                                 true,                           //inclusive left
01392                                                 false,                          //inclusive right
01393                                                 true,                           //push left
01394                                                 false);                         //push right
01395         if(temp.isEmpty()) return false;
01396         if(temp != Upp+Mp || machine.get_current_state() != v)
01397                 return false;
01398 
01399         //std::cout << "here15" << std::endl;
01400 
01401         //M'vM -> NM'v
01402         leftBound = machine.access_tape_read_write().currentLocation();
01403         rightBound = machine.access_tape_read_write().currentLocation();
01404         for(int j = 0; j < Mp.tapeConfig.size(); j++)
01405                 leftBound--;
01406         for(int j = 0; j < M.tapeConfig.size(); j++)
01407                 rightBound++;
01408         temp = getNextChunk(machine,
01409                                                 leftBound,
01410                                                 rightBound,
01411                                                 secondRightBound,
01412                                                 step_counter,
01413                                                 transition_limit,
01414                                                 false,                          //stop at left
01415                                                 true,                           //stop at right
01416                                                 true,                           //inclusive left
01417                                                 false,                          //inclusive right
01418                                                 false,                          //push left
01419                                                 false);                         //push right
01420         if(temp.isEmpty()) return false;
01421         if(temp != N+Mp || machine.get_current_state() != v)
01422                 return false;
01423 
01424         //std::cout << "here16" << std::endl;
01425 
01426         //M'rV''' -> NVs''''
01427         leftBound = machine.access_tape_read_write().currentLocation();
01428         rightBound = machine.access_tape_read_write().currentLocation();
01429         for(int j = 0; j < Mp.tapeConfig.size(); j++)
01430                 leftBound--;
01431         temp = getNextChunk(machine,
01432                                                 leftBound,
01433                                                 rightBound,
01434                                                 fifthRightBound,
01435                                                 step_counter,
01436                                                 transition_limit,
01437                                                 false,                          //stop at left
01438                                                 false,                          //stop at right
01439                                                 true,                           //inclusive left
01440                                                 true,                           //inclusive right
01441                                                 false,                          //push left
01442                                                 true);                          //push right
01443         if(temp.isEmpty()) return false;
01444         if(temp != N+Vpppp || machine.get_current_state() != s)
01445                 return false;
01446 
01447         //std::cout << "here17" << std::endl;
01448 
01449         if(Upp + N + N + Vpppp != U + X + X + X + V)
01450                 return false;
01451         return true;
01452 }
01453 
01454 bool checkAlternateChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
01455 {
01456         machine.resetMachine();
01457         unsigned int step_counter = 0;
01458 
01459         std::list<d_type>::iterator leftBound = machine.access_tape_read_write().currentLocation();
01460         std::list<d_type>::iterator rightBound = machine.access_tape_read_write().currentLocation();
01461 
01462         std::list<d_type>::iterator firstLeftBoundPt, secondLeftBoundPt, thirdLeftBoundPt, fourthLeftBoundPt;
01463 
01464         //run for a bit to establish sweeping motion
01465         for(step_counter = 0; step_counter < transition_limit &&
01466                                                   step_counter < 150; step_counter++)
01467         {
01468                 if(step_counter == 50)
01469                 {
01470                         leftBound = machine.access_tape_read_write().currentLocation();
01471                         rightBound = machine.access_tape_read_write().currentLocation();
01472                 }
01473                 if(step_counter >= 50)
01474                 {
01475                         if(machine.access_tape_read_write().currentLocation() == rightBound)
01476                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
01477                                 {
01478                                         machine.access_tape_read_write().checkIteratorRight(rightBound);
01479                                         rightBound++;
01480                                 }
01481                         if(machine.access_tape_read_write().currentLocation() == leftBound)
01482                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
01483                                 {
01484                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
01485                                         leftBound--;
01486                                 }
01487                 }
01488                 if(machine.run_one()==turing_machine<d_type>::halt)
01489                         return false;
01490 
01491         }
01492 
01493         //get the step counters of the left and right bounds
01494         unsigned int firstRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01495         if(firstRightBound == 0)
01496                 return false;
01497 
01498         unsigned int secondRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01499         if(secondRightBound == 0)
01500                 return false;
01501 
01502         unsigned int thirdRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01503         if(thirdRightBound == 0)
01504                 return false;
01505 
01506         unsigned int fourthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01507         if(fourthRightBound == 0)
01508                 return false;
01509 
01510         unsigned int fifthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01511         if(fifthRightBound == 0)
01512                 return false;
01513 
01514         unsigned int sixthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01515         if(sixthRightBound == 0)
01516                 return false;
01517 
01518         unsigned int seventhRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
01519         if(seventhRightBound == 0)
01520                 return false;
01521 
01522         /*std::cout << firstRightBound << std::endl;
01523         std::cout << secondRightBound << std::endl;
01524         std::cout << thirdRightBound << std::endl;
01525         std::cout << fourthRightBound << std::endl;
01526         std::cout << fifthRightBound << std::endl;
01527         std::cout << sixthRightBound << std::endl;
01528         std::cout << seventhRightBound << std::endl;*/
01529 
01530         //reset the machine and use step counters to get tape configuration at each point
01531         machine.resetMachine();
01532         tapeChunk<d_type> beforeSweep, afterSweep;
01533 
01534         std::vector<state<d_type> >::size_type stateS;
01535 
01536         leftBound = machine.access_tape_read_write().currentLocation();
01537         for(unsigned int j = 0; j <= seventhRightBound; j++)
01538         {
01539                 if(j < 50)
01540                         machine.run_one();
01541                 if(j == 50)
01542                         leftBound = machine.access_tape_read_write().currentLocation();
01543                 if(j >= 50)
01544                 {
01545                         if(machine.access_tape_read_write().currentLocation() == leftBound)
01546                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
01547                                 {
01548                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
01549                                         leftBound--;
01550                                 }
01551                         machine.run_one();
01552 
01553                         if(j == firstRightBound)
01554                         {
01555                                 rightBound = machine.access_tape_read_write().currentLocation();
01556                                 beforeSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
01557                                 stateS = machine.get_current_state();
01558                         }
01559                         else if(j == thirdRightBound)
01560                         {
01561                                 rightBound = machine.access_tape_read_write().currentLocation();
01562                                 afterSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
01563                                 if(machine.get_current_state() != stateS)
01564                                         return false;
01565                         }
01566                         else if(j == fourthRightBound)
01567                                 firstLeftBoundPt = leftBound;
01568                         else if(j == fifthRightBound)
01569                                 secondLeftBoundPt = leftBound;
01570                         else if(j == sixthRightBound)
01571                                 thirdLeftBoundPt = leftBound;
01572                         else if(j == seventhRightBound)
01573                                 fourthLeftBoundPt = leftBound;
01574                 }
01575         }
01576 
01577         tapeChunk<d_type> chunkX, chunkU, chunkV;
01578         if(!findMidSection(beforeSweep, afterSweep, chunkX, chunkU, chunkV))
01579                 return false;
01580         /*chunkU.print();
01581         chunkX.print();
01582         chunkV.print();*/
01583         if(!checkAlternateChristmasTreeGrammar(machine,
01584                                                 thirdRightBound,
01585                                                 fourthRightBound,
01586                                                 fifthRightBound,
01587                                                 sixthRightBound,
01588                                                 seventhRightBound,
01589                                                 firstLeftBoundPt,
01590                                                 secondLeftBoundPt,
01591                                                 thirdLeftBoundPt,
01592                                                 fourthLeftBoundPt,
01593                                                 transition_limit,
01594                                                 chunkU,
01595                                                 chunkX,
01596                                                 chunkV,
01597                                                 stateS))
01598                 return false;
01599         return true;
01600 }
01601 
01602 bool alternateChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
01603 {
01604         if(checkAlternateChristmasTree(machine, transition_limit))
01605                 return true;
01606         else
01607         {
01608                 turing_machine<d_type> reverse = machine.reverseMachine();
01609                 if(checkAlternateChristmasTree(reverse, transition_limit))
01610                         return true;
01611         }
01612         return false;
01613 }
01614 
01615 
01616 //end alternateChristmasTree routines
01617 
01618 //begin leaningChristmasTree routines
01619 
01638 bool checkLeaningChristmasTreeGrammar(turing_machine<d_type> &machine,
01639                                                            unsigned int firstRightBound,
01640                                                            unsigned int secondRightBound,
01641                                                            unsigned int thirdRightBound,
01642                                                            std::list<d_type>::iterator firstLeftBound,
01643                                                            std::list<d_type>::iterator secondLeftBound,
01644                                                            std::list<d_type>::iterator thirdLeftBound,
01645                                                            unsigned int transition_limit,
01646                                                            tapeChunk<d_type> &N,
01647                                                            tapeChunk<d_type> &U,
01648                                                            tapeChunk<d_type> &X,
01649                                                            tapeChunk<d_type> &V,
01650                                                            std::vector<state<d_type> >::size_type s)
01651 {
01652         machine.resetMachine();
01653         unsigned int step_counter = 0;
01654         tapeChunk<d_type> Xp, Y, Yp, Z, Vp, Vpp, Up, temp;
01655         std::vector<state<d_type> >::size_type q, r;
01656 
01657         for(step_counter; step_counter <= firstRightBound; step_counter++)
01658                 machine.run_one();
01659 
01660         std::list<d_type>::iterator leftBound, rightBound;
01661 
01662         //XVs0* -> qX'V'0*
01663         leftBound = machine.access_tape_read_write().currentLocation();
01664         rightBound = machine.access_tape_read_write().currentLocation();
01665         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
01666                 leftBound--;
01667         temp = getNextChunk(machine,
01668                                                 leftBound,
01669                                                 rightBound,
01670                                                 secondRightBound,
01671                                                 step_counter,
01672                                                 transition_limit,
01673                                                 true,                           //stop at left
01674                                                 false,                          //stop at right
01675                                                 false,                          //inclusive left
01676                                                 true,                           //inclusive right
01677                                                 false,                          //push left
01678                                                 false);                         //push right
01679         if(temp.isEmpty()) return false;
01680         q = machine.get_current_state();
01681         Xp.fillTape(temp, 0, X.tapeConfig.size()-1);
01682         Vp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
01683 
01684         //std::cout << "here1" << std::endl;
01685 
01686         //NUqX' -> NNU'Y'r
01687         leftBound = firstLeftBound;
01688         rightBound = machine.access_tape_read_write().currentLocation();
01689         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
01690                 rightBound++;
01691         temp = getNextChunk(machine,
01692                                                 leftBound,
01693                                                 rightBound,
01694                                                 secondRightBound,
01695                                                 step_counter,
01696                                                 transition_limit,
01697                                                 false,                          //stop at left
01698                                                 true,                           //stop at right
01699                                                 true,                           //inclusive left
01700                                                 false,                          //inclusive right
01701                                                 true,                           //push left
01702                                                 false);                         //push right
01703         if(temp.isEmpty()) return false;
01704         r = machine.get_current_state();
01705         Up.fillTape(temp, N.tapeConfig.size(), temp.tapeConfig.size()-X.tapeConfig.size()-1);
01706         Yp.fillTape(temp, temp.tapeConfig.size()-X.tapeConfig.size(), temp.tapeConfig.size()-1);
01707         if(temp != N+Up+Yp)
01708                 return false;
01709 
01710         //std::cout << "here2" << std::endl;
01711 
01712         //Y'rV' -> ZVs''
01713         leftBound = machine.access_tape_read_write().currentLocation();
01714         rightBound = machine.access_tape_read_write().currentLocation();
01715         for(int j = 0; j < Yp.tapeConfig.size(); j++)
01716                 leftBound--;
01717         temp = getNextChunk(machine,
01718                                                 leftBound,
01719                                                 rightBound,
01720                                                 secondRightBound,
01721                                                 step_counter,
01722                                                 transition_limit,
01723                                                 false,                          //stop at left
01724                                                 false,                          //stop at right
01725                                                 true,                           //inclusive left
01726                                                 true,                           //inclusive right
01727                                                 false,                          //push left
01728                                                 true);                          //push right
01729         if(temp.isEmpty()) return false;
01730         Z.fillTape(temp, 0, X.tapeConfig.size()-1);
01731         Vpp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
01732         if(machine.get_current_state() != s)
01733                 return false;
01734 
01735         /*std::cout << "Up : "; Up.print();
01736         std::cout << "Z  : "; Z.print();
01737         std::cout << "Vpp: "; Vpp.print();
01738         std::cout << "U :  "; U.print();
01739         std::cout << "X :  "; X.print();
01740         std::cout << "V :  "; V.print();
01741         std::cout << "N :  "; N.print();
01742         std::cout << "Xp : "; Xp.print();
01743         std::cout << "Yp : "; Yp.print();*/
01744 
01745         if(Up + Z + Vpp != U + X + X + V)
01746                 return false;
01747 
01748         //XVs0* -> qX'V'0*
01749         leftBound = machine.access_tape_read_write().currentLocation();
01750         rightBound = machine.access_tape_read_write().currentLocation();
01751         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
01752                 leftBound--;
01753         temp = getNextChunk(machine,
01754                                                 leftBound,
01755                                                 rightBound,
01756                                                 secondRightBound,
01757                                                 step_counter,
01758                                                 transition_limit,
01759                                                 true,                           //stop at left
01760                                                 false,                          //stop at right
01761                                                 false,                          //inclusive left
01762                                                 true,                           //inclusive right
01763                                                 false,                          //push left
01764                                                 false);                         //push right
01765         if(temp.isEmpty()) return false;
01766         if(temp != Xp + Vp || machine.get_current_state() != q)
01767                 return false;
01768 
01769         //std::cout << "here3" << std::endl;
01770 
01771         //XqX' -> qX'Y
01772         leftBound = machine.access_tape_read_write().currentLocation();
01773         rightBound = machine.access_tape_read_write().currentLocation();
01774         for(int j = 0; j < X.tapeConfig.size(); j++)
01775                 leftBound--;
01776         for(int j = 0; j < Xp.tapeConfig.size(); j++)
01777                 rightBound++;
01778         temp = getNextChunk(machine,
01779                                                 leftBound,
01780                                                 rightBound,
01781                                                 secondRightBound,
01782                                                 step_counter,
01783                                                 transition_limit,
01784                                                 true,                           //stop at left
01785                                                 false,                          //stop at right
01786                                                 false,                          //inclusive left
01787                                                 true,                           //inclusive right
01788                                                 false,                          //push left
01789                                                 false);                         //push right
01790         if(temp.isEmpty()) return false;
01791         Y.fillTape(temp, Xp.tapeConfig.size(), temp.tapeConfig.size()-1);
01792         if(temp != Xp+Y || machine.get_current_state() != q)
01793                 return false;
01794 
01795         //std::cout << "here4" << std::endl;
01796 
01797         //NUqX' -> NNU'Y'r
01798         leftBound = secondLeftBound;
01799         rightBound = machine.access_tape_read_write().currentLocation();
01800         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
01801                 rightBound++;
01802         temp = getNextChunk(machine,
01803                                                 leftBound,
01804                                                 rightBound,
01805                                                 secondRightBound,
01806                                                 step_counter,
01807                                                 transition_limit,
01808                                                 false,                          //stop at left
01809                                                 true,                           //stop at right
01810                                                 true,                           //inclusive left
01811                                                 false,                          //inclusive right
01812                                                 true,                           //push left
01813                                                 false);                         //push right
01814         if(temp.isEmpty()) return false;
01815         if(temp != N+Up+Yp || machine.get_current_state() != r)
01816                 return false;
01817 
01818         //std::cout << "here5" << std::endl;
01819 
01820         //Y'rY -> ZY'r
01821         leftBound = machine.access_tape_read_write().currentLocation();
01822         rightBound = machine.access_tape_read_write().currentLocation();
01823         for(int j = 0; j < Yp.tapeConfig.size(); j++)
01824                 leftBound--;
01825         for(int j = 0; j < Y.tapeConfig.size(); j++)
01826                 rightBound++;
01827         temp = getNextChunk(machine,
01828                                                 leftBound,
01829                                                 rightBound,
01830                                                 secondRightBound,
01831                                                 step_counter,
01832                                                 transition_limit,
01833                                                 false,                          //stop at left
01834                                                 true,                           //stop at right
01835                                                 true,                           //inclusive left
01836                                                 false,                          //inclusive right
01837                                                 false,                          //push left
01838                                                 false);                         //push right
01839         if(temp.isEmpty()) return false;
01840         if(temp != Z+Yp || machine.get_current_state() != r)
01841                 return false;
01842 
01843         //std::cout << "here6" << std::endl;
01844 
01845         //Y'rV' -> ZVs''
01846         leftBound = machine.access_tape_read_write().currentLocation();
01847         rightBound = machine.access_tape_read_write().currentLocation();
01848         for(int j = 0; j < Yp.tapeConfig.size(); j++)
01849                 leftBound--;
01850         temp = getNextChunk(machine,
01851                                                 leftBound,
01852                                                 rightBound,
01853                                                 thirdRightBound,
01854                                                 step_counter,
01855                                                 transition_limit,
01856                                                 false,                          //stop at left
01857                                                 false,                          //stop at right
01858                                                 true,                           //inclusive left
01859                                                 true,                           //inclusive right
01860                                                 false,                          //push left
01861                                                 true);                          //push right
01862         if(temp.isEmpty()) return false;
01863         if(temp != Z+Vpp || machine.get_current_state() != s)
01864                 return false;
01865         if(Up + Z + Z + Vpp != U + X + X + X + V)
01866                 return false;
01867         return true;
01868 }
01869 
01882 unsigned int getNextLeaningRightBound(turing_machine<d_type> &machine,
01883                                                            std::list<d_type>::iterator &rightBound,
01884                                                            unsigned int &step_counter,
01885                                                            unsigned int transition_limit)
01886 {
01887         bool rightBoundPushed = false, leftBoundPushed = false;
01888         unsigned int rightBoundStepCounter = 0;
01889 
01890         std::list<d_type>::iterator originalRightBound = rightBound;
01891         std::list<d_type>::iterator leftBound = rightBound;
01892 
01893         for(step_counter; step_counter < transition_limit; step_counter++)
01894         {
01895                 if(machine.access_tape_read_write().currentLocation() == leftBound)
01896                 {
01897                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
01898                         {
01899                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
01900                                 leftBound--;
01901                                 leftBoundPushed = true;
01902                                 if(rightBoundPushed)
01903                                 {
01904                                         return rightBoundStepCounter;
01905                                 }
01906                         }
01907                         if(rightBoundPushed && leftBoundPushed)
01908                         {
01909                                 return rightBoundStepCounter;
01910                         }
01911                 }
01912                 if(machine.access_tape_read_write().currentLocation() == rightBound)
01913                 {
01914                         rightBoundPushed = true;
01915                         rightBoundStepCounter = step_counter-1;
01916                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
01917                         {
01918                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
01919                                 rightBound++;
01920                                 rightBoundPushed = true;
01921                                 rightBoundStepCounter = step_counter;
01922                         }
01923                 }
01924                 if(machine.run_one()==turing_machine<d_type>::halt)
01925                         return 0;
01926         }
01927         return 0;
01928 }
01929 
01937 bool checkLeaningChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
01938 {
01939         machine.resetMachine();
01940         unsigned int step_counter = 0;
01941 
01942         std::list<d_type>::iterator leftBound;
01943         std::list<d_type>::iterator rightBound;
01944 
01945         //last bound push
01946         //0 = left
01947         //1 = right
01948         int lastPush = 0;
01949 
01950         //run for a bit to establish sweeping motion
01951         for(step_counter = 0; step_counter < transition_limit &&
01952                                                   step_counter < 200; step_counter++)
01953         {
01954                 if(step_counter == 50)
01955                 {
01956                         leftBound = machine.access_tape_read_write().currentLocation();
01957                         rightBound = machine.access_tape_read_write().currentLocation();
01958                 }
01959                 if(step_counter >= 50)
01960                 {
01961                         if(machine.access_tape_read_write().currentLocation() == rightBound)
01962                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
01963                                 {
01964                                         machine.access_tape_read_write().checkIteratorRight(rightBound);
01965                                         rightBound++;
01966                                 }
01967                         if(machine.access_tape_read_write().currentLocation() == leftBound)
01968                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
01969                                 {
01970                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
01971                                         leftBound--;
01972                                 }
01973                 }
01974                 if(machine.run_one()==turing_machine<d_type>::halt)
01975                         return false;
01976 
01977         }
01978 
01979         //get the step counters of the left and right bounds
01980         unsigned int firstRightBound = getNextLeaningRightBound(machine, rightBound, step_counter, transition_limit);
01981         if(firstRightBound == 0)
01982                 return false;
01983 
01984         unsigned int secondRightBound = getNextLeaningRightBound(machine, rightBound, step_counter, transition_limit);
01985         if(secondRightBound == 0)
01986                 return false;
01987 
01988         unsigned int thirdRightBound = getNextLeaningRightBound(machine, rightBound, step_counter, transition_limit);
01989         if(thirdRightBound == 0)
01990                 return false;
01991 
01992         unsigned int fourthRightBound = getNextLeaningRightBound(machine, rightBound, step_counter, transition_limit);
01993         if(fourthRightBound == 0)
01994                 return false;
01995 
01996         unsigned int fifthRightBound = getNextLeaningRightBound(machine, rightBound, step_counter, transition_limit);
01997         if(fifthRightBound == 0)
01998                 return false;
01999 
02000         /*std::cout << firstRightBound << std::endl;
02001         std::cout << secondRightBound << std::endl;
02002         std::cout << thirdRightBound << std::endl;
02003         std::cout << fourthRightBound << std::endl;*/
02004 
02005         //reset the machine and use step counters to get tape configuration at each point
02006         machine.resetMachine();
02007         tapeChunk<d_type> chunkN, beforeSweep, afterSweep;
02008 
02009         std::vector<state<d_type> >::size_type stateS;
02010         std::list<d_type>::iterator firstLeftBound, secondLeftBound, thirdLeftBound, fourthLeftBound;
02011         std::list<d_type>::iterator tempHelper;
02012 
02013         for(unsigned int j = 0; j <= fifthRightBound; j++)
02014         {
02015                 if(j < firstRightBound)
02016                         machine.run_one();
02017                 else if(j == firstRightBound)
02018                 {
02019                         firstLeftBound = machine.access_tape_read_write().currentLocation();
02020                         machine.run_one();
02021                 }
02022                 else if(j > firstRightBound && j < secondRightBound)
02023                 {
02024                         if(machine.access_tape_read_write().currentLocation() == firstLeftBound)
02025                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
02026                                 {
02027                                         machine.access_tape_read_write().checkIteratorLeft(firstLeftBound);
02028                                         firstLeftBound--;
02029                                 }
02030                         machine.run_one();
02031                 }
02032                 else if(j == secondRightBound)
02033                 {
02034                         machine.run_one();
02035                         beforeSweep.fillTape(machine.access_tape_read_write(), firstLeftBound, machine.access_tape_read_write().currentLocation());
02036                         secondLeftBound = machine.access_tape_read_write().currentLocation();
02037                         stateS = machine.get_current_state();
02038                 }
02039                 else if(j > secondRightBound && j < thirdRightBound)
02040                 {
02041                         if(machine.access_tape_read_write().currentLocation() == secondLeftBound)
02042                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
02043                                 {
02044                                         machine.access_tape_read_write().checkIteratorLeft(secondLeftBound);
02045                                         secondLeftBound--;
02046                                 }
02047                         machine.run_one();
02048                 }
02049                 else if(j == thirdRightBound)
02050                 {
02051                         machine.run_one();
02052                         tempHelper = secondLeftBound;
02053                         tempHelper--;
02054                         chunkN.fillTape(machine.access_tape_read_write(), firstLeftBound, tempHelper);
02055                         afterSweep.fillTape(machine.access_tape_read_write(), secondLeftBound, machine.access_tape_read_write().currentLocation());
02056 
02057                         if(machine.get_current_state() != stateS)
02058                                 return false;
02059                         thirdLeftBound = machine.access_tape_read_write().currentLocation();
02060                 }
02061                 else if(j > thirdRightBound && j < fourthRightBound)
02062                 {
02063                         if(machine.access_tape_read_write().currentLocation() == thirdLeftBound)
02064                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
02065                                 {
02066                                         machine.access_tape_read_write().checkIteratorLeft(thirdLeftBound);
02067                                         thirdLeftBound--;
02068                                 }
02069                         machine.run_one();
02070                 }
02071                 else if(j == fourthRightBound)
02072                 {
02073                         machine.run_one();
02074                         fourthLeftBound = machine.access_tape_read_write().currentLocation();
02075                 }
02076                 else
02077                 {
02078                         if(machine.access_tape_read_write().currentLocation() == fourthLeftBound)
02079                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
02080                                 {
02081                                         machine.access_tape_read_write().checkIteratorLeft(fourthLeftBound);
02082                                         fourthLeftBound--;
02083                                 }
02084                         machine.run_one();
02085                 }
02086         }
02087 
02088 
02089         tapeChunk<d_type> chunkX, chunkU, chunkV;
02090 
02091         if(!findMidSection(beforeSweep, afterSweep, chunkX, chunkU, chunkV))
02092                 return false;
02093 
02094         /*chunkN.print();
02095         chunkX.print();
02096         chunkU.print();
02097         chunkV.print();*/
02098 
02099         if(!checkLeaningChristmasTreeGrammar(machine,
02100                                                 thirdRightBound,
02101                                                 fourthRightBound,
02102                                                 fifthRightBound,
02103                                                 secondLeftBound,
02104                                                 thirdLeftBound,
02105                                                 fourthLeftBound,
02106                                                 transition_limit,
02107                                                 chunkN,
02108                                                 chunkU,
02109                                                 chunkX,
02110                                                 chunkV,
02111                                                 stateS))
02112                 return false;
02113 
02114 
02115 
02116         return true;
02117 }
02118 
02126 bool leaningChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
02127 {
02128         if(checkLeaningChristmasTree(machine, transition_limit))
02129                 return true;
02130         else
02131         {
02132                 turing_machine<d_type> reverse = machine.reverseMachine();
02133                 if(checkLeaningChristmasTree(reverse, transition_limit))
02134                         return true;
02135         }
02136         return false;
02137 }
02138 
02139 //end leaningChristmasTree routines
02140 
02141 //begin tripleSweepChristmasTree routines
02142 
02143 bool checkTripleSweepChristmasTreeGrammar(turing_machine<d_type> &machine,
02144                                                                                 unsigned int firstRightBound,
02145                                                                                 unsigned int secondRightBound,
02146                                                                                 unsigned int thirdRightBound,
02147                                                                                 unsigned int fourthRightBound,
02148                                                                                 unsigned int fifthRightBound,
02149                                                                                 unsigned int sixthRightBound,
02150                                                                                 unsigned int seventhRightBound,
02151                                                                                 std::list<d_type>::iterator firstLeftBound,
02152                                                                                 std::list<d_type>::iterator secondLeftBound,
02153                                                                                 std::list<d_type>::iterator thirdLeftBound,
02154                                                                                 std::list<d_type>::iterator fourthLeftBound,
02155                                                                                 std::list<d_type>::iterator fifthLeftBound,
02156                                                                                 std::list<d_type>::iterator sixthLeftBound,
02157                                                                                 unsigned int transition_limit,
02158                                                                                 tapeChunk<d_type> &U,
02159                                                                                 tapeChunk<d_type> &X,
02160                                                                                 tapeChunk<d_type> &V,
02161                                                                                 std::vector<state<d_type> >::size_type s)
02162 {
02163         machine.resetMachine();
02164         unsigned int step_counter = 0;
02165         tapeChunk<d_type> Up, Upp, Uppp, Vp, Vpp, Vppp, Vpppp, Vppppp, Vpppppp,
02166                           Xp, Y, Yp, Z, Zp, M, Mp, N, Np, J, Jp, K, temp;
02167         std::vector<state<d_type> >::size_type q, r, t, u, v, n, o, p;
02168 
02169         for(step_counter; step_counter <= firstRightBound; step_counter++)
02170                 machine.run_one();
02171 
02172         std::list<d_type>::iterator leftBound, rightBound;
02173 
02174         //XVs0* -> qX'V'0*
02175         leftBound = machine.access_tape_read_write().currentLocation();
02176         rightBound = machine.access_tape_read_write().currentLocation();
02177         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
02178                 leftBound--;
02179         temp = getNextChunk(machine,
02180                                                 leftBound,
02181                                                 rightBound,
02182                                                 secondRightBound,
02183                                                 step_counter,
02184                                                 transition_limit,
02185                                                 true,                           //stop at left
02186                                                 false,                          //stop at right
02187                                                 false,                          //inclusive left
02188                                                 true,                           //inclusive right
02189                                                 false,                          //push left
02190                                                 false);                         //push right
02191         if(temp.isEmpty()) return false;
02192         q = machine.get_current_state();
02193         Xp.fillTape(temp, 0, X.tapeConfig.size()-1);
02194         Vp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
02195 
02196         //std::cout << "here1" << std::endl;
02197 
02198         //0*UqX' -> 0*U'Y'r
02199         leftBound = machine.access_tape_read_write().currentLocation();
02200         rightBound = machine.access_tape_read_write().currentLocation();
02201         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
02202                 rightBound++;
02203         temp = getNextChunkUnevenCheck(machine,
02204                                                 firstLeftBound,
02205                                                 leftBound,
02206                                                 rightBound,
02207                                                 secondRightBound,
02208                                                 step_counter,
02209                                                 transition_limit,
02210                                                 false,                          //stop at left
02211                                                 true,                           //stop at right
02212                                                 true,                           //inclusive left
02213                                                 false,                          //inclusive right
02214                                                 true,                           //push left
02215                                                 false);                         //push right
02216         if(temp.isEmpty()) return false;
02217         r = machine.get_current_state();
02218         Up.fillTape(temp, 0, temp.tapeConfig.size()-X.tapeConfig.size()-1);
02219         Yp.fillTape(temp, temp.tapeConfig.size()-X.tapeConfig.size(), temp.tapeConfig.size()-1);
02220 
02221         //std::cout << "here2" << std::endl;
02222 
02223         //Y'rV' -> ZVt''
02224         leftBound = machine.access_tape_read_write().currentLocation();
02225         rightBound = machine.access_tape_read_write().currentLocation();
02226         for(int j = 0; j < Yp.tapeConfig.size(); j++)
02227                 leftBound--;
02228         temp = getNextChunk(machine,
02229                                                 leftBound,
02230                                                 rightBound,
02231                                                 secondRightBound,
02232                                                 step_counter,
02233                                                 transition_limit,
02234                                                 false,                          //stop at left
02235                                                 false,                          //stop at right
02236                                                 true,                           //inclusive left
02237                                                 true,                           //inclusive right
02238                                                 false,                          //push left
02239                                                 true);                          //push right
02240         if(temp.isEmpty()) return false;
02241         t = machine.get_current_state();
02242         Z.fillTape(temp, 0, X.tapeConfig.size()-1);
02243         Vpp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
02244 
02245         //std::cout << "here3" << std::endl;
02246 
02247         //--------------------------------------------------------------------------
02248         //ZVt''0* -> uZ'V'''0*
02249         leftBound = machine.access_tape_read_write().currentLocation();
02250         rightBound = machine.access_tape_read_write().currentLocation();
02251         for(int j = 0; j < Vpp.tapeConfig.size() + Z.tapeConfig.size(); j++)
02252                 leftBound--;
02253         temp = getNextChunk(machine,
02254                                                 leftBound,
02255                                                 rightBound,
02256                                                 secondRightBound,
02257                                                 step_counter,
02258                                                 transition_limit,
02259                                                 true,                           //stop at left
02260                                                 false,                          //stop at right
02261                                                 false,                          //inclusive left
02262                                                 true,                           //inclusive right
02263                                                 false,                          //push left
02264                                                 false);                         //push right
02265         if(temp.isEmpty()) return false;
02266         u = machine.get_current_state();
02267         Zp.fillTape(temp, 0, Z.tapeConfig.size()-1);
02268         Vppp.fillTape(temp, Z.tapeConfig.size(), temp.tapeConfig.size()-1);
02269 
02270         //std::cout << "here4" << std::endl;
02271 
02272         //0*Uu'Z' ->  U''Mv'
02273         leftBound = machine.access_tape_read_write().currentLocation();
02274         rightBound = machine.access_tape_read_write().currentLocation();
02275         for(int j = 0; j < Zp.tapeConfig.size()+1; j++)
02276                 rightBound++;
02277         temp = getNextChunkUnevenCheck(machine,
02278                                                 secondLeftBound,
02279                                                 leftBound,
02280                                                 rightBound,
02281                                                 secondRightBound,
02282                                                 step_counter,
02283                                                 transition_limit,
02284                                                 false,                          //stop at left
02285                                                 true,                           //stop at right
02286                                                 true,                           //inclusive left
02287                                                 false,                          //inclusive right
02288                                                 true,                           //push left
02289                                                 false);                         //push right
02290         if(temp.isEmpty()) return false;
02291         Upp.fillTape(temp, 0, temp.tapeConfig.size()-Zp.tapeConfig.size()-1);
02292         Mp.fillTape(temp, temp.tapeConfig.size()-Zp.tapeConfig.size(), temp.tapeConfig.size()-1);
02293         v = machine.get_current_state();
02294 
02295         //std::cout << "here5" << std::endl;
02296 
02297 
02298         //M'vV''' -> NVn''''
02299         leftBound = machine.access_tape_read_write().currentLocation();
02300         rightBound = machine.access_tape_read_write().currentLocation();
02301         for(int j = 0; j < Mp.tapeConfig.size(); j++)
02302                 leftBound--;
02303         temp = getNextChunk(machine,
02304                                                 leftBound,
02305                                                 rightBound,
02306                                                 thirdRightBound,
02307                                                 step_counter,
02308                                                 transition_limit,
02309                                                 false,                          //stop at left
02310                                                 false,                          //stop at right
02311                                                 true,                           //inclusive left
02312                                                 true,                           //inclusive right
02313                                                 false,                          //push left
02314                                                 true);                          //push right
02315         if(temp.isEmpty()) return false;
02316         n = machine.get_current_state();
02317         N.fillTape(temp, 0, Zp.tapeConfig.size()-1);
02318         Vpppp.fillTape(temp, Zp.tapeConfig.size(), temp.tapeConfig.size()-1);
02319 
02320         //std::cout << "here6" << std::endl;
02321 
02322         //--------------------------------------------------------------------------
02323         //NVn''''0* -> oN'V'''''0*
02324         leftBound = machine.access_tape_read_write().currentLocation();
02325         rightBound = machine.access_tape_read_write().currentLocation();
02326         for(int j = 0; j < Vpppp.tapeConfig.size() + N.tapeConfig.size(); j++)
02327                 leftBound--;
02328         temp = getNextChunk(machine,
02329                                                 leftBound,
02330                                                 rightBound,
02331                                                 thirdRightBound,
02332                                                 step_counter,
02333                                                 transition_limit,
02334                                                 true,                           //stop at left
02335                                                 false,                          //stop at right
02336                                                 false,                          //inclusive left
02337                                                 true,                           //inclusive right
02338                                                 false,                          //push left
02339                                                 false);                         //push right
02340         if(temp.isEmpty()) return false;
02341         o = machine.get_current_state();
02342         Np.fillTape(temp, 0, N.tapeConfig.size()-1);
02343         Vppppp.fillTape(temp, N.tapeConfig.size(), temp.tapeConfig.size()-1);
02344 
02345         //std::cout << "here7" << std::endl;
02346 
02347         //0*Uo''N' ->  U'''Jp'
02348         leftBound = machine.access_tape_read_write().currentLocation();
02349         rightBound = machine.access_tape_read_write().currentLocation();
02350         for(int j = 0; j < Np.tapeConfig.size()+1; j++)
02351                 rightBound++;
02352         temp = getNextChunkUnevenCheck(machine,
02353                                                 thirdLeftBound,
02354                                                 leftBound,
02355                                                 rightBound,
02356                                                 thirdRightBound,
02357                                                 step_counter,
02358                                                 transition_limit,
02359                                                 false,                          //stop at left
02360                                                 true,                           //stop at right
02361                                                 true,                           //inclusive left
02362                                                 false,                          //inclusive right
02363                                                 true,                           //push left
02364                                                 false);                         //push right
02365         if(temp.isEmpty()) return false;
02366         Uppp.fillTape(temp, 0, temp.tapeConfig.size()-Np.tapeConfig.size()-1);
02367         Jp.fillTape(temp, temp.tapeConfig.size()-Np.tapeConfig.size(), temp.tapeConfig.size()-1);
02368         p = machine.get_current_state();
02369 
02370         //std::cout << "here8" << std::endl;
02371 
02372         //J'pV''''' -> KVs''''''
02373         leftBound = machine.access_tape_read_write().currentLocation();
02374         rightBound = machine.access_tape_read_write().currentLocation();
02375         for(int j = 0; j < Jp.tapeConfig.size(); j++)
02376                 leftBound--;
02377         temp = getNextChunk(machine,
02378                                                 leftBound,
02379                                                 rightBound,
02380                                                 fourthRightBound,
02381                                                 step_counter,
02382                                                 transition_limit,
02383                                                 false,                          //stop at left
02384                                                 false,                          //stop at right
02385                                                 true,                           //inclusive left
02386                                                 true,                           //inclusive right
02387                                                 false,                          //push left
02388                                                 true);                          //push right
02389         if(temp.isEmpty()) return false;
02390         K.fillTape(temp, 0, Np.tapeConfig.size()-1);
02391         Vpppppp.fillTape(temp, Np.tapeConfig.size(), temp.tapeConfig.size()-1);
02392         if(machine.get_current_state() != s)
02393                 return false;
02394 
02395         /*std::cout << "here9" << std::endl;
02396 
02397         tapeChunk<d_type> one, two, three, four, five, six;
02398         one = U+V;
02399         two = U+X+V;
02400         three = Up+Z+Vpp;
02401         four = Upp+N+Vpppp;
02402         five = Uppp+K+Vpppppp;
02403         six = U+X+X+V;
02404         one.print();
02405         two.print();
02406         three.print();
02407         four.print();
02408         five.print();
02409         six.print();
02410         std::cout << "U      : ";
02411         U.print();
02412         std::cout << "Up     : ";
02413         Up.print();
02414         std::cout << "Upp    : ";
02415         Upp.print();
02416         std::cout << "Uppp   : ";
02417         Uppp.print();
02418         std::cout << "V      : ";
02419         V.print();
02420         std::cout << "Vp     : ";
02421         Vp.print();
02422         std::cout << "Vpp    : ";
02423         Vpp.print();
02424         std::cout << "Vppp   : ";
02425         Vppp.print();
02426         std::cout << "Vpppp  : ";
02427         Vpppp.print();
02428         std::cout << "Vppppp : ";
02429         Vppppp.print();
02430         std::cout << "Vpppppp: ";
02431         Vpppppp.print();
02432         std::cout << "X    : ";
02433         X.print();
02434         std::cout << "K    : ";
02435         K.print();*/
02436 
02437         if(Uppp + K + Vpppppp != U + X + X + V)
02438                 return false;
02439 
02440         //std::cout << "here7" << std::endl;
02441 
02442         //-----------------------------------------------------------------
02443         //XVs0* -> qX'V'0*
02444         leftBound = machine.access_tape_read_write().currentLocation();
02445         rightBound = machine.access_tape_read_write().currentLocation();
02446         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
02447                 leftBound--;
02448         temp = getNextChunk(machine,
02449                                                 leftBound,
02450                                                 rightBound,
02451                                                 secondRightBound,
02452                                                 step_counter,
02453                                                 transition_limit,
02454                                                 true,                           //stop at left
02455                                                 false,                          //stop at right
02456                                                 false,                          //inclusive left
02457                                                 true,                           //inclusive right
02458                                                 false,                          //push left
02459                                                 false);                         //push right
02460         if(temp.isEmpty()) return false;
02461         if(temp != Xp + Vp || machine.get_current_state() != q)
02462                 return false;
02463 
02464         //std::cout << "here10" << std::endl;
02465 
02466         //XqX' -> qX'Y
02467         leftBound = machine.access_tape_read_write().currentLocation();
02468         rightBound = machine.access_tape_read_write().currentLocation();
02469         for(int j = 0; j < X.tapeConfig.size(); j++)
02470                 leftBound--;
02471         for(int j = 0; j < Xp.tapeConfig.size(); j++)
02472                 rightBound++;
02473         temp = getNextChunk(machine,
02474                                                 leftBound,
02475                                                 rightBound,
02476                                                 secondRightBound,
02477                                                 step_counter,
02478                                                 transition_limit,
02479                                                 true,                           //stop at left
02480                                                 false,                          //stop at right
02481                                                 false,                          //inclusive left
02482                                                 true,                           //inclusive right
02483                                                 false,                          //push left
02484                                                 false);                         //push right
02485         if(temp.isEmpty()) return false;
02486         Y.fillTape(temp, Xp.tapeConfig.size(), temp.tapeConfig.size()-1);
02487         if(temp != Xp+Y || machine.get_current_state() != q)
02488                 return false;
02489 
02490         //std::cout << "here11" << std::endl;
02491 
02492         //0*UqX' -> 0*U'Y'r
02493         leftBound = machine.access_tape_read_write().currentLocation();
02494         rightBound = machine.access_tape_read_write().currentLocation();
02495         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
02496                 rightBound++;
02497         temp = getNextChunkUnevenCheck(machine,
02498                                                 fourthLeftBound,
02499                                                 leftBound,
02500                                                 rightBound,
02501                                                 secondRightBound,
02502                                                 step_counter,
02503                                                 transition_limit,
02504                                                 false,                          //stop at left
02505                                                 true,                           //stop at right
02506                                                 true,                           //inclusive left
02507                                                 false,                          //inclusive right
02508                                                 true,                           //push left
02509                                                 false);                         //push right
02510         if(temp.isEmpty()) return false;
02511         if(temp != Up+Yp || machine.get_current_state() != r)
02512                 return false;
02513 
02514         //std::cout << "here12" << std::endl;
02515 
02516         //Y'rY -> ZY'r
02517         leftBound = machine.access_tape_read_write().currentLocation();
02518         rightBound = machine.access_tape_read_write().currentLocation();
02519         for(int j = 0; j < Yp.tapeConfig.size(); j++)
02520                 leftBound--;
02521         for(int j = 0; j < Y.tapeConfig.size(); j++)
02522                 rightBound++;
02523         temp = getNextChunk(machine,
02524                                                 leftBound,
02525                                                 rightBound,
02526                                                 secondRightBound,
02527                                                 step_counter,
02528                                                 transition_limit,
02529                                                 false,                          //stop at left
02530                                                 true,                           //stop at right
02531                                                 true,                           //inclusive left
02532                                                 false,                          //inclusive right
02533                                                 false,                          //push left
02534                                                 false);                         //push right
02535         if(temp.isEmpty()) return false;
02536         if(temp != Z+Yp || machine.get_current_state() != r)
02537                 return false;
02538 
02539         //std::cout << "here13" << std::endl;
02540 
02541         //Y'rV' -> ZVt''
02542         leftBound = machine.access_tape_read_write().currentLocation();
02543         rightBound = machine.access_tape_read_write().currentLocation();
02544         for(int j = 0; j < Yp.tapeConfig.size(); j++)
02545                 leftBound--;
02546         temp = getNextChunk(machine,
02547                                                 leftBound,
02548                                                 rightBound,
02549                                                 fifthRightBound,
02550                                                 step_counter,
02551                                                 transition_limit,
02552                                                 false,                          //stop at left
02553                                                 false,                          //stop at right
02554                                                 true,                           //inclusive left
02555                                                 true,                           //inclusive right
02556                                                 false,                          //push left
02557                                                 true);                          //push right
02558         if(temp.isEmpty()) return false;
02559         if(temp != Z+Vpp || machine.get_current_state() != t)
02560                 return false;
02561 
02562         //std::cout << "here14" << std::endl;
02563 
02564         //---------------------------------------------------------------------------
02565         //ZVt''0* -> uZ'V'''0*
02566         leftBound = machine.access_tape_read_write().currentLocation();
02567         rightBound = machine.access_tape_read_write().currentLocation();
02568         for(int j = 0; j < Vpp.tapeConfig.size() + Z.tapeConfig.size(); j++)
02569                 leftBound--;
02570         temp = getNextChunk(machine,
02571                                                 leftBound,
02572                                                 rightBound,
02573                                                 secondRightBound,
02574                                                 step_counter,
02575                                                 transition_limit,
02576                                                 true,                           //stop at left
02577                                                 false,                          //stop at right
02578                                                 false,                          //inclusive left
02579                                                 true,                           //inclusive right
02580                                                 false,                          //push left
02581                                                 false);                         //push right
02582         if(temp.isEmpty()) return false;
02583         if(temp != Zp+Vppp || machine.get_current_state() != u)
02584                 return false;
02585 
02586         //std::cout << "here15" << std::endl;
02587 
02588         //ZuZ' -> uZ'M
02589         leftBound = machine.access_tape_read_write().currentLocation();
02590         rightBound = machine.access_tape_read_write().currentLocation();
02591         for(int j = 0; j < Z.tapeConfig.size(); j++)
02592                 leftBound--;
02593         for(int j = 0; j < Zp.tapeConfig.size(); j++)
02594                 rightBound++;
02595         temp = getNextChunk(machine,
02596                                                 leftBound,
02597                                                 rightBound,
02598                                                 secondRightBound,
02599                                                 step_counter,
02600                                                 transition_limit,
02601                                                 true,                           //stop at left
02602                                                 false,                          //stop at right
02603                                                 false,                          //inclusive left
02604                                                 true,                           //inclusive right
02605                                                 false,                          //push left
02606                                                 false);                         //push right
02607         if(temp.isEmpty()) return false;
02608         M.fillTape(temp, Zp.tapeConfig.size(), temp.tapeConfig.size()-1);
02609         if(temp != Zp+M || machine.get_current_state() != u)
02610                 return false;
02611 
02612         //std::cout << "here16" << std::endl;
02613 
02614         //0*Uu'Z' ->  U''Mv'
02615         leftBound = machine.access_tape_read_write().currentLocation();
02616         rightBound = machine.access_tape_read_write().currentLocation();
02617         for(int j = 0; j < Zp.tapeConfig.size()+1; j++)
02618                 rightBound++;
02619         temp = getNextChunkUnevenCheck(machine,
02620                                                 fifthLeftBound,
02621                                                 leftBound,
02622                                                 rightBound,
02623                                                 secondRightBound,
02624                                                 step_counter,
02625                                                 transition_limit,
02626                                                 false,                          //stop at left
02627                                                 true,                           //stop at right
02628                                                 true,                           //inclusive left
02629                                                 false,                          //inclusive right
02630                                                 true,                           //push left
02631                                                 false);                         //push right
02632         if(temp.isEmpty()) return false;
02633         if(temp != Upp+Mp || machine.get_current_state() != v)
02634                 return false;
02635 
02636         //std::cout << "here17" << std::endl;
02637 
02638         //M'vM -> NM'v
02639         leftBound = machine.access_tape_read_write().currentLocation();
02640         rightBound = machine.access_tape_read_write().currentLocation();
02641         for(int j = 0; j < Mp.tapeConfig.size(); j++)
02642                 leftBound--;
02643         for(int j = 0; j < M.tapeConfig.size(); j++)
02644                 rightBound++;
02645         temp = getNextChunk(machine,
02646                                                 leftBound,
02647                                                 rightBound,
02648                                                 secondRightBound,
02649                                                 step_counter,
02650                                                 transition_limit,
02651                                                 false,                          //stop at left
02652                                                 true,                           //stop at right
02653                                                 true,                           //inclusive left
02654                                                 false,                          //inclusive right
02655                                                 false,                          //push left
02656                                                 false);                         //push right
02657         if(temp.isEmpty()) return false;
02658         if(temp != N+Mp || machine.get_current_state() != v)
02659                 return false;
02660 
02661         //std::cout << "here18" << std::endl;
02662 
02663         //M'vV''' -> NVn''''
02664         leftBound = machine.access_tape_read_write().currentLocation();
02665         rightBound = machine.access_tape_read_write().currentLocation();
02666         for(int j = 0; j < Mp.tapeConfig.size(); j++)
02667                 leftBound--;
02668         temp = getNextChunk(machine,
02669                                                 leftBound,
02670                                                 rightBound,
02671                                                 sixthRightBound,
02672                                                 step_counter,
02673                                                 transition_limit,
02674                                                 false,                          //stop at left
02675                                                 false,                          //stop at right
02676                                                 true,                           //inclusive left
02677                                                 true,                           //inclusive right
02678                                                 false,                          //push left
02679                                                 true);                          //push right
02680         if(temp.isEmpty()) return false;
02681         if(temp != N+Vpppp || machine.get_current_state() != n)
02682                 return false;
02683 
02684         //std::cout << "here19" << std::endl;
02685 
02686         //---------------------------------------------------------------------------
02687         //NVn''''0* -> oN'V'''''0*
02688         leftBound = machine.access_tape_read_write().currentLocation();
02689         rightBound = machine.access_tape_read_write().currentLocation();
02690         for(int j = 0; j < Vpppp.tapeConfig.size() + N.tapeConfig.size(); j++)
02691                 leftBound--;
02692         temp = getNextChunk(machine,
02693                                                 leftBound,
02694                                                 rightBound,
02695                                                 secondRightBound,
02696                                                 step_counter,
02697                                                 transition_limit,
02698                                                 true,                           //stop at left
02699                                                 false,                          //stop at right
02700                                                 false,                          //inclusive left
02701                                                 true,                           //inclusive right
02702                                                 false,                          //push left
02703                                                 false);                         //push right
02704         if(temp.isEmpty()) return false;
02705         if(temp != Np+Vppppp || machine.get_current_state() != o)
02706                 return false;
02707 
02708         //std::cout << "here20" << std::endl;
02709 
02710         //NoN' -> oN'J
02711         leftBound = machine.access_tape_read_write().currentLocation();
02712         rightBound = machine.access_tape_read_write().currentLocation();
02713         for(int j = 0; j < N.tapeConfig.size(); j++)
02714                 leftBound--;
02715         for(int j = 0; j < Np.tapeConfig.size(); j++)
02716                 rightBound++;
02717         temp = getNextChunk(machine,
02718                                                 leftBound,
02719                                                 rightBound,
02720                                                 secondRightBound,
02721                                                 step_counter,
02722                                                 transition_limit,
02723                                                 true,                           //stop at left
02724                                                 false,                          //stop at right
02725                                                 false,                          //inclusive left
02726                                                 true,                           //inclusive right
02727                                                 false,                          //push left
02728                                                 false);                         //push right
02729         if(temp.isEmpty()) return false;
02730         J.fillTape(temp, Np.tapeConfig.size(), temp.tapeConfig.size()-1);
02731         if(temp != Np+J || machine.get_current_state() != o)
02732                 return false;
02733 
02734         //std::cout << "here21" << std::endl;
02735 
02736         //0*Uo''N' ->  U'''Jp'
02737         leftBound = machine.access_tape_read_write().currentLocation();
02738         rightBound = machine.access_tape_read_write().currentLocation();
02739         for(int j = 0; j < Np.tapeConfig.size()+1; j++)
02740                 rightBound++;
02741         temp = getNextChunkUnevenCheck(machine,
02742                                                 sixthLeftBound,
02743                                                 leftBound,
02744                                                 rightBound,
02745                                                 secondRightBound,
02746                                                 step_counter,
02747                                                 transition_limit,
02748                                                 false,                          //stop at left
02749                                                 true,                           //stop at right
02750                                                 true,                           //inclusive left
02751                                                 false,                          //inclusive right
02752                                                 true,                           //push left
02753                                                 false);                         //push right
02754         if(temp.isEmpty()) return false;
02755         if(temp != Uppp+Jp || machine.get_current_state() != p)
02756                 return false;
02757 
02758         //std::cout << "here22" << std::endl;
02759 
02760         //J'pJ -> KJ'p
02761         leftBound = machine.access_tape_read_write().currentLocation();
02762         rightBound = machine.access_tape_read_write().currentLocation();
02763         for(int j = 0; j < Jp.tapeConfig.size(); j++)
02764                 leftBound--;
02765         for(int j = 0; j < J.tapeConfig.size(); j++)
02766                 rightBound++;
02767         temp = getNextChunk(machine,
02768                                                 leftBound,
02769                                                 rightBound,
02770                                                 secondRightBound,
02771                                                 step_counter,
02772                                                 transition_limit,
02773                                                 false,                          //stop at left
02774                                                 true,                           //stop at right
02775                                                 true,                           //inclusive left
02776                                                 false,                          //inclusive right
02777                                                 false,                          //push left
02778                                                 false);                         //push right
02779         if(temp.isEmpty()) return false;
02780         if(temp != K+Jp || machine.get_current_state() != p)
02781                 return false;
02782 
02783         //std::cout << "here23" << std::endl;
02784 
02785         //J'pV''''' -> KVs''''''
02786         leftBound = machine.access_tape_read_write().currentLocation();
02787         rightBound = machine.access_tape_read_write().currentLocation();
02788         for(int j = 0; j < Jp.tapeConfig.size(); j++)
02789                 leftBound--;
02790         temp = getNextChunk(machine,
02791                                                 leftBound,
02792                                                 rightBound,
02793                                                 seventhRightBound,
02794                                                 step_counter,
02795                                                 transition_limit,
02796                                                 false,                          //stop at left
02797                                                 false,                          //stop at right
02798                                                 true,                           //inclusive left
02799                                                 true,                           //inclusive right
02800                                                 false,                          //push left
02801                                                 true);                          //push right
02802         if(temp.isEmpty()) return false;
02803         if(temp != K+Vpppppp || machine.get_current_state() != s)
02804                 return false;
02805 
02806         //std::cout << "here24" << std::endl;
02807 
02808         if(Uppp + K + K + Vpppppp != U + X + X + X + V)
02809                 return false;
02810         return true;
02811 }
02812 
02813 bool checkTripleSweepChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
02814 {
02815         machine.resetMachine();
02816         unsigned int step_counter = 0;
02817 
02818         std::list<d_type>::iterator leftBound = machine.access_tape_read_write().currentLocation();
02819         std::list<d_type>::iterator rightBound = machine.access_tape_read_write().currentLocation();
02820 
02821         std::list<d_type>::iterator firstLeftBoundPt, secondLeftBoundPt, thirdLeftBoundPt, fourthLeftBoundPt, fifthLeftBoundPt, sixthLeftBoundPt;
02822 
02823         //run for a bit to establish sweeping motion
02824         for(step_counter = 0; step_counter < transition_limit &&
02825                                                   step_counter < 150; step_counter++)
02826         {
02827                 if(step_counter == 50)
02828                 {
02829                         leftBound = machine.access_tape_read_write().currentLocation();
02830                         rightBound = machine.access_tape_read_write().currentLocation();
02831                 }
02832                 if(step_counter >= 50)
02833                 {
02834                         if(machine.access_tape_read_write().currentLocation() == rightBound)
02835                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
02836                                 {
02837                                         machine.access_tape_read_write().checkIteratorRight(rightBound);
02838                                         rightBound++;
02839                                 }
02840                         if(machine.access_tape_read_write().currentLocation() == leftBound)
02841                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
02842                                 {
02843                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
02844                                         leftBound--;
02845                                 }
02846                 }
02847                 if(machine.run_one()==turing_machine<d_type>::halt)
02848                         return false;
02849 
02850         }
02851 
02852         //get the step counters of the left and right bounds
02853         unsigned int firstRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02854         if(firstRightBound == 0)
02855                 return false;
02856 
02857         unsigned int secondRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02858         if(secondRightBound == 0)
02859                 return false;
02860 
02861         unsigned int thirdRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02862         if(thirdRightBound == 0)
02863                 return false;
02864 
02865         unsigned int fourthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02866         if(fourthRightBound == 0)
02867                 return false;
02868 
02869         unsigned int fifthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02870         if(fifthRightBound == 0)
02871                 return false;
02872 
02873         unsigned int sixthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02874         if(sixthRightBound == 0)
02875                 return false;
02876 
02877         unsigned int seventhRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02878         if(seventhRightBound == 0)
02879                 return false;
02880 
02881         unsigned int eighthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02882         if(eighthRightBound == 0)
02883                 return false;
02884 
02885         unsigned int ninthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02886         if(ninthRightBound == 0)
02887                 return false;
02888 
02889         unsigned int tenthRightBound = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
02890         if(tenthRightBound == 0)
02891                 return false;
02892 
02893         //reset the machine and use step counters to get tape configuration at each point
02894         machine.resetMachine();
02895         tapeChunk<d_type> beforeSweep, afterSweep;
02896 
02897         std::vector<state<d_type> >::size_type stateS;
02898 
02899         leftBound = machine.access_tape_read_write().currentLocation();
02900         for(unsigned int j = 0; j <= tenthRightBound; j++)
02901         {
02902                 if(j < 50)
02903                         machine.run_one();
02904                 if(j == 50)
02905                         leftBound = machine.access_tape_read_write().currentLocation();
02906                 if(j >= 50)
02907                 {
02908                         if(machine.access_tape_read_write().currentLocation() == leftBound)
02909                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
02910                                 {
02911                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
02912                                         leftBound--;
02913                                 }
02914                         machine.run_one();
02915 
02916                         if(j == firstRightBound)
02917                         {
02918                                 rightBound = machine.access_tape_read_write().currentLocation();
02919                                 beforeSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
02920                                 stateS = machine.get_current_state();
02921                         }
02922                         else if(j == fourthRightBound)
02923                         {
02924                                 rightBound = machine.access_tape_read_write().currentLocation();
02925                                 afterSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
02926                                 if(machine.get_current_state() != stateS)
02927                                         return false;
02928                         }
02929                         else if(j == fifthRightBound)
02930                                 firstLeftBoundPt = leftBound;
02931                         else if(j == sixthRightBound)
02932                                 secondLeftBoundPt = leftBound;
02933                         else if(j == seventhRightBound)
02934                                 thirdLeftBoundPt = leftBound;
02935                         else if(j == eighthRightBound)
02936                                 fourthLeftBoundPt = leftBound;
02937                         else if(j == ninthRightBound)
02938                                 fifthLeftBoundPt = leftBound;
02939                         else if(j == tenthRightBound)
02940                                 sixthLeftBoundPt = leftBound;
02941                 }
02942         }
02943 
02944 
02945         tapeChunk<d_type> chunkX, chunkU, chunkV;
02946         if(!findMidSection(beforeSweep, afterSweep, chunkX, chunkU, chunkV))
02947                 return false;
02948         /*chunkU.print();
02949         chunkX.print();
02950         chunkV.print();*/
02951         if(!checkTripleSweepChristmasTreeGrammar(machine,
02952                                                 fourthRightBound,
02953                                                 fifthRightBound,
02954                                                 sixthRightBound,
02955                                                 seventhRightBound,
02956                                                 eighthRightBound,
02957                                                 ninthRightBound,
02958                                                 tenthRightBound,
02959                                                 firstLeftBoundPt,
02960                                                 secondLeftBoundPt,
02961                                                 thirdLeftBoundPt,
02962                                                 fourthLeftBoundPt,
02963                                                 fifthLeftBoundPt,
02964                                                 sixthLeftBoundPt,
02965                                                 transition_limit,
02966                                                 chunkU,
02967                                                 chunkX,
02968                                                 chunkV,
02969                                                 stateS))
02970                 return false;
02971         return true;
02972 }
02973 
02974 bool tripleSweepChristmasTree(turing_machine<d_type> &machine, unsigned int transition_limit)
02975 {
02976         if(checkTripleSweepChristmasTree(machine, transition_limit))
02977                 return true;
02978         else
02979         {
02980                 turing_machine<d_type> reverse = machine.reverseMachine();
02981                 if(checkTripleSweepChristmasTree(reverse, transition_limit))
02982                         return true;
02983         }
02984         return false;
02985 }
02986 
02987 //end tripleSweepChristmasTree routines
02988 
02989 //begin counter routines
02990 
03002 unsigned int getNextBlankLocation(turing_machine<d_type> &machine,
03003                                         std::list<d_type>::iterator &rightBound,
03004                                         std::list<d_type>::iterator &leftBound,
03005                                         unsigned int &step_counter,
03006                                         unsigned int transition_limit)
03007 {
03008         bool rightBoundPushed = false;
03009         unsigned int rightBoundStepCounter = 0;
03010 
03011         for(step_counter; step_counter < transition_limit; step_counter++)
03012         {
03013                 if(machine.access_tape_read_write().currentLocation() == rightBound)
03014                 {
03015                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
03016                         {
03017                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
03018                                 rightBound++;
03019                                 if(!rightBoundPushed)
03020                                 {
03021                                         rightBoundStepCounter = step_counter;
03022                                         rightBoundPushed = true;
03023                                 }
03024                         }
03025                 }
03026                 if(machine.access_tape_read_write().currentLocation() == leftBound)
03027                 {
03028                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
03029                                 return 0;
03030                         if(rightBoundPushed)
03031                                 return rightBoundStepCounter;
03032                 }
03033                 if(machine.run_one()==turing_machine<d_type>::halt)
03034                         return 0;
03035         }
03036         return 0;
03037 }
03038 
03053 bool checkCounterConversion(turing_machine<d_type> &machine,
03054                                 tapeChunk<d_type> originalTape,
03055                                 tapeChunk<d_type> desiredTape,
03056                                 int originalReadHead,
03057                                 int desiredReadHead,
03058                                 std::vector<state<d_type> >::size_type originalState,
03059                                 std::vector<state<d_type> >::size_type desiredState)
03060 {
03061         std::list<d_type>::iterator leftBound;
03062         std::list<d_type>::iterator rightBound;
03063         std::list<d_type>::iterator desiredLocation;
03064         machine.rigMachine(originalTape.tapeConfig, originalReadHead, desiredReadHead, originalState, leftBound, rightBound, desiredLocation);
03065 
03066         for(int j = 0; j < 100; j++)
03067         {
03068                 if(machine.access_tape_read_write().currentLocation() == leftBound)
03069                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
03070                         {
03071                                 machine.run_one();
03072                                 break;
03073                         }
03074                 if(machine.access_tape_read_write().currentLocation() == rightBound)
03075                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
03076                         {
03077                                 machine.run_one();
03078                                 break;
03079                         }
03080                 machine.run_one();
03081         }
03082 
03083         tapeChunk<d_type> result;
03084         result.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
03085 
03086         /*result.print();
03087         desiredTape.print();
03088         std::cout << machine.get_current_state() << " " << desiredState << std::endl;
03089         std::cout << std::endl;*/
03090 
03091         if(machine.access_tape_read_write().currentLocation() == desiredLocation &&
03092            machine.get_current_state() == desiredState &&
03093            result == desiredTape)
03094                 return true;
03095         return false;
03096 }
03097 
03114 bool checkFinalCounterGrammar(turing_machine<d_type> &machine,
03115                                 tapeChunk<d_type> splitLeftSide,
03116                                 tapeChunk<d_type> splitRightSide,
03117                                 tapeChunk<d_type> zeroCell,
03118                                 tapeChunk<d_type> oneCell,
03119                                 tapeChunk<d_type> onePrimeCell,
03120                                 tapeChunk<d_type> endCell,
03121                                 int cellSize,
03122                                 std::vector<state<d_type> >::size_type stateC,
03123                                 std::vector<state<d_type> >::size_type stateR)
03124 {
03125         int index = 0;
03126         while(index < splitLeftSide.length())
03127         {
03128                 if(index == 0)
03129                 {
03130                         if(!splitLeftSide.compareNextChunk(endCell, index))
03131                                 return false;
03132                 }
03133                 else
03134                 {
03135                         if(!splitLeftSide.compareNextChunk(onePrimeCell, index))
03136                                 return false;
03137                 }
03138         }
03139         index = 0;
03140         while(index < splitRightSide.length())
03141         {
03142                 if(index + cellSize >= splitRightSide.length())
03143                 {
03144                         if(!splitRightSide.compareNextChunk(oneCell, index))
03145                                 return false;
03146                 }
03147                 else
03148                 {
03149                         if(!splitRightSide.compareNextChunk(zeroCell, index))
03150                                 return false;
03151                 }
03152         }
03153 
03154         //std::cout << "here" << std::endl;
03155 
03156         tapeChunk<d_type> onePrimeZero, zeroOne;
03157         onePrimeZero = onePrimeCell + zeroCell;
03158         zeroOne = zeroCell + oneCell;
03159 
03160         tapeChunk<d_type> onePrimeOne, zeroZero;
03161         onePrimeOne = onePrimeCell + oneCell;
03162         zeroZero = zeroCell + zeroCell;
03163 
03164         if(checkCounterConversion(machine, onePrimeCell, zeroCell, cellSize - 1, -1, stateR, stateR) &&
03165            checkCounterConversion(machine, endCell, endCell, endCell.length()-1, endCell.length(), stateR, stateC) &&
03166            checkCounterConversion(machine, onePrimeOne, zeroZero, onePrimeCell.length(), onePrimeOne.length(), stateC, stateC) &&
03167            checkCounterConversion(machine, onePrimeZero, zeroOne, onePrimeCell.length(), -1, stateC, stateR))
03168            //checkCounterConversion(machine, oneCell, onePrimeCell, 0, cellSize, stateC, stateC) &&
03169            //checkCounterConversion(machine, zeroCell, oneCell, 0, -1, stateC, stateR))
03170                 return true;
03171         return false;
03172 }
03173 
03190 bool checkCounterRun(turing_machine<d_type> &machine,
03191                         unsigned int transition_limit,
03192                         unsigned int firstBlankLocationCounter,
03193                         tapeChunk<d_type> firstBlankLocation,
03194                         tapeChunk<d_type> zeroCell,
03195                         tapeChunk<d_type> oneCell,
03196                         tapeChunk<d_type> onePrimeCell,
03197                         tapeChunk<d_type> endCell,
03198                         unsigned int cellSize,
03199                         std::vector<state<d_type> >::size_type stateC)
03200 {
03201         int currentLocation = firstBlankLocation.length() - 1, onePrimeCount = 0;
03202         tapeChunk<d_type> temp(onePrimeCell);
03203 
03204         /*std::cout << "test : ";
03205         firstBlankLocation.print();*/
03206 
03207         while(currentLocation - cellSize >= endCell.length() && temp == onePrimeCell)
03208         {
03209                 temp.emptyTape();
03210                 temp.fillTape(firstBlankLocation, currentLocation - cellSize, currentLocation - 1);
03211                 onePrimeCount++;
03212                 currentLocation -= cellSize;
03213         }
03214 
03215         //std::cout << "oneprimes : " << onePrimeCount << std::endl;
03216 
03217         unsigned int snipLocation = cellSize*(onePrimeCount/2) + 1;
03218 
03219         machine.resetMachine();
03220         unsigned int step_counter = 0;
03221         std::list<d_type>::iterator leftBound = machine.access_tape_read_write().currentLocation();
03222         std::list<d_type>::iterator rightBound = machine.access_tape_read_write().currentLocation();
03223         std::list<d_type>::iterator snipSpot;
03224         tapeChunk<d_type> leftSide, rightSide;
03225         std::vector<state<d_type> >::size_type stateR;
03226 
03227 
03228         for(step_counter; step_counter <= firstBlankLocationCounter; step_counter++)
03229         {
03230                 if(machine.access_tape_read_write().currentLocation() == leftBound)
03231                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
03232                         {
03233                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
03234                                 leftBound--;
03235                         }
03236                 if(machine.access_tape_read_write().currentLocation() == rightBound)
03237                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
03238                         {
03239                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
03240                                 rightBound++;
03241                         }
03242                 machine.run_one();
03243         }
03244         snipSpot = rightBound;
03245         for(unsigned int j = 0; j < snipLocation; j++)
03246                 snipSpot--;
03247 
03248         while(step_counter < transition_limit && machine.access_tape_read_write().currentLocation() != snipSpot)
03249         {
03250                 if(machine.access_tape_read_write().currentLocation() == leftBound)
03251                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
03252                         {
03253                                 return false;
03254                         }
03255                 if(machine.access_tape_read_write().currentLocation() == rightBound)
03256                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
03257                         {
03258                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
03259                                 rightBound++;
03260                         }
03261                 machine.run_one();
03262                 step_counter++;
03263         }
03264 
03265         if(step_counter == transition_limit)
03266                 return false;
03267 
03268         stateR = machine.get_current_state();
03269         leftSide.fillTape(machine.access_tape_read_write(), leftBound, snipSpot);
03270         rightSide.fillTape(machine.access_tape_read_write(), ++snipSpot, rightBound);
03271 
03272         /*std::cout << std::endl;
03273         leftSide.print();
03274         rightSide.print();*/
03275 
03276         if(!checkFinalCounterGrammar(machine,
03277                                         leftSide,
03278                                         rightSide,
03279                                         zeroCell,
03280                                         oneCell,
03281                                         onePrimeCell,
03282                                         endCell,
03283                                         cellSize,
03284                                         stateC,
03285                                         stateR))
03286                 return false;
03287 
03288         return true;
03289 }
03290 
03302 bool extractCounterElements(turing_machine<d_type> &machine,
03303                                 unsigned int transition_limit,
03304                                 unsigned int firstBlankLocationCounter,
03305                                 tapeChunk<d_type> firstBlankLocation,
03306                                 tapeChunk<d_type> secondBlankLocation,
03307                                 tapeChunk<d_type> middleLocation,
03308                                 std::vector<state<d_type> >::size_type stateC)
03309 {
03310         int cellSize = secondBlankLocation.length() - firstBlankLocation.length();
03311         if(cellSize < 0 || middleLocation.length() < 2*cellSize + 1 || firstBlankLocation.length() < cellSize + 1)
03312                 return false;
03313 
03314         tapeChunk<d_type> zeroCell, oneCell, onePrimeCell, endCell;
03315         tapeChunk<d_type> temp;
03316 
03317         oneCell.fillTape(middleLocation, middleLocation.length() - cellSize, middleLocation.length() - 1);
03318         zeroCell.fillTape(middleLocation, middleLocation.length() - 2*cellSize, middleLocation.length() - cellSize - 1);
03319         onePrimeCell.fillTape(firstBlankLocation, firstBlankLocation.length() - cellSize - 1, firstBlankLocation.length() - 2);
03320 
03321         int currentLocation = firstBlankLocation.length() - cellSize - 1;
03322         do
03323         {
03324                 temp.emptyTape();
03325                 temp.fillTape(firstBlankLocation, currentLocation - cellSize, currentLocation - 1);
03326                 currentLocation -= cellSize;
03327         }while(currentLocation - cellSize > 0 && temp == onePrimeCell);
03328 
03329         endCell.fillTape(firstBlankLocation, 0, currentLocation + cellSize + 1);
03330 
03331         /*zeroCell.print();
03332         oneCell.print();
03333         onePrimeCell.print();
03334         endCell.print();*/
03335 
03336         if(!checkCounterRun(machine,
03337                                 transition_limit,
03338                                 firstBlankLocationCounter,
03339                                 firstBlankLocation,
03340                                 zeroCell,
03341                                 oneCell,
03342                                 onePrimeCell,
03343                                 endCell,
03344                                 cellSize,
03345                                 stateC))
03346                 return false;
03347 
03348         return true;
03349 }
03350 
03357 bool testCounter(turing_machine<d_type> &machine, unsigned int transition_limit)
03358 {
03359         machine.resetMachine();
03360         unsigned int step_counter = 0;
03361 
03362         std::list<d_type>::iterator leftBound = machine.access_tape_read_write().currentLocation();
03363         std::list<d_type>::iterator rightBound = machine.access_tape_read_write().currentLocation();
03364 
03365         //run for a bit to account for startup
03366         for(step_counter = 0; step_counter < transition_limit &&
03367                                                   step_counter < 750; step_counter++)
03368         {
03369                 if(step_counter == 50)
03370                 {
03371                         leftBound = machine.access_tape_read_write().currentLocation();
03372                         rightBound = machine.access_tape_read_write().currentLocation();
03373                 }
03374                 if(step_counter >= 50)
03375                 {
03376                         if(machine.access_tape_read_write().currentLocation() == rightBound)
03377                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
03378                                 {
03379                                         machine.access_tape_read_write().checkIteratorRight(rightBound);
03380                                         rightBound++;
03381                                 }
03382                         if(machine.access_tape_read_write().currentLocation() == leftBound)
03383                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
03384                                 {
03385                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
03386                                         leftBound--;
03387                                 }
03388                 }
03389                 if(machine.run_one()==turing_machine<d_type>::halt)
03390                         return false;
03391         }
03392 
03393         unsigned int firstBlankLocation = getNextBlankLocation(machine, rightBound, leftBound, step_counter, transition_limit);
03394         if(firstBlankLocation == 0)
03395                 return false;
03396         unsigned int firstLeftBound = step_counter - 1;
03397 
03398 
03399         unsigned int secondBlankLocation = getNextBlankLocation(machine, rightBound, leftBound, step_counter, transition_limit);
03400         if(secondBlankLocation == 0)
03401                 return false;
03402 
03403         machine.resetMachine();
03404         tapeChunk<d_type> firstTape, middleTape, secondTape;
03405         std::vector<state<d_type> >::size_type stateC, stateM;
03406 
03407 
03408         for(unsigned int j = 0; j <= secondBlankLocation; j++)
03409         {
03410                 if(machine.access_tape_read_write().currentLocation() == leftBound)
03411                         if(machine.nextMove() ==  infinite_tape<d_type>::left)
03412                         {
03413                                 machine.access_tape_read_write().checkIteratorLeft(leftBound);
03414                                 leftBound--;
03415                         }
03416                 if(machine.access_tape_read_write().currentLocation() == rightBound)
03417                         if(machine.nextMove() ==  infinite_tape<d_type>::right)
03418                         {
03419                                 machine.access_tape_read_write().checkIteratorRight(rightBound);
03420                                 rightBound++;
03421                         }
03422                 machine.run_one();
03423 
03424                 if(j == firstBlankLocation)
03425                 {
03426                         rightBound = machine.access_tape_read_write().currentLocation();
03427                         firstTape.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
03428                         stateC = machine.get_current_state();
03429                 }
03430                 else if(j == firstLeftBound)
03431                 {
03432                         middleTape.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
03433                         stateM = machine.get_current_state();
03434                 }
03435                 else if(j == secondBlankLocation)
03436                 {
03437                         rightBound = machine.access_tape_read_write().currentLocation();
03438                         secondTape.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
03439                         if(stateC != machine.get_current_state())
03440                                 return false;
03441                 }
03442         }
03443 
03444         //std::cout << firstBlankLocation << std::endl;
03445         //std::cout << secondBlankLocation << std::endl;
03446 
03447         /*firstTape.print();
03448         middleTape.print();
03449         secondTape.print();
03450         std::cout << std::endl;*/
03451 
03452         if(!extractCounterElements(machine, transition_limit, firstBlankLocation, firstTape, secondTape, middleTape, stateC))
03453                 return false;
03454 
03455         return true;
03456 }
03457 
03464 bool counter(turing_machine<d_type> &machine, unsigned int transition_limit)
03465 {
03466         if(testCounter(machine, transition_limit))
03467                 return true;
03468         else
03469         {
03470                 turing_machine<d_type> reverse = machine.reverseMachine();
03471                 if(testCounter(reverse, transition_limit))
03472                         return true;
03473         }
03474         return false;
03475 }
03476 
03477 //end counter routines
03478 
03479 //general multisweep tree routines
03480 
03492 bool establishSweep(turing_machine<d_type> &machine,
03493                         std::list<d_type>::iterator &leftBound,
03494                         std::list<d_type>::iterator &rightBound,
03495                         unsigned int &step_counter,
03496                         unsigned int step_limit,
03497                         unsigned int transition_limit)
03498 {
03499         for(step_counter; step_counter < transition_limit &&
03500                                                   step_counter < step_limit; step_counter++)
03501         {
03502                 if(step_counter == 50)
03503                 {
03504                         leftBound = machine.access_tape_read_write().currentLocation();
03505                         rightBound = machine.access_tape_read_write().currentLocation();
03506                 }
03507                 if(step_counter >= 50)
03508                 {
03509                         if(machine.access_tape_read_write().currentLocation() == rightBound)
03510                                 if(machine.nextMove() ==  infinite_tape<d_type>::right)
03511                                 {
03512                                         machine.access_tape_read_write().checkIteratorRight(rightBound);
03513                                         rightBound++;
03514                                 }
03515                         if(machine.access_tape_read_write().currentLocation() == leftBound)
03516                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
03517                                 {
03518                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
03519                                         leftBound--;
03520                                 }
03521                 }
03522                 if(machine.run_one()==turing_machine<d_type>::halt)
03523                         return false;
03524 
03525         }
03526         return true;
03527 }
03528 
03547 bool checkMultiSweepFirstPass(turing_machine<d_type> &machine,
03548                                 unsigned int currentSweep,
03549                                 unsigned int totalSweeps,
03550                                 std::vector<unsigned int> rightBoundCounters,
03551                                 std::vector< std::list<d_type>::iterator > leftBoundPointers,
03552                                 unsigned int transition_limit,
03553                                 unsigned int &step_counter,
03554                                 tapeChunk<d_type> &U,
03555                                 tapeChunk<d_type> &X,
03556                                 tapeChunk<d_type> &V,
03557                                 std::vector<state<d_type> >::size_type s,
03558                                 std::vector<sweepStats<d_type> > &statistics)
03559 {
03560         tapeChunk<d_type> Xp, Y, Yp, Z, Vp, Vpp, Up, temp;
03561         std::vector<state<d_type> >::size_type q, r, t;
03562         sweepStats<d_type> myStats;
03563 
03564         statistics.push_back(myStats);
03565 
03566         if(currentSweep == 1)
03567                 for(step_counter; step_counter <= rightBoundCounters[totalSweeps]; step_counter++)
03568                         machine.run_one();
03569 
03570         std::list<d_type>::iterator leftBound, rightBound;
03571 
03572         //XVs0* -> qX'V'0*
03573         leftBound = machine.access_tape_read_write().currentLocation();
03574         rightBound = machine.access_tape_read_write().currentLocation();
03575         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
03576                 leftBound--;
03577         temp = getNextChunk(machine,
03578                                                 leftBound,
03579                                                 rightBound,
03580                                                 0,
03581                                                 step_counter,
03582                                                 transition_limit,
03583                                                 true,                           //stop at left
03584                                                 false,                          //stop at right
03585                                                 false,                          //inclusive left
03586                                                 true,                           //inclusive right
03587                                                 false,                          //push left
03588                                                 false);                         //push right
03589         if(temp.isEmpty()) return false;
03590         q = machine.get_current_state();
03591         Xp.fillTape(temp, 0, X.tapeConfig.size()-1);
03592         Vp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
03593 
03594         //0*UqX' -> 0*U'Y'r
03595         leftBound = machine.access_tape_read_write().currentLocation();
03596         rightBound = machine.access_tape_read_write().currentLocation();
03597         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
03598                 rightBound++;
03599         temp = getNextChunkUnevenCheck(machine,
03600                                                 leftBoundPointers[currentSweep-1],
03601                                                 leftBound,
03602                                                 rightBound,
03603                                                 0,
03604                                                 step_counter,
03605                                                 transition_limit,
03606                                                 false,                          //stop at left
03607                                                 true,                           //stop at right
03608                                                 true,                           //inclusive left
03609                                                 false,                          //inclusive right
03610                                                 true,                           //push left
03611                                                 false);                         //push right
03612         if(temp.isEmpty()) return false;
03613         r = machine.get_current_state();
03614         Up.fillTape(temp, 0, temp.tapeConfig.size()-X.tapeConfig.size()-1);
03615         Yp.fillTape(temp, temp.tapeConfig.size()-X.tapeConfig.size(), temp.tapeConfig.size()-1);
03616 
03617         //Y'rV' -> ZVs''
03618         leftBound = machine.access_tape_read_write().currentLocation();
03619         rightBound = machine.access_tape_read_write().currentLocation();
03620         for(int j = 0; j < Yp.tapeConfig.size(); j++)
03621                 leftBound--;
03622         temp = getNextChunk(machine,
03623                                                 leftBound,
03624                                                 rightBound,
03625                                                 rightBoundCounters[currentSweep+totalSweeps],
03626                                                 step_counter,
03627                                                 transition_limit,
03628                                                 false,                          //stop at left
03629                                                 false,                          //stop at right
03630                                                 true,                           //inclusive left
03631                                                 true,                           //inclusive right
03632                                                 false,                          //push left
03633                                                 true);                          //push right
03634         if(temp.isEmpty()) return false;
03635         t = machine.get_current_state();
03636         Z.fillTape(temp, 0, X.tapeConfig.size()-1);
03637         Vpp.fillTape(temp, X.tapeConfig.size(), temp.tapeConfig.size()-1);
03638 
03639         statistics[statistics.size()-1].fill(U, V, X, Xp, Y, Yp, Z, Vp, Vpp, Up, q, r, t);
03640 
03641         if(currentSweep == totalSweeps)
03642         {
03643                 if(t != s || Up + Z + Vpp != statistics[0].U + statistics[0].X + statistics[0].X + statistics[0].V)
03644                         return false;
03645         }
03646         else
03647         {
03648                 return checkMultiSweepFirstPass(machine, currentSweep+1, totalSweeps, rightBoundCounters, leftBoundPointers,
03649                                                 transition_limit, step_counter, Up, Z, Vpp, s, statistics);
03650         }
03651         return true;
03652 }
03653 
03669 bool checkMultiSweepSecondPass(turing_machine<d_type> &machine,
03670                                         unsigned int currentSweep,
03671                                         unsigned int totalSweeps,
03672                                         std::vector<unsigned int> rightBoundCounters,
03673                                         std::vector< std::list<d_type>::iterator > leftBoundPointers,
03674                                         unsigned int transition_limit,
03675                                         unsigned int &step_counter,
03676                                         std::vector<state<d_type> >::size_type s,
03677                                         std::vector<sweepStats<d_type> > &statistics)
03678 {
03679         tapeChunk<d_type> U, V, X, Xp, Y, Yp, Z, Vp, Vpp, Up, temp;
03680         std::vector<state<d_type> >::size_type q, r, t;
03681 
03682         statistics[currentSweep-1].populate(U, V, X, Xp, Y, Yp, Z, Vp, Vpp, Up, q, r, t);
03683 
03684         std::list<d_type>::iterator leftBound, rightBound;
03685 
03686         //XVs0* -> qX'V'0*
03687         leftBound = machine.access_tape_read_write().currentLocation();
03688         rightBound = machine.access_tape_read_write().currentLocation();
03689         for(int j = 0; j < V.tapeConfig.size() + X.tapeConfig.size(); j++)
03690                 leftBound--;
03691         temp = getNextChunk(machine,
03692                                                 leftBound,
03693                                                 rightBound,
03694                                                 0,
03695                                                 step_counter,
03696                                                 transition_limit,
03697                                                 true,                           //stop at left
03698                                                 false,                          //stop at right
03699                                                 false,                          //inclusive left
03700                                                 true,                           //inclusive right
03701                                                 false,                          //push left
03702                                                 false);                         //push right
03703         if(temp.isEmpty()) return false;
03704         if(temp != Xp + Vp || machine.get_current_state() != q)
03705                 return false;
03706 
03707         //XqX' -> qX'Y
03708         leftBound = machine.access_tape_read_write().currentLocation();
03709         rightBound = machine.access_tape_read_write().currentLocation();
03710         for(int j = 0; j < X.tapeConfig.size(); j++)
03711                 leftBound--;
03712         for(int j = 0; j < Xp.tapeConfig.size(); j++)
03713                 rightBound++;
03714         temp = getNextChunk(machine,
03715                                                 leftBound,
03716                                                 rightBound,
03717                                                 0,
03718                                                 step_counter,
03719                                                 transition_limit,
03720                                                 true,                           //stop at left
03721                                                 false,                          //stop at right
03722                                                 false,                          //inclusive left
03723                                                 true,                           //inclusive right
03724                                                 false,                          //push left
03725                                                 false);                         //push right
03726         if(temp.isEmpty()) return false;
03727         Y.fillTape(temp, Xp.tapeConfig.size(), temp.tapeConfig.size()-1);
03728         statistics[currentSweep-1].Y.fillTape(temp, Xp.tapeConfig.size(), temp.tapeConfig.size()-1);
03729         if(temp != Xp+Y || machine.get_current_state() != q)
03730                 return false;
03731 
03732         //0*UqX' -> 0*U'Y'r
03733         leftBound = machine.access_tape_read_write().currentLocation();
03734         rightBound = machine.access_tape_read_write().currentLocation();
03735         for(int j = 0; j < Xp.tapeConfig.size()+1; j++)
03736                 rightBound++;
03737         temp = getNextChunkUnevenCheck(machine,
03738                                                 leftBoundPointers[currentSweep+totalSweeps-1],
03739                                                 leftBound,
03740                                                 rightBound,
03741                                                 0,
03742                                                 step_counter,
03743                                                 transition_limit,
03744                                                 false,                          //stop at left
03745                                                 true,                           //stop at right
03746                                                 true,                           //inclusive left
03747                                                 false,                          //inclusive right
03748                                                 true,                           //push left
03749                                                 false);                         //push right
03750         if(temp.isEmpty()) return false;
03751         if(temp != Up+Yp || machine.get_current_state() != r)
03752                 return false;
03753 
03754         //Y'rY -> ZY'r
03755         leftBound = machine.access_tape_read_write().currentLocation();
03756         rightBound = machine.access_tape_read_write().currentLocation();
03757         for(int j = 0; j < Yp.tapeConfig.size(); j++)
03758                 leftBound--;
03759         for(int j = 0; j < Y.tapeConfig.size(); j++)
03760                 rightBound++;
03761         temp = getNextChunk(machine,
03762                                                 leftBound,
03763                                                 rightBound,
03764                                                 0,
03765                                                 step_counter,
03766                                                 transition_limit,
03767                                                 false,                          //stop at left
03768                                                 true,                           //stop at right
03769                                                 true,                           //inclusive left
03770                                                 false,                          //inclusive right
03771                                                 false,                          //push left
03772                                                 false);                         //push right
03773         if(temp.isEmpty()) return false;
03774         if(temp != Z+Yp || machine.get_current_state() != r)
03775                 return false;
03776 
03777         //Y'rV' -> ZVs''
03778         leftBound = machine.access_tape_read_write().currentLocation();
03779         rightBound = machine.access_tape_read_write().currentLocation();
03780         for(int j = 0; j < Yp.tapeConfig.size(); j++)
03781                 leftBound--;
03782         temp = getNextChunk(machine,
03783                                                 leftBound,
03784                                                 rightBound,
03785                                                 rightBoundCounters[currentSweep+2*totalSweeps],
03786                                                 step_counter,
03787                                                 transition_limit,
03788                                                 false,                          //stop at left
03789                                                 false,                          //stop at right
03790                                                 true,                           //inclusive left
03791                                                 true,                           //inclusive right
03792                                                 false,                          //push left
03793                                                 true);                          //push right
03794         if(temp.isEmpty()) return false;
03795         if(temp != Z+Vpp || machine.get_current_state() != t)
03796                 return false;
03797 
03798         /*std::cout << "Up : "; Up.print();
03799         std::cout << "Z  : "; Z.print();
03800         std::cout << "Vpp: "; Vpp.print();
03801         std::cout << "U :  "; U.print();
03802         std::cout << "X :  "; X.print();
03803         std::cout << "V :  "; V.print();*/
03804 
03805         if(currentSweep == totalSweeps)
03806         {
03807                 if(t != s || Up + Z + Z + Vpp != statistics[0].U + statistics[0].X + statistics[0].X + statistics[0].X + statistics[0].V)
03808                         return false;
03809         }
03810         else
03811         {
03812                 return checkMultiSweepSecondPass(machine, currentSweep+1, totalSweeps, rightBoundCounters, leftBoundPointers,
03813                                                 transition_limit, step_counter, s, statistics);
03814         }
03815         return true;
03816 }
03817 
03833 bool checkMultiSweepChristmasTreeGrammar(turing_machine<d_type> &machine,
03834                                         unsigned int totalSweeps,
03835                                         std::vector<unsigned int> rightBoundCounters,
03836                                         std::vector< std::list<d_type>::iterator > leftBoundPointers,
03837                                         unsigned int transition_limit,
03838                                         tapeChunk<d_type> &U,
03839                                         tapeChunk<d_type> &X,
03840                                         tapeChunk<d_type> &V,
03841                                         std::vector<state<d_type> >::size_type s)
03842 {
03843         machine.resetMachine();
03844 
03845         unsigned int step_counter = 0;
03846         std::vector<sweepStats<d_type> > statistics(0);
03847 
03848         if(checkMultiSweepFirstPass(machine, 1, totalSweeps, rightBoundCounters, leftBoundPointers, transition_limit, step_counter, U, X, V, s, statistics) &&
03849                 checkMultiSweepSecondPass(machine, 1, totalSweeps, rightBoundCounters, leftBoundPointers, transition_limit, step_counter, s, statistics))
03850                 return true;
03851         return false;
03852 }
03853 
03863 bool checkMultiSweepChristmasTree(turing_machine<d_type> &machine, unsigned int sweeps, unsigned int transition_limit)
03864 {
03865         machine.resetMachine();
03866         unsigned int step_counter = 0;
03867 
03868         std::list<d_type>::iterator leftBound;
03869         std::list<d_type>::iterator rightBound;
03870 
03871         std::vector<unsigned int> rightBoundCounters;
03872         std::vector< std::list<d_type>::iterator > leftBoundPointers;
03873 
03874         //run for a bit to establish sweeping motion
03875         if(!establishSweep(machine, leftBound, rightBound, step_counter, 150, transition_limit))
03876                 return false;
03877 
03878         //get step counters for each right bound
03879         unsigned int temp;
03880         for(int j = 0; j < 3*sweeps + 1; j++)
03881         {
03882                 temp = getNextRightBound(machine, rightBound, leftBound, step_counter, transition_limit);
03883                 if(temp == 0)
03884                         return false;
03885                 rightBoundCounters.push_back(temp);
03886         }
03887 
03888         //reset the machine and use step counters to get tape configuration at each point
03889         machine.resetMachine();
03890         tapeChunk<d_type> beforeSweep, afterSweep;
03891 
03892         std::vector<state<d_type> >::size_type stateS;
03893 
03894         for(unsigned int j = 0; j <= rightBoundCounters[rightBoundCounters.size()-1]; j++)
03895         {
03896                 if(j < 50)
03897                         machine.run_one();
03898                 if(j == 50)
03899                         leftBound = machine.access_tape_read_write().currentLocation();
03900                 if(j >= 50)
03901                 {
03902                         if(machine.access_tape_read_write().currentLocation() == leftBound)
03903                                 if(machine.nextMove() ==  infinite_tape<d_type>::left)
03904                                 {
03905                                         machine.access_tape_read_write().checkIteratorLeft(leftBound);
03906                                         leftBound--;
03907                                 }
03908                         machine.run_one();
03909 
03910                         if(j == rightBoundCounters[0])
03911                         {
03912                                 rightBound = machine.access_tape_read_write().currentLocation();
03913                                 beforeSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
03914                                 stateS = machine.get_current_state();
03915                         }
03916 
03917                         else if(j == rightBoundCounters[sweeps])
03918                         {
03919                                 rightBound = machine.access_tape_read_write().currentLocation();
03920                                 afterSweep.fillTape(machine.access_tape_read_write(), leftBound, rightBound);
03921                                 if(machine.get_current_state() != stateS)
03922                                         return false;
03923                         }
03924 
03925                         else
03926                         {
03927                                 for(int i = sweeps+1; i < rightBoundCounters.size(); i++)
03928                                         if(j == rightBoundCounters[i])
03929                                                 leftBoundPointers.push_back(leftBound);
03930                         }
03931                 }
03932         }
03933 
03934 
03935         tapeChunk<d_type> chunkX, chunkU, chunkV;
03936 
03937         if(!findMidSection(beforeSweep, afterSweep, chunkX, chunkU, chunkV))
03938                 return false;
03939 
03940         /*chunkX.print();
03941         chunkU.print();
03942         chunkV.print();*/
03943 
03944         if(!checkMultiSweepChristmasTreeGrammar(machine, sweeps, rightBoundCounters, leftBoundPointers, transition_limit, chunkU, chunkX, chunkV, stateS))
03945                 return false;
03946 
03947 
03948 
03949         return true;
03950 }
03951 
03961 bool multiSweepChristmasTree(turing_machine<d_type> &machine, unsigned int sweeps, unsigned int transition_limit)
03962 {
03963         if(checkMultiSweepChristmasTree(machine, sweeps, transition_limit))
03964                 return true;
03965         else
03966         {
03967                 turing_machine<d_type> reverse = machine.reverseMachine();
03968                 if(checkMultiSweepChristmasTree(reverse, sweeps, transition_limit))
03969                         return true;
03970         }
03971         return false;
03972 }
03973 
03974 //end general multisweep tree routines
03975 
03976 #endif

Generated on Thu Nov 20 00:17:32 2003 for BusyBeaver by doxygen 1.3.3