%********************************************************************* module gensep_lin$ %********************************************************************* % Routines for generalized separation of de's % Author: Andreas Brand, Thomas Wolf 1990 1994 1997 % Thomas Wolf since 1997 symbolic procedure quick_gen_separation(arglist)$ % Indirect separation of a pde if vl_ then % otherwise not possible --> save time begin scalar p,l,l1,pdes,stp$ % pdes:=clean_up(car arglist)$ % if pdes then l:=list(pdes,cadr arglist)$ % because the bookeeping of to_drop is not complete instead: pdes:=car arglist$ % to return the new list of pdes in case gensep is not successful if expert_mode then << l1:=selectpdes(pdes,1); if get(car l1,'starde) then flag(l1,'to_gensep) >> else l1:=cadddr arglist$ if (p:=get_gen_separ_pde(l1,t,t)) then % high priority <> >>$ l:=list(pdes,cadr arglist)>>$ return l$ end$ symbolic procedure gen_separation(arglist)$ % Indirect separation of a pde if vl_ then % otherwise not possible --> save time begin scalar p,l,l1,pdes,stp$ % pdes:=clean_up(car arglist)$ % if pdes then l:=list(pdes,cadr arglist)$ % because the bookeeping of to_drop is not complete instead: pdes:=car arglist$ % to return the new list of pdes in case gensep is not successful if expert_mode then << l1:=selectpdes(pdes,1); if get(car l1,'starde) then flag(l1,'to_gensep) >> else l1:=cadddr arglist$ if (p:=get_gen_separ_pde(l1,nil,t)) then % low priority <> >>$ l:=list(pdes,cadr arglist)>>$ return l$ end$ symbolic procedure maxnoargs(fl,v)$ % determines the maximal number of arguments of any of the % functions of fl begin scalar f,n,m; n:=0; for each f in fl do <>; return n end$ symbolic procedure get_gen_separ_pde(pdes,high_priority,lin)$ % looking for a pde in pdes which can be indirectly separated % if lin then only a liner PDE % p ...the next equation that will be chosen % dw...whether p was already delt with % na...number of variables in the equation % nv...maximal number of arguments of any of the functions of p % nf...min number of functions to be dropped before direct sep. % leng...length of p begin scalar p,nv,nf,dw,len,h1,h2,h3,h4,nvmax$ %na,h5 % ncmax:=nvmax$ if high_priority then << nvmax:=0; for each p in pdes do if (h1:=get(p,'nvars))>nvmax then nvmax:=h1; p:=nil >>$ while pdes do << if flagp(car pdes,'to_gensep) and (null lin or get(car pdes,'linear_)) and % not too many terms or enough terms <h1) or (high_gensep> and % no single function depending on all variables: (h3:=get(car pdes,'starde) ) and % not directly separable: (cdr h3 neq 0 ) and % Each time the equation is investigated and differentiated % wrt the first element of car h3, this element is dropped. % --> The equation should not already have been differentiated % wrt all variables: (not null car h3 ) and % If equations have been investigated by generalized % separation or if equations resulted from generalized % separation then they get the flag used_ to be solved % first, not to have too many unevaluated new functions % at a time ((h4:=flagp(car pdes,'used_) ) or (null dw) ) and % The variables in h3 are the ones wrt which direct separation % shall be achieved after differentiation, therefore functions % of these variables have to be thrown out. The remaining % functions shall be of as many as possible arguments to % make quick progress: ((null p ) or (len > h1 ) or % neu ((len = h1) and ( % neu (nv < (h2:=maxnoargs( get(car pdes,'fcts), car h3 )) ) or ((nv = h2) and ( % (na < (h5:=get(car pdes,'nvars)) ) or % ((na = h5) and ( ((null dw) and flagp(car pdes,'used_)) or (( nf > cdr h3 ) or ((nf = cdr h3 ) and (len > h1 ) ) ) ) )))) then <>$ pdes:=cdr pdes$ >>; return p end$ %----------------- symbolic procedure gensep(p,pdes)$ % generalized separation of pde p if zerop cdr get(p,'starde) then separate(p,pdes) % be dropped? else % e.g. a=((x y z).2) % POSSIBLE REASONS FOR FAILURE: % - After the sequence of divisions and differentiations in the direct % separation, if there explicit v-dependent coefficients are taken % out which also contain later integration variables, then the integrands % are not total derivatives anymore --> no backintegration is possible. % - This corresponds to the case when all variables occur explicitly but % in a non-product expression, like sin(x*y*z) begin scalar a,pl$ if print_ then <>$ if tr_gensep then <>$ cp_sq2p_val(p)$ %#?# to be dropped in later versions %--- so far only one DE p in the pool starlist of equations pl:=partitn(get(p,'pval), % expression %#?# to be dropped in later versions nil, % history of divisions/diff so far get(p,'fcts), % functions get(p,'vars), % variables car get(p,'starde) % separation charac. ); if pl then << pl:=append(for each a in car pl collect simp cdr a,for each a in cadr pl collect simp a); % <--- old % pl:=append(for each a in car pl collect simp a,for each a in cadr pl collect simp a); % <--- next pl:=mkeqSQlist(pl,nil,nil,fctsort union(ftem_,get(p,'fcts)),get(p,'vars), cons('to_drop,allflags_),t,get(p,'orderings),pdes)$ drop_pde(p,nil,nil); flag(pl,'used_); if print_ then < 1 then write"s"$ write" : "$ if tr_gensep then typeeqlist pl else listprint pl$ terpri() >> >> else << remflag1(p,'to_gensep)$ pl:=list p >>$ return pl$ end$ %----------------- symbolic procedure partitn(q,old_histy,ftem,vl,a)$ % This procedure calls itself recursively! % q: a **-expression to be separated (currently still in prefix form) % old_histy: a list of elements {denom,v,{(divisor . expr_before),..}} % where a sequence of divisions through factors from the % list of divisors and differentiations wrt. v and % afterwards multiplication with denom resulted in q % ftem: functions in the expression % vl: variables in the expression % a: the variables for direct separation=car starp() % % RETURNS {{(c1.q1),(c2.q2),(c3.q3),..},{s1,s2,s3,..},{r1,r2,..},{f1,f2,..}} % where qi=0 are necessary consequences, % qi are not **-expressions, and not *-expressions % sum_i ci*qi = q % si=0 are consistency conditions determining constants/functions % of integration % ri=0 are other cases to be checked --> case distinctions begin scalar histy,l1,l4,nv,vl1,nv1,h,x,f,ft,aa,bb,cc, ruli,extra_cond,par,cases,newf$ %--- ft: the list of functions to drop from q by differentiation %--- to do a direct separation wrt x: % x = any one variable in a on which a function with as % many as possible variables does not depend on % Find such a function and variable x ft:=ftem; nv:=0; while ft do << vl1:=fctargs car ft; nv1:=if vl1 then length vl1 else 0; if nv1 > nv then << h:=setdiff(a,vl1); if h then << x:=car h; % if possible find an x occuring explicitly in q while h and freeof(q,car h) do h:=cdr h; if h then x:=car h; f:=car ft; nv:=nv1 >> >>; ft:=cdr ft >>; if nv=0 then x:=car a; % no x was found if tr_gensep then <>$ % Find all functions ft in q depending on x ft:=nil$ for each f in ftem do if member(x,fctargs f) and not freeof(q,f) then ft:=cons(f,ft)$ ft:=fctsort reverse ft$ % sorting w.r.t. number of args ruli:=start_let_rules()$ %--- throwing out functions ft until ft=nil %--- or until the expression lost the *-property while ft do % for each function to get rid of % (possibly each time a different diff variable) if null (l1:=felim(q,car ft,ftem,vl)) then ft:=nil % to stop else << for each h in cdadr l1 do % special extra cases if not freeoflist(car h,ftem) then cases:=cons(car h,cases); if zerop car l1 then << % q:=reval {'QUOTIENT,cdr cadadr l1,car cadadr l1}; % This division through car cadadr l1 had to be dropped because the % back-multiplication will not happen --> check_sum gets wrong --> loop cc:=cons(car cadr l1,cddadr l1); >> else << q:=car l1$ % new expression cc:=cadr l1; >>$ if (pairp q) and (car q='QUOTIENT) then << bb:=caddr q; % we take off the denimonator q:=cadr q >> else bb:=1$ histy:=cons(cons(bb,cc),histy)$ % extended history ftem:=smemberl(ftem,q)$ % functions still in q aa:=stardep(ftem,argset(ftem))$ % still *-expression? if not aa or zerop cdr aa then ft:=nil % to stop else ft:=smemberl(cdr ft,ftem) % remain. fcts of x >>$ stop_let_rules(ruli)$ if null l1 then if tr_gensep then <>; %--- prepare list of variables vl1 for direct separation % vl1:=nil$ % for each h in vl do if my_freeof(ftem,h) then vl1:=cons(h,vl1); vl1:=vl$ % It is not good enough to separate wrt. vl1 because it could % be that further direct separability could be possible wrt. variables % the still occuring functions ftem do not depend on. %--- direct separation if useful (i.e. if aa(=stardep) neq nil) if vl1 and not (q=0) then <>$ l1:=separ(q,ftem,vl1,nil,nil)$ % direct separation of the numerator if tr_gensep then <>$ >> else l1:=list cons(1,q)$ if tr_gensep then << terpri()$ write"Separation gave ",length l1," condition(s)" >>; % Although the vaiable x does not occur anymore % (each felim call removed one function of x % and direct separation removed explicit occurences of x) % the remaining expression may still be indirectly separable % --> recursive call of partitn % l4 becomes a list of pairs (sep_coefficient . sep_remainding_factor) % for each h in l1 do << while l1 do << h:=car l1; l1:=cdr l1; ft:=smemberl(ftem,cdr h); vl1:=argset(ft)$ if null (aa:=stardep(ft,vl1)) then l4:=cons(h,l4) else << par:=partitn(cdr h, % expression append(histy, % history so far, old_histy), % needed to add new functions % of integration properly differentiated to be % able to integrate below ft, % functions vl1, % variables car aa % separation charac. ); % RETURNS {{(c1.q1),(c2.q2),(c3.q3),..},{s1,s2,s3,..}, % {r1,r2,..},{f1,f2,..} } % where qi=0 are necessary consequences, % qi are not *-expressions, % sum_i ci*qi = q % si=0 are consistency conditions determining constants/functions % of integration % ri=0 are other cases to be checked --> case distinctions if par then << l4:=append(l4,for each f in car par collect ({'TIMES,car h,car f} . cdr f)); % <--- changed % ( car h . cdr f)); % <--- new extra_cond:=append(extra_cond,cadr par); % collecting any % appearing conditions cases:=append(cases,caddr par); newf:=cadddr par; ftem:=append(ftem,newf); >> else l1:=nil >> >>$ %--- backintegration par:=backint(l4,old_histy,histy,ftem,vl)$ if par then << extra_cond:=append(extra_cond,cadr par); % collecting any conditions {car par,extra_cond,cases,append(newf,caddr par)} >> else nil >> end$ %----------- symbolic procedure felim(q,f,ftem,vl)$ % returns: nil if not successful (quotient) otherwise % {the expression after all the divisions and differentiations, % {diff variable, sequence of (factor . expression before)} } begin scalar a,b,l,l1,ft1,v,prflag$ %--- getting rid of f through diff. wrt. v v:=car setdiff(vl,fctargs f)$ %--- ft1 are all v-independent functions %--- In the call to separ one has to disregard v-dep. functions ft1:=nil$ for each f in ftem do if my_freeof(f,v) then ft1:=cons(f,ft1)$ %--- To run separ, functions ft1 should not be in the denominator %--- ?????? What if nonl. Problems? if not (pairp q and (car q='QUOTIENT) and smemberl(ft1,caddr q)) then % This exceptional case should not occure anymore <>$ print_:=prflag$ %--- l is a list of dotted pairs a each representing a term in q % where car(a) is the product of v-dep. factors and cdr(a) the % product of v-independent factors %--- A list l1 of car(a) is generated for which cdr(a) depends % on f. l1 is the list of divisions to be done before differen. l1:=nil$ while l do <>$ if tr_gensep then <>$ %--- Now the divisions and differentiations are done while l1 do << !#if (equal version!* "REDUCE 3.6") b:=reval aeval car l1$ %--- b is the v-dep. coefficient !#else b:=reval car l1$ %--- b is the v-dep. coefficient !#endif l1:=cdr l1$ %--- ????? If for non-linear Problems b includes ftem functions % then the extra case 0 = b has to be considered if not zerop b then << !#if (equal version!* "REDUCE 3.6") a:=reval aeval list('QUOTIENT,q,b)$ !#else a:=reval list('QUOTIENT,q,b)$ !#endif %--- for later backward integrations: extension of the history l:=cons(b . q ,l)$ %--- new: q is the equ. before division & diff. % formerly: l:=cons(b ,l)$ % l will be returned later by felim %--- l1 has to be updated as the coefficients % change through division and differentiation l1:=for each c in l1 collect reval list('DF,list('QUOTIENT,c,b),v)$ %--- the differentiation q:=reval list('DF,a,v)$ if tr_gensep then <> >> >>$ %if l then part_histy:=cons(v,l)$ %--- output if tr_gensep then <>$ if tr_gensep and l then <>$ l1:=list(q,cons(v,l)) >>$ return l1 end$ symbolic procedure backint(l4,old_histy,histy,ftem,vl)$ % l4 is a list of pairs (sep_coefficient . % sep_remainding_factor_to_be_integrated) % old_histy, histy are lists of elements % {denom,v,{(divisor . expr_before),..}} % where a sequence of divisions through factors from the % list of divisors and differentiations wrt. v and % afterwards multiplication with denom resulted in q % Integrations should only be done inverting histy, but % in choosing functions of integration, both should be used % % returns {- integrated equivalent of l4 where the cdr of each element % is the integrated expression, % - a list of check_sum conditions, % - a list of new functions} begin scalar succ,ft,q,l,v,v1,vf,s1,s2,p,f1,f2,fctr,check_sum, allfnew,new_cond,denomi$ % start of the backintegration succ:=t$ while histy and succ do <>$ % Now the sequence of integrations wrt v % l is the list of (factor . expression before division & diff) while l and succ do << % while l and q do fctr:=caar l; check_sum:=cdar l; l:=cdr l; if tr_gensep then <>$ %write"l4="$ %prettyprint l4; % l4 is a list of pairs (sep_coefficient . sep_remainding_factor) l4:=for each h in l4 collect if null car h then h % one integration % <-- old % l4:=for each h in l4 collect if null car h then cdr h % one integration % <-- next % was not succ.ful else << ft:=smemberl(ftem,cdr h)$ fnew_:=nil$ if tr_gensep then <>$ q:=integratepde(cdr h,ft,v,nil,nil)$ % genflag:=nil, potflag=nil % <--- changed if null q then << succ:=nil$ if print_ then << terpri()$ write "#### Back integration of "$ eqprint cdr h$ write " wrt ",v," during generalized ", "separation was not successful ####."$ terpri()$ write "The coeff. dropped in direct separation was "$ mathprint car h >> >> else << if tr_gensep then <>$ q:=reval list('TIMES,fctr,car h,car q)$ % One has to multiply with car h now % and not before back-integration with the call of integratepde() because % car h may depend on variables on which ft do not depend and then the % new constants/functions of integration would depend on too few variables. % fctr is the next integrating factor % Neccessary: Substituting the new functions of integration by % derivatives of them such that back-integration can be made % hat fnew_ nur ein element, d.h. wird nur eine Integration gemacht % oder mehrere? for each f1 in fnew_ do <>$ if not smemberl(vf,car s1) then f2:=list('TIMES,f2,car s1)$ >>$ % the remaining integrations in the current element of histy if histy then << s2:=reverse l$ while s2 do <>; >>; if f1 neq f2 then <>$ q:=subst(f2,f1,q)$ >> >>$ allfnew:=append(fnew_,allfnew)$ ftem:=union(fnew_,ftem); % if succ then check_sum:={'DIFFERENCE,check_sum,{'TIMES,q,car h}}; <-------- changed % % car h is the coefficient dropped through direct separation <-------- changed if succ then check_sum:={'DIFFERENCE,check_sum,q}; % <-------- new >>$ % (car h . q) % the value to be collected to give the new l4 % <-------- changed (1 . q) % the value to be collected to give the new l4 % <-------- new % q % the value to be collected to give the new l4 % <-------- next >>; if succ then << check_sum:=reval check_sum$ new_cond:=cons(check_sum,new_cond)$ if succ and tr_gensep then <> >> >> >>$ if succ then << for each f in allfnew do << ftem_:=fctinsert(f,ftem_)$ flin_:=cons(f,flin_)$ >>; flin_:=sort_according_to(flin_,ftem_) >>$ if tr_gensep then if succ then <> else <>$ fnew_:=nil$ return if succ then {l4,new_cond,allfnew} else nil end$ endmodule$ %********************************************************************* module gensep_non_lin$ %********************************************************************* % Routines for generalized separation of de's % Author: Thomas Wolf since 1997 symbolic procedure my_smemberl(p,vl)$ begin scalar l,v; for each v in vl do if not my_freeof(p,v) then l:=cons(v,l); return reverse l end$ %----------- symbolic procedure stripcond(conds)$ begin scalar newconds,condi; newconds:=nil; while conds do << condi:=cdar conds; conds:=cdr conds; if length condi=1 then condi:=car condi else condi:=cons('PLUS,condi); newconds:=cons(condi,newconds) >>; return newconds end$ %----------- symbolic procedure checkli(exlist,condi)$ begin scalar ok,isincondi,isinexli,excopy,n; ok:=t; while condi and ok do << % all i in the condition car condi isincondi:=car condi; %smemberl(ilist,car condi); n:=length isincondi; % are all isincondi contained in one of the elements of exlist? excopy:=exlist; while excopy and ok do << isinexli:=smemberl(isincondi,car excopy); if isinexli then if length(isinexli) = n then ok:=nil; excopy:=cdr excopy >>; condi:=cdr condi >>; return ok end$ %----------- symbolic procedure longst(exlist)$ % returns the element of exlist which (is a list and) % has the most elements begin scalar lo; while exlist do << if not lo then lo:=car exlist else if length(lo)>; return lo end$ %----------- symbolic procedure starequ(n,alindep,blindep)$ % alindep is a list of lists of factors ai which are all non-zero and % are all linear independent from each other within such a list % blindep like alindep % generates all cases each with all conditions with _i representing % ai or bi, equations and new functions are not generated begin comment The equation to separate has the form 0 = sum_i ai*bi where the bi do not depend on some variable x. The procedure starequ generates cases: cases ... ( all cases ) each case ... ( list of all a-conditions, list of all b-conditions) each condition ... ( the ai,bi contained in the condition with _i representing ai and bi ) ; scalar i,j,cases,oldcases,case,ai,bi,ci,oldaconds,oldbconds, newaconds,newbcond,newbconds,newacond, ilist,cona,conb,unin,el,pri; % ,oldpri % Determine the longest union of two list, one, ai, being element of % alindep and one, bi, being from blindep %pri:=t; i:=0; if alindep then for each cona in alindep do if blindep then for each conb in blindep do if (j:=length union(cona,conb)) > i then <> else else % no blindep given if (j:=length cona) > i then <> else else % no alindep given if blindep then for each conb in blindep do if (j:=length conb) > i then <>; % ai, bi will now be determined % preparation of the sequence ilist of extensions ilist:=for i:=1:n collect i; if pri then <>$ if i neq 0 then << if ai then i:=length ai else i:=0; if bi then j:=length bi else j:=0; unin:=union(ai,bi); % extensions through bch should be done when elements from % bi are treated. This is coded in ilist through negative numbers ilist:=setdiff(ilist,unin); if i>j then << for each el in setdiff(unin,ai) do ilist:=cons(-el,ilist); for each el in ai do ilist:=cons( el,ilist) >> else << for each el in setdiff(unin,bi) do ilist:=cons( el,ilist); for each el in bi do ilist:=cons(-el,ilist) >>; ilist:=reverse ilist >>; % ilist is prepared now if pri then <>$ while ilist do << i:=car ilist;ilist:=cdr ilist; if pri then <>$ if i>0 then ci:=mkid('_, i) else ci:=mkid('_,-i); if pri then << write"666 car ilist=",i; terpri() >>$ % if i>0 then the list of cases is extended with ai else with bi oldcases:=cases; cases:=nil; while oldcases do << % for each old case do: case:=car oldcases; if pri then <>$ oldcases:=cdr oldcases; if i>0 then << oldaconds:=car case; if pri then <>; % newcases will be the new list of all cases newcases:=nil; while cases do << % car cases is one case with alltogether n conditions which % The conditions for the a-factors are called below acons % and for the b-factors bcons. acons:= caar cases; bcons:=cadar cases; cases:= cdr cases; if pri then <>$ ali:= if not zerop car ali then for each i in cdr ali collect reval list('DF,list('QUOTIENT,i,car ali),x) else cdr ali; if pri then <>$ % Drop that element from bcons which includes % car ali (as first element) if bco:=find_cond(bcons,car aco) then bcons:=setdiff(bcons,list bco); aco:=cdr aco >>; acond:=car ali; if (pairp acond) and (car acond = 'QUOTIENT) then acond:=cadr acond; >>; newca:=cons(acond,newca) >>; if pri then <>; >>; % all a-conditions have been dealt with if pri then <>; % completing all b-conditions for each bi in ili do bcons:=subst(cdr pickfac(ex,bi),bi,bcons); % adding all b-conditions to the new case newca while bcons do << if length car bcons = 1 then newca:=cons(caar bcons,newca) else newca:=cons(cons('PLUS,car bcons), newca); bcons:=cdr bcons >>; % if ex is an *-expression with grade>1 then possibly b-conditions % had to be dropped, so ex must be added if addex then newca:=cons(exx,newca); if pri then <>; % adding the list of constants of integeration newca:=cons(cilist,newca); if pri then <>; newcases:=cons(newca,newcases) >>; return newcases end$ % of starsep %----------- symbolic procedure separizable(p,ftem,vl)$ begin scalar x,ft,f,ex,v,a,b,vlcp,allvarcaara,print_bak$ vlcp:=vl; repeat << x:=car vl; vl:=cdr vl; % Determining all x-dependent functions ft ft:=nil; for each f in ftem do if member(x,fctargs f) and not my_freeof(p,f) then ft:=cons(f,ft)$ f:=car reverse fctsort ft$ % sorting w.r.t. number of args v:=car setdiff(vlcp,fctargs f)$ % getting rid of f by v-differen. % preparation of the separ-call, ft are now v-indep. functions ft:=nil$ for each f in ftem do if my_freeof(f,v) then ft:=cons(f,ft)$ % ex:=separ(p,ft,list v,nil)$ % det. all lin. ind. factors print_bak:=print_; print_:=nil; ex:=separ2(p,ft,list v)$ % det. all lin. ind. factors print_:=print_bak; a:=ex; while a and << b:=vlcp; while b and not my_freeof(caar a,car b) do b:=cdr b; b >> do a:=cdr a; if a then allvarcaara:=cons(caar a,allvarcaara); >> until (null a) or (null vl); % if a then null vl then whatever x was, there is allways one % element (car a) of ex such that car of this element (caar a) % does depend on all variables --> no separability possible, % new functions would depend on all variables % if a then test whether separation would be possible by getting % rid of functions through differentiation % (this would not be the case if e.g. sin(all variables) would occur) % --> use of smemberl vl:=vlcp; while allvarcaara and not not_included(vlcp,smemberl(vlcp,car allvarcaara)) do <>$ return if a and null allvarcaara then nil % no chance else if a then {nil,car allvarcaara,car vl} % deleting functions first else << % separation now possible if tr_gensep then <>$ {ex,v} >> end$ %----------- symbolic procedure newgensep(p,starpro,ftem,vl)$ % ftem, vl should be correct: % ftem:=smemberl(ftem_,p)$ % vl:=varslist(p,ftem,vl)$ % starpro:=stardep(ftem,vl)$ % returns what starsep returns begin scalar pl,v,ex,a,b$ % ,gense,el1,el2,conds,newcali,l,clist$ % if pairp p and (car p = 'QUOTIENT) then <>$ % ftem:=smemberl(ftem,p)$ % vl:=varslist(p,ftem,vl)$ % if not (starpro:=stardep(ftem,vl)) then % then no *-equation % pl:=list list(nil,p) % one case, no new functions % else % e.g. starpro=((x y z).2) % if zerop cdr starpro then pl:=nil% ############################## % %list cons(nil,separate(p,ftem,vl)) % direct sep % else % if delength(p) leq gensep_ then % generalized separation % << if print_ then <>$ if tr_gensep then <>$ for each v in car starpro do vl:=delete(v,vl); vl:=append(car starpro,vl); a:=separizable(p,ftem,vl)$ if null a then return nil else if null car a then return << % functions to be deleted before separation are those in cadr a % ft:=smemberl(ftem,cadr a); if print_ then <>; nil >> else <>$ for each a in rev_idx_sort for each b in ex collect cons(delength car b,b) collect cdr a$ if tr_gensep then <>$ % with v and v-dep. functions as first factors in the terms in ex pl:=starsep(p,ex,ftem,vl,v); if tr_gensep then <>$ % print_:=oldpri$ %%############################################################ % % l is a list of cases each (list of new fncts, cond1, cond2, ...) % % for each condition (neq p) in all cases calling gensep again % % if needed % pl:=nil; % the final list of cases of only non-*-equ. % while l do % checking all cases % <>; % conds:=cdr conds % >>; % pl:=append(newcali,pl) % >> % >>; return pl end$ % of newgensep %----------- symbolic procedure gen_separation2(arglist)$ % Indirect separation of a pde, 2nd version for non-linear PDEs begin scalar p,h,fl,l,l1,pdes,forg,n,result,d,contrad,newpdes$%,newfdep,bak,sol pdes:=car arglist$ forg:=cadr arglist$ if expert_mode then << l1:=selectpdes(pdes,1); if get(car l1,'starde) then flag(l1,'to_gensep) >> else l1:=pdes$ if (p:=get_gen_separ_pde(l1,nil,nil)) then % if l:=newgensep(get(p,'val), % get(p,'starde), % get(p,'fcts), % get(p,'vars)) then if << cp_sq2p_val(p)$ % #?# not in future version l:=newgensep(get(p,'pval), % #?# sqval in future version get(p,'starde), get(p,'fcts), get(p,'vars)) >> then if cdr l then << if print_ then << terpri()$ write"The indirect separation leads to ",length l," cases."$ %terpri()$ >>$ contrad:=t$ n:=0; remflag1(p,'to_gensep)$ % bak:=backup_pdes(pdes,forg)$ % must come before drop_pde(... backup_to_file(pdes,forg,nil)$ % newfdep:=nil$ while l do << d:=car l; l:=cdr l; if not memberl(cdr d,ineq_) then << % non of the equations is an inequality if n neq 0 then << h:=restore_and_merge(l1,pdes,forg)$ pdes:= car h; forg:=cadr h; % was not assigned above as it has not changed probably % h:=restore_pdes(bak); % pdes:=car h; forg:=cadr h >>; n:=n+1$ start_level(n,list {'EQUAL,0,cdr d})$ %# level_:=cons(n,level_)$ if print_ then << %# print_level(t)$ terpri()$ write "CRACK is now called with the assumption : "$ deprint(cdr d) >>$ % formulation of new equations for each h in car d do << ftem_:=fctinsert(h,ftem_); flin_:=cons(h,flin_) >>$ flin_:=sort_according_to(flin_,ftem_); fl:=append(get(p,'fcts),car d); newpdes:=pdes$ for each h in cdr d do % newpdes:=eqinsert(mkeq ( h,fl,vl_,allflags_,t,list(0),nil,newpdes),newpdes); newpdes:=eqinsert(mkeqSQ(nil,nil,h,fl,vl_,allflags_,t,list(0),nil,newpdes),newpdes); % #?# % further necessary step to call crackmain(): recycle_fcts:=nil$ % such that functions generated in the sub-call % will not clash with existing functions l1:=crackmain_if_possible_remote(newpdes,forg)$ % for each sol in l1 do % if sol then << % for each f in caddr sol do % if h:=assoc(f,depl!*) then newfdep:=cons(h,newfdep); % >>; if not contradiction_ then contrad:=nil$ if l1 and not contradiction_ then result:=merge_crack_returns(l1,result); contradiction_:=nil$ >> >>; delete_backup()$ % % newfdep are additional dependencies of the new functions in l1 % depl!*:=append(depl!*,newfdep); contradiction_:=contrad$ if contradiction_ then result:=nil$ if print_ then << terpri()$ write"This completes the investigation of all cases of an ", "indirect separation."$ terpri()$ >>$ result:=list result % to tell crackmain that computation is completed >> else << % only one case l:=car l; for each h in car l do << ftem_:=fctinsert(h,ftem_); flin_:=cons(h,flin_) >>; flin_:=sort_according_to(flin_,ftem_); fl:=append(get(p,'fcts),car l); pdes:=drop_pde(p,pdes,nil)$ for each h in cdr l do % pdes:=eqinsert(mkeq ( h,fl,vl_,allflags_,t,list(0),nil,pdes),pdes); pdes:=eqinsert(mkeqSQ(nil,nil,h,fl,vl_,allflags_,t,list(0),nil,pdes),pdes); % #?# result:=list(pdes,forg) >>$ return result$ end$ endmodule$ end$