123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- module subs3q; % Routines for matching products.
- % Author: Anthony C. Hearn.
- % Copyright (c) 1992 RAND. All rights reserved.
- fluid '(!*mcd powlis1!* !*sub2 subfg!*);
- global '(!*match !*resubs mchfg!*);
- symbolic procedure subs3q u;
- %U is a standard quotient.
- %Value is a standard quotient with all product substitutions made;
- begin scalar x;
- x := mchfg!*; %save value in case we are in inner loop;
- mchfg!* := nil;
- u := quotsq(subs3f numr u,subs3f denr u);
- mchfg!* := x;
- return u
- end;
- symbolic procedure subs3f u;
- %U is a standard form.
- %Value is a standard quotient with all product substitutions made;
- subs3f1(u,!*match,t);
- symbolic procedure subs3f1(u,l,bool);
- %U is a standard form.
- %L is a list of possible matches.
- %BOOL is a boolean variable which is true if we are at top level.
- %Value is a standard quotient with all product substitutions made;
- begin scalar x,z;
- z := nil ./ 1;
- a: if null u then return z
- else if domainp u then return addsq(z,u ./ 1)
- else if bool and domainp lc u then go to c;
- x := subs3t(lt u,l);
- if not bool %not top level;
- or not mchfg!* then go to b; %no replacement made;
- mchfg!* := nil;
- if numr x = u and denr x = 1 then <<x := u ./ 1; go to b>>
- % also shows no replacement made (sometimes true with non
- % commuting expressions)
- else if null !*resubs then go to b
- else if !*sub2 or powlis1!* then x := subs2q x;
- %make another pass;
- x := subs3q x;
- b: z := addsq(z,x);
- u := cdr u;
- go to a;
- c: x := list lt u ./ 1;
- go to b
- end;
- symbolic procedure subs3t(u,v);
- % U is a standard term, V a list of matching templates.
- % Value is a standard quotient for the substituted term.
- begin scalar bool,w,x,y,z;
- x := mtchk(car u,if domainp cdr u then sizchk(v,1) else v);
- if null x then go to a %lpow doesn't match;
- else if null caar x then go to b; %complete match found;
- y := subs3f1(cdr u,x,nil); %check tc for match;
- if mchfg!* then return multpq(car u,y);
- a: return list u . 1; %no match;
- b: x := cddar x; %list(<subst value>,<denoms>);
- z := caadr x; %leading denom;
- mchfg!* := nil; %initialize for tc check;
- y := subs3f1(cdr u,!*match,nil);
- mchfg!* := t;
- if car z neq caar u then go to e
- else if z neq car u %powers don't match;
- then y := multpq(caar u .** (cdar u-cdr z),y);
- b1: y := multsq(simpcar x,y);
- x := cdadr x;
- if null x then return y;
- z := 1; %unwind remaining denoms;
- c: if null x then go to d;
- w:= if atom caar x or sfp caar x then caar x else
- ((lambda ww;
- if kernp ww and eqcar(ww := mvar numr ww,car caar x)
- then ww
- else revop1 caar x)
- (simp caar x) where subfg!* = nil);
- % In the non-commutative case we have to be very careful about
- % order of terms in a product. Introducing negative powers
- % solves this problem.
- if noncomp w or not !*mcd then bool := t;
- % z := multpf(mksp(w,if null bool then cdar x else -cdar x),z);
- % original line
- z := multf(z,!*p2f mksp(w,
- if null bool then cdar x else -cdar x));
- % kernel CAAR X is not unique here. Earlier versions used just
- % CAAR X, but this leads to sums of terms in the wrong order.
- % The code here is probably still not correct in all cases, and
- % may lead to unbounded calculations. Maybe SIMP should be used
- % instead of REVOP1, with appropriate adjustments in the code
- % to construct Z.
- x := cdr x;
- go to c;
- d: return if not bool then car y . multf(z,cdr y)
- else multf(z,car y) . cdr y;
- e: if simp car z neq simp caar u then errach list('subs3t,u,x,z);
- %maybe arguments were in different order, otherwise it's fatal;
- if cdr z neq cdar u
- then y:= multpq(caar u .** (cdar u-cdr z),y);
- go to b1
- end;
- symbolic procedure sizchk(u,n);
- if null u then nil
- else if length caar u>n then sizchk(cdr u,n)
- else car u . sizchk(cdr u,n);
- symbolic procedure mtchk(u,v);
- %U is a standard power, V a list of matching templates.
- %If a match is made, value is of the form:
- %list list(NIL,<boolean form>,<subst value>,<denoms>),
- %otherwise value is an updated list of templates;
- begin scalar flg,v1,w,x,y,z;
- flg := noncomp car u;
- a0: if null v then return z;
- v1 := car v;
- w := car v1;
- a: if null w then go to d;
- x := mtchp1(u,car w,caadr v1,cdadr v1);
- b: if null x then go to c
- else if car (y := subla(car x,delete(car w,car v1))
- . list(subla(car x,cadr v1),
- subla(car x,caddr v1),
- subla(car x,car w)
- . cadddr v1))
- then z := y . z
- else if lispeval subla(car x,cdadr v1) then return list y;
- x := cdr x;
- go to b;
- c: if null flg then <<w := cdr w; go to a>>
- else if cadddr v1 and nocp w then go to e;
- d: z :=aconc(z,v1); % Could also be append(z,list v1).
- e: v := cdr v;
- go to a0
- end;
- symbolic procedure nocp u;
- null u or (noncomp caar u and nocp cdr u);
- endmodule;
- end;
|