aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2015-02-22 17:14:15 +0100
committerAdrian Kummerlaender2015-02-22 17:14:15 +0100
commit41b63eff7f76e6574ef238f821dad0212a619c2a (patch)
tree291652f853e32c80183fd1178d470c5499eee1c5
parent18fe83991563c0072fabaa60ff161e781a5364c2 (diff)
downloadTypeAsValue-41b63eff7f76e6574ef238f821dad0212a619c2a.tar
TypeAsValue-41b63eff7f76e6574ef238f821dad0212a619c2a.tar.gz
TypeAsValue-41b63eff7f76e6574ef238f821dad0212a619c2a.tar.bz2
TypeAsValue-41b63eff7f76e6574ef238f821dad0212a619c2a.tar.xz
TypeAsValue-41b63eff7f76e6574ef238f821dad0212a619c2a.zip
Improved `simulate` function of the Turing machine example
* introduced `state::state_accessor` helper function and moved position logic into `updatePosition` * added `IsEqual` comparator and expressed other basic comparators in terms of itself
-rw-r--r--example/turing/src/machine.h92
-rw-r--r--example/turing/src/state.h20
-rw-r--r--src/list/list.h8
-rw-r--r--src/type.h16
-rw-r--r--test.cc22
5 files changed, 107 insertions, 51 deletions
diff --git a/example/turing/src/machine.h b/example/turing/src/machine.h
index c1338e1..a30c6e3 100644
--- a/example/turing/src/machine.h
+++ b/example/turing/src/machine.h
@@ -8,21 +8,41 @@
namespace machine {
+// (define (updatePosition direction position)
+// (cond ((= direction RIGHT) (+ position 1))
+// ((= direction LEFT) (- Position 1))
+// (else position)))
+template <
+ typename Direction,
+ typename Position
+>
+using updatePosition = tav::Cond<
+ tav::Branch<
+ tav::IsEqualValue<Direction, tav::Char<'R'>>,
+ tav::Add<Position, tav::Size<1>>
+ >,
+ tav::Branch<
+ tav::IsEqualValue<Direction, tav::Char<'L'>>,
+ tav::Substract<Position, tav::Size<1>>
+ >,
+ tav::Else<
+ Position
+ >
+>;
+
+
// (define (simulate transition tape state position)
// (if (= state FINAL)
// tape
-// (let* ((current_symbol (readSymbol position tape))
-// (current_state (transition state current_symbol))
-// (direction (nth MOVE current_state))
-// (next_symbol (nth WRITE current_state))
-// (next_state (nth NEXT current_state))
-// (next_position (cond ((= direction RIGHT) (+ position 1))
-// ((= direction LEFT) (- Position 1))
-// (else position))))
+// (let ((current_state (transition state
+// (readSymbol position tape))))
// (simulate transition
-// (writeSymbol position next_symbol tape)
-// next_state,
-// next_position)))
+// (current_state NEXT)
+// (writeSymbol position
+// (current_state WRITE)
+// tape)
+// (updatePosition (current_state MOVE)
+// position)))))
template <
template<typename, typename> class Transition,
typename State,
@@ -30,39 +50,31 @@ template <
typename Position
>
class simulate {
- private:
- using current_symbol = tape::readSymbol<Position, Tape>;
- using current_state = Transition<State, current_symbol>;
-
- using direction = tav::Nth<state::field::MOVE, current_state>;
-
- using next_symbol = tav::Nth<state::field::WRITE, current_state>;
- using next_state = tav::Nth<state::field::NEXT, current_state>;
- using next_position = tav::Cond<
- tav::Branch<
- tav::IsEqualValue<direction, tav::Char<'R'>>,
- tav::Add<Position, tav::Size<1>>
- >,
- tav::Branch<
- tav::IsEqualValue<direction, tav::Char<'L'>>,
- tav::Substract<Position, tav::Size<1>>
- >,
- tav::Else<
- Position
- >
- >;
+ static_assert(
+ tav::Not<tav::LowerThan<Position, tav::Size<0>>>::value,
+ "machine head position out of bounds"
+ );
- static_assert(
- tav::Not<tav::LowerThan<next_position, tav::Size<0>>>::value,
- "next position out of bounds"
- );
+ private:
+ template <typename Field>
+ using current_state = typename Transition<
+ State,
+ tape::readSymbol<Position, Tape>
+ >::template get<Field>;
public:
using type = tav::Eval<simulate<
Transition,
- next_state,
- tape::writeSymbol<Position, next_symbol, Tape>,
- next_position
+ current_state<state::field::NEXT>,
+ tape::writeSymbol<
+ Position,
+ current_state<state::field::WRITE>,
+ Tape
+ >,
+ updatePosition<
+ current_state<state::field::MOVE>,
+ Position
+ >
>>;
};
@@ -77,8 +89,8 @@ struct simulate<Transition, void, Tape, Position> {
// (define (run program state tape position)
// (simulate (transition program)
-// tape
// state
+// tape
// position))
template <
typename Program,
diff --git a/example/turing/src/state.h b/example/turing/src/state.h
index f5bd7f2..51fe347 100644
--- a/example/turing/src/state.h
+++ b/example/turing/src/state.h
@@ -9,12 +9,26 @@ namespace machine {
namespace state {
-struct field {
+namespace field {
using ID = tav::Size<0>;
using READ = tav::Size<1>;
using WRITE = tav::Size<2>;
using NEXT = tav::Size<3>;
using MOVE = tav::Size<4>;
+}
+
+// (define (state_accessor state)
+// (lambda (field)
+// (nth field state)))
+template <typename State>
+struct state_accessor {
+ static_assert(
+ tav::IsPair<State>::value,
+ "machine state is invalid"
+ );
+
+ template <typename Field>
+ using get = tav::Nth<Field, State>;
};
// (define (state_predicate id read)
@@ -54,7 +68,9 @@ struct transition {
typename State,
typename Symbol
>
- using state = findState<State, Symbol, States>;
+ using state = state_accessor<
+ findState<State, Symbol, States>
+ >;
};
}
diff --git a/src/list/list.h b/src/list/list.h
index cf4f415..c23362a 100644
--- a/src/list/list.h
+++ b/src/list/list.h
@@ -18,11 +18,11 @@ using ListOfType = List<
std::integral_constant<Type, Values>...
>;
-template <typename Cons>
-using Head = Car<Cons>;
+template <typename Pair>
+using Head = Car<Pair>;
-template <typename Cons>
-using Tail = Cdr<Cons>;
+template <typename Pair>
+using Tail = Cdr<Pair>;
}
diff --git a/src/type.h b/src/type.h
index c2ad2d8..2537b70 100644
--- a/src/type.h
+++ b/src/type.h
@@ -24,10 +24,16 @@ template <
typename X,
typename Y
>
-using IsEqualType = Eval<std::is_same<
+using IsEqual = Eval<std::is_same<X, Y>>;
+
+template <
+ typename X,
+ typename Y
+>
+using IsEqualType = IsEqual<
typename X::value_type,
typename Y::value_type
->>;
+>;
template <
typename X,
@@ -36,13 +42,13 @@ template <
using IsEqualValue = Boolean<X::value == Y::value>;
template <typename X>
-using IsTrue = IsEqualValue<X, Boolean<true>>;
+using IsBoolean = IsEqual<typename X::value_type, bool>;
template <typename X>
-using IsBoolean = Eval<std::is_same<typename X::value_type, bool>>;
+using IsTrue = IsEqualValue<X, Boolean<true>>;
template <typename X>
-using IsSize = Eval<std::is_same<typename X::value_type, std::size_t>>;
+using IsSize = IsEqual<typename X::value_type, std::size_t>;
}
diff --git a/test.cc b/test.cc
index 774f9be..44c0f6f 100644
--- a/test.cc
+++ b/test.cc
@@ -33,6 +33,28 @@ int main(int, char **) { }
static_assert(
std::is_same<
tav::Boolean<true>,
+ tav::IsEqual<
+ tav::Pair<tav::Int<1>, tav::Int<2>>,
+ tav::Pair<tav::Int<1>, tav::Int<2>>
+ >
+ >::value,
+ "(IsEqual '(1 . 2) '(1 . 2)) != #t"
+);
+
+static_assert(
+ std::is_same<
+ tav::Boolean<false>,
+ tav::IsEqual<
+ tav::Pair<tav::Int<1>, tav::Int<2>>,
+ tav::Pair<tav::Int<2>, tav::Int<3>>
+ >
+ >::value,
+ "(IsEqual '(1 . 2) '(2 . 3)) != #f"
+);
+
+static_assert(
+ std::is_same<
+ tav::Boolean<true>,
tav::IsEqualType<tav::Int<1>, tav::Int<2>>
>::value,
"(IsEqualType 1 2) != #t"