module nestdom; % nested domain: domain elements are standard quotients
% coefficients are taken from the integers or another
% dnest.
% Original version by Herbert Melenk, 1993(?)
% Improved version with Rainer mod.
% Changes to nestlevel, nestdmode and nestsq by Winfried Neun, 1998.
%%%%%%%%%
% Adaption to allow convertion between arnum and nested.
%%%%%%%%%
symbolic procedure ident(x);x;
put('!:ar!:,'!:nest!:,'ident);
%%%%%%%%%
% data structure:
% a domain element is a list
% ('!:nest!: level# dmode* . sq)
smacro procedure nestlevel u; if fixp u then 0 else cadr u;
smacro procedure nestdmode u; if fixp u then nil else caddr u;
smacro procedure nestsq u; if fixp u then simp u else cdddr u;
global '(domainlist!*);
fluid '(alglist!* nestlevel!*);
nestlevel!* := 0;
switch nested;
domainlist!* := union('(!:nest!:),domainlist!*);
put('nested,'tag,'!:nest!:);
put('!:nest!:,'dname,'nested);
flag('(!:nest!:),'field);
flag('(!:nest!:),'convert);
put('!:nest!:,'i2d,'!*i2nest);
%put('!:nest!:,'!:bf!:,'nestcnv);
%put('!:nest!:,'!:ft!:,'nestcnv);
%put('!:nest!:,'!:rn!:,'nestcnv);
put('!:nest!:,'!:bf!:,mkdmoderr('!:nest!:,'!:bf!:));
put('!:nest!:,'!:ft!:,mkdmoderr('!:nest!:,'!:ft!:));
put('!:nest!:,'!:rn!:,mkdmoderr('!:nest!:,'!:rn!:));
put('!:nest!:,'minusp,'nestminusp!:);
put('!:nest!:,'plus,'nestplus!:);
put('!:nest!:,'times,'nesttimes!:);
put('!:nest!:,'difference,'nestdifference!:);
put('!:nest!:,'quotient,'nestquotient!:);
put('!:nest!:,'divide,'nestdivide!:);
% put('!:nest!:,'gcd,'nestgcd!:);
put('!:nest!:,'zerop,'nestzerop!:);
put('!:nest!:,'onep,'nestonep!:);
% put('!:nest!:,'factorfn,'factornest!:);
put('!:nest!:,'prepfn,'nestprep!:);
put('!:nest!:,'prifn,'prin2);
put('!:rn!:,'!:nest!:,'rn2nest);
symbolic procedure !*i2nest u;
%converts integer u to nested form;
if domainp u then u else
'!:nest!: . 0 . dmode!* . (u ./ 1);
symbolic procedure rn2nest u;
%converts integer u to nested form;
if domainp u then u else
'!:nest!: . 0 . dmode!* . (cdr u);
symbolic procedure nestcnv u;
rederr list("Conversion between `nested' and",
get(car u,'dname),"not defined");
symbolic procedure nestminusp!: u;
nestlevel u = 0 and minusf car nestsq u;
symbolic procedure sq2nestedf sq;
'!:nest!: . nestlevel!* . dmode!* . sq;
symbolic procedure nest2op!:(u,v,op);
(begin scalar r,nlu,nlv,nlr,dm,nestlevel!*;
nlu := if not eqcar (u,'!:nest!:) then 0 else nestlevel u;
nlv := if not eqcar (v,'!:nest!:) then 0 else nestlevel v;
if nlu = nlv then goto case1
else if nlu #> nlv then goto case2
else goto case3;
case1: % same level for u and v
dm := nestdmode u;
if dm then setdmode(dm,t);
nlr := nlu;
nestlevel!* := nlu - 1;
r := apply(op,list(nestsq u,nestsq v));
goto ready;
case2: % v below u
dm := nestdmode u;
if dm then setdmode(dm,t);
nlr := nlu;
nestlevel!* := nlv;
r := apply(op,list (nestsq u, v ./ 1));
goto ready;
case3: % u below v
dm := nestdmode v;
if dm then setdmode(dm,t);
nlr := nlv;
nestlevel!* := nlu;
r := apply(op,list (u ./ 1,nestsq v));
ready:
r := if null numr r then nil
% The next line was commented out for a while, but is
% needed for the normform tests.
else if domainp numr r and denr r = 1 then numr r
else '!:nest!: . nlr . dm . r;
if dm then setdmode (dm,nil);
return r;
end ) where dmode!* = nil;
symbolic procedure nestplus!:(u,v); nest2op!:(u,v,'addsq);
symbolic procedure nesttimes!:(u,v); nest2op!:(u,v,'multsq);
symbolic procedure nestdifference!:(u,v);
nest2op!:(u,v,function (lambda(x,y); addsq(x,negsq y)));
symbolic procedure nestdivide!:(u,v); nest2op!:(u,v,'quotsq) . 1;
% symbolic procedure nestgcd!:(u,v); !*i2nest 1;
symbolic procedure nestquotient!:(u,v); nest2op!:(u,v,'quotsq);
symbolic procedure nestzerop!: u; null numr nestsq u;
symbolic procedure nestonep!: u;
(car v = 1 and cdr v = 1) where v = nestsq u;
initdmode 'nested;
% nested routines are defined in the gennest nestule with the exception
% of the following:
symbolic procedure setnest u;
begin
u := reval u;
if not fixp u then typerr(u,"nestulus");
nestlevel!* := u;
end;
flag('(setnest),'opfn); %to make it a symbolic operator;
flag('(setnest),'noval);
algebraic operator co;
symbolic procedure simpco u;
% conmvert an expression to a nested coefficient
begin scalar sq,lev;
if not (length u = 2 and fixp car u) then
typerr(u,"nested coefficient");
sq := simp cadr u;
lev := car u;
return (if null numr sq then nil else ('!:nest!: . lev . dmode!* .
sq)) ./ 1;
end;
put('co,'simpfn,'simpco);
symbolic procedure nestprep!: u; list('co,nestlevel u,prepsq nestsq u);
endmodule;
end;