summaryrefslogtreecommitdiff
path: root/ipl/progs/miu.icn
blob: 627629e8a1efd3c6324522a370bd1abd8790368d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
############################################################################
#
#	File:     miu.icn
#
#	Subject:  Program to generate strings from MIU system
#
#	Author:   Cary A. Coutant, modified by Ralph E. Griswold
#
#	Date:     January 3, 1994
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#     This program generates strings from the MIU string system.
#
#     The number of generations is determined by the command-line argument.
#  The default is 7.
#
#  Reference:
#
#     Godel, Escher, and Bach: an Eternal Golden Braid, Douglas R.
#  Hofstadter, Basic Books, 1979. pp. 33-36.
#
############################################################################

procedure main(arg)
   local count, gen, limit

   limit := integer(arg[1]) | 7
   gen := set(["MI"])

   every count := 1 to limit do {
      gen := nextgen(gen)
      show(count,gen)
      }

end

# show - show a generation of strings

procedure show(count,gen)

   write("Generation #",count,", ",*gen," strings")
   every write("   ",image(!sort(gen)))
   write()

end

# nextgen - given a generation of strings, compute the next generation

procedure nextgen(gen)
   local new

   new := set()
   every insert(new,apply(!gen))
   return new

end

# apply - produce all strings derivable from s in a single rule application

procedure apply(s)

# Here's a case where referring to the subject by name inside scanning
# is justified.

   s ? {
     if ="M" then suspend s || tab(0)
     tab(-1)			# to last character
     if ="I" then suspend s || "U"
     tab(1)			# back to the beginning
     suspend tab(find("III")) || (move(3) & "U") || tab(0)
     tab(1)			# back to the beginning
     suspend tab(find("UU")) || (move(2) & tab(0))
     }

end