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 st := &runtime.MemStats
127 t0 := time.Nanoseconds()
129 for i := 0; i <= 9; i++ {
130 print(i, "! = ", count(fact(gen(i))), "\n")
133 t1 := time.Nanoseconds()
135 fmt.Printf("garbage.BenchmarkPeano 1 %d ns/op\n", t1-t0)
136 fmt.Printf("garbage.BenchmarkPeanoPause %d %d ns/op\n", st.NumGC, int64(st.PauseNs)/int64(st.NumGC))