maximaのロジックシステム(1)

 ちょっとした経緯があり,maximaに,有理数体上の有理式を項とし,=,<,>,≦,≧を2項述語記号とする(量化記号のない)論理式を有理整数環上の多項式を項とする論理式に変換するコマンドtoimplxを実装してみました.

 論理記号は,否定negx,選言orx,連言andx,等価eqxの全てを含意implxに帰着させるスタイルです.

infix(implx);
infix(orx);
infix(andx);
infix(eqx);
matchdeclare(aa,true,bb,true); 
negx(aa):=(aa)implx(0=1);
aa orx bb:=(negx(aa))implx(bb);
aa andx bb:=negx((negx(aa))orx(negx(bb)));
aa eqx bb:=((aa)andx(bb))orx((negx(bb))andx(negx(aa)));

defrule(sf1,aa>=bb,bb<=aa);
defrule(sf2,aa>bb,bb<aa);
defrule(fr1,aa=bb,xthru(aa)=xthru(bb));
defrule(fr2,aa<bb,xthru(aa)<xthru(bb));
defrule(fr3,aa<=bb,xthru(aa)<=xthru(bb));

matchdeclare(rr,lambda([x],is(denom(x)#1)),cc,true);
defrule(cd1,rr=cc,(num(rr)=cc*denom(rr)) andx (negx(denom(rr)=0)));
defrule(cd2,cc=rr,(num(rr)=cc*denom(rr)) andx (negx(denom(rr)=0)));
defrule(cd3,cc<=rr, 
       ( (0<denom(rr)) andx (cc*denom(rr)<=num(rr)) ) orx
       ( (denom(rr)<0) andx (num(rr)<=cc*denom(rr)) ) );
defrule(cd4,cc<rr, 
       ( (0<denom(rr)) andx (cc*denom(rr)<num(rr)) ) orx
       ( (denom(rr)<0) andx (num(rr)<cc*denom(rr)) ) );
defrule(cd5,rr<=cc, 
       ( (denom(rr)<0) andx (cc*denom(rr)<=num(rr)) ) orx
       ( (0<denom(rr)) andx (num(rr)<=cc*denom(rr)) ) );
defrule(cd6,rr<cc, 
       ( (denom(rr)<0) andx (cc*denom(rr)<num(rr)) ) orx
       ( (0<denom(rr)) andx (num(rr)<cc*denom(rr)) ) );

toimplx1(x):=applyb1(x,sf1,sf2,fr1,fr2,fr3,cd1,cd2,cd3,cd4,cd5,cd6);
toimplx(x):=toimplx1(toimplx1(x));

 結合の強さはデフォルトのままなので,項は丸カッコで挟む必要があります.また,非等号#は用いず,negxで等式を否定して下さい.

 入出力例

toimplx(y=1/x);
(%o51) (1=x*y) implx (0=1) implx (0=1) implx ((x=0) implx (0=1) implx (0=1)) implx (0=1)

toimplx(negx(y=1/x));
(%o52) (1=x*y) implx (0=1) implx (0=1) implx ((x=0) implx (0=1) implx (0=1)) implx (0=1)
 implx (0=1)

toimplx((0<=1/x)eqx(a<x));
(%o53) (0<x) implx (0=1) implx (0=1) implx ((0<=1) implx (0=1)) implx (0=1) implx (0=1) implx 
((x<0) implx (0=1) implx (0=1) implx ((1<=0) implx (0=1)) implx (0=1)) implx (0=1) implx (0=1)
 implx ((a<x) implx (0=1)) implx (0=1) implx (0=1) implx ((a<x) implx (0=1) implx (0=1) implx 
(0=1) implx ((0<x) implx (0=1) implx (0=1) implx ((0<=1) implx (0=1)) implx (0=1) implx (0=1)
 implx ((x<0) implx (0=1) implx (0=1) implx ((1<=0) implx (0=1)) implx (0=1)) implx (0=1)
 implx (0=1)) implx (0=1))

toimplx(((0<x) andx (0<y)) implx (x/y+y/x>=c));
(%o54) (0<x) implx (0=1) implx (0=1) implx ((0<y) implx (0=1)) implx (0=1) implx ((0<x*y)
 implx (0=1) implx (0=1) implx ((c*x*y<=y^2+x^2) implx (0=1)) implx (0=1) implx (0=1) implx 
((x*y<0) implx (0=1) implx (0=1) implx ((y^2+x^2<=c*x*y) implx (0=1)) implx (0=1)))