% ----------------------------------------------------------------------
% $Id: dvfsfqe.red,v 1.5 1999/04/08 11:52:50 dolzmann Exp $
% ----------------------------------------------------------------------
% Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
% ----------------------------------------------------------------------
% $Log: dvfsfqe.red,v $
% Revision 1.5 1999/04/08 11:52:50 dolzmann
% Fixed a bug reporteb by Tony Hearn: Added additional parameter bvl to
% procedure dvfsf_trygauss.
%
% Revision 1.4 1999/03/23 08:50:37 dolzmann
% Changed copyright information.
% Added module comment.
%
% Revision 1.3 1999/01/10 11:13:54 sturm
% Added black box implementation dvfsf_qemkans for rlqea.
%
% Revision 1.2 1996/10/07 11:32:08 sturm
% Added fluids for CVS and copyright information.
%
% Revision 1.1 1996/07/08 12:15:23 sturm
% Initial check-in.
%
% ----------------------------------------------------------------------
lisp <<
fluid '(dvfsf_qe_rcsid!* dvfsf_qe_copyright!*);
dvfsf_qe_rcsid!* :=
"$Id: dvfsfqe.red,v 1.5 1999/04/08 11:52:50 dolzmann Exp $";
dvfsf_qe_copyright!* := "Copyright (c) 1995-1999 by A. Dolzmann and T. Sturm"
>>;
module dvfsfqe;
% Discretely valued field standard form quantifier elimination.
% Submodule of [dvfsf].
procedure dvfsf_varsel(f,vl,theo);
car vl;
procedure dvfsf_pmultf(u);
multf(u,numr simp 'p);
procedure dvfsf_pmultsq(u);
multsq(u,simp 'p);
procedure dvfsf_ipmultsq(u);
quotsq(u,simp 'p);
procedure dvfsf_translat(atf,v,theo,pos,ans);
begin scalar op,lhs,rhs;
if not (v memq dvfsf_varlat atf) then
return nil . nil;
if not pos then atf := dvfsf_negateat atf;
op := dvfsf_op atf;
lhs := dvfsf_arg2l atf;
rhs := dvfsf_arg2r atf;
if op eq 'neq then
return dvfsf_translat2(v,'sdiv,{lhs . rhs});
if op = 'sdiv or op = 'div or op = 'equal then
return dvfsf_translat2(v,op,{lhs . rhs});
if op eq 'assoc then
return dvfsf_translat2(v,'div,{lhs . rhs,rhs . lhs});
if op eq 'nassoc then
return dvfsf_translat2(v,'sdiv,{lhs . rhs,rhs . lhs});
rederr "BUG IN dvfsf_translat"
end;
procedure dvfsf_translat2(v,op,l);
begin scalar m,eqsoll,pr,cl,dl,el,fl,a,aa,b,bb,co;
if op = 'equal then
return {'equal . {dvfsf_mkcsol dvfsf_mkpair(caar l,v)}} . nil;
for each x in l do <<
pr := dvfsf_mkpair(car x,v);
a := car pr;
b := cdr pr;
pr := dvfsf_mkpair(cdr x,v);
aa := car pr;
bb := cdr pr;
if null aa then <<
cl := lto_insert(dvfsf_mkcpoint(negf b,a),cl);
dl := lto_insert(dvfsf_mkcpoint(bb,a),dl)
>> else if null a then <<
el := lto_insert(dvfsf_mkcpoint(b,aa),el);
fl := lto_insert(dvfsf_mkcpoint(negf bb,aa),fl)
>> else <<
cl := lto_insert(dvfsf_mkcpoint(negf b,a),cl);
dl := lto_insert(dvfsf_mkcpoint(bb,a),dl);
el := lto_insert(dvfsf_mkcpoint(b,aa),el);
fl := lto_insert(dvfsf_mkcpoint(negf bb,aa),fl);
fl := lto_insert(dvfsf_mkcpoint(negf bb,a),fl);
co := rl_mkn('and,{dvfsf_0mk2('neq,a),dvfsf_0mk2('neq,aa)});
a := !*f2q a;
b := !*f2q b;
aa := !*f2q aa;
bb := !*f2q bb;
m := subtrsq(quotsq(bb,aa),quotsq(b,a));
el := lto_insert({co,multsq(quotsq(a,aa),m)},el);
dl := lto_insert({co,multsq(quotsq(aa,a),m)},dl)
>>
>>;
return {'c . cl,'d . dl,'e . el,'f . fl} . nil
end;
procedure dvfsf_mkpair(u,v);
begin scalar d;
u := sfto_reorder(u,v);
d := degr(u,v);
if d=0 then
return nil . reorder u;
if d=1 then
return reorder lc u . reorder red u;
rederr {"degree violation in",prepf reorder u}
end;
procedure dvfsf_mkcsol(pr);
{dvfsf_0mk2('neq,car pr),quotsq(!*f2q negf cdr pr,!*f2q car pr)};
procedure dvfsf_mkcpoint(b,a);
{dvfsf_0mk2('neq,a),quotsq(!*f2q b,!*f2q a)};
procedure dvfsf_elimset(v,alp);
% Discretely valued field elimination set. [v] is a variable;
% [alp] is a pair of alists.
begin scalar w,esetl,atal,cl,el,m1,m2; integer i;
atal := car alp;
cl := lto_catsoc('c,atal);
el := lto_catsoc('e,atal);
if !*rlverbose and null el then ioto_prin2 "#u"; % only upper bounds
esetl := {'true,simp 1} . lto_catsoc('equal,atal); % 1
esetl := nconc(lto_catsoc('f,atal),esetl); % F
for each d in lto_catsoc('d,atal) do
esetl := {car d,dvfsf_ipmultsq cadr d} . esetl; % p^{-1} d
for each c in cl do <<
esetl := {car c,dvfsf_ipmultsq cadr c} . esetl; % p^{-1} c
if el then << % also lower bounds
for each e in el do
esetl := {rl_mkn('and,{car c,car e}),
addsq(cadr e,cadr c)} . esetl; % e+c
for each cc in cl do <<
m2 := cadr cc;
m1 := subtrsq(cadr c,m2);
esetl := {rl_mkn('and,{car c,car cc}),
addsq(dvfsf_pmultsq m1,m2)} . esetl; % p(c-cc)+cc
% Avoid cosets.
w := if dvfsf_p!* neq 0 then
min(length cl,abs(dvfsf_p!*)-1)
else
length cl;
for z := 1:w do
esetl := {rl_mkn('and,{car c,car cc}),
addsq(multsq(simp z,m1),m2)} . esetl % z(c-cc)+cc
>>
>>
>>;
if el then % also lower bounds
esetl := nconc(cl,esetl); % C
return {'dvfsf_qesubcq . esetl}
end;
procedure dvfsf_qesubcq(bvl,theo,f,v,c,u);
% Substitute conditionally 1 quotient. [f] is a formula; [v] is a
% variable; [c] is a formula which implies that the denominator of
% [u] is nonzero; [u] is an SQ. Returns a quantifier-free formula
% equivalent to $[c] \land [f]([v]/[u])$.
if (c := cl_simpl(c,nil,-1)) eq 'false then
nil . 'false
else
nil . rl_mkn('and,{c,dvfsf_qesubq(f,v,u)});
procedure dvfsf_qesubq(f,v,u);
% Substitute quotient. [f] is a formula; [v] is a variable; [u] is
% an SQ. Returns a quantifier-free formula equivalent to
% $[f]([v]/[u])$ provided that the denominator of [u] is nonzero.
cl_apply2ats1(f,'dvfsf_qesubqat,{v,u});
procedure dvfsf_qesubqat(atf,v,u);
% Substitute quotient into atomic formula. [atf] is an atomic
% formula; [v] is a variable; [u] is an SQ. Returns a
% quantifier-free formula equivalent to $[atf]([v]/[u])$ provided
% that the denominator of [u] is nonzero.
begin scalar op,al,lhs,rhs;
op := dvfsf_op atf;
al := {v . prepsq u};
lhs := subf(dvfsf_arg2l atf,al);
if op memq '(equal neq) then
return dvfsf_0mk2(op,numr lhs);
rhs := subf(dvfsf_arg2r atf,al);
return dvfsf_mk2(op,multf(numr lhs,denr rhs),multf(numr rhs,denr lhs))
end;
procedure dvfsf_transform(f,v);
f . nil;
procedure dvfsf_trygauss(f,vl,theo,ans,bvl);
begin scalar w,v,fargl;
if rl_op f = 'and then
fargl := rl_argn f
else if cl_atfp f then
fargl := {f}
else
return 'failed;
while vl do <<
v := car vl;
vl := cdr vl;
w := dvfsf_findeqsol(fargl,v,theo,ans);
if w neq 'failed then <<
w := (v . w) . theo;
vl := nil
>>
>>;
return w
end;
procedure dvfsf_findeqsol(fl,v,theo,ans);
begin scalar w;
w := dvfsf_findeqsol1(car fl,v,theo,ans);
if w neq 'failed then return w;
if cdr fl then return dvfsf_findeqsol(cdr fl,v,theo,ans);
return 'failed
end;
procedure dvfsf_findeqsol1(a,v,theo,ans);
if cl_cxfp a or dvfsf_op a neq 'equal or not (v memq dvfsf_varlat a) then
'failed
else
dvfsf_gelimset(a,v);
procedure dvfsf_gelimset(a,v);
begin scalar pr;
pr := dvfsf_mkpair(dvfsf_arg2l a,v);
if numberp car pr then
return {'dvfsf_qesubcq . {dvfsf_mkcsol pr}};
return 'failed
end;
procedure dvfsf_qemkans(an,atr);
sort(dvfsf_qebacksub dvfsf_qemkans1 an,
function(lambda(x,y); ordp(cadr x,cadr y)));
procedure dvfsf_qemkans1(an);
% [an] is an answer. Returns a list of equations.
for each y in an collect
% cadr y = 'dvfsf_qesubcq, cadddr y = nil (atr)
{'equal,car y,prepsq cadr caddr y};
procedure dvfsf_qebacksub(eql);
% Quantifier elimination back substitution. [eql] is a list of
% equations. Returns a list of equations.
begin scalar subl,rhs,w;
return for each e in eql collect <<
rhs := simp caddr e;
w := {'equal,cadr e,prepsq subsq(rhs,subl)};
subl := (cadr w . caddr w) . subl;
w
>>
end;
endmodule; % [dvfsfqe]
end; % of file