summaryrefslogtreecommitdiff
path: root/ipl/progs/polydemo.icn
blob: d90d8f9672106fce8e60c1e09ccd997abeacc277 (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
############################################################################
#
#       File:     polydemo.icn
#
#       Subject:  Program to demonstrate polynomial library
#
#       Author:   Erik Eid
#                         
#       Date:     May 23, 1994
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#     This program is an example for the use of the polystuf library.  The
# user is given a number of options that allow the creation, output,
# deletion, or operations on up to 26 polynomials, indexed by letter.
#
# Available commands:
#     (R)ead      - allows input of a polynomial by giving pairs of
#                   coefficients and exponents.  For example, entering
#                   5, 6, 2, and 3 will create 5x^6 + 2x^3.  This polynomial
#                   will be stored by an index which is a lower-case letter.
#     (W)rite     - outputs to the screen a chosen polynomial.
#     (A)dd       - adds two polynomials and defines the sum as a third
#     (S)ubtract  - subtracts two polynomials and defines the difference as
#                   a third.
#     (M)ultiply  - multiplies two polynomials and defines the product as a
#                   third.
#     (E)valuate  - gives the result of setting x in a polynomial to a value
#     (C)lear     - deletes one polynomial
#     (H)elp      - lists all commands
#     (Q)uit      - end the demonstration
#
############################################################################
#
#  Links: polystuf
#
############################################################################

link polystuf

global filled, undefined, poly_table

procedure main()
local option
  poly_table := table()                    # Set up a table that will hold
                                           # all of the polynomials (which
                                           # are tables themselves).
  filled := "That slot is already filled!"
  undefined := "That has not been defined!"
  SetUpDisplay()
  repeat {
    ShowInUse()
    writes ("RWASMECHQ> ")
    option := choice(read())               # Get first letter of entry in
                                           # lower-case format.
    case option of {
      "r": PRead()
      "w": PWrite()
      "a": PCalc ("+")
      "s": PCalc ("-")
      "m": PCalc ("*")
      "e": PEval()
      "c": PClear()
      "h": ShowHelp()
      "q": break
      default: write ("Invalid command!")
    }
    write()
  }
end

procedure SetUpDisplay()
  write (center ("Icon v8.10 Polynomial Demo", 80))
  write()
  ShowHelp()
  write (repl("-", 80))
  return
end

procedure ShowHelp()
  write (repl(" ", 10), "(R)ead      (W)rite     (A)dd       (S)ubtract")
  write (repl(" ", 10), "(M)ultiply  (E)valuate  (C)lear     _
    (H)elp      (Q)uit")
  return
end

procedure ShowInUse()
local keylist
  keylist := list()
  writes ("In Use:")
  every push (keylist, key(poly_table))    # Construct a list of the keys in
                                           # poly_table, corresponding to
                                           # which slots are being used.
  keylist := sort (keylist)
  every writes (" ", !keylist)
  write()
  return
end

procedure is_lower(c)
  if /c then fail
  if c == "" then fail
  return (c >>= "a") & (c <<= "z")         # Succeeds only if c is a lower-
end                                        # case letter.

procedure choice(s)
  return map(s[1], &ucase, &lcase)         # Returns the first character of
                                           # the given string converted to
                                           # lower-case.
end

procedure PRead()
local slot, terms, c, e
  repeat {
    writes ("Which slot to read into? ")
    slot := choice(read())
    if is_lower(slot) then break
  }
  if member (poly_table, slot) then {      # Disallow reading into an
    write (filled)                         # already occupied slot.
    fail
  }
  write ("Input terms as coefficient-exponent pairs.  Enter 0 for")
  write ("coefficient to stop.  Entries must be numerics.")
  terms := list()
  repeat {
    write()
    repeat {
      writes ("Coefficient> ")     
      c := read()
      if numeric(c) then break
    }
    if c = 0 then break
    repeat {
      writes ("   Exponent> ")     
      e := read()
      if numeric(e) then break
    }
    put (terms, c)                         # This makes a list compatible
    put (terms, e)                         # with the format needed by
                                           # procedure poly of polystuf.
  }
  if *terms = 0 then terms := [0, 0]       # No terms = zero polynomial.
  poly_table[slot] := poly ! terms         # Send the elements of terms as
                                           # parameters to poly and store
                                           # the resulting polynomial in the
                                           # proper slot.
  return
end

procedure PWrite ()
local slot
  repeat {
    writes ("Which polynomial to display? ")
    slot := choice(read())
    if is_lower(slot) then break
  }
  if member (poly_table, slot) then {      # Make sure there is a polynomial
    write (poly_string(poly_table[slot]))  # to write!
    return
  }
  else {
    write (undefined)
    fail
  }
end

procedure PCalc (op)
local slot1, slot2, slot_ans, res
  writes ("Which two polynomials to ")
  case op of {
    "+": write ("add? ")                   # Note that this procedure is
    "-": write ("subtract? ")              # used for all three operations
    "*": write ("multiply? ")              # since similar tasks, such as
  }                                        # checking on the status of slots,
                                           # are needed for all of them.
  repeat {
    writes ("First: ")     
    slot1 := choice(read())
    if is_lower(slot1) then break
  }
  if member (poly_table, slot1) then {
    repeat {
      writes ("Second: ")     
      slot2 := choice(read())
      if is_lower(slot2) then break
    }
    if member (poly_table, slot2) then {
      repeat {
        writes ("Slot for answer: ")     
        slot_ans := choice(read())
        if is_lower(slot_ans) then break
      }
      if member (poly_table, slot_ans) then {
        write (filled)     
        fail
      }
      else {
        case op of {
          "+": {
            res := poly_add(poly_table[slot1], poly_table[slot2])
            writes ("Sum ")
          }
          "-": {
            res := poly_sub(poly_table[slot1], poly_table[slot2])
            writes ("Difference ")
          }
          "*": {
            res := poly_mul(poly_table[slot1], poly_table[slot2])
            writes ("Product ")
          }
        }
        write ("has been defined as polynomial \"", slot_ans, "\"")
        poly_table[slot_ans] := res
      }
    }
    else {
      write (undefined)     
      fail
    }
  }
  else {
    write (undefined)     
    fail
  }
  return
end

procedure PEval ()
local slot, x, answer
  repeat {
    writes ("Which polynomial to evaluate? ")
    slot := choice(read())
    if is_lower(slot) then break
  }
  if member (poly_table, slot) then {
    repeat {
      writes ("What positive x to evaluate at? ")
      x := read()
      if numeric(x) then if x > 0 then break
    }
    answer := poly_eval (poly_table[slot], x)
    write ("The result is ", answer)
    return
  }
  else {
    write (undefined)     
    fail
  }
end

procedure PClear ()
local slot
  repeat {
    writes ("Which polynomial to clear? ")
    slot := choice(read())
    if is_lower(slot) then break
  }
  if member (poly_table, slot) then {
    delete (poly_table, slot)
    return
  }
  else {
    write (undefined)     
    fail
  }
end