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

bb-run.cpp

00001 /*Authored 2002    by  Kyle  Ross,  Undergraduate  Philosophy   Thesis
00002 (Advisor: Professor Bram van Heuveln)
00003 
00004 Modified 2003    by Owen Kellett, Undergraduate Research
00005 (Advisor: Professor Bram van Heuveln)
00006 
00007 This  file is part of the   "Generic Turing Machine Implementation for
00008 Use in the Exploration of the Busy Beaver Problem".
00009 
00010 The "Generic Turing Machine Implementation for  Use in the Exploration
00011 of the Busy Beaver Problem" is free  software; you can redistribute it
00012 and/or modify it under the terms of the  GNU General Public License as
00013 published   by the Free Software Foundation;   either version 2 of the
00014 License, or (at your option) any later version.
00015 
00016 This programme is distributed in the hope that it  will be useful, but
00017 WITHOUT    ANY  WARRANTY;  without   even  the    implied warranty  of
00018 MERCHANTABILITY or FITNESS FOR  A  PARTICULAR  PURPOSE.  See  the  GNU
00019 General Public License for more details.
00020 
00021 You should have received   a copy of  the  GNU General Public  License
00022 along  with  this   programme; if  not,  write   to the Free  Software
00023 Foundation, Inc., 59  Temple Place, Suite  330, Boston, MA  02111-1307
00024 USA (or visit http://www.fsf.org/licenses/licenses.html)
00025 
00026 Created as part of the Busy Beaver Project:
00027 Bram van Heuveln <heuveb@rpi.edu>
00028 Boleshaw Szymanski <szymansk@cs.rpi.edu>
00029 Selmer Bringsjord <selmer@rpi.edu>
00030 Carlos Varela <cvarela@cs.rpi.edu>
00031 Owen Kellett <kelleo@rpi.edu>
00032 Shailesh Kelkar <kelkas@rpi.edu>
00033 Kyle Ross <rossk2@rpi.edu>
00034 Rensselaer Reasoning Group
00035 Department of Cognitive Science
00036 Department of Computer Science
00037 Rensselaer Polytechnic Institute
00038 Troy, New York 12180
00039 U.S.A.
00040 */
00041 //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)
00042 //enforcing of alphabet rules (i.e. which symbols belong to the alphabet, etc.) will be left to the finite-state automaton
00043 
00044 #include <fstream>
00045 #include <iostream>
00046 #include <iterator>
00047 #include <list>
00048 #include <vector>
00049 #include <sys/stat.h>
00050 #include <sys/types.h>
00051 #include <stdlib.h>
00052 #include <stdio.h>
00053 #include <string>
00054 
00055 
00056 #include "../bb/stats.hpp"
00057 tm_stats g_counter_implicit;
00058 tm_stats c_counter_implicit;
00059 tm_stats g_counter_explicit;
00060 tm_stats c_counter_explicit;
00061 
00062 #include "../bb/infinite_tape.hpp"
00063 #include "../bb/long_int.hpp"
00064 #include "../bb/state.hpp"
00065 #include "../bb/turing_machine.hpp"
00066 #include "../bb/non_halt_detection.hpp"
00067 #include "../bb/non_halt_data_structures.hpp"
00068 #include "../bb/machine_storage.hpp"
00069 
00070 #include "../bb/watch.hpp"
00071 typedef unsigned short d_type;
00072 enum machine_type{B, P, O, R};
00073 
00074 void run_quadruple_bb_search(unsigned int size, std::list<turing_machine<d_type> > &machines_to_consider, const std::list<d_type> &alphabet, std::ostream &stats_stream, unsigned int transition_limit)
00075 {
00076         char buffer[10];
00077         sprintf(buffer,"%d",size);
00078         std::string stateValue(buffer);
00079         std::string outerDir = "../output/BB" + stateValue;
00080         std::string holdoutDir = outerDir + "/holdouts";
00081         std::string bDir = outerDir + "/B" + stateValue;
00082         std::string oDir = outerDir + "/O" + stateValue;
00083         std::string pDir = outerDir + "/P" + stateValue;
00084         std::string rDir = outerDir + "/R" + stateValue;
00085 
00086         if(mkdir(outerDir.c_str(), 0744) == -1 ||
00087                 mkdir(holdoutDir.c_str(), 0744) == -1 ||
00088                 mkdir(bDir.c_str(), 0744) == -1 ||
00089                 mkdir(oDir.c_str(), 0744) == -1 ||
00090                 mkdir(pDir.c_str(), 0744) == -1 ||
00091                 mkdir(rDir.c_str(), 0744) == -1)
00092         {
00093                 std::cerr << "problem creating directories" << std::endl;
00094                 return;
00095         }
00096 
00097         outputLog<d_type> loggingOutputHoldouts(holdoutDir + "/");
00098         championLog<d_type> loggingOutputB(bDir + "/");
00099         championLog<d_type> loggingOutputO(oDir + "/");
00100         championLog<d_type> loggingOutputP(pDir + "/");
00101         championLog<d_type> loggingOutputR(rDir + "/");
00102 
00103         //create statical recording variables
00104         unsigned int standard_count_implicit=0, nonstandard_count_implicit=0, holdout_count_implicit=0;
00105         unsigned int standard_count_explicit=0, nonstandard_count_explicit=0, holdout_count_explicit=0;
00106 
00107         unsigned int max_productivity_b=0, max_shifts_b=0, max_productivity_o=0, max_shifts_o=0;
00108         unsigned int max_productivity_p=0, max_shifts_p=0, max_productivity_r=0, max_shifts_r=0;
00109 
00110         long_int counterCount = 0;
00111 
00112         //consider machines until machine number limit reached or all machines exhausted
00113         unsigned int machine_trial;
00114         for(machine_trial=0; machines_to_consider.size()!=0; ++machine_trial)
00115         {
00116                 //if stats output is on and this is a thousand-mark machine, output stats
00117                 if(machine_trial%100000==0)
00118                 {
00119                         #ifdef ross_debug_mode
00120                                 stats_stream<<"[stats-stream\n";
00121                         #endif
00122                         stats_stream<<"considering machine "<<machine_trial<<std::endl;
00123                         stats_stream<<" holdouts="<<holdout_count_implicit<<std::endl;
00124                         stats_stream<<" implicit standard="<<standard_count_implicit<<std::endl;
00125                         stats_stream<<" implicit non-standard="<<nonstandard_count_implicit<<std::endl;
00126                         stats_stream<<" explicit standard="<<standard_count_explicit<<std::endl;
00127                         stats_stream<<" explicit non-standard="<<nonstandard_count_explicit<<std::endl;
00128                         #ifdef ross_debug_mode
00129                                 stats_stream<<"stats-stream]\n";
00130                         #endif
00131                 }
00132                 if(machine_trial%1000000==0)
00133                 {
00134                         stats_stream<<c_counter_implicit<<std::endl;
00135                 }
00136 
00137                 //get the next machine to be evaluated in DFS order
00138                 turing_machine<d_type> current_machine=*(machines_to_consider.begin());
00139                 machines_to_consider.pop_front();
00140 
00141                 //initialise step counter
00142                 unsigned int step_counter=0;
00143 
00144 
00145                 if(backTrack(current_machine, 20))
00146                 {
00147                         g_counter_implicit.increment(tm_stats::backTracker, current_machine.number_represented());
00148                         c_counter_implicit.increment(tm_stats::backTracker, 1);
00149                         g_counter_explicit.increment(tm_stats::backTracker, current_machine.number_represented_explicit());
00150                         c_counter_explicit.increment(tm_stats::backTracker, 1);
00151                 }
00152                 else if(loopStates(current_machine))
00153                 {
00154                         g_counter_implicit.increment(tm_stats::subsetLoop, current_machine.number_represented());
00155                         c_counter_implicit.increment(tm_stats::subsetLoop, 1);
00156                         g_counter_explicit.increment(tm_stats::subsetLoop, current_machine.number_represented_explicit());
00157                         c_counter_explicit.increment(tm_stats::subsetLoop, 1);
00158                 }
00159                 else if(simpleLoopCheck(current_machine, 1500))
00160                 {
00161                         g_counter_implicit.increment(tm_stats::simpleLoop, current_machine.number_represented());
00162                         c_counter_implicit.increment(tm_stats::simpleLoop, 1);
00163                         g_counter_explicit.increment(tm_stats::simpleLoop, current_machine.number_represented_explicit());
00164                         c_counter_explicit.increment(tm_stats::simpleLoop, 1);
00165                 }
00166                 else if(multiSweepChristmasTree(current_machine, 1, 25000))
00167                 {
00168                         g_counter_implicit.increment(tm_stats::christmasTree, current_machine.number_represented());
00169                         c_counter_implicit.increment(tm_stats::christmasTree, 1);
00170                         g_counter_explicit.increment(tm_stats::christmasTree, current_machine.number_represented_explicit());
00171                         c_counter_explicit.increment(tm_stats::christmasTree, 1);
00172                 }
00173                 else if(multiSweepChristmasTree(current_machine, 2, 50000))
00174                 {
00175                         g_counter_implicit.increment(tm_stats::alternateChristmasTree, current_machine.number_represented());
00176                         c_counter_implicit.increment(tm_stats::alternateChristmasTree, 1);
00177                         g_counter_explicit.increment(tm_stats::alternateChristmasTree, current_machine.number_represented_explicit());
00178                         c_counter_explicit.increment(tm_stats::alternateChristmasTree, 1);
00179                 }
00180                 else if(leaningChristmasTree(current_machine, 25000))
00181                 {
00182                         g_counter_implicit.increment(tm_stats::leaningChristmasTree, current_machine.number_represented());
00183                         c_counter_implicit.increment(tm_stats::leaningChristmasTree, 1);
00184                         g_counter_explicit.increment(tm_stats::leaningChristmasTree, current_machine.number_represented_explicit());
00185                         c_counter_explicit.increment(tm_stats::leaningChristmasTree, 1);
00186                 }
00187                 else if(multiSweepChristmasTree(current_machine, 3, 100000))
00188                 {
00189                         g_counter_implicit.increment(tm_stats::tripleSweepChristmasTree, current_machine.number_represented());
00190                         c_counter_implicit.increment(tm_stats::tripleSweepChristmasTree, 1);
00191                         g_counter_explicit.increment(tm_stats::tripleSweepChristmasTree, current_machine.number_represented_explicit());
00192                         c_counter_explicit.increment(tm_stats::tripleSweepChristmasTree, 1);
00193                 }
00194                 else if(multiSweepChristmasTree(current_machine, 4, 100000))
00195                 {
00196                         g_counter_implicit.increment(tm_stats::quadrupleSweepChristmasTree, current_machine.number_represented());
00197                         c_counter_implicit.increment(tm_stats::quadrupleSweepChristmasTree, 1);
00198                         g_counter_explicit.increment(tm_stats::quadrupleSweepChristmasTree, current_machine.number_represented_explicit());
00199                         c_counter_explicit.increment(tm_stats::quadrupleSweepChristmasTree, 1);
00200                 }
00201                 else if(multiSweepChristmasTree(current_machine, 5, 100000))
00202                 {
00203                         g_counter_implicit.increment(tm_stats::quintupleSweepChristmasTree, current_machine.number_represented());
00204                         c_counter_implicit.increment(tm_stats::quintupleSweepChristmasTree, 1);
00205                         g_counter_explicit.increment(tm_stats::quintupleSweepChristmasTree, current_machine.number_represented_explicit());
00206                         c_counter_explicit.increment(tm_stats::quintupleSweepChristmasTree, 1);
00207                 }
00208                 else if(counter(current_machine, 50000))
00209                 {
00210                         g_counter_implicit.increment(tm_stats::counter, current_machine.number_represented());
00211                         c_counter_implicit.increment(tm_stats::counter, 1);
00212                         g_counter_explicit.increment(tm_stats::counter, current_machine.number_represented_explicit());
00213                         c_counter_explicit.increment(tm_stats::counter, 1);
00214                 }
00215 
00216                 else
00217                 {
00218                 current_machine.resetMachine();
00219                 //run the machine until it halts or the step-limit has been reached
00220                 #ifdef enable_optimisations
00221                         #ifdef blank_tape_optimisation
00222                                 while(step_counter<transition_limit && current_machine.run_one()!=turing_machine<d_type>::halt && !(step_counter>0 && current_machine.blank_tape()))
00223                         #else
00224                                 while(step_counter<transition_limit && current_machine.run_one()!=turing_machine<d_type>::halt)
00225                         #endif
00226                 #else
00227                         while(step_counter<transition_limit && current_machine.run_one()!=turing_machine<d_type>::halt)
00228                 #endif
00229                 {
00230                         ++step_counter;
00231                 }
00232 
00233                 #ifdef enable_optimisations
00234                         #ifdef blank_tape_optimisation
00235                                 if(step_counter>0 && current_machine.blank_tape())
00236                                 {
00237                                         #ifdef ross_debug_mode
00238                                                 std::cout<<"MACHINE ELIMINATED BECAUSE IT IS A BLANK-TAPE MACHINE"<<std::endl;
00239                                                 std::cout<<current_machine<<std::endl;
00240                                         #endif
00241                                         if(current_machine.implicitMachine())
00242                                         {
00243                                                 g_counter_implicit.increment(tm_stats::empty_tape, current_machine.number_represented());
00244                                                 c_counter_implicit.increment(tm_stats::empty_tape, 1);
00245                                         }
00246                                         g_counter_explicit.increment(tm_stats::empty_tape, current_machine.number_represented_explicit());
00247                                         c_counter_explicit.increment(tm_stats::empty_tape, 1);
00248                                 }
00249                                 else
00250                         #endif
00251                 #endif
00252 
00253                 //if(subsetLoop);
00254                 //if the machine is still running, add it as an holdout
00255                 if(current_machine.get_status()==turing_machine<d_type>::run)
00256                 {
00257                         g_counter_implicit.increment(tm_stats::holdout, current_machine.number_represented());
00258                         c_counter_implicit.increment(tm_stats::holdout, 1);
00259                         g_counter_explicit.increment(tm_stats::holdout, current_machine.number_represented_explicit());
00260                         c_counter_explicit.increment(tm_stats::holdout, 1);
00261 
00262                         loggingOutputHoldouts.print(current_machine);
00263 
00264                         ++holdout_count_implicit;
00265                         ++holdout_count_explicit;
00266                 }
00267                 //otherwise, it's a non-standard halter xor a standard halter
00268                 else if(current_machine.in_halt_state())
00269                 {
00270                         //if it's a non-standard halter:
00271                         if(current_machine.implicitMachine())
00272                         {
00273                                 if(current_machine.in_standard_position())
00274                                 {
00275                                         g_counter_implicit.increment(tm_stats::candidate, current_machine.number_represented());
00276                                         c_counter_implicit.increment(tm_stats::candidate, 1);
00277 
00278                                         ++standard_count_implicit;
00279 
00280                                         //is it a new most-shift machine?
00281                                         if(current_machine.get_steps_count()>max_shifts_b)
00282                                         {
00283                                                 max_shifts_b=current_machine.get_steps_count();
00284                                                 loggingOutputB.printChampion(current_machine, championLog<d_type>::transitions, max_shifts_b);
00285                                                 stats_stream<<"a new b champion found with shift count "<<max_shifts_b<<std::endl;
00286                                         }
00287 
00288                                         //is it a new most-productive machine?
00289                                         if(current_machine.count_occurrences(1)>=max_productivity_b)
00290                                         {
00291                                                 max_productivity_b=current_machine.count_occurrences(1);
00292                                                 loggingOutputB.printChampion(current_machine, championLog<d_type>::ones, max_productivity_b);
00293                                                 stats_stream<<"a new B champion found with productivity "<<max_productivity_b<<std::endl;
00294                                         }
00295                                 }
00296                                 else
00297                                 {
00298                                         g_counter_implicit.increment(tm_stats::not_in_standard_position, current_machine.number_represented());
00299                                         c_counter_implicit.increment(tm_stats::not_in_standard_position, 1);
00300 
00301                                         ++nonstandard_count_implicit;
00302                                 }
00303                                 //is it a new most-shift machine?
00304                                 if(current_machine.get_steps_count()>max_shifts_o)
00305                                 {
00306                                         max_shifts_o=current_machine.get_steps_count();
00307                                         loggingOutputO.printChampion(current_machine, championLog<d_type>::transitions, max_shifts_o);
00308                                         stats_stream<<"a new o champion found with shift count "<<max_shifts_o<<std::endl;
00309                                 }
00310 
00311                                 //is it a new most-productive machine?
00312                                 if(current_machine.count_occurrences(1)>=max_productivity_o)
00313                                 {
00314                                         max_productivity_o=current_machine.count_occurrences(1);
00315                                         loggingOutputO.printChampion(current_machine, championLog<d_type>::ones, max_productivity_o);
00316                                         stats_stream<<"a new O champion found with productivity "<<max_productivity_o<<std::endl;
00317                                 }
00318                         }
00319 
00320                         if(current_machine.in_standard_position())
00321                         {
00322                                 g_counter_explicit.increment(tm_stats::candidate, current_machine.number_represented_explicit());
00323                                 c_counter_explicit.increment(tm_stats::candidate, 1);
00324 
00325                                 ++standard_count_explicit;
00326 
00327                                 //is it a new most-shift machine?
00328                                 if(current_machine.get_steps_count()>max_shifts_p && !current_machine.implicitMachine())
00329                                 {
00330                                         max_shifts_p=current_machine.get_steps_count();
00331                                         loggingOutputP.printChampion(current_machine, championLog<d_type>::transitions, max_shifts_p);
00332                                         stats_stream<<"a new p champion found with shift count "<<max_shifts_p<<std::endl;
00333                                 }
00334 
00335                                 //is it a new most-productive machine?
00336                                 if(current_machine.count_occurrences(1)>=max_productivity_p && !current_machine.implicitMachine())
00337                                 {
00338                                         max_productivity_p=current_machine.count_occurrences(1);
00339                                         loggingOutputP.printChampion(current_machine, championLog<d_type>::ones, max_productivity_p);
00340                                         stats_stream<<"a new P champion found with productivity "<<max_productivity_p<<std::endl;
00341                                 }
00342                         }
00343                         else
00344                         {
00345                                 g_counter_explicit.increment(tm_stats::not_in_standard_position, current_machine.number_represented_explicit());
00346                                 c_counter_explicit.increment(tm_stats::not_in_standard_position, 1);
00347 
00348                                 ++nonstandard_count_explicit;
00349                         }
00350                         //is it a new most-shift machine?
00351                         if(current_machine.get_steps_count()>max_shifts_r && !current_machine.implicitMachine())
00352                         {
00353                                 max_shifts_r=current_machine.get_steps_count();
00354                                 loggingOutputR.printChampion(current_machine, championLog<d_type>::transitions, max_shifts_r);
00355                                 stats_stream<<"a new r champion found with shift count "<<max_shifts_r<<std::endl;
00356                         }
00357 
00358                         //is it a new most-productive machine?
00359                         if(current_machine.count_occurrences(1)>=max_productivity_r && !current_machine.implicitMachine())
00360                         {
00361                                 max_productivity_r=current_machine.count_occurrences(1);
00362                                 loggingOutputR.printChampion(current_machine, championLog<d_type>::ones, max_productivity_r);
00363                                 stats_stream<<"a new R champion found with productivity "<<max_productivity_r<<std::endl;
00364                         }
00365                 }
00366                 //halted because transition does not exist
00367                 else
00368                 {
00369                         //generate appropriate children (i.e. taking into account implicit/explicit halt)
00370                         /*if(implicit)
00371                         {
00372                                 current_machine.generate_tn_quadruple_children(alphabet, front_inserter(machines_to_consider));
00373                         }
00374                         else
00375                         {
00376                                 current_machine.generate_tn_quadruple_children_explicit(alphabet, front_inserter(machines_to_consider));
00377                         }*/
00378                         current_machine.generate_all_tn_quadruple_children(alphabet, front_inserter(machines_to_consider));
00379                 }
00380                 }
00381         }
00382 
00383         stats_stream<<"<finished>"<<std::endl;
00384         stats_stream<<"considered machine "<<machine_trial<<std::endl;
00385         stats_stream<<" holdouts="<<holdout_count_implicit<<std::endl;
00386         stats_stream<<" implicit standard="<<standard_count_implicit<<std::endl;
00387         stats_stream<<" implicit non-standard="<<nonstandard_count_implicit<<std::endl;
00388         stats_stream<<" explicit standard="<<standard_count_explicit<<std::endl;
00389         stats_stream<<" explicit non-standard="<<nonstandard_count_explicit<<std::endl;
00390 }
00391 
00392 
00393 void run_simple_quadruple(unsigned int size, unsigned int halt_limit, std::ostream &cand_file)
00394 {
00395         cand_file<<"running ";
00396         cand_file<<"("<<size<<") with step-limit of "<<halt_limit<<std::endl;
00397         display_optimisation_settings(cand_file);
00398 
00399         typedef turing_machine<unsigned short> m_type;
00400 
00401         //create the initial machine queue
00402         std::list<m_type> machines;
00403         m_type original_machine(size+1, 0); //the root machine of the tree
00404         original_machine.set_halt_state(size);
00405         machines.push_front(original_machine);
00406         std::cerr<<"implicit target="<<original_machine.number_represented()<<std::endl;
00407         std::cerr<<"explicit target="<<original_machine.number_represented_explicit()<<std::endl;
00408 
00409         //create the alphabet
00410         std::list<unsigned short> alphabet;
00411         alphabet.push_back(0);
00412         alphabet.push_back(1);
00413 
00414         //create a list for the candidates
00415         std::list<m_type> bs_list;
00416 
00417         run_quadruple_bb_search(
00418                 size,
00419                 machines, //list of machines
00420                 alphabet, //1-0 alphabet
00421                 cand_file, //stats output
00422                 halt_limit); //number of transitions to run
00423 }
00424 
00425 
00426 int main(int argc, char *argv[])
00427 {
00428         if(argc != 3)
00429         {
00430                 std::cerr << "Wrong number of arguments" << std::endl;
00431                 return 0;
00432         }
00433         int numStates = atoi(argv[1]);
00434         int haltLimit = atoi(argv[2]);
00435         if(numStates < 0 || haltLimit < 0)
00436         {
00437                 std::cerr << "Invalid arguments" << std::endl;
00438                 return 0;
00439         }
00440 
00441         run_simple_quadruple(numStates, haltLimit, std::cout);
00442 
00443         std::cerr<<"observed "<<c_counter_implicit<<std::endl;
00444         std::cerr<<"representative "<<g_counter_implicit<<std::endl;
00445         std::cerr<<"observed "<<c_counter_explicit<<std::endl;
00446         std::cerr<<"representative "<<g_counter_explicit<<std::endl;
00447 
00448         return EXIT_SUCCESS;
00449 }
00450 
00451 
00452 

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