123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- module str; % Routines for structuring expressions.
- % Author: Anthony C. Hearn.
- % Copyright (c) 1991 The RAND Corporation. All rights reserved.
- fluid '(!*fort !*nat !*savestructr scountr svar svarlis);
- global '(varnam!*);
- varnam!* := 'ans;
- switch savestructr;
- flag('(structr),'intfn); % To fool the supervisor into printing
- % results of STRUCTR.
- % ***** two essential uses of RPLACD occur in this module.
- symbolic procedure structr u;
- begin scalar scountr,fvar,svar,svarlis;
- % SVARLIS is a list of elements of form:
- % (<unreplaced expression> . <newvar> . <replaced exp>);
- scountr :=0;
- fvar := svar := varnam!*;
- if cdr u
- then <<fvar := svar := cadr u; if cddr u then fvar := caddr u>>;
- u := structr1 aeval car u;
- if !*fort then svarlis := reversip!* svarlis
- else if not !*savestructr
- then <<assgnpri(u,nil,'only);
- if not eqcar(u,'mat) then terpri(); % MAT already has eol
- if scountr=0 then return nil
- else <<if null !*nat then terpri();
- prin2t " where">>>>;
- if !*fort or not !*savestructr
- then for each x in svarlis do
- <<terpri!* t;
- if null !*fort then prin2!* " ";
- assgnpri(cddr x,list cadr x,t)>>;
- if !*fort then assgnpri(u,list fvar,t)
- else if !*savestructr
- then return 'list . u .
- foreach x in svarlis
- collect list('equal,cadr x,
- mkquote cddr x)
- end;
- rlistat '(structr);
- symbolic procedure structr1 u;
- % This routine considers special case STRUCTR arguments. It could be
- % easily generalized.
- if atom u then u
- else if car u eq 'mat
- then car u .
- (for each j in cdr u collect for each k in j collect structr1 k)
- else if car u eq 'list
- then 'list . for each j in cdr u collect structr1 j
- else if car u eq 'equal then list('equal,cadr u,structr1 caddr u)
- else if car u eq '!*sq
- then mk!*sq(structf numr cadr u ./ structf denr cadr u)
- else if getrtype u then typerr(u,"STRUCTR argument")
- else u;
- symbolic procedure structf u;
- if null u then nil
- else if domainp u then u
- else begin scalar x,y;
- x := mvar u;
- if sfp x then if y := assoc(x,svarlis) then x := cadr y
- else x := structk(prepsq!*(structf x ./ 1),
- structvar(),x)
- % else if not atom x and not atomlis cdr x
- else if not atom x
- and not(atom car x and flagp(car x,'noreplace))
- then if y := assoc(x,svarlis) then x := cadr y
- else x := structk(x,structvar(),x);
- % Suggested patch by Rainer Schoepf to cache powers.
- % if ldeg u = 1
- % then return x .** ldeg u .* structf lc u .+ structf red u;
- % z := retimes exchk list (x .** ldeg u);
- % if y := assoc(z,svarlis) then x := cadr y
- % else x := structk(z, structvar(), z);
- % return x .** 1 .* mystructf lc u .+ mystructf red u
- return x .** ldeg u .* structf lc u .+ structf red u
- end;
- symbolic procedure structk(u,id,v);
- begin scalar x;
- if x := subchk1(u,svarlis,id)
- then rplacd(x,(v . id . u) . cdr x)
- else if x := subchk2(u,svarlis)
- then svarlis := (v . id . x) . svarlis
- else svarlis := (v . id . u) . svarlis;
- return id
- end;
- symbolic procedure subchk1(u,v,id);
- begin scalar w;
- while v do
- <<smember(u,cddar v)
- and <<w := v; rplacd(cdar v,subst(id,u,cddar v))>>;
- v := cdr v>>;
- return w
- end;
- symbolic procedure subchk2(u,v);
- begin scalar bool;
- for each x in v do
- smember(cddr x,u)
- and <<bool := t; u := subst(cadr x,cddr x,u)>>;
- if bool then return u else return nil
- end;
- symbolic procedure structvar;
- begin
- scountr := scountr + 1;
- return if arrayp svar then list(svar,scountr)
- else intern compress append(explode svar,explode scountr)
- end;
- endmodule;
- end;
|