Created
June 20, 2014 16:10
-
-
Save lnicola/80ecc93747e74148777f to your computer and use it in GitHub Desktop.
C++ TMP Turing machine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "stdafx.h" | |
| using namespace std; | |
| enum class Direction | |
| { | |
| L, | |
| R | |
| }; | |
| #define TM_BEGIN(TM_NAME, INITIAL_STATE, FINAL_STATE) \ | |
| struct TM_NAME \ | |
| { \ | |
| template<int, typename> \ | |
| struct transition_table; \ | |
| \ | |
| struct INITIAL_STATE; \ | |
| struct FINAL_STATE; \ | |
| \ | |
| typedef INITIAL_STATE initial_state; \ | |
| typedef FINAL_STATE final_state; | |
| #define TM_STATE(STATE) \ | |
| struct STATE; | |
| #define TM_END() \ | |
| }; | |
| #define TM_TRANSITION(TM_NAME, STATE, SYM, NEW_STATE, OUTPUT, DIR) \ | |
| template<> \ | |
| struct TM_NAME::transition_table<SYM, TM_NAME::STATE> \ | |
| { \ | |
| static const int symbol = OUTPUT; \ | |
| static const Direction direction = Direction::DIR; \ | |
| typedef NEW_STATE state; \ | |
| }; | |
| template<int Value> | |
| struct repeat | |
| { | |
| static const int head = Value; | |
| typedef repeat<Value> tail; | |
| }; | |
| template<int Head, typename Tail> | |
| struct cons | |
| { | |
| static const int head = Head; | |
| typedef Tail tail; | |
| }; | |
| template<Direction, typename Left, typename Right> | |
| struct step { }; | |
| template<typename Left, typename Right> | |
| struct step<Direction::L, Left, Right> | |
| { | |
| typedef typename Left::tail left; | |
| typedef cons<Left::head, Right> right; | |
| }; | |
| template<typename Left, typename Right> | |
| struct step<Direction::R, Left, Right> | |
| { | |
| typedef cons<Right::head, Left> left; | |
| typedef typename Right::tail right; | |
| }; | |
| template<typename TuringMachine, typename Left, typename Right, typename State = typename TuringMachine::initial_state> | |
| struct turing_machine | |
| { | |
| typedef typename TuringMachine::template transition_table<Right::head, State> transition; | |
| typedef step<transition::direction, Left, cons<transition::symbol, typename Right::tail>> after; | |
| typedef turing_machine<TuringMachine, typename after::left, typename after::right, typename transition::state> next; | |
| typedef typename next::final_left final_left; | |
| typedef typename next::final_right final_right; | |
| }; | |
| template<typename TuringMachine, typename Left, typename Right> | |
| struct turing_machine<TuringMachine, Left, Right, typename TuringMachine::final_state> | |
| { | |
| typedef Left final_left; | |
| typedef Right final_right; | |
| }; | |
| template<typename> | |
| struct type_list_to_vector | |
| { | |
| void operator()(std::vector<int> &output); | |
| }; | |
| template<int Head, typename Tail> | |
| struct type_list_to_vector<cons<Head, Tail>> | |
| { | |
| void operator()(std::vector<int> &output) | |
| { | |
| output.push_back(Head); | |
| type_list_to_vector<Tail>()(output); | |
| } | |
| }; | |
| template<int Value> | |
| struct type_list_to_vector<repeat<Value>> | |
| { | |
| void operator()(std::vector<int> &output) | |
| { | |
| output.push_back(Value); | |
| } | |
| }; | |
| template<typename Left, typename Right> | |
| void dump_tape() | |
| { | |
| vector<int> tape; | |
| type_list_to_vector<Left>()(tape); | |
| cout << ".. " << tape.back() << ' '; | |
| for (auto it = tape.crbegin(); it != tape.crend(); ++it) | |
| cout << *it << ' '; | |
| tape.clear(); | |
| type_list_to_vector<Right>()(tape); | |
| cout << '*' << tape.front() << "* "; | |
| for (auto it = tape.cbegin() + 1; it != tape.cend(); ++it) | |
| cout << *it << ' '; | |
| cout << tape.back() << " .." << endl; | |
| } | |
| template<typename> | |
| struct simulator | |
| { | |
| void operator()(); | |
| }; | |
| template<typename TuringMachine, typename Left, typename Right, typename State> | |
| struct simulator<turing_machine<TuringMachine, Left, Right, State>> | |
| { | |
| void operator()() | |
| { | |
| dump_tape<Left, Right>(); | |
| simulator<typename turing_machine<TuringMachine, Left, Right, State>::next>()(); | |
| } | |
| }; | |
| template<typename TuringMachine, typename Left, typename Right> | |
| struct simulator<turing_machine<TuringMachine, Left, Right, typename TuringMachine::final_state>> | |
| { | |
| void operator()() | |
| { | |
| dump_tape<Left, Right>(); | |
| } | |
| }; | |
| TM_BEGIN(busy_beaver, A, H) | |
| TM_STATE(A) | |
| TM_STATE(B) | |
| TM_STATE(H) | |
| TM_END() | |
| TM_TRANSITION(busy_beaver, A, 0, B, 1, R) | |
| TM_TRANSITION(busy_beaver, B, 0, A, 1, L) | |
| TM_TRANSITION(busy_beaver, A, 1, B, 1, L) | |
| TM_TRANSITION(busy_beaver, B, 1, H, 1, R) | |
| int main() | |
| { | |
| typedef turing_machine<busy_beaver, repeat<0>, repeat<0>> tm; | |
| //cout << typeid(tm::next).name() << endl; | |
| //cout << typeid(tm::next::next).name() << endl; | |
| //cout << typeid(tm::next::next::next).name() << endl; | |
| //cout << typeid(tm::next::next::next::next).name() << endl; | |
| //cout << typeid(tm::next::next::next::next::next).name() << endl; | |
| //cout << typeid(tm::next::next::next::next::next::next).name() << endl; | |
| //cout << endl; | |
| simulator<tm>()(); | |
| //cout << typeid(tm::final_left).name() << endl; | |
| //cout << typeid(tm::final_right).name() << endl; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment