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

infinite_tape.hpp

00001 #ifndef ross_infinite_tape_header
00002 #define ross_infinite_tape_header
00003 
00004 /*Authored 2002    by  Kyle  Ross,  Undergraduate  Philosophy   Thesis
00005 (Advisor: Professor Bram van Heuveln)
00006 
00007 Modified 2003    by Owen Kellett, Undergraduate Research
00008 (Advisor: Professor Bram van Heuveln)
00009 
00010 This  file is part of the   "Generic Turing Machine Implementation for
00011 Use in the Exploration of the Busy Beaver Problem".
00012 
00013 The "Generic Turing Machine Implementation for  Use in the Exploration
00014 of the Busy Beaver Problem" is free  software; you can redistribute it
00015 and/or modify it under the terms of the  GNU General Public License as
00016 published   by the Free Software Foundation;   either version 2 of the
00017 License, or (at your option) any later version.
00018 
00019 This programme is distributed in the hope that it  will be useful, but
00020 WITHOUT    ANY  WARRANTY;  without   even  the    implied warranty  of
00021 MERCHANTABILITY or FITNESS FOR  A  PARTICULAR  PURPOSE.  See  the  GNU
00022 General Public License for more details.
00023 
00024 You should have received   a copy of  the  GNU General Public  License
00025 along  with  this   programme; if  not,  write   to the Free  Software
00026 Foundation, Inc., 59  Temple Place, Suite  330, Boston, MA  02111-1307
00027 USA (or visit http://www.fsf.org/licenses/licenses.html)
00028 
00029 Created as part of the Busy Beaver Project:
00030 Bram van Heuveln <heuveb@rpi.edu>
00031 Boleshaw Szymanski <szymansk@cs.rpi.edu>
00032 Selmer Bringsjord <selmer@rpi.edu>
00033 Carlos Varela <cvarela@cs.rpi.edu>
00034 Owen Kellett <kelleo@rpi.edu>
00035 Shailesh Kelkar <kelkas@rpi.edu>
00036 Kyle Ross <rossk2@rpi.edu>
00037 Rensselaer Reasoning Group
00038 Department of Cognitive Science
00039 Department of Computer Science
00040 Rensselaer Polytechnic Institute
00041 Troy, New York 12180
00042 U.S.A.
00043 */
00044 //implements an infinite-length tape of an arbitrary alphabet to be used in a generalised turing machine implementation; assumes small-size alphabet (this could easily be expanded through a derived class)
00045 //enforcing of alphabet rules (i.e. which symbols belong to the alphabet, etc.) will be left to the finite-state automaton
00046 
00047 #include <iostream>
00048 #include <list>
00049 #include "debug.hpp"
00050 
00061 template <typename T>
00062 class infinite_tape
00063 {
00064 public:
00065         enum direction{left, right, do_nothing, halt_move};
00066 
00071         infinite_tape()
00072         :tape(start_size, 0), default_value(0), counter(0), non_blank_count(0)
00073         {
00074                 current=tape.begin();
00075                 for(typename std::list<T>::size_type i=start_size/2; i!=0; --i)
00076                 {
00077                         ++current;
00078                 }
00079                 cardinal=current;
00080                 #ifdef ross_debug_mode
00081                         std::cout<<"["<<this<<"]infinite-tape("<<0<<") constructed"<<std::endl;
00082                 #endif
00083         }
00084 
00085         //complexity: O(1)+overhead for construction incurred by the implementation (O(1) since start_size is constant)
00092         infinite_tape(T new_default_value)
00093         :tape(start_size, new_default_value), default_value(new_default_value), counter(0), non_blank_count(0)
00094         {
00095                 current=tape.begin();
00096                 for(typename std::list<T>::size_type i=start_size/2; i!=0; --i)
00097                 {
00098                         ++current;
00099                 }
00100                 cardinal=current;
00101                 #ifdef ross_debug_mode
00102                         std::cout<<"["<<this<<"]infinite-tape("<<default_value<<") constructed"<<std::endl;
00103                 #endif
00104         }
00105 
00106         //complexity: O(new_size)+overhead for construction incurred by the implementation
00114         infinite_tape(typename std::list<T>::size_type new_size, T new_default_value)
00115         :tape(new_size, new_default_value), default_value(new_default_value), counter(0), non_blank_count(0)
00116         {
00117                 current=tape.begin();
00118                 for(typename std::list<T>::size_type i=new_size/2; i!=0; --i)
00119                 {
00120                         ++current;
00121                 }
00122                 cardinal=current;
00123                 #ifdef ross_debug_mode
00124                         std::cout<<"["<<this<<"]infinite-tape("<<new_size<<", "<<default_value<<") constructed"<<std::endl;
00125                 #endif
00126         }
00127 
00128         //complexity: O(N) in the allocated size of hrs+overhead for construction incurred by the implementation
00136         infinite_tape(const infinite_tape<T> &rhs)
00137         :tape(rhs.tape), default_value(rhs.default_value), counter(0), non_blank_count(rhs.non_blank_count)
00138         {
00139                 current=tape.begin();
00140                 typename std::list<T>::const_iterator matcher=rhs.tape.begin();
00141                 while((matcher++)!=rhs.current)
00142                 {
00143                         ++current;
00144                 }
00145                 cardinal=current;
00146         }
00147 
00152         const infinite_tape<T>& operator=(const infinite_tape<T> &rhs)
00153         {
00154                 tape=rhs.tape;
00155                 current=cardinal=tape.begin();
00156                 typename std::list<T>::const_iterator temp_iter=rhs.tape.begin();
00157                 while(temp_iter!=rhs.current)
00158                 {
00159                         ++current;
00160                         ++temp_iter;
00161                 }
00162                 temp_iter=rhs.tape.begin();
00163                 while(temp_iter!=rhs.cardinal)
00164                 {
00165                         ++cardinal;
00166                         ++temp_iter;
00167                 }
00168                 counter=rhs.counter;
00169                 default_value=rhs.default_value;
00170                 non_blank_count=rhs.non_blank_count;
00171 
00172                 return *this;
00173         }
00174 
00179         ~infinite_tape()
00180         {
00181                 #ifdef ross_debug_mode
00182                         std::cout<<"["<<this<<"]infinite-tape destructed"<<std::endl;
00183                 #endif
00184         }
00185 
00191         T read() const
00192         {
00193                 return (*current);
00194         }
00195 
00200         void clear()
00201         {
00202                 *this=infinite_tape<T>(default_value);
00203         }
00204 
00211         void write(T to_write)
00212         {
00213                 //switching a blank to a non-blank increment non-blank count
00214                 if(*current==default_value && to_write!=default_value)
00215                 {
00216                         ++non_blank_count;
00217                 }
00218                 //switching a non-blank to a blank; decrement non-blank count
00219                 else if(*current!=default_value && to_write==default_value)
00220                 {
00221                         --non_blank_count;
00222                 }
00223                 (*current)=to_write;
00224         }
00225 
00235         void move(direction which)
00236         {
00237                 if(which==do_nothing)
00238                 {
00239                         return;
00240                 }
00241                 tape_check(which);
00242                 if(which==left)
00243                 {
00244                         #ifdef ross_debug_mode
00245                                 std::cout<<"["<<this<<"]moving left"<<std::endl;
00246                         #endif
00247                         --current;
00248                 }
00249                 else
00250                 {
00251                         #ifdef ross_debug_mode
00252                                 std::cout<<"["<<this<<"]moving right"<<std::endl;
00253                         #endif
00254                         ++current;
00255                 }
00256                 ++counter;
00257         }
00258 
00263         void reset_head()
00264         {
00265                 current=cardinal;
00266                 #ifdef ross_debug_mode
00267                         std::cout<<"["<<this<<"]resetting head to cardinal"<<std::endl;
00268                 #endif
00269         }
00270 
00276         bool is_blank() const
00277         {
00278                 return non_blank_count==0;
00279         }
00280 
00287         bool is_contiguous() const
00288         {
00289                 typename std::list<T>::const_iterator iter=tape.begin();
00290                 while(iter!=tape.end() && (*iter)==default_value)//recognises blanks at beginning of tape
00291                 {
00292                         ++iter;
00293                 }
00294                 if(iter==tape.end())//an empty tape is contiguous? not sure how this should be defined
00295                 {
00296                         return true;
00297                 }
00298                 while(iter!=tape.end() && (*iter)!=default_value)//recognises non-blanks after blanks-block
00299                 {
00300                         ++iter;
00301                 }
00302                 if(iter==tape.end())//blanks followed by symbols ... it's good
00303                 {
00304                         return true;
00305                 }
00306                 while(iter!=tape.end() && (*iter)==default_value)//recognises after symbols-block
00307                 {
00308                         ++iter;
00309                 }
00310                 return iter==tape.end();//if all symbols of the tape have been recognised then it meets the contiguous requirement
00311         }
00312 
00318         bool on_blank() const
00319         {
00320                 return (*current)==default_value;
00321         }
00322 
00330         bool symbols_to_direction(direction which) const
00331         {
00332                 if(which==do_nothing)//meaningless
00333                 {
00334                         return false;
00335                 }
00336                 if(which==left)
00337                 {
00338                         typename std::list<T>::const_reverse_iterator iter(current);
00339                         //no initial ++ because "the fundamental identity of reverse iterators is '&*(reverse_bidirectional_iterator(i)) == &*(i - 1)'" (quote from sgi-stl docs)
00340                         while(iter!=tape.rend() && (*iter)==default_value)//move left until symbol reached xor beginning of tape reached
00341                         {
00342                                 ++iter;
00343                         }
00344                         return iter!=tape.rend();//if it's not reached the beginning of the tape, there must have been a symbol to the left of the read-head
00345                 }
00346                 else
00347                 {
00348                         typename std::list<T>::const_iterator iter(current);
00349                         ++iter;//don't consider symbol under read-head
00350                         while(iter!=tape.end() && (*iter)==default_value)//move right until symbol reached xor end of tape reached
00351                         {
00352                                 ++iter;
00353                         }
00354                         return iter!=tape.end();//if it's not reached the end of the tape, there must have been a symbol to the right of the read-head
00355                 }
00356         }
00357 
00365         bool in_standard_position() const
00366         {
00367                 return (!on_blank() && is_contiguous() && (!symbols_to_direction(left) || !symbols_to_direction(right)));
00368         }
00369 
00376         typename std::list<T>::size_type count_occurrences(T to_count) const
00377         {
00378                 typename std::list<T>::size_type accumulate(0);
00379                 for(typename std::list<T>::const_iterator i=tape.begin(); i!=tape.end(); ++i)
00380                 {
00381                         if((*i)==to_count)
00382                         {
00383                                 ++accumulate;
00384                         }
00385                 }
00386                 #ifdef ross_debug_mode
00387                         if(to_count==default_value)
00388                         {
00389                                 std::cout<<"["<<this<<"]count-occurrences WARNING count may be inaccurate since default_value was parameter"<<std::endl;
00390                         }
00391                 #endif
00392                 return accumulate;
00393         }
00394 
00401         void show(std::ostream &out) const
00402         {
00403                 if(tape.begin()==tape.end())
00404                 {
00405                         out<<"< tape is empty >";
00406                 }
00407                 else
00408                 {
00409                         for(typename std::list<T>::const_iterator i=tape.begin(); i!=tape.end(); ++i)
00410                         {
00411                                 if(i==current)
00412                                 {
00413                                         out<<"->";
00414                                 }
00415                                 if(i==cardinal)
00416                                 {
00417                                         out<<"[";
00418                                 }
00419                                 out<<(*i);
00420                                 if(i==cardinal)
00421                                 {
00422                                         out<<"]";
00423                                 }
00424                                 if(i==current)
00425                                 {
00426                                         out<<"<-";
00427                                 }
00428                                 out<<' ';
00429                         }
00430                 }
00431         }
00432 
00439         template <typename delim_type1, typename delim_type2, typename delim_type3, typename delim_type4, typename delim_type5, typename delim_type6, typename delim_type7, typename delim_type8>
00440         void show(std::ostream &out, const delim_type1 &before_delim, const delim_type2 &between_delim, const delim_type3 &after_delim, const delim_type4 &before_cardinal, const delim_type5 &after_cardinal, const delim_type6 &before_head, const delim_type7 &after_head, const delim_type8 &blank_delim, bool extra_between_delims) const
00441         {
00442                 typename std::list<T>::size_type first_non_blank_index, last_non_blank_index, head_index, cardinal_index;
00443                 bool symbols_on_tape(false);
00444                 typename std::list<T>::const_iterator iter, first_non_blank, last_non_blank;
00445 
00446                 //figures out the relative positions of and establishes and iterator to the first and last non-blank symbols, the head, and the cardinal
00447                 typename std::list<T>::size_type index(0);
00448                 for(iter=tape.begin(); iter!=tape.end(); ++iter, ++index)
00449                 {
00450                         if(iter==current)
00451                         {
00452                                 head_index=index;
00453                         }
00454                         if(iter==cardinal)
00455                         {
00456                                 cardinal_index=index;
00457                         }
00458                         if((*iter)!=default_value)
00459                         {
00460                                 if(!symbols_on_tape)
00461                                 {
00462                                         first_non_blank=iter;
00463                                         first_non_blank_index=index;
00464                                         symbols_on_tape=true;
00465                                 }
00466                                 last_non_blank=iter;
00467                                 last_non_blank_index=index;
00468                         }
00469                 }
00470                 //displays output for debugging the generalised display function
00471                 #ifdef ross_debug_mode
00472                         #ifdef ross_debug_verbose
00473                                 {
00474                                         typename std::list<T>::size_type i(0);
00475                                         for(iter=tape.begin(); iter!=tape.end(); ++iter, ++i)
00476                                         {
00477                                                 if(i==head_index)
00478                                                 {
00479                                                         if(iter!=current)
00480                                                         {
00481                                                                 std::cout<<"oh, no, head's index is set improperly-E01"<<std::endl;
00482                                                                 return;
00483                                                         }
00484                                                         std::cout<<"<head>";
00485                                                 }
00486                                                 if(i==cardinal_index)
00487                                                 {
00488                                                         if(iter!=cardinal)
00489                                                         {
00490                                                                 std::cout<<"oh, no, current's index is set improperly-E02"<<std::endl;
00491                                                                 return;
00492                                                         }
00493                                                         std::cout<<"<cardinal>";
00494                                                 }
00495                                                 if(symbols_on_tape && i==first_non_blank_index)
00496                                                 {
00497                                                         if(iter!=first_non_blank)
00498                                                         {
00499                                                                 std::cout<<"oh, no, fnb index is set improperly-E03"<<std::endl;
00500                                                                 return;
00501                                                         }
00502                                                         std::cout<<"<fnb>";
00503                                                 }
00504                                                 if(symbols_on_tape && i==last_non_blank_index)
00505                                                 {
00506                                                         if(iter!=last_non_blank)
00507                                                         {
00508                                                                 std::cout<<"oh, no, lnb index is set improperly-E04"<<std::endl;
00509                                                                 return;
00510                                                         }
00511                                                         std::cout<<"<lnb>";
00512                                                 }
00513                                                 std::cout<<(*iter);
00514                                                 if(symbols_on_tape && i==last_non_blank_index)
00515                                                 {
00516                                                         std::cout<<"<\\lnb>";
00517                                                 }
00518                                                 if(symbols_on_tape && i==first_non_blank_index)
00519                                                 {
00520                                                         std::cout<<"<\\fnb>";
00521                                                 }
00522                                                 if(i==cardinal_index)
00523                                                 {
00524                                                         std::cout<<"<\\cardinal>";
00525                                                 }
00526                                                 if(i==head_index)
00527                                                 {
00528                                                         std::cout<<"<\\head>";
00529                                                 }
00530                                         }
00531                                         std::cout<<std::endl;
00532                                 }
00533                         #endif
00534                 #endif
00535 
00536                 //adjust indices so that [first_non_blank_index, last_non_blank_index] demarks the set of symbols to be printed as proper symbols
00537                 if(symbols_on_tape)
00538                 {
00539                         if(head_index<first_non_blank_index)
00540                         {
00541                                 first_non_blank_index=head_index;
00542                                 first_non_blank=current;
00543                         }
00544                         else if(head_index>last_non_blank_index)
00545                         {
00546                                 last_non_blank_index=head_index;
00547                                 last_non_blank=current;
00548                         }
00549                 }
00550                 //displays output for debugging the generalised display function
00551                 #ifdef ross_debug_mode
00552                         #ifdef ross_debug_verbose
00553                                 {
00554                                         typename std::list<T>::size_type i(0);
00555                                         for(iter=tape.begin(); iter!=tape.end(); ++iter, ++i)
00556                                         {
00557                                                 if(i==head_index)
00558                                                 {
00559                                                         if(iter!=current)
00560                                                         {
00561                                                                 std::cout<<"oh, no, head's index is set improperly-E01"<<std::endl;
00562                                                                 return;
00563                                                         }
00564                                                         std::cout<<"<head>";
00565                                                 }
00566                                                 if(i==cardinal_index)
00567                                                 {
00568                                                         if(iter!=cardinal)
00569                                                         {
00570                                                                 std::cout<<"oh, no, current's index is set improperly-E02"<<std::endl;
00571                                                                 return;
00572                                                         }
00573                                                         std::cout<<"<cardinal>";
00574                                                 }
00575                                                 if(symbols_on_tape && i==first_non_blank_index)
00576                                                 {
00577                                                         if(iter!=first_non_blank)
00578                                                         {
00579                                                                 std::cout<<"oh, no, fnb index is set improperly-E03"<<std::endl;
00580                                                                 return;
00581                                                         }
00582                                                         std::cout<<"<fnb>";
00583                                                 }
00584                                                 if(symbols_on_tape && i==last_non_blank_index)
00585                                                 {
00586                                                         if(iter!=last_non_blank)
00587                                                         {
00588                                                                 std::cout<<"oh, no, lnb index is set improperly-E04"<<std::endl;
00589                                                                 return;
00590                                                         }
00591                                                         std::cout<<"<lnb>";
00592                                                 }
00593                                                 std::cout<<(*iter);
00594                                                 if(symbols_on_tape && i==last_non_blank_index)
00595                                                 {
00596                                                         std::cout<<"<\\lnb>";
00597                                                 }
00598                                                 if(symbols_on_tape && i==first_non_blank_index)
00599                                                 {
00600                                                         std::cout<<"<\\fnb>";
00601                                                 }
00602                                                 if(i==cardinal_index)
00603                                                 {
00604                                                         std::cout<<"<\\cardinal>";
00605                                                 }
00606                                                 if(i==head_index)
00607                                                 {
00608                                                         std::cout<<"<\\head>";
00609                                                 }
00610                                         }
00611                                         std::cout<<std::endl;
00612                                 }
00613                         #endif
00614                 #endif
00615 
00616                 //performs the output operations ... very complicated in format, but well-defined
00617                 out<<before_delim;
00618 
00619                 if(!symbols_on_tape) //if tape is empty, treat as special case
00620                 {
00621                         if(current==cardinal) //current and cardinal are same, singleton output
00622                         {
00623                                 out<<before_cardinal<<before_head<<(*current)<<after_head<<after_cardinal;
00624                         }
00625                         else if(cardinal_index<head_index) //output elements [cardinal_index, head_index]
00626                         {
00627                                 out<<before_cardinal<<blank_delim<<after_cardinal; //output cardinal_index, leaving (cardinal_index, head_index]
00628                                 if(extra_between_delims)
00629                                 {
00630                                         out<<between_delim;
00631                                 }
00632                                 for(typename std::list<T>::size_type i=cardinal_index+1; i<head_index-1; ++i) //output [cardinal_index+1, head_index-1), leaving [head_index-1, head_index]
00633                                 {
00634                                         out<<blank_delim<<between_delim;
00635                                 }
00636                                 if(head_index-cardinal_index>1)
00637                                 {
00638                                         out<<blank_delim; //output head_index-1, leaving head_index
00639                                         if(extra_between_delims)
00640                                         {
00641                                                 out<<between_delim;
00642                                         }
00643                                 }
00644                                 out<<before_head<<(*current)<<after_head;
00645                         }
00646                         else //cardinal_index>head_index ... output elements [head_index, cardinal_index]
00647                         {
00648                                 out<<before_head<<(*current)<<after_head; //output head_index, leaving [head_index+1, cardinal_index]
00649                                 if(extra_between_delims)
00650                                 {
00651                                         out<<between_delim;
00652                                 }
00653                                 for(typename std::list<T>::size_type i=head_index+1; i<cardinal_index-1; ++i) //output [head_index+1, cardinal_index-1)
00654                                 {
00655                                         out<<blank_delim<<between_delim;
00656                                 }
00657                                 if(cardinal_index-head_index>1)
00658                                 {
00659                                         out<<blank_delim; //output cardinal_index-1, leaving cardinal_index
00660                                         if(extra_between_delims)
00661                                         {
00662                                                 out<<between_delim;
00663                                         }
00664                                 }
00665                                 out<<before_cardinal<<blank_delim<<after_cardinal;
00666                         }
00667                 }
00668                 else
00669                 {
00670                         if(first_non_blank_index<=cardinal_index && cardinal_index<=last_non_blank_index) //cardinal lies within [fnb, lnb] so don't worry about it
00671                         {
00672                                 typename std::list<T>::size_type i;
00673                                 for(iter=first_non_blank, i=first_non_blank_index; i<=last_non_blank_index; ++i, ++iter) //outputs [fnb, lnb]
00674                                 {
00675                                         if(i==cardinal_index) //cardinal tag (i.e. cardinal tag outside head tag)
00676                                         {
00677                                                 out<<before_cardinal;
00678                                         }
00679                                         if(i==head_index) //head tag
00680                                         {
00681                                                 out<<before_head;
00682                                         }
00683                                         out<<(*iter); //display symbol
00684                                         if(i==head_index) //head closing tag
00685                                         {
00686                                                 out<<after_head;
00687                                         }
00688                                         if(i==cardinal_index) //cardinal closing tag
00689                                         {
00690                                                 out<<after_cardinal;
00691                                         }
00692                                         if(i!=last_non_blank_index) //don't output between_delim after last index
00693                                         {
00694                                                 if(i==cardinal_index || i==head_index || i==cardinal_index-1 || i==head_index-1) //only output between_delim before/after head/cardinal if that is required
00695                                                 {
00696                                                         if(extra_between_delims)
00697                                                         {
00698                                                                 out<<between_delim;
00699                                                         }
00700                                                 }
00701                                                 else
00702                                                 {
00703                                                         out<<between_delim;
00704                                                 }
00705                                         }
00706                                 }
00707                         }
00708                         else if(cardinal_index<first_non_blank_index) //cardinal before [fnb, lnb], must print cardinal and blank place-holders
00709                         {
00710                                 out<<before_cardinal<<blank_delim<<after_cardinal; //fnb<=head<=lnb, so cardinal can safely be assumed to *not* be the head; outputs [cardinal], leaving [cardinal+1, lnb]
00711                                 if(extra_between_delims)
00712                                 {
00713                                         out<<between_delim;
00714                                 }
00715                                 typename std::list<T>::size_type i;
00716                                 for(++(iter=cardinal), i=cardinal_index+1; i<first_non_blank_index; ++i, ++iter) //outputs [cardinal+1, fnb), leaving [fnb, lnb]
00717                                 {
00718                                         out<<blank_delim;
00719                                         if(i==head_index-1) //handle case where head immediately follows blanks; only print between_delim before if that is required
00720                                         {
00721                                                 if(extra_between_delims)
00722                                                 {
00723                                                         out<<between_delim;
00724                                                 }
00725                                         }
00726                                         else
00727                                         {
00728                                                 out<<between_delim;
00729                                         }
00730                                 }
00731                                 for(iter=first_non_blank, i=first_non_blank_index; i<=last_non_blank_index; ++i, ++iter) //outputs [fnb, lnb]
00732                                 {
00733                                         if(i==head_index) //head tag
00734                                         {
00735                                                 out<<before_head;
00736                                         }
00737                                         out<<(*iter); //output symbol
00738                                         if(i==head_index) //head closing tag
00739                                         {
00740                                                 out<<after_head;
00741                                         }
00742                                         if(i!=last_non_blank_index) //do not output between_delim after last element
00743                                         {
00744                                                 if(i==head_index || i==head_index-1) //do not output between_delim before/after head unless this is required
00745                                                 {
00746                                                         if(extra_between_delims)
00747                                                         {
00748                                                                 out<<between_delim;
00749                                                         }
00750                                                 }
00751                                                 else
00752                                                 {
00753                                                         out<<between_delim;
00754                                                 }
00755                                         }
00756                                 }
00757                         }
00758                         else //cardinal after [fnb, lnb], again must print place-holder blanks and cardinal specially
00759                         {
00760                                 typename std::list<T>::size_type i;
00761                                 for(iter=first_non_blank, i=first_non_blank_index; i<=last_non_blank_index; ++i, ++iter) //outputs [fnb, lnb], leaving [lnb+1, cardinal]
00762                                 {
00763                                         if(i==head_index) //head tag
00764                                         {
00765                                                 out<<before_head;
00766                                         }
00767                                         out<<(*iter);
00768                                         if(i==head_index) //head closing tag
00769                                         {
00770                                                 out<<after_head;
00771                                         }
00772                                         if(i!=last_non_blank_index) //don't output between_delim for last index
00773                                         {
00774                                                 if(i==head_index || i==head_index-1 || i==cardinal_index-1) //don't output between_delim's before/after head unless required, use cardinal-1 check in case cardinal immediately follows lnb and don't output between_delim unless required
00775                                                 {
00776                                                         if(extra_between_delims)
00777                                                         {
00778                                                                 out<<between_delim;
00779                                                         }
00780                                                 }
00781                                                 else
00782                                                 {
00783                                                         out<<between_delim;
00784                                                 }
00785                                         }
00786                                 }
00787                                 for(++(iter=last_non_blank), i=last_non_blank_index+1; i!=cardinal_index; ++i, ++iter) //outputs [lnb+1, cardinal), leaving cardinal
00788                                 {
00789                                         out<<blank_delim; //display place-holder blanks
00790                                         if(i==cardinal_index-1) //do not print between_delim before cardinal unless required
00791                                         {
00792                                                 if(extra_between_delims)
00793                                                 {
00794                                                         out<<between_delim;
00795                                                 }
00796                                         }
00797                                         else
00798                                         {
00799                                                 out<<between_delim;
00800                                         }
00801                                 }
00802                                 out<<before_cardinal<<blank_delim<<after_cardinal; //outputs cardinal
00803                         }
00804                 }
00805 
00806                 out<<after_delim;
00807         }
00808 
00809         //Begin Owen Kellett modifications
00810         //note: due to the nature of the non halting routines implemented, the following blatant breaches of information hiding were necessary
00811 
00816         void reset()
00817         {
00818                 for(typename std::list<T>::iterator i=tape.begin(); i!=tape.end(); ++i)
00819                 {
00820                         (*i) = default_value;
00821                 }
00822                 non_blank_count = 0;
00823                 counter = 0;
00824         }
00825 
00831         void setCurrentLocation(typename std::list<T>::iterator location)
00832         {
00833                 current = location;
00834         }
00835 
00841         T defaultValue()
00842         {
00843                 return default_value;
00844         }
00845 
00851         typename std::list<T>::iterator currentLocation()
00852         {
00853                 return current;
00854         }
00855 
00861         typename std::list<T>::iterator begin()
00862         {
00863                 return tape.begin();
00864         }
00865 
00871         typename std::list<T>::const_iterator begin() const
00872         {
00873                 return tape.begin();
00874         }
00875 
00883         bool find(typename std::list<T>::iterator find)
00884         {
00885                 typename std::list<T>::iterator temp = tape.begin();
00886                 while(temp != tape.end())
00887                 {
00888                         if(temp == find)
00889                                 return true;
00890                         temp++;
00891                 }
00892                 return false;
00893         }
00894 
00903         bool repeatConfigRight(infinite_tape<T> &rhs, typename std::list<T>::iterator lhsLeftBound)
00904         {
00905                 typename std::list<T>::iterator lRightCounter = current;
00906                 typename std::list<T>::iterator lLeftCounter = current;
00907                 typename std::list<T>::iterator rRightCounter = rhs.current;
00908                 typename std::list<T>::iterator rLeftCounter = rhs.current;
00909                 bool go = false;
00910 
00911                 //--check to the right of current
00912                 //all cells starting from the read head of both states must be same
00913                 //an unequal number of default_value's at the end is allowed (since the tape is conceptually infinite)
00914                 while(*lRightCounter == *rRightCounter && lRightCounter != tape.end() && rRightCounter != rhs.tape.end())
00915                 {
00916                         ++lRightCounter;
00917                         ++rRightCounter;
00918                 }
00919                 if(lRightCounter == tape.end() && rRightCounter == rhs.tape.end())
00920                         go = true;
00921                 else if(lRightCounter == tape.end())
00922                 {
00923                         while(*rRightCounter == rhs.default_value && rRightCounter != rhs.tape.end())
00924                                 ++rRightCounter;
00925                         if(rRightCounter == rhs.tape.end())
00926                                 go = true;
00927                 }
00928                 else if(rRightCounter == rhs.tape.end())
00929                 {
00930                         while(*lRightCounter == default_value && lRightCounter != tape.end())
00931                                 ++lRightCounter;
00932                         if(lRightCounter == tape.end())
00933                                 go = true;
00934                 }
00935                 else
00936                         go = false;
00937                 //--//
00938 
00939                 //if above check fails, return false
00940                 if(!go)
00941                         return false;
00942 
00943 
00944                 //--check to the left of current
00945                 //the following configuration is required: C, X, Y, Z are words, A is one symbol -><- represents read head
00946                 //this: 0*CX->A<-Y0*
00947                 //rhs:  0*CZX->A<-Y0*
00948                 //one additional requirement is that lhsLeftBound must be to the right of C in this
00949                 while(*lLeftCounter == *rLeftCounter && lLeftCounter != tape.begin() && rLeftCounter != rhs.tape.begin())
00950                 {
00951                         --lLeftCounter;
00952                         --rLeftCounter;
00953                 }
00954                 if(lLeftCounter == tape.begin() && rLeftCounter == rhs.tape.begin())
00955                         go = true;
00956                 else if(lLeftCounter == tape.begin())
00957                         go = true;
00958                 else if(rLeftCounter == rhs.tape.begin())
00959                 {
00960                         while(*lLeftCounter == default_value && lLeftCounter != tape.begin())
00961                                 --lLeftCounter;
00962                         if(lLeftCounter == tape.begin())
00963                                 go = true;
00964                 }
00965                 //else if(*lLeftCounter != default_value)
00966                 //      go = false;
00967                 else
00968                 {
00969                         typename std::list<T>::iterator lTempCounter = tape.begin();
00970                         typename std::list<T>::iterator rTempCounter = rhs.tape.begin();
00971                         while(*(++lTempCounter) == default_value && lTempCounter != lLeftCounter)
00972                         {
00973                                 if(lTempCounter == lhsLeftBound)
00974                                         return false;
00975                         }
00976                         while(*(++rTempCounter) == rhs.default_value && rTempCounter != rLeftCounter);
00977                         while(lTempCounter != lLeftCounter && rTempCounter != rLeftCounter)
00978                         {
00979                                 if(lTempCounter == lhsLeftBound || *lTempCounter != *rTempCounter || rTempCounter == rLeftCounter)
00980                                         return false;
00981                                 lTempCounter++;
00982                                 rTempCounter++;
00983                         }
00984                         if(lLeftCounter == lhsLeftBound || rTempCounter == rLeftCounter)
00985                                 return false;
00986                         go = true;
00987                 }
00988                 //--//
00989                 return go;
00990         }
00991 
01000         bool repeatConfigLeft(infinite_tape<T> &rhs, typename std::list<T>::iterator lhsRightBound)
01001         {
01002                 typename std::list<T>::iterator lRightCounter = current;
01003                 typename std::list<T>::iterator lLeftCounter = current;
01004                 typename std::list<T>::iterator rRightCounter = rhs.current;
01005                 typename std::list<T>::iterator rLeftCounter = rhs.current;
01006                 bool go = false;
01007 
01008                 //check to the left of current
01009                 while(*lLeftCounter == *rLeftCounter && lLeftCounter != tape.begin() && rLeftCounter != rhs.tape.begin())
01010                 {
01011                         --lLeftCounter;
01012                         --rLeftCounter;
01013                 }
01014                 if(lLeftCounter == tape.begin() && rLeftCounter == rhs.tape.begin())
01015                         go = true;
01016                 else if(lLeftCounter == tape.begin())
01017                 {
01018                         while(*rLeftCounter == rhs.default_value && rLeftCounter != rhs.tape.begin())
01019                                 --rLeftCounter;
01020                         if(rLeftCounter == rhs.tape.begin())
01021                                 go = true;
01022                 }
01023                 else if(rLeftCounter == rhs.tape.begin())
01024                 {
01025                         while(*lLeftCounter == default_value && lLeftCounter != tape.begin())
01026                                 --lLeftCounter;
01027                         if(lLeftCounter == tape.begin())
01028                                 go = true;
01029                 }
01030                 else
01031                         go = false;
01032 
01033                 if(!go)
01034                         return false;
01035 
01036                 //check to the right of current
01037                 while(*lRightCounter == *rRightCounter && lRightCounter != tape.end() && rRightCounter != rhs.tape.end())
01038                 {
01039                         ++lRightCounter;
01040                         ++rRightCounter;
01041                 }
01042                 if(lRightCounter == tape.end() && rRightCounter == rhs.tape.end())
01043                         go = true;
01044                 else if(lRightCounter == tape.end())
01045                         go = true;
01046                 else if(rRightCounter == rhs.tape.end())
01047                 {
01048                         while(*lRightCounter == default_value && lRightCounter != tape.end())
01049                                 ++lRightCounter;
01050                         if(lRightCounter == tape.end())
01051                                 go = true;
01052                 }
01053                 //else if(*lRightCounter != default_value)
01054                         //go = false;
01055                 else
01056                 {
01057                         typename std::list<T>::iterator lTempCounter = tape.end();
01058                         typename std::list<T>::iterator rTempCounter = rhs.tape.end();
01059                         while(*(--lTempCounter) == default_value && lTempCounter != lRightCounter)
01060                         {
01061                                 //std::cout << *lTempCounter << " " << *lhsRightBound << std::endl;
01062                                 if(lTempCounter == lhsRightBound)
01063                                         return false;
01064                         }
01065                         while(*(--rTempCounter) == rhs.default_value && rTempCounter != rRightCounter);
01066                         while(lTempCounter != lRightCounter && rTempCounter != rRightCounter)
01067                         {
01068                                 //std::cout << *lTempCounter << " " << *lhsRightBound << std::endl;
01069                                 if(lTempCounter == lhsRightBound || *lTempCounter != *rTempCounter || rTempCounter == rRightCounter)
01070                                         return false;
01071                                 lTempCounter--;
01072                                 rTempCounter--;
01073                         }
01074                         //std::cout << *lTempCounter << " " << *lhsRightBound << std::endl;
01075                         if(lRightCounter == lhsRightBound || rTempCounter == rRightCounter)
01076                                 return false;
01077                         go = true;
01078                 }
01079                 return go;
01080         }
01081 
01087         void checkIteratorLeft(typename std::list<T>::iterator leftEdge)
01088         {
01089                 typename std::list<T>::iterator tempIter(leftEdge);
01090                 if((--tempIter) == tape.begin())
01091                 {
01092                         expand_tape(left, 10);
01093                         //cout << "expanded tape " << counter << " to the left" << endl;
01094                 }
01095         }
01096 
01102         void checkIteratorRight(typename std::list<T>::iterator rightEdge)
01103         {
01104                 typename std::list<T>::iterator tempIter(rightEdge);
01105                 if((++tempIter) == tape.end())
01106                 {
01107                         expand_tape(right, 10);
01108                         //cout << "expanded tape " << counter << " to the right" << endl;
01109                 }
01110         }
01111 
01112         //end Owen Kellett modifications
01113 
01114 protected:
01115         //private functions used to maintain invariants regarding the tape to ensure correct operation
01116 
01124         void tape_check(direction which)
01125         {
01126                 if(which==left)
01127                 {
01128                         typename std::list<T>::reverse_iterator temp_iter(current);
01129                         if((++temp_iter)==tape.rend())
01130                         {
01131                                 #ifdef ross_debug_mode
01132                                         std::cout<<"["<<this<<"] expanding on left"<<std::endl;
01133                                 #endif
01134                                 if(counter<1) //should never happen if tape is created with at least three cells ... but just to be sure
01135                                 {
01136                                         counter=1;
01137                                 }
01138                                 expand_tape(left, counter);
01139                         }
01140                 }
01141                 else
01142                 {
01143                         typename std::list<T>::iterator temp_iter(current);
01144                         if((++temp_iter)==tape.end())
01145                         {
01146                                 #ifdef ross_debug_mode
01147                                         std::cout<<"["<<this<<"] expanding on right"<<std::endl;
01148                                 #endif
01149                                 if(counter<1)
01150                                 {
01151                                         counter=1;
01152                                 }
01153                                 expand_tape(right, counter);
01154                         }
01155                         else
01156                         {
01157                                 #ifdef ross_debug_mode
01158                                         #ifdef ross_debug_verbose
01159                                                 std::cout<<"["<<this<<"]no expansion needed"<<std::endl;
01160                                         #endif
01161                                 #endif
01162                                 return;
01163                         }
01164                 }
01165         }
01166 
01174         void expand_tape(direction which, typename std::list<T>::size_type how_many)
01175         {
01176                 if(which==left)
01177                 {
01178                         tape.insert(tape.begin(), how_many, default_value);
01179                 }
01180                 else if(which==right)
01181                 {
01182                         tape.insert(tape.end(), how_many, default_value);
01183                 }
01184                 #ifdef ross_debug_mode
01185                         std::cout<<"["<<this<<"]expanded by "<<counter<<" on "<<(which==left?"left":"right")<<" to "<<tape.size()<<std::endl;
01186                 #endif
01187                 counter=0;
01188         }
01189 
01194         static const typename std::list<T>::size_type start_size=101;
01198         typename std::list<T> tape;
01202         typename std::list<T>::iterator current, cardinal;
01207         typename std::list<T>::size_type counter;
01211         T default_value;
01215         typename std::list<T>::size_type non_blank_count;
01216 };
01217 
01227 template <typename T>
01228 std::ostream& operator<<(std::ostream &out, const infinite_tape<T> &to_print)
01229 {
01230         to_print.show(out);
01231         return out;
01232 }
01233 
01234 #endif
01235 

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