############################################################################ # # 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