peano.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Peano integers are represented by a linked
  2. // list whose nodes contain no data
  3. // (the nodes are the data).
  4. // http://en.wikipedia.org/wiki/Peano_axioms
  5. // This program demonstrates that Go's automatic
  6. // stack management can handle heavily recursive
  7. // computations.
  8. package main
  9. import "fmt"
  10. // Number is a pointer to a Number
  11. type Number *Number
  12. // The arithmetic value of a Number is the
  13. // count of the nodes comprising the list.
  14. // (See the count function below.)
  15. // -------------------------------------
  16. // Peano primitives
  17. func zero() *Number {
  18. return nil
  19. }
  20. func isZero(x *Number) bool {
  21. return x == nil
  22. }
  23. func add1(x *Number) *Number {
  24. e := new(Number)
  25. *e = x
  26. return e
  27. }
  28. func sub1(x *Number) *Number {
  29. return *x
  30. }
  31. func add(x, y *Number) *Number {
  32. if isZero(y) {
  33. return x
  34. }
  35. return add(add1(x), sub1(y))
  36. }
  37. func mul(x, y *Number) *Number {
  38. if isZero(x) || isZero(y) {
  39. return zero()
  40. }
  41. return add(mul(x, sub1(y)), x)
  42. }
  43. func fact(n *Number) *Number {
  44. if isZero(n) {
  45. return add1(zero())
  46. }
  47. return mul(fact(sub1(n)), n)
  48. }
  49. // -------------------------------------
  50. // Helpers to generate/count Peano integers
  51. func gen(n int) *Number {
  52. if n > 0 {
  53. return add1(gen(n - 1))
  54. }
  55. return zero()
  56. }
  57. func count(x *Number) int {
  58. if isZero(x) {
  59. return 0
  60. }
  61. return count(sub1(x)) + 1
  62. }
  63. // -------------------------------------
  64. // Print i! for i in [0,9]
  65. func main() {
  66. for i := 0; i <= 9; i++ {
  67. f := count(fact(gen(i)))
  68. fmt.Println(i, "! =", f)
  69. }
  70. }