00001 #ifndef kellett_non_halt_detection_header
00002 #define kellett_non_halt_detection_header
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
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,
00574 false,
00575 false,
00576 true,
00577 false,
00578 false);
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
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,
00596 true,
00597 true,
00598 false,
00599 true,
00600 false);
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
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,
00618 false,
00619 true,
00620 true,
00621 false,
00622 true);
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
00630
00631
00632
00633
00634
00635
00636 if(Up + Z + Vpp != U + X + X + V)
00637 return false;
00638
00639
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,
00651 false,
00652 false,
00653 true,
00654 false,
00655 false);
00656 if(temp.isEmpty()) return false;
00657 if(temp != Xp + Vp || machine.get_current_state() != q)
00658 return false;
00659
00660
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,
00674 false,
00675 false,
00676 true,
00677 false,
00678 false);
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
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,
00696 true,
00697 true,
00698 false,
00699 true,
00700 false);
00701 if(temp.isEmpty()) return false;
00702 if(temp != Up+Yp || machine.get_current_state() != r)
00703 return false;
00704
00705
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,
00719 true,
00720 true,
00721 false,
00722 false,
00723 false);
00724 if(temp.isEmpty()) return false;
00725 if(temp != Z+Yp || machine.get_current_state() != r)
00726 return false;
00727
00728
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,
00740 false,
00741 true,
00742 true,
00743 false,
00744 true);
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
00762
00763
00764 int lastPush = 0;
00765
00766
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
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
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
00858
00859
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
00883
00884
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
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,
01031 false,
01032 false,
01033 true,
01034 false,
01035 false);
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
01042
01043
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,
01056 true,
01057 true,
01058 false,
01059 true,
01060 false);
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
01067
01068
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,
01080 false,
01081 true,
01082 true,
01083 false,
01084 true);
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
01091
01092
01093
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,
01105 false,
01106 false,
01107 true,
01108 false,
01109 false);
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
01116
01117
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,
01130 true,
01131 true,
01132 false,
01133 true,
01134 false);
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
01141
01142
01143
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,
01155 false,
01156 true,
01157 true,
01158 false,
01159 true);
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
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 if(Upp + N + Vpppp != U + X + X + V)
01201 return false;
01202
01203
01204
01205
01206
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,
01218 false,
01219 false,
01220 true,
01221 false,
01222 false);
01223 if(temp.isEmpty()) return false;
01224 if(temp != Xp + Vp || machine.get_current_state() != q)
01225 return false;
01226
01227
01228
01229
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,
01243 false,
01244 false,
01245 true,
01246 false,
01247 false);
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
01254
01255
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,
01268 true,
01269 true,
01270 false,
01271 true,
01272 false);
01273 if(temp.isEmpty()) return false;
01274 if(temp != Up+Yp || machine.get_current_state() != r)
01275 return false;
01276
01277
01278
01279
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,
01293 true,
01294 true,
01295 false,
01296 false,
01297 false);
01298 if(temp.isEmpty()) return false;
01299 if(temp != Z+Yp || machine.get_current_state() != r)
01300 return false;
01301
01302
01303
01304
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,
01316 false,
01317 true,
01318 true,
01319 false,
01320 true);
01321 if(temp.isEmpty()) return false;
01322 if(temp != Z+Vpp || machine.get_current_state() != t)
01323 return false;
01324
01325
01326
01327
01328
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,
01340 false,
01341 false,
01342 true,
01343 false,
01344 false);
01345 if(temp.isEmpty()) return false;
01346 if(temp != Zp+Vppp || machine.get_current_state() != u)
01347 return false;
01348
01349
01350
01351
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,
01365 false,
01366 false,
01367 true,
01368 false,
01369 false);
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
01376
01377
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,
01390 true,
01391 true,
01392 false,
01393 true,
01394 false);
01395 if(temp.isEmpty()) return false;
01396 if(temp != Upp+Mp || machine.get_current_state() != v)
01397 return false;
01398
01399
01400
01401
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,
01415 true,
01416 true,
01417 false,
01418 false,
01419 false);
01420 if(temp.isEmpty()) return false;
01421 if(temp != N+Mp || machine.get_current_state() != v)
01422 return false;
01423
01424
01425
01426
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,
01438 false,
01439 true,
01440 true,
01441 false,
01442 true);
01443 if(temp.isEmpty()) return false;
01444 if(temp != N+Vpppp || machine.get_current_state() != s)
01445 return false;
01446
01447
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
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
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
01523
01524
01525
01526
01527
01528
01529
01530
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
01581
01582
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
01617
01618
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
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,
01674 false,
01675 false,
01676 true,
01677 false,
01678 false);
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
01685
01686
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,
01698 true,
01699 true,
01700 false,
01701 true,
01702 false);
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
01711
01712
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,
01724 false,
01725 true,
01726 true,
01727 false,
01728 true);
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
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 if(Up + Z + Vpp != U + X + X + V)
01746 return false;
01747
01748
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,
01760 false,
01761 false,
01762 true,
01763 false,
01764 false);
01765 if(temp.isEmpty()) return false;
01766 if(temp != Xp + Vp || machine.get_current_state() != q)
01767 return false;
01768
01769
01770
01771
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,
01785 false,
01786 false,
01787 true,
01788 false,
01789 false);
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
01796
01797
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,
01809 true,
01810 true,
01811 false,
01812 true,
01813 false);
01814 if(temp.isEmpty()) return false;
01815 if(temp != N+Up+Yp || machine.get_current_state() != r)
01816 return false;
01817
01818
01819
01820
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,
01834 true,
01835 true,
01836 false,
01837 false,
01838 false);
01839 if(temp.isEmpty()) return false;
01840 if(temp != Z+Yp || machine.get_current_state() != r)
01841 return false;
01842
01843
01844
01845
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,
01857 false,
01858 true,
01859 true,
01860 false,
01861 true);
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
01946
01947
01948 int lastPush = 0;
01949
01950
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
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
02001
02002
02003
02004
02005
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
02095
02096
02097
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
02140
02141
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
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,
02186 false,
02187 false,
02188 true,
02189 false,
02190 false);
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
02197
02198
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,
02211 true,
02212 true,
02213 false,
02214 true,
02215 false);
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
02222
02223
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,
02235 false,
02236 true,
02237 true,
02238 false,
02239 true);
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
02246
02247
02248
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,
02260 false,
02261 false,
02262 true,
02263 false,
02264 false);
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
02271
02272
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,
02285 true,
02286 true,
02287 false,
02288 true,
02289 false);
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
02296
02297
02298
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,
02310 false,
02311 true,
02312 true,
02313 false,
02314 true);
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
02321
02322
02323
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,
02335 false,
02336 false,
02337 true,
02338 false,
02339 false);
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
02346
02347
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,
02360 true,
02361 true,
02362 false,
02363 true,
02364 false);
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
02371
02372
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,
02384 false,
02385 true,
02386 true,
02387 false,
02388 true);
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
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437 if(Uppp + K + Vpppppp != U + X + X + V)
02438 return false;
02439
02440
02441
02442
02443
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,
02455 false,
02456 false,
02457 true,
02458 false,
02459 false);
02460 if(temp.isEmpty()) return false;
02461 if(temp != Xp + Vp || machine.get_current_state() != q)
02462 return false;
02463
02464
02465
02466
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,
02480 false,
02481 false,
02482 true,
02483 false,
02484 false);
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
02491
02492
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,
02505 true,
02506 true,
02507 false,
02508 true,
02509 false);
02510 if(temp.isEmpty()) return false;
02511 if(temp != Up+Yp || machine.get_current_state() != r)
02512 return false;
02513
02514
02515
02516
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,
02530 true,
02531 true,
02532 false,
02533 false,
02534 false);
02535 if(temp.isEmpty()) return false;
02536 if(temp != Z+Yp || machine.get_current_state() != r)
02537 return false;
02538
02539
02540
02541
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,
02553 false,
02554 true,
02555 true,
02556 false,
02557 true);
02558 if(temp.isEmpty()) return false;
02559 if(temp != Z+Vpp || machine.get_current_state() != t)
02560 return false;
02561
02562
02563
02564
02565
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,
02577 false,
02578 false,
02579 true,
02580 false,
02581 false);
02582 if(temp.isEmpty()) return false;
02583 if(temp != Zp+Vppp || machine.get_current_state() != u)
02584 return false;
02585
02586
02587
02588
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,
02602 false,
02603 false,
02604 true,
02605 false,
02606 false);
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
02613
02614
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,
02627 true,
02628 true,
02629 false,
02630 true,
02631 false);
02632 if(temp.isEmpty()) return false;
02633 if(temp != Upp+Mp || machine.get_current_state() != v)
02634 return false;
02635
02636
02637
02638
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,
02652 true,
02653 true,
02654 false,
02655 false,
02656 false);
02657 if(temp.isEmpty()) return false;
02658 if(temp != N+Mp || machine.get_current_state() != v)
02659 return false;
02660
02661
02662
02663
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,
02675 false,
02676 true,
02677 true,
02678 false,
02679 true);
02680 if(temp.isEmpty()) return false;
02681 if(temp != N+Vpppp || machine.get_current_state() != n)
02682 return false;
02683
02684
02685
02686
02687
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,
02699 false,
02700 false,
02701 true,
02702 false,
02703 false);
02704 if(temp.isEmpty()) return false;
02705 if(temp != Np+Vppppp || machine.get_current_state() != o)
02706 return false;
02707
02708
02709
02710
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,
02724 false,
02725 false,
02726 true,
02727 false,
02728 false);
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
02735
02736
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,
02749 true,
02750 true,
02751 false,
02752 true,
02753 false);
02754 if(temp.isEmpty()) return false;
02755 if(temp != Uppp+Jp || machine.get_current_state() != p)
02756 return false;
02757
02758
02759
02760
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,
02774 true,
02775 true,
02776 false,
02777 false,
02778 false);
02779 if(temp.isEmpty()) return false;
02780 if(temp != K+Jp || machine.get_current_state() != p)
02781 return false;
02782
02783
02784
02785
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,
02797 false,
02798 true,
02799 true,
02800 false,
02801 true);
02802 if(temp.isEmpty()) return false;
02803 if(temp != K+Vpppppp || machine.get_current_state() != s)
02804 return false;
02805
02806
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
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
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
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
02949
02950
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
02988
02989
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
03087
03088
03089
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
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
03169
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
03205
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
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
03273
03274
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
03332
03333
03334
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
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
03445
03446
03447
03448
03449
03450
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
03478
03479
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
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,
03584 false,
03585 false,
03586 true,
03587 false,
03588 false);
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
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,
03607 true,
03608 true,
03609 false,
03610 true,
03611 false);
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
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,
03629 false,
03630 true,
03631 true,
03632 false,
03633 true);
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
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,
03698 false,
03699 false,
03700 true,
03701 false,
03702 false);
03703 if(temp.isEmpty()) return false;
03704 if(temp != Xp + Vp || machine.get_current_state() != q)
03705 return false;
03706
03707
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,
03721 false,
03722 false,
03723 true,
03724 false,
03725 false);
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
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,
03745 true,
03746 true,
03747 false,
03748 true,
03749 false);
03750 if(temp.isEmpty()) return false;
03751 if(temp != Up+Yp || machine.get_current_state() != r)
03752 return false;
03753
03754
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,
03768 true,
03769 true,
03770 false,
03771 false,
03772 false);
03773 if(temp.isEmpty()) return false;
03774 if(temp != Z+Yp || machine.get_current_state() != r)
03775 return false;
03776
03777
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,
03789 false,
03790 true,
03791 true,
03792 false,
03793 true);
03794 if(temp.isEmpty()) return false;
03795 if(temp != Z+Vpp || machine.get_current_state() != t)
03796 return false;
03797
03798
03799
03800
03801
03802
03803
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
03875 if(!establishSweep(machine, leftBound, rightBound, step_counter, 150, transition_limit))
03876 return false;
03877
03878
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
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
03941
03942
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
03975
03976 #endif