--* From postmaster%watson.vnet.ibm.com@yktvmv.watson.ibm.com  Tue May 10 11:53:10 1994
--* Received: from yktvmv.watson.ibm.com by asharp.watson.ibm.com (AIX 3.2/UCB 5.64/930311)
--*           id AA25681; Tue, 10 May 1994 11:53:10 -0400
--* Received: from watson.vnet.ibm.com by yktvmv.watson.ibm.com (IBM VM SMTP V2R3)
--*    with BSMTP id 6605; Tue, 10 May 94 11:53:12 EDT
--* Received: from YKTVMV by watson.vnet.ibm.com with "VAGENT.V1.0"
--*           id <A.BRONSTEI.NOTE.YKTVMV.1649.May.10.11:53:11.-0400>
--*           for asbugs@watson; Tue, 10 May 94 11:53:11 -0400
--* Received: from inf.ethz.ch by watson.ibm.com (IBM VM SMTP V2R3) with TCP;
--*    Tue, 10 May 94 11:53:10 EDT
--* Received: from vinci.inf.ethz.ch (vinci.inf.ethz.ch [129.132.12.46]) by inf.ethz.ch (8.6.8/8.6.6) with ESMTP id RAA05108 for <asbugs@watson.ibm.com>; Tue, 10 May 1994 17:53:06 +0200
--* From: Manuel Bronstein <bronstei@inf.ethz.ch>
--* Received: (bronstei@localhost) by vinci.inf.ethz.ch (8.6.8/8.6.6) id RAA19124 for asbugs@watson.ibm.com; Tue, 10 May 1994 17:53:05 +0200
--* Date: Tue, 10 May 1994 17:53:05 +0200
--* Message-Id: <199405101553.RAA19124@vinci.inf.ethz.ch>
--* To: asbugs@watson.ibm.com
--* Subject: [5] List Record as Rep ==> seg fault [minisup.as][0.35.0 [=]]

--@ Fixed  by:  PAB   Mon May 30 17:47:56 EDT 1994 
--@ Tested by:  listper2.as 
--@ Summary:    F ignored when computing Record(F: X) 

--------------------------- minisup.as -------------------------------
-- It seems that List Record as Rep still produces runtime seg faults
--
-- vinci.inf.ethz.ch{bronstei} 232: minisup
-- Segmentation fault

#include "aslib.as"

macro Z == Integer;

SUP(F:Ring): Ring with {
	monomial: (F, Z) -> %;
	degree  : % -> Z;
	leadingCoefficient: % -> F;
	reductum: % -> %;
	coerce  : F -> %;
	*       : (F, %) -> %;
	apply: (OutPort, %, String) -> OutPort;
} == add {
        macro Term == Record(cf:F, xp:Z);
	macro Rep == List Term;   -- sorted, highest term first
	import from {Term, Rep, F, Z};

	0:%                       == per empty();
	1:%                       == per list [1, 0];
	degree(p:%):Z             == {zero? p => 0; first(rep p).xp}
	leadingCoefficient(p:%):F == {zero? p => 0; first(rep p).cf}
	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 +-> [c * t.cf, t.xp];

	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 [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([c, nx], rep z);
	}

	applyTerm(p:OutPort, c:F, n:Z, v:String):OutPort == {
		if c ~= 1 then
			if zero? n then p := p(c);
					else p := p("\left(")(c)("\right)")("");
		if zero? n and c = 1 then 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 = t.xp => return t.cf }
		0
	}

	(x:%) * (y:%):% == {
		zero? x => 0;
		a := leadingCoefficient x; n := degree x;
		reductum(x) * y + per [[a * t.cf, n + t.xp] for t in rep y];
	}

}

main():Integer == {
        macro Z == Integer;

        import from {SingleInteger, Z, SUP Z};

        a := monomial(1, 1);
        q := p := a + 1;
        for i in 1..5 repeat {
		print("$$")(q)("$$")();
                q := p * q;
        }
        1;
}

main()

 
