]> Cypherpunks.ru repositories - gostls13.git/blob - test/peano.go
single argument panic
[gostls13.git] / test / peano.go
1 // $G $F.go && $L $F.$A && ./$A.out
2
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.
6
7 package main
8
9 type Number struct {
10         next *Number
11 }
12
13
14 // -------------------------------------
15 // Peano primitives
16
17 func zero() *Number {
18         return nil
19 }
20
21
22 func is_zero(x *Number) bool {
23         return x == nil
24 }
25
26
27 func add1(x *Number) *Number {
28         e := new(Number)
29         e.next = x
30         return e
31 }
32
33
34 func sub1(x *Number) *Number {
35         return x.next
36 }
37
38
39 func add(x, y *Number) *Number {
40         if is_zero(y) {
41                 return x
42         }
43
44         return add(add1(x), sub1(y))
45 }
46
47
48 func mul(x, y *Number) *Number {
49         if is_zero(x) || is_zero(y) {
50                 return zero()
51         }
52
53         return add(mul(x, sub1(y)), x)
54 }
55
56
57 func fact(n *Number) *Number {
58         if is_zero(n) {
59                 return add1(zero())
60         }
61
62         return mul(fact(sub1(n)), n)
63 }
64
65
66 // -------------------------------------
67 // Helpers to generate/count Peano integers
68
69 func gen(n int) *Number {
70         if n > 0 {
71                 return add1(gen(n - 1))
72         }
73
74         return zero()
75 }
76
77
78 func count(x *Number) int {
79         if is_zero(x) {
80                 return 0
81         }
82
83         return count(sub1(x)) + 1
84 }
85
86
87 func check(x *Number, expected int) {
88         var c = count(x)
89         if c != expected {
90                 print("error: found ", c, "; expected ", expected, "\n")
91                 panic("fail")
92         }
93 }
94
95
96 // -------------------------------------
97 // Test basic functionality
98
99 func verify() {
100         check(zero(), 0)
101         check(add1(zero()), 1)
102         check(gen(10), 10)
103
104         check(add(gen(3), zero()), 3)
105         check(add(zero(), gen(4)), 4)
106         check(add(gen(3), gen(4)), 7)
107
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)
114
115         check(fact(zero()), 1)
116         check(fact(add1(zero())), 1)
117         check(fact(gen(5)), 120)
118 }
119
120
121 // -------------------------------------
122 // Factorial
123
124
125 func main() {
126
127         verify()
128         for i := 0; i <= 9; i++ {
129                 print(i, "! = ", count(fact(gen(i))), "\n")
130         }
131 }