--* From postmaster%watson.vnet.ibm.com@yktvmv.watson.ibm.com  Tue Dec 21 07:40:08 1993
--* Received: from yktvmv.watson.ibm.com by leonardo.watson.ibm.com (AIX 3.2/UCB 5.64/4.03)
--*           id AA20748; Tue, 21 Dec 1993 07:40:08 -0500
--* X-External-Networks: yes
--* Received: from watson.vnet.ibm.com by yktvmv.watson.ibm.com (IBM VM SMTP V2R3)
--*    with BSMTP id 3637; Tue, 21 Dec 93 07:46:27 EST
--* Received: from YKTVMV by watson.vnet.ibm.com with "VAGENT.V1.0"
--*           id <A.BRONSTEI.NOTE.YKTVMV.8637.Dec.21.07:46:27.-0500>
--*           for asbugs@watson; Tue, 21 Dec 93 07:46:27 -0500
--* Received: from bernina.ethz.ch by watson.ibm.com (IBM VM SMTP V2R3) with TCP;
--*    Tue, 21 Dec 93 07:46:25 EST
--* Received: from neptune by bernina.ethz.ch with SMTP inbound id <28837-0@bernina.ethz.ch>; Tue, 21 Dec 1993 13:46:06 +0100
--* From: Manuel Bronstein <bronstei@inf.ethz.ch>
--* Received: from rutishauser.inf.ethz.ch (rutishauser-gw.inf.ethz.ch) by neptune id AA14893; Tue, 21 Dec 93 13:46:01 +0100
--* Date: Tue, 21 Dec 93 13:46:00 +0100
--* Message-Id: <9312211246.AA16256@rutishauser.inf.ethz.ch>
--* Received: from vinci.inf.ethz.ch.rutishauser by rutishauser.inf.ethz.ch id AA16256; Tue, 21 Dec 93 13:46:00 +0100
--* To: asbugs@watson.ibm.com
--* Subject: [1] Finally compiles ok, but "Export not found" at runtime [minisup.as][33.2]

--@ Fixed  by:  SSD   Mon Nov 21 10:48:45 EST 1994 
--@ Tested by:  none 
--@ Summary:    Inner domain Term does not export '=' as required by BasicType. v0-37-0 now correctly reports this error. 

-- This file compiles ok, but produces a runtime error (RS/6000 33.2):
--
-- peano [/u/manuel/a#] 51> asharp -Fx minisup.as
-- peano [/u/manuel/a#] 52> minisup
-- Looking for 200102 with code 45055810
-- Export not found


----------------------------- minisup.as ----------------------------------
#include "aslib.as"

macro Z == Integer

MiniPoly(F:Ring): Ring with {
		monomial: (F, Z) -> %;
		degree  : % -> Z;
		leadingCoefficient: % -> F;
		reductum: % -> %;
		coerce  : F -> %;
		*       : (F, %) -> %;
	} == add {
		Term: BasicType with {
			term: (F, Z) -> %;    -- term(c, n) creates the monomial c x^n
			coef: % -> F;         -- coef(c x^n) returns c
			expt: % -> Z;         -- expt(c x^n) returns n
		} == add {
			macro Rep == Record(coef:F, expt:Z);
			import from Rep;

			term(c:F, n:Z):% == per [c, n];
			coef(t:%):F      == rep(t).coef;
			expt(t:%):Z      == rep(t).expt;
			sample:%         == term(1, 1);
			apply(p:OutPort, x:%):OutPort == p;  -- never used

		}
		macro Rep == List Term;   -- sorted, highest term first
		import from Term;
		import from Rep;
		import from F;
		import from Z;

		0:%                       == per empty();
		1:%                       == per list term(1, 0);
		degree(p:%):Z             == {zero? p => 0; expt first rep p}
		leadingCoefficient(p:%):F == {zero? p => 0; coef first rep p}
    	reductum(p:%):%           == {zero? p => 0; per rest rep p}
  		coerce(c:F):%             == monomial(c, 0);
		(x:%) = (y:%):Boolean     == rep x = rep y;
		-(p:%):%                  == per map(cterm(-1), rep p);
  		(c:F) * (p:%):%           == per map(cterm c, rep p);
		cterm(c:F):(Term->Term)   == (t:Term):Term +-> term(c * coef t,expt t);
		apply(p:OutPort, x:%):OutPort == {import from String; apply(p, x, " ?")}

		monomial(c:F, n:Z):% == {
			n < 0 => error("monomial: exponent should be nonnegative!");
			zero? c => 0;
			per list term(c, n);
		}

		(x:%) + (y:%):% == {
			zero? x => y; zero? y => x;
			nx := degree x; ny := degree y;
			nx > ny => per cons(first rep x, rep(reductum x + y));
			nx < ny => per cons(first rep y, rep(x + reductum y));
			z := reductum x + reductum y;
			zero?(c := leadingCoefficient x + leadingCoefficient y) => z;
			per cons(term(c, nx), rep z);
		}

		applyTerm(p:OutPort, c:F, n:Z, v:String):OutPort == {
			p := p(c);
			if n > 0 then {p := p v; if n > 1 then p := p("^")(n);}
			p;
		}

		apply(p:OutPort, x:%, v:String):OutPort == {
			zero? x => p(0$F);
			while x ~= 0 repeat {
				p := applyTerm(p, leadingCoefficient x, degree x, v);
				x := reductum x;
				if (x ~= 0) then p := p(" + ");
			}
			p;
		}

		coefficient(p:%, n:Z):F == {
			for t in rep p repeat { n = expt t => return coef t }
			0
		}

		-- dummy for now
		(x:%) * (y:%):% == x;

}

macro R == MiniPoly Z

main():OutPort == {
	import from Z;
	import from R;

	p := monomial(1, 3) + 1;
	q := monomial(1, 2) - p;
	print("p = ")(p)()("5p = ")(5 * p)()("q = ")(q)();
}

main();

 
