自然数の定義には、ペアノの公理[anchor=ref1 goto=ref1_][1][/anchor]を使っています。(数学屋ではないので、間違ったことやってたらすいません)
方針としては、ある構造体Xを定義し、Xを評価したものを内部でtypedefして
X::evalという別の型を作り上げています。(XとX::evalが同じになることもあります。)
そして、二つの型X, Yに対して、X::eval型のオブジェクトにY::eval型のオブジェクトに代入できるとき、XとYは等価であるとしています。
以下ソースコード
// 0
// 自然数の先頭元を表す
struct zero
{
typedef zero eval;
};
// 任意の自然数 N の successor s(N)
// N の次の自然数を表す
template
struct suc
{
typedef suc eval;
};
// 任意の自然数 N, M に対して、加算 N + M を定義する
// テンプレートの特殊化により分岐
template
struct add
{
typedef typename add::eval eval;
};
// N + 0 = N
template
struct add
{
typedef typename N::eval eval;
};
// N + s(M) = s(N + M)
template
struct add>
{
typedef typename suc>::eval eval;
};
// 1 := s(0), 2 := s(1) = s(s(0)) と定義する
// 1 + 1 = 2を証明する
int main()
{
// 左辺 1 + 1
add, suc>::eval lhs;
// 右辺 2
suc>::eval rhs;
// コンパイルが通れば証明完了
lhs = rhs;
}
http://ja.wikipedia.org/wiki/%E3%83%9A% ... C%E7%90%86