00001 #ifndef ross_turing_machine_header
00002 #define ross_turing_machine_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
00044
00045
00046 #define enableLoggingOutput
00047 #define enable_optimisations
00048 #define blank_tape_optimisation
00049 #define no_ss_optimisation
00050 #define no_ssprime_sprimes_optimisation
00051 #define first_write_optimisation
00052 #define first_move_optimisation
00053
00054 void display_optimisation_settings(std::ostream &out)
00055 {
00056 #ifdef enable_optimisations
00057 out<<"optimisations enabled:"<<std::endl;
00058 out<<" blank-tape-optimisation: ";
00059 #ifdef blank_tape_optimisation
00060 out<<"on"<<std::endl;
00061 #else
00062 out<<"off"<<std::endl;
00063 #endif
00064 out<<" no-ss-optimisation: ";
00065 #ifdef no_ss_optimisation
00066 out<<"on"<<std::endl;
00067 #else
00068 out<<"off"<<std::endl;
00069 #endif
00070 out<<" no-ssprime-sprimes-optimisation: ";
00071 #ifdef no_ssprime_sprimes_optimisation
00072 out<<"on"<<std::endl;
00073 #else
00074 out<<"off"<<std::endl;
00075 #endif
00076 out<<" first-write-optimisation: ";
00077 #ifdef first_write_optimisation
00078 out<<"on"<<std::endl;
00079 #else
00080 out<<"off"<<std::endl;
00081 #endif
00082 out<<" first-move-optimisation: ";
00083 #ifdef first_move_optimisation
00084 #ifndef first_write_optimisation
00085 out<<"disabled because first-write is not on"<<std::endl;
00086 #else
00087 out<<"on"<<std::endl;
00088 #endif
00089 #else
00090 out<<"off"<<std::endl;
00091 #endif
00092 #else
00093 out<<"optimisations disabled"<<std::endl;
00094 #endif
00095 }
00096
00097 #include <cmath>
00098 #include <vector>
00099 #include "debug.hpp"
00100 #include "infinite_tape.hpp"
00101 #include "state.hpp"
00102 #include "machine_storage.hpp"
00103 #include "watch.hpp"
00104 template <typename T>
00105 T& last_element(std::vector<T> &the_list);
00106
00111 template <typename T>
00112 class turing_machine
00113 {
00114 public:
00115 typedef typename std::vector<state<T> >::size_type transition_index_type;
00116 typedef typename infinite_tape<T>::direction move_type;
00117 typedef typename state<T>::transition_result result_type;
00118 typedef unsigned long int transition_count_type;
00119 static const move_type left=infinite_tape<T>::left;
00120 static const move_type right=infinite_tape<T>::right;
00121 static const move_type do_nothing=infinite_tape<T>::do_nothing;
00122 static const move_type halt_move=infinite_tape<T>::halt_move;
00123 static const result_type run=state<T>::run;
00124 static const result_type halt=state<T>::halt;
00125
00133 turing_machine(const turing_machine<T> &rhs)
00134 :current(rhs.current), transition_function(rhs.transition_function), tape(rhs.tape), steps(rhs.steps), run_status(rhs.run_status), halt_state(rhs.halt_state), halt_state_exists(rhs.halt_state_exists), first_unreachable_state(rhs.first_unreachable_state)
00135 {
00136 #ifdef ross_debug_mode
00137 std::cout<<"["<<this<<"]turing-machine copy-constructed"<<std::endl;
00138 #endif
00139 }
00140
00148 turing_machine(T default_tape_value)
00149 :tape(default_tape_value), current(0), steps(0), run_status(run), halt_state_exists(false), first_unreachable_state(1)
00150 {
00151 #ifdef ross_debug_mode
00152 std::cout<<"["<<this<<"]turing-machine constructed"<<std::endl;
00153 #endif
00154 }
00155
00164 turing_machine(transition_index_type N, T default_tape_value)
00165 :tape(default_tape_value), current(0), transition_function(N), steps(0), run_status(run), halt_state_exists(false), first_unreachable_state(1)
00166 {
00167 #ifdef ross_debug_mode
00168 std::cout<<"["<<this<<"]turing-machine constructed"<<std::endl;
00169 #endif
00170 }
00171
00179 turing_machine(const infinite_tape<T> &new_tape)
00180 :tape(new_tape), current(0), steps(0), run_status(run), halt_state_exists(false), first_unreachable_state(1)
00181 {
00182 #ifdef ross_debug_mode
00183 std::cout<<"["<<this<<"]turing-machine constructed"<<std::endl;
00184 #endif
00185 }
00186
00191 ~turing_machine()
00192 {
00193 #ifdef ross_debug_mode
00194 std::cout<<"["<<this<<"]turing-machine destroyed"<<std::endl;
00195 #endif
00196 }
00197
00205 transition_index_type add_state()
00206 {
00207 transition_function.push_back(state<T>());
00208 return transition_function.size();
00209 }
00210
00217 bool set_halt_state(transition_index_type new_halt_state)
00218 {
00219 if(halt_state_exists)
00220 {
00221 #ifdef ross_debug_mode
00222 std::cout<<"["<<this<<"] could not set halt state since one already exists"<<std::endl;
00223 #endif
00224 return false;
00225 }
00226 else
00227 {
00228 if(bounds_check(new_halt_state))
00229 {
00230 halt_state_exists=true;
00231 halt_state=new_halt_state;
00232 #ifdef ross_debug_mode
00233 std::cout<<"["<<this<<"] halt state set successfully"<<std::endl;
00234 #endif
00235 return true;
00236 }
00237 else
00238 {
00239 #ifdef ross_debug_mode
00240 std::cout<<"["<<this<<"] could not create halt state since index was invalid"<<std::endl;
00241 #endif
00242 return false;
00243 }
00244 }
00245 }
00246
00258 bool add_transition(transition_index_type start_state, T read, T write, move_type move, transition_index_type end_state)
00259 {
00260 if(bounds_check(start_state) && bounds_check(end_state))
00261 {
00262 #ifdef ross_debug_mode
00263 std::cout<<"["<<this<<"]turing-machine::add-transition to state "<<start_state<<std::endl;
00264 #endif
00265 transition_function[start_state].create_transition(read, write, end_state, move);
00266 if(end_state!=halt_state && end_state>=first_unreachable_state)
00267 {
00268 first_unreachable_state=end_state+1;
00269 }
00270 return true;
00271 }
00272 else
00273 {
00274 #ifdef ross_debug_mode
00275 std::cout<<"["<<this<<"]turing-machine::add-transition WARNING transition not added because of bounds-check failure"<<std::endl;
00276 #endif
00277 return false;
00278 }
00279 }
00280
00291 bool add_write_transition(transition_index_type start_state, T read, T write, transition_index_type end_state)
00292 {
00293 return add_transition(start_state, read, write, do_nothing, end_state);
00294 }
00295
00306 bool add_move_transition(transition_index_type start_state, T read, move_type move, transition_index_type end_state)
00307 {
00308 return add_transition(start_state, read, read, move, end_state);
00309 }
00310
00318 bool bounds_check(transition_index_type to_check)
00319 {
00320 return to_check<transition_function.size();
00321 }
00322
00330 result_type run_one()
00331 {
00332 if((run_status=transition_function[current].perform_transition(tape, current))==run)
00333 {
00334 ++steps;
00335 }
00336 if(halt_state_exists && current==halt_state)
00337 {
00338 run_status=halt;
00339 }
00340 return run_status;
00341 }
00342
00343
00344
00353 transition_index_type count_occurrences(T to_count) const
00354 {
00355 return tape.count_occurrences(to_count);
00356 }
00357
00363 const infinite_tape<T>& access_tape() const
00364 {
00365 return tape;
00366 }
00367
00375 infinite_tape<T>& access_tape_read_write()
00376 {
00377 #ifdef ross_debug_mode
00378 std::cout<<"["<<this<<"]turing-machine::access-tape-read-write WARNING this function should be used carefully"<<std::endl;
00379 #endif
00380 return tape;
00381 }
00382
00389 bool in_standard_position() const
00390 {
00391 return tape.in_standard_position();
00392 }
00393
00399 bool blank_tape() const
00400 {
00401 return tape.is_blank();
00402 }
00403
00409 transition_index_type count_states() const
00410 {
00411 return transition_function.size();
00412 }
00413
00419 transition_index_type get_current_state() const
00420 {
00421 return current;
00422 }
00423
00430 result_type get_status() const
00431 {
00432 return run_status;
00433 }
00434
00440 transition_count_type get_steps_count() const
00441 {
00442 return steps;
00443 }
00444
00450 bool in_halt_state() const
00451 {
00452 return halt_state_exists && current==halt_state;
00453 }
00454
00460 long_int number_represented() const
00461 {
00462 unsigned int m=0;
00463 unsigned int n=count_states()-1;
00464
00465 for(typename std::vector<state<T> >::const_iterator i=transition_function.begin(); (i+1)!=transition_function.end(); ++i)
00466 {
00467 for(T j=0; j<=1; ++j)
00468 {
00469 T write;
00470 typename infinite_tape<T>::direction move;
00471 typename std::vector<state<T> >::size_type index;
00472 if((*i).simulate_transition(j, write, move, index)==run)
00473 {
00474 ++m;
00475 }
00476 }
00477 }
00478
00479 return permutations(n-1, first_unreachable_state-1)*pow(long_int(4*n+1), long_int(2*n-m));
00480 }
00481
00487 long_int number_represented_explicit() const
00488 {
00489 unsigned int m=0;
00490 unsigned int n=count_states()-1;
00491
00492 for(typename std::vector<state<T> >::const_iterator i=transition_function.begin(); (i+1)!=transition_function.end(); ++i)
00493 {
00494 for(T j=0; j<=1; ++j)
00495 {
00496 T write;
00497 typename infinite_tape<T>::direction move;
00498 typename std::vector<state<T> >::size_type index;
00499 if((*i).simulate_transition(j, write, move, index)==run)
00500 {
00501 ++m;
00502 }
00503 }
00504 }
00505
00506 return permutations(n-1, first_unreachable_state-1)*pow(long_int(4*n+4), long_int(2*n-m));
00507 }
00508
00509
00510
00511
00512
00517 void print(std::ostream &out) const
00518 {
00519 out<<tape<<std::endl;
00520 typename std::vector<state<T> >::const_iterator i=transition_function.begin();
00521 if(i==transition_function.end())
00522 {
00523 out<<"< no states exist >"<<std::endl;
00524 }
00525 else
00526 {
00527 for(int count(0); i!=transition_function.end(); ++i)
00528 {
00529 out<<"state "<<(count++)<<std::endl<<(*i);
00530 }
00531 out<<"current state is "<<current<<std::endl;
00532 if(halt_state_exists)
00533 {
00534 out<<"halt state is "<<halt_state<<std::endl;
00535 }
00536 out<<"first unreachable state is "<<first_unreachable_state<<std::endl;
00537 }
00538 out<<"current run status is: "<<(run_status==run?"running":"halted")<<" after "<<steps<<" transitions"<<std::endl;
00539 }
00540
00546 bool is_tn_possible() const
00547 {
00548 if(halt_state_exists)
00549 {
00550 return run_status==halt && current!=halt_state;
00551 }
00552 else
00553 {
00554 return run_status==halt;
00555 }
00556 }
00557
00565 template <typename OutputIterator>
00566 void generate_tn_quadruple_children(const std::list<T> &alphabet, OutputIterator destination) const
00567 {
00568
00569 T tape_symbol=tape.read();
00570
00571
00572 turing_machine<T> temp_machine=*this;
00573
00574
00575 for(transition_index_type end_state=0; end_state!=first_unreachable_state; ++end_state)
00576 {
00577
00578 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin(); alpha_iter!=alphabet.end(); ++alpha_iter)
00579 {
00580 #ifdef no_ss_optimisation
00581 if((*alpha_iter)!=tape_symbol)
00582 {
00583 temp_machine=*this;
00584 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00585 output_machine(temp_machine, destination, alphabet);
00586 }
00587 else
00588 {
00589 temp_machine=*this;
00590 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00591 g_counter_implicit.increment(tm_stats::simple_nonproductive, temp_machine.number_represented());
00592 c_counter_implicit.increment(tm_stats::simple_nonproductive, 1);
00593 }
00594 #else
00595 temp_machine=*this;
00596 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00597 output_machine(temp_machine, destination, alphabet);
00598 #endif
00599 }
00600
00601
00602 temp_machine=*this;
00603 temp_machine.add_move_transition(current, tape_symbol, left, end_state);
00604 output_machine(temp_machine, destination, alphabet);
00605 temp_machine=*this;
00606 temp_machine.add_move_transition(current, tape_symbol, right, end_state);
00607 output_machine(temp_machine, destination, alphabet);
00608 }
00609
00610
00611 if(halt_state_exists)
00612 {
00613
00614 if(first_unreachable_state!=halt_state)
00615 {
00616 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin(); alpha_iter!=alphabet.end(); ++alpha_iter)
00617 {
00618 #ifdef no_ss_optimisation
00619 if((*alpha_iter)!=tape_symbol)
00620 {
00621 temp_machine=*this;
00622 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00623 output_machine(temp_machine, destination, alphabet);
00624 }
00625 else
00626 {
00627 temp_machine=*this;
00628 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00629 g_counter_implicit.increment(tm_stats::simple_nonproductive, temp_machine.number_represented());
00630 c_counter_implicit.increment(tm_stats::simple_nonproductive, 1);
00631 }
00632 #else
00633 temp_machine=*this;
00634 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00635 output_machine(temp_machine, destination, alphabet);
00636 #endif
00637 }
00638 temp_machine=*this;
00639 temp_machine.add_move_transition(current, tape_symbol, left, first_unreachable_state);
00640 output_machine(temp_machine, destination, alphabet);
00641 temp_machine=*this;
00642 temp_machine.add_move_transition(current, tape_symbol, right, first_unreachable_state);
00643 output_machine(temp_machine, destination, alphabet);
00644 }
00645
00646
00647 temp_machine=*this;
00648 temp_machine.add_write_transition(current, tape_symbol, tape_symbol, halt_state);
00649 output_machine(temp_machine, destination, alphabet);
00650 }
00651 }
00652
00660 template <typename OutputIterator>
00661 void generate_tn_quadruple_children_explicit(const std::list<T> &alphabet, OutputIterator destination) const
00662 {
00663
00664 T tape_symbol=tape.read();
00665
00666
00667 turing_machine<T> temp_machine=*this;
00668
00669
00670 for(transition_index_type end_state=0; end_state!=first_unreachable_state; ++end_state)
00671 {
00672
00673 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin(); alpha_iter!=alphabet.end(); ++alpha_iter)
00674 {
00675 #ifdef no_ss_optimisation
00676 if((*alpha_iter)!=tape_symbol)
00677 {
00678 temp_machine=*this;
00679 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00680 output_machine(temp_machine, destination, alphabet);
00681 }
00682 #else
00683 temp_machine=*this;
00684 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00685 output_machine(temp_machine, destination, alphabet);
00686 #endif
00687 }
00688
00689
00690 temp_machine=*this;
00691 temp_machine.add_move_transition(current, tape_symbol, left, end_state);
00692 output_machine(temp_machine, destination, alphabet);
00693 temp_machine=*this;
00694 temp_machine.add_move_transition(current, tape_symbol, right, end_state);
00695 output_machine(temp_machine, destination, alphabet);
00696 }
00697
00698
00699 if(halt_state_exists)
00700 {
00701
00702 if(first_unreachable_state<halt_state)
00703 {
00704 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin(); alpha_iter!=alphabet.end(); ++alpha_iter)
00705 {
00706 #ifdef no_ss_optimisation
00707 if((*alpha_iter)!=tape_symbol)
00708 {
00709 temp_machine=*this;
00710 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00711 output_machine(temp_machine, destination, alphabet);
00712 }
00713 #else
00714 temp_machine=*this;
00715 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00716 output_machine(temp_machine, destination, alphabet);
00717 #endif
00718 }
00719 temp_machine=*this;
00720 temp_machine.add_move_transition(current, tape_symbol, left, first_unreachable_state);
00721 output_machine(temp_machine, destination, alphabet);
00722 temp_machine=*this;
00723 temp_machine.add_move_transition(current, tape_symbol, right, first_unreachable_state);
00724 output_machine(temp_machine, destination, alphabet);
00725 }
00726
00727
00728
00729
00730
00731 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin() ; alpha_iter!=alphabet.end(); ++alpha_iter)
00732 {
00733 #ifdef no_ss_optimisation
00734 if((*alpha_iter)!=tape_symbol)
00735 {
00736 temp_machine=*this;
00737 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, halt_state);
00738 output_machine(temp_machine, destination, alphabet);
00739 }
00740 #else
00741 temp_machine=*this;
00742 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, halt_state);
00743 output_machine(temp_machine, destination, alphabet);
00744 #endif
00745 }
00746 temp_machine=*this;
00747 temp_machine.add_move_transition(current, tape_symbol, left, halt_state);
00748 output_machine(temp_machine, destination, alphabet);
00749 temp_machine=*this;
00750 temp_machine.add_move_transition(current, tape_symbol, right, halt_state);
00751 output_machine(temp_machine, destination, alphabet);
00752 }
00753 }
00754
00762 template <typename OutputIterator>
00763 void generate_all_tn_quadruple_children(const std::list<T> &alphabet, OutputIterator destination) const
00764 {
00765
00766 T tape_symbol=tape.read();
00767
00768
00769 turing_machine<T> temp_machine=*this;
00770
00771
00772 for(transition_index_type end_state=0; end_state!=first_unreachable_state; ++end_state)
00773 {
00774
00775 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin(); alpha_iter!=alphabet.end(); ++alpha_iter)
00776 {
00777 #ifdef no_ss_optimisation
00778 if((*alpha_iter)!=tape_symbol)
00779 {
00780 temp_machine=*this;
00781 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00782 output_machine(temp_machine, destination, alphabet);
00783 }
00784 else
00785 {
00786 temp_machine=*this;
00787 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00788 g_counter_implicit.increment(tm_stats::simple_nonproductive, temp_machine.number_represented());
00789 c_counter_implicit.increment(tm_stats::simple_nonproductive, 1);
00790 g_counter_explicit.increment(tm_stats::simple_nonproductive, temp_machine.number_represented_explicit());
00791 c_counter_explicit.increment(tm_stats::simple_nonproductive, 1);
00792 }
00793 #else
00794 temp_machine=*this;
00795 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, end_state);
00796 output_machine(temp_machine, destination, alphabet);
00797 #endif
00798 }
00799
00800
00801 temp_machine=*this;
00802 temp_machine.add_move_transition(current, tape_symbol, left, end_state);
00803 output_machine(temp_machine, destination, alphabet);
00804 temp_machine=*this;
00805 temp_machine.add_move_transition(current, tape_symbol, right, end_state);
00806 output_machine(temp_machine, destination, alphabet);
00807 }
00808
00809
00810 if(halt_state_exists)
00811 {
00812
00813 if(first_unreachable_state!=halt_state)
00814 {
00815 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin(); alpha_iter!=alphabet.end(); ++alpha_iter)
00816 {
00817 #ifdef no_ss_optimisation
00818 if((*alpha_iter)!=tape_symbol)
00819 {
00820 temp_machine=*this;
00821 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00822 output_machine(temp_machine, destination, alphabet);
00823 }
00824 else
00825 {
00826 temp_machine=*this;
00827 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00828 g_counter_implicit.increment(tm_stats::simple_nonproductive, temp_machine.number_represented());
00829 c_counter_implicit.increment(tm_stats::simple_nonproductive, 1);
00830 g_counter_explicit.increment(tm_stats::simple_nonproductive, temp_machine.number_represented_explicit());
00831 c_counter_explicit.increment(tm_stats::simple_nonproductive, 1);
00832 }
00833 #else
00834 temp_machine=*this;
00835 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, first_unreachable_state);
00836 output_machine(temp_machine, destination, alphabet);
00837 #endif
00838 }
00839 temp_machine=*this;
00840 temp_machine.add_move_transition(current, tape_symbol, left, first_unreachable_state);
00841 output_machine(temp_machine, destination, alphabet);
00842 temp_machine=*this;
00843 temp_machine.add_move_transition(current, tape_symbol, right, first_unreachable_state);
00844 output_machine(temp_machine, destination, alphabet);
00845 }
00846
00847
00848 for(typename std::list<T>::const_iterator alpha_iter=alphabet.begin() ; alpha_iter!=alphabet.end(); ++alpha_iter)
00849 {
00850 temp_machine=*this;
00851 temp_machine.add_write_transition(current, tape_symbol, *alpha_iter, halt_state);
00852 output_machine(temp_machine, destination, alphabet);
00853 }
00854 temp_machine=*this;
00855 temp_machine.add_move_transition(current, tape_symbol, left, halt_state);
00856 output_machine(temp_machine, destination, alphabet);
00857 temp_machine=*this;
00858 temp_machine.add_move_transition(current, tape_symbol, right, halt_state);
00859 output_machine(temp_machine, destination, alphabet);
00860 }
00861 }
00862
00863
00869 bool resetMachine()
00870 {
00871
00872 tape.reset();
00873 tape.reset_head();
00874 current = 0;
00875 steps = 0;
00876 run_status = run;
00877 return true;
00878 }
00879
00885 turing_machine<T> reverseMachine()
00886 {
00887 turing_machine<T> reverse(transition_function.size(), 0);
00888 int j;
00889
00890 for(j = 0; j < transition_function.size(); j++)
00891 {
00892 T write;
00893 typename infinite_tape<T>::direction move;
00894 typename std::vector<state<T> >::size_type nextState;
00895
00896 if(transition_function[j].simulate_transition(0, write, move, nextState) == state<T>::run)
00897 {
00898 switch(move)
00899 {
00900 case infinite_tape<T>::left:
00901 reverse.add_move_transition(j,0, infinite_tape<T>::right, nextState);
00902 break;
00903 case infinite_tape<T>::right:
00904 reverse.add_move_transition(j,0, infinite_tape<T>::left, nextState);
00905 break;
00906 case infinite_tape<T>::do_nothing:
00907 reverse.add_write_transition(j,0, write, nextState);
00908 }
00909 }
00910 if(transition_function[j].simulate_transition(1, write, move, nextState) == state<T>::run)
00911 {
00912 switch(move)
00913 {
00914 case infinite_tape<T>::left:
00915 reverse.add_move_transition(j,1, infinite_tape<T>::right, nextState);
00916 break;
00917 case infinite_tape<T>::right:
00918 reverse.add_move_transition(j,1, infinite_tape<T>::left, nextState);
00919 break;
00920 case infinite_tape<T>::do_nothing:
00921 reverse.add_write_transition(j,1, write, nextState);
00922 }
00923 }
00924 }
00925 return reverse;
00926 }
00927
00940 void rigMachine(typename std::vector<T> &riggedTape,
00941 int originalReadHead,
00942 int desiredReadHead,
00943 typename std::vector<state<T> >::size_type state,
00944 typename std::list<T>::iterator &leftBound,
00945 typename std::list<T>::iterator &rightBound,
00946 typename std::list<T>::iterator &desiredLocation)
00947 {
00948 resetMachine();
00949 typename std::list<T>::iterator currentLocation = tape.currentLocation();
00950 desiredLocation = tape.currentLocation();
00951 leftBound = tape.currentLocation();
00952
00953 for(int j = 0; j < riggedTape.size(); j++)
00954 {
00955 if(j == originalReadHead)
00956 tape.setCurrentLocation(currentLocation);
00957 *currentLocation = riggedTape[j];
00958 tape.checkIteratorRight(currentLocation);
00959 currentLocation++;
00960 }
00961 rightBound = currentLocation;
00962 rightBound--;
00963 if(desiredReadHead == -1)
00964 desiredLocation--;
00965 if(desiredReadHead == riggedTape.size())
00966 desiredLocation = currentLocation;
00967
00968 current = state;
00969 }
00970
00976 std::vector<state<T> >& stateSet()
00977 {
00978 return transition_function;
00979 }
00980
00986 transition_index_type haltState()
00987 {
00988 if(!halt_state_exists)
00989 return first_unreachable_state;
00990 return halt_state;
00991 }
00992
00998 move_type nextMove()
00999 {
01000 T write;
01001 move_type move;
01002 typename std::vector<state<T> >::size_type nextState;
01003 if(transition_function[current].simulate_transition(tape.read(), write, move, nextState) == state<T>::halt)
01004 return halt_move;
01005 return move;
01006 }
01007
01014 void printTMO(std::ostream &out) const
01015 {
01016 out << "digraph TM" << std::endl;
01017 out << "{" << std::endl;
01018 out << "/*This machine represents " << number_represented() << " machines*/" << std::endl;
01019 out << "/*Settings*/" << std::endl;
01020 out << "rankdir = LR;" << std::endl;
01021 out << "start [shape=plaintext];" << std::endl;
01022 out << "halt [shape=plaintext];" << std::endl;
01023
01024 typename std::vector<state<T> >::const_iterator i=transition_function.begin();
01025 int count = 0;
01026 T write;
01027 typename infinite_tape<T>::direction move;
01028 typename std::vector<state<T> >::size_type nextState;
01029 for(count = 0; i!=transition_function.end(); ++i)
01030 {
01031 if(count != halt_state)
01032 out << (count++) << " [shape=circle];" << std::endl;
01033 }
01034
01035 out << std::endl;
01036 out << "/*GraphOutput*/" << std::endl;
01037 out << "/*NumStates = " << count << "*/" << std::endl;
01038 out << "/*Quadruple*/" << std::endl;
01039 if(implicitMachine())
01040 out << "/*Implicit*/" << std::endl;
01041 else
01042 out << "/*Explicit*/" << std::endl;
01043 out << "start -> 0;" << std::endl;
01044
01045 i=transition_function.begin();
01046 count = 0;
01047 for(count = 0; i!=transition_function.end(); ++i, ++count)
01048 {
01049 if(count != halt_state)
01050 {
01051 if((*i).simulate_transition(0, write, move, nextState) == state<T>::run)
01052 {
01053 if(nextState == halt_state && write == 0 && move == infinite_tape<T>::do_nothing)
01054 out << count << " -> halt [label=\"" << 0 << "\"];" << std::endl;
01055 else
01056 {
01057 if(nextState == halt_state)
01058 out << count << " -> halt [label=\"" << 0 << ':';
01059 else
01060 out << count << " -> " << nextState << " [label=\"" << 0 << ':';
01061 if(write != 0)
01062 out << write << "\"];";
01063 else
01064 {
01065 if(move == infinite_tape<T>::left)
01066 out << "L\"];";
01067 else
01068 out << "R\"];";
01069 }
01070 out << std::endl;
01071 }
01072 }
01073
01074
01075 if((*i).simulate_transition(1, write, move, nextState) == state<T>::run)
01076 {
01077 if(nextState == halt_state && write == 1 && move == infinite_tape<T>::do_nothing)
01078 out << count << " -> halt [label=\"" << 1 << "\"];" << std::endl;
01079 else
01080 {
01081 if(nextState == halt_state)
01082 out << count << " -> halt [label=\"" << 1 << ':';
01083 else
01084 out << count << " -> " << nextState << " [label=\"" << 1 << ':';
01085 if(write != 1)
01086 out << write << "\"];";
01087 else
01088 {
01089 if(move == infinite_tape<T>::left)
01090 out << "L\"];";
01091 else
01092 out << "R\"];";
01093 }
01094 out << std::endl;
01095 }
01096 }
01097
01098
01099 }
01100 }
01101 out << "/*EndGraphOutput*/" << std::endl;
01102 out << "}" << std::endl;
01103 }
01104
01110 bool implicitMachine() const
01111 {
01112 if(!halt_state_exists)
01113 return true;
01114 else
01115 {
01116 typename std::vector<state<T> >::const_iterator i=transition_function.begin();
01117 T write;
01118 typename infinite_tape<T>::direction move;
01119 typename std::vector<state<T> >::size_type nextState;
01120 for(i; i != transition_function.end(); i++)
01121 {
01122 if((*i).simulate_transition(0, write, move, nextState) == state<T>::run)
01123 {
01124 if(nextState == halt_state && (write != 0 || move != infinite_tape<T>::do_nothing))
01125 return false;
01126 }
01127 if((*i).simulate_transition(1, write, move, nextState) == state<T>::run)
01128 {
01129 if(nextState == halt_state && (write != 1 || move != infinite_tape<T>::do_nothing))
01130 return false;
01131 }
01132 }
01133 return true;
01134 }
01135 }
01136
01137
01138
01139 private:
01140
01141 template <typename OutputIterator>
01142 inline void output_machine(turing_machine<T>& to_output, OutputIterator destination) const
01143 {
01144 std::cout<<"fuck"<<std::endl;
01145 }
01146
01147 template <typename OutputIterator>
01148 inline void output_machine(turing_machine<T>& to_output, OutputIterator destination, const std::list<T> &alphabet) const
01149 {
01150 #ifdef enable_optimisations
01151 if(run_checks(to_output, alphabet))
01152 {
01153 to_output.run_status=run;
01154 *(destination++)=to_output;
01155 }
01156 #else
01157 to_output.run_status=run;
01158 *(destination++)=to_output;
01159 #endif
01160 }
01161
01162 public:
01163 private:
01164
01169 bool inline run_checks(const turing_machine<T> &to_check, const std::list<T> &alphabet) const
01170 {
01171 #ifdef first_write_optimisation
01172 T fw_write;
01173 typename infinite_tape<T>::direction fw_move;
01174 transition_index_type fw_next;
01175 to_check.transition_function[0].simulate_transition(0, fw_write, fw_move, fw_next);
01176
01177 if(fw_write!=1 || fw_move!=do_nothing)
01178 {
01179 if(to_check.implicitMachine())
01180 {
01181 g_counter_implicit.increment(tm_stats::first_write_1, to_check.number_represented());
01182 c_counter_implicit.increment(tm_stats::first_write_1, 1);
01183 }
01184 g_counter_explicit.increment(tm_stats::first_write_1, to_check.number_represented_explicit());
01185 c_counter_explicit.increment(tm_stats::first_write_1, 1);
01186 return false;
01187 }
01188
01189 #ifdef first_move_optimisation
01190 T fm_write;
01191 typename infinite_tape<T>::direction fm_move;
01192 transition_index_type fm_next;
01193 to_check.transition_function[fw_next].simulate_transition(1, fm_write, fm_move, fm_next);
01194
01195 if(fm_move==left)
01196 {
01197 if(to_check.implicitMachine())
01198 {
01199 g_counter_implicit.increment(tm_stats::first_move_right, to_check.number_represented());
01200 c_counter_implicit.increment(tm_stats::first_move_right, 1);
01201 }
01202 g_counter_explicit.increment(tm_stats::first_move_right, to_check.number_represented_explicit());
01203 c_counter_explicit.increment(tm_stats::first_move_right, 1);
01204 return false;
01205 }
01206 #endif
01207 #endif
01208
01209 #ifdef no_ssprime_sprimes_optimisation
01210
01211 T c_read=to_check.tape.read(), c_write;
01212 typename infinite_tape<T>::direction c_move;
01213 transition_index_type c_current=to_check.current, c_next;
01214
01215
01216 if(to_check.transition_function[c_current].simulate_transition(c_read, c_write, c_move, c_next)==run && c_move==do_nothing)
01217 {
01218
01219 T n_read=c_write, n_write;
01220 typename infinite_tape<T>::direction n_move;
01221 transition_index_type n_current=c_next, n_next;
01222
01223
01224 if(to_check.transition_function[n_current].simulate_transition(n_read, n_write, n_move, n_next)==run && n_move==do_nothing)
01225 {
01226
01227 if(c_read==n_write)
01228 {
01229 if(to_check.implicitMachine())
01230 {
01231 g_counter_implicit.increment(tm_stats::complex_nonproductive, to_check.number_represented());
01232 c_counter_implicit.increment(tm_stats::complex_nonproductive, 1);
01233 }
01234 g_counter_explicit.increment(tm_stats::complex_nonproductive, to_check.number_represented_explicit());
01235 c_counter_explicit.increment(tm_stats::complex_nonproductive, 1);
01236 return false;
01237 }
01238 }
01239
01240
01241 T p_read=c_write, p_write;
01242 typename infinite_tape<T>::direction p_move;
01243 transition_index_type p_next;
01244
01245 for(transition_index_type p_current=0, p_end=std::min(to_check.halt_state, to_check.first_unreachable_state); p_current!=p_end; ++p_current)
01246 {
01247
01248 if(to_check.transition_function[p_current].simulate_transition(p_read, p_write, p_move, p_next)==run && p_move==do_nothing && p_next==c_current && p_write==c_read)
01249 {
01250 if(to_check.implicitMachine())
01251 {
01252 g_counter_implicit.increment(tm_stats::complex_nonproductive, to_check.number_represented());
01253 c_counter_implicit.increment(tm_stats::complex_nonproductive, 1);
01254 }
01255 g_counter_explicit.increment(tm_stats::complex_nonproductive, to_check.number_represented_explicit());
01256 c_counter_explicit.increment(tm_stats::complex_nonproductive, 1);
01257 return false;
01258 }
01259 }
01260 }
01261 #endif
01262
01263 return true;
01264 }
01265
01266 public:
01267
01268 protected:
01269 bool halt_state_exists;
01270 transition_index_type current, halt_state, first_unreachable_state;
01271 typename std::vector<state<T> > transition_function;
01272 infinite_tape<T> tape;
01273 transition_count_type steps;
01274 result_type run_status;
01275 };
01276
01277
01278
01279
01280
01281
01282
01283 template <typename T>
01284 std::ostream& operator<<(std::ostream &out, const turing_machine<T> &to_print)
01285 {
01286 to_print.print(out);
01287 return out;
01288 }
01289
01290 #endif