1
// $G $F.go && $L $F.$A && ./$A.out
3
// Copyright 2009 The Go Authors. All rights reserved.
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file.
21
// -------------------------------------
24
func zero() *Number { return nil }
27
func is_zero(x *Number) bool { return x == nil }
30
func add1(x *Number) *Number {
37
func sub1(x *Number) *Number { return x.next }
40
func add(x, y *Number) *Number {
45
return add(add1(x), sub1(y))
49
func mul(x, y *Number) *Number {
50
if is_zero(x) || is_zero(y) {
54
return add(mul(x, sub1(y)), x)
58
func fact(n *Number) *Number {
63
return mul(fact(sub1(n)), n)
67
// -------------------------------------
68
// Helpers to generate/count Peano integers
70
func gen(n int) *Number {
72
return add1(gen(n - 1))
79
func count(x *Number) int {
84
return count(sub1(x)) + 1
88
func check(x *Number, expected int) {
91
panic(fmt.Sprintf("error: found %d; expected %d", c, expected))
96
// -------------------------------------
97
// Test basic functionality
101
check(add1(zero()), 1)
104
check(add(gen(3), zero()), 3)
105
check(add(zero(), gen(4)), 4)
106
check(add(gen(3), gen(4)), 7)
108
check(mul(zero(), zero()), 0)
109
check(mul(gen(3), zero()), 0)
110
check(mul(zero(), gen(4)), 0)
111
check(mul(gen(3), add1(zero())), 3)
112
check(mul(add1(zero()), gen(4)), 4)
113
check(mul(gen(3), gen(4)), 12)
115
check(fact(zero()), 1)
116
check(fact(add1(zero())), 1)
117
check(fact(gen(5)), 120)
121
// -------------------------------------
126
t0 := time.Nanoseconds()
128
for i := 0; i <= 9; i++ {
129
print(i, "! = ", count(fact(gen(i))), "\n")
132
t1 := time.Nanoseconds()
134
gcstats("BenchmarkPeano", 1, t1-t0)