Sindbad~EG File Manager
/* M Beeson, for MathXpert
Additional operations for inequalities with squares and square roots.
Original date 6.5.96
modified 2.27.98
3.28.00 modified several operations adding a guard to cause failure
on inappropriate input.
*/
#define ALGEBRA_DLL
#include <string.h>
#include <math.h>
#include "globals.h"
#include <assert.h>
#include "operator.h"
#include "ops.h"
#include "probtype.h"
#include "algaux.h"
#include "order.h"
#include "polynoms.h"
#include "eqn.h"
#include "factor.h"
#include "complex.h" /* rootofunity */
#include "mstring.h"
#include "solvelin.h"
#include "prover.h"
#include "symbols.h"
#include "cancel.h" /* naive_lcm */
#include "errbuf.h"
#include "deval.h"
#include "pvalaux.h" /* iseven, obviously_positive */
#include "simpprod.h" /* square */
#include "advfact.h"
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq14(term t, term arg, term *next, char *reason)
/* u^2 < a => - sqrt a < u < sqrt a */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = sqrtineq14(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(0,t);
a = ARG(1,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(lessthan(zero,a));
if(err)
{ errbuf(0,english(1570)); /* a must be positive */
return 1;
}
err = sqrt_aux(usq,&u);
if(err)
return 1;
err = sqrt_aux(a,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = and(lessthan(tnegate(sqrta),u), lessthan(u2,sqrta2));
HIGHLIGHT(*next);
strcpy(reason,english(2193)); /* $u^2<a iff -�a < u < �a$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq24(term t, term arg, term *next, char *reason)
/* u^2 � a => -�a � u � �a */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = sqrtineq24(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(0,t);
a = ARG(1,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(le(zero,a));
if(err)
{ errbuf(0,english(1571)); /* a must be non-negative */
return 1;
}
err = sqrt_aux(usq,&u);
if(err)
return 1;
err = sqrt_aux(a,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = and(le(tnegate(sqrta),u), le(u2,sqrta2));
HIGHLIGHT(*next);
strcpy(reason, english(2202)); /* $u^2�a iff -�a � u � �a$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq15(term t, term arg, term *next, char *reason)
/* a < u^2 => u < -�a or �a < u */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = sqrtineq15(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(1,t);
a = ARG(0,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(le(zero,a));
if(err)
{ errbuf(0,english(1571)); /* a must be non-negative */
return 1;
}
err = sqrt_aux(usq,&u);
if(err)
return 1;
err = sqrt_aux(a,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = or(lessthan(u,tnegate(sqrta)), lessthan(sqrta2,u2));
HIGHLIGHT(*next);
strcpy(reason, english(2194)); /* $a<u^2 iff u<-�a or �a<u$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtineq25(term t, term arg, term *next, char *reason)
/* a � u^2 => u � -�a or �a � u */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = sqrtineq25(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(1,t);
a = ARG(0,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(lessthan(zero,a));
if(err)
{ errbuf(0,english(1570)); /* a must be positive */
return 1;
}
err = sqrt_aux(usq,&u);
if(err)
return 1;
err = sqrt_aux(a,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = or(le(u,tnegate(sqrta)), le(sqrta2,u2));
HIGHLIGHT(*next);
strcpy(reason, english(2195)); /* $a�u^2 iff u�-�a or �a�u$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval1(term t, term arg, term *next, char *reason)
/* a<u^2<b => -�b<u<-�a or �a<u<�b */
{ if(!interval_as_and(t))
return 1;
if(FUNCTOR(ARG(0,t)) != '<')
return 1;
if(FUNCTOR(ARG(1,t)) != '<')
return 1;
return sqrtinterval2(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval3(term t, term arg, term *next, char *reason)
/* -a<u^2<b => u^2 < b if 0 < a */
{ return sqrtinterval4(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval5(term t, term arg, term *next, char *reason)
/* -a<u^2�b => u^2 � b if 0 < a */
{ return sqrtinterval4(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval6(term t, term arg, term *next, char *reason)
/* -a�u^2<b => u^2 < b if 0 < a */
{ return sqrtinterval4(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval4(term t, term arg, term *next, char *reason)
/* -a<u^2<b => u^2 < b if 0 < a,
with any combination of < and LE in the interval
*/
{ term a,mid;
unsigned short f,g;
if(!interval_as_and(t))
return 1;
mid = ARG(1,ARG(0,t));
a = ARG(0,ARG(0,t));
f = FUNCTOR(ARG(0,t));
if(!obviously_nonnegative(mid))
return 1;
if(f == '<' && infer(lessthan(a,zero)))
{ errbuf(0,english(1596));
/* Left side must be negative. */
return 1;
}
if(f == LE && infer(le(a,zero)))
{ errbuf(0,english(1597));
/* Left side must not be negative */
return 1;
}
*next = ARG(1,t);
HIGHLIGHT(*next);
g = FUNCTOR(ARG(1,t));
if(f == '<' && g == '<')
strcpy(reason, english(2196)); /* $-a<x^2<b$ iff $x^2<b$ */
else if(f == LE && g == LE)
strcpy(reason, english(2197)); /* $-a�x^2�b$ iff $x^2�b$ */
else if(f == '<' && g == LE)
strcpy(reason, english(2198)); /* $-a<x^2�b$ iff $x^2�b$ */
else if(f == LE && g == '<')
strcpy(reason, english(2199)); /* $-a�x^2<b$ iff $x^2<b$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int sqrtinterval2(term t, term arg, term *next, char *reason)
/* a�u^2�b => -�b�u�-�a or �a�u�b */
{ int err;
unsigned short f = FUNCTOR(ARG(0,t));
unsigned short g = FUNCTOR(ARG(1,t));
term a,b,sqrta,sqrtb,sqrta2,sqrtb2,usq,u,u2,u3,u4;
if(!interval_as_and(t))
return 1;
a = ARG(0,ARG(0,t));
b = ARG(1,ARG(1,t));
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
if(!constant(b))
{ errbuf(0, english(1573)); /* b must be constant */
return 1;
}
if(f == '<')
{ err = infer(le(zero,a));
if(err)
{ errbuf(0,english(1571)); /* a must be non-negative */
return 1;
}
}
else
{ err = infer(lessthan(zero,a));
if(err)
{ errbuf(0,english(1570)); /* a must be positive */
return 1;
}
}
err = infer(lessthan(zero,b));
if(err)
{ errbuf(0, english(1572)); /* b must be positive */
return 1;
}
usq = ARG(1,ARG(0,t));
err = sqrt_aux(usq,&u);
if(err)
return 1;
err = sqrt_aux(a,&sqrta);
if(err)
return 1; /* assert(0) */
err = sqrt_aux(b,&sqrtb);
if(err)
return 1; /* assert(0) */
copy(sqrta,&sqrta2);
copy(sqrtb,&sqrtb2);
copy(u,&u2);
copy(u,&u3);
copy(u,&u4);
if(f == '<' && g == '<')
{ *next = or(
and(lessthan(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
and(lessthan(sqrta2,u3),lessthan(u4,sqrtb2))
);
strcpy(reason,english(2148));
/* $a<u^2<b => -�b<u<-�a$ or $�a<u<�b$ */
}
else if (f == LE && g == LE)
{ *next = or(
and(le(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
and(le(sqrta2,u3),le(u4,sqrtb2))
);
strcpy(reason, english(2149));
/* a�u^2�b => -�b�u�-�a or �a�u�b */
}
else if (f == '<' && g == LE)
{ *next = or(
and(le(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
and(lessthan(sqrta2,u3),le(u4,sqrtb2))
);
strcpy(reason, english(2150));
/* a<u^2�b => -�b�u<-�a or �a<u�b */
}
else if (f == LE && g == '<')
{ *next = or(
and(lessthan(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
and(le(sqrta2,u3),lessthan(u4,sqrtb2))
);
strcpy(reason, english(2151));
/* a�u^2<b => -�b<u�-�a or �a�u<�b */
}
HIGHLIGHT(*next);
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq13(term t, term arg, term *next, char *reason)
/* u^2� < a => -^2��a < u < ^2��a */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2,m;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = rootineq13(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(0,t);
a = ARG(1,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(lessthan(zero,a));
if(err)
{ errbuf(0,english(1570)); /* a must be positive */
return 1;
}
if(FUNCTOR(usq) != '^')
return 1;
m = ARG(1,usq);
if(!iseven(m))
return 1;
if(!INTEGERP(m))
{ err = check(lessthan(zero,m));
if(err)
{ errbuf(0,english(447)); /* Exponent must be positive. */
return 1;
}
}
u = ARG(0,usq);
err = nthroot_aux(a,m,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = and(lessthan(tnegate(sqrta),u), lessthan(u2,sqrta2));
HIGHLIGHT(*next);
strcpy(reason, english(2200));
/* $u^2� < a$ iff $-^2��a < u < ^2��a$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq23(term t, term arg, term *next, char *reason)
/* u^2� � a => -^2��a � u � ^2��a */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2,m;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = rootineq23(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(0,t);
a = ARG(1,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(le(zero,a));
if(err)
{ errbuf(0,english(1571)); /* a must be non-negative */
return 1;
}
if(FUNCTOR(usq) != '^')
return 1;
m = ARG(1,usq);
if(!iseven(m))
return 1;
if(!INTEGERP(m))
{ err = check(lessthan(zero,m));
if(err)
{ errbuf(0,english(447)); /* Exponent must be positive. */
return 1;
}
}
u = ARG(0,usq);
err = nthroot_aux(a,m,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = and(lessthan(tnegate(sqrta),u), lessthan(u2,sqrta2));
HIGHLIGHT(*next);
strcpy(reason, english(2201));
/* $u^2� � a$ iff $-^2��a � u � ^2��a$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq15(term t, term arg, term *next, char *reason)
/* a < u^2 => u < -sqrt a or sqrt a < u */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2,m;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = rootineq15(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(1,t);
if(FUNCTOR(usq) != '^')
return 1;
m = ARG(1,usq);
if(!iseven(m))
return 1;
if(!INTEGERP(m))
{ err = check(lessthan(zero,m));
if(err)
{ errbuf(0,english(447)); /* Exponent must be positive. */
return 1;
}
}
if(!INTEGERP(m))
{ err = check(lessthan(zero,m));
if(err)
{ errbuf(0,english(447)); /* Exponent must be positive. */
return 1;
}
}
u = ARG(0,usq);
a = ARG(0,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(le(zero,a));
if(err)
{ errbuf(0,english(1571)); /* a must be non-negative */
return 1;
}
err = nthroot_aux(a,m,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = or(lessthan(u,tnegate(sqrta)), lessthan(sqrta2,u2));
HIGHLIGHT(*next);
strcpy(reason,english(2152));
/* $a < u^2�$ iff $u<-^2��a$ or $^2��a<u$ */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootineq25(term t, term arg, term *next, char *reason)
/* a � u^2� => u � -^2��a or ^2��a � u */
{ unsigned short f = FUNCTOR(t);
int err;
term temp,u,u2,usq,a,sqrta,sqrta2,m;
if(f == GE || f == '>') /* reduce to LE or '<' */
{ invert(t,&temp);
err = rootineq25(temp,arg,next, reason);
if(err)
{ RELEASE(temp);
return 1;
}
return 0;
}
if(f != '<' && f != LE)
return 1;
usq = ARG(1,t);
if(FUNCTOR(usq) != '^')
return 1;
u = ARG(0,usq);
m = ARG(1,usq);
if(!iseven(m))
return 1;
if(!INTEGERP(m))
{ err = check(lessthan(zero,m));
if(err)
{ errbuf(0,english(447)); /* Exponent must be positive. */
return 1;
}
}
a = ARG(0,t);
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
err = infer(lessthan(zero,a));
if(err)
{ errbuf(0,english(1570)); /* a must be positive */
return 1;
}
err = nthroot_aux(a,m,&sqrta);
if(err)
return 1;
copy(u,&u2);
copy(sqrta,&sqrta2); /* avoid DAGs */
*next = or(le(u,tnegate(sqrta)), le(sqrta2,u2));
HIGHLIGHT(*next);
strcpy(reason,english(2153));
/* a�u^2 iff u�-�a or �a�u */
return 0;
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootinterval1(term t, term arg, term *next, char *reason)
/* a<u^2�<b => -^2��b<u<-^2��a or ^2��a<u<^2��b */
{ if(!interval_as_and(t))
return 1;
if(FUNCTOR(ARG(0,t)) != '<')
return 1;
if(FUNCTOR(ARG(1,t)) != '<')
return 1;
return rootinterval2(t,arg,next,reason);
}
/*_________________________________________________________________*/
MEXPORT_ALGEBRA int rootinterval2(term t, term arg, term *next, char *reason)
/* a�u^2��b => -^2��b�u�-^2��a or ^2��a�u�^2��b */
{ int err;
unsigned short f = FUNCTOR(ARG(0,t));
unsigned short g = FUNCTOR(ARG(1,t));
term a,b,sqrta,sqrtb,sqrta2,sqrtb2,usq,u,u2,u3,u4,m;
if(!interval_as_and(t))
return 1;
a = ARG(0,ARG(0,t));
b = ARG(1,ARG(1,t));
if(!constant(a))
{ errbuf(0,english(1569)); /* a must be constant */
return 1;
}
if(!constant(b))
{ errbuf(0, english(1573)); /* b must be constant */
return 1;
}
usq = ARG(1,ARG(0,t));
if(FUNCTOR(usq) != '^')
return 1;
m = ARG(1,usq);
if(!iseven(m))
return 1;
if(!INTEGERP(m))
{ err = check(lessthan(zero,m));
if(err)
{ errbuf(0,english(447)); /* Exponent must be positive. */
return 1;
}
}
u = ARG(0,usq);
if(f == '<')
{ err = infer(le(zero,a));
if(err)
{ errbuf(0,english(1571)); /* a must be non-negative */
return 1;
}
}
else
{ err = infer(lessthan(zero,a));
if(err)
{ errbuf(0,english(1570)); /* a must be positive */
return 1;
}
}
err = infer(lessthan(zero,b));
if(err)
{ errbuf(0, english(1572)); /* b must be positive */
return 1;
}
err = nthroot_aux(a,m,&sqrta);
if(err)
return 1; /* assert(0) */
err = nthroot_aux(b,m,&sqrtb);
if(err)
return 1; /* assert(0) */
copy(sqrta,&sqrta2);
copy(sqrtb,&sqrtb2);
copy(u,&u2);
copy(u,&u3);
copy(u,&u4);
if(f == '<' && g == '<')
{ *next = or(
and(lessthan(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
and(lessthan(sqrta2,u3),lessthan(u4,sqrtb2))
);
strcpy(reason,english(2154));
/* a<u^2�<b => -^2��b<u<-^2��a or ^2��a<u<^2��b */
}
else if (f == LE && g == LE)
{ *next = or(
and(le(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
and(le(sqrta2,u3),le(u4,sqrtb2))
);
strcpy(reason, english(2155));
/* a�u^2��b => -^2��b�u�-^2��a or ^2��a�u�^2��b") */
}
else if (f == '<' && g == LE)
{ *next = or(
and(le(tnegate(sqrtb),u),lessthan(u2,tnegate(sqrta))),
and(lessthan(sqrta2,u3),le(u4,sqrtb2))
);
strcpy(reason, english(2156));
/* a<u^2��b => -^2��b�u<-^2��a or ^2��a<u�^2��b */
}
else if (f == LE && g == '<')
{ *next = or(
and(lessthan(tnegate(sqrtb),u),le(u2,tnegate(sqrta))),
and(le(sqrta2,u3),lessthan(u4,sqrtb2))
);
strcpy(reason, english(2157));
/* a�u^2�<b iff -^2��b<u�-^2��a or ^2��a�u<^2��b */
}
HIGHLIGHT(*next);
return 0;
}
/*______________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt1(term ineq, term arg, term *next, char *reason)
/* 0 < u/sqrt v => 0 < uv */
/* u/sqrt v > 0 => uv > 0 */
{ unsigned short f = FUNCTOR(ineq);
unsigned short n,k,j;
int i;
char *r;
term left,right,u,v,w,denom,temp,q;
if(f != '<' && f != '>')
return 1;
if(f == '<')
r = "$0 < u/�v => 0 < uv$";
else
r = "$u/�v > 0 => uv > 0$";
left = ARG(f == '<' ? 0 : 1, ineq);
right = ARG(f == '<' ? 1 : 0, ineq);
if(!ZERO(left))
return 1;
if(!FRACTION(right))
return 1;
denom = ARG(1, right);
if(FUNCTOR(denom) == SQRT)
{ v = ARG(0,denom);
HIGHLIGHT(v);
u = ARG(0,right);
w = product(u,v);
if(FUNCTOR(w) == '*')
sortargs(w);
if(f == '>')
*next = greaterthan(w,zero);
else
*next = lessthan(zero,w);
strcpy(reason,r);
return 0;
}
if(FUNCTOR(denom) == '*')
{ /* extract the sqrt term (or terms) */
n = ARITY(denom);
v = make_term('*',n);
q = make_term('*',n);
k = j = 0;
for(i=0;i<n;i++)
{ if(FUNCTOR(ARG(i,denom)) == SQRT)
{ ARGREP(v,k,ARG(0,ARG(i,denom)));
HIGHLIGHT(ARG(k,v));
++k;
}
else
{ ARGREP(q,j,ARG(i,denom));
++j;
}
}
if(k == 0)
return 1; /* no SQRT term */
else if(k == 1)
{ temp = ARG(0,v);
RELEASE(v);
v = temp;
}
else
SETFUNCTOR(v,'*',k);
if(j == 0)
{ RELEASE(q);
q = one;
}
else if(j == 1)
{ temp = ARG(0,q);
RELEASE(q);
q = temp;
}
else
SETFUNCTOR(q,'*',j);
u = ARG(0,right);
w = product(u,v);
if(f == '<')
*next = lessthan(zero, ONE(q) ? w : make_fraction(w,q));
else
*next = greaterthan(ONE(q) ? w : make_fraction(w,q),zero);
strcpy(reason,r);
return 0;
}
return 1;
}
/*______________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt2(term ineq, term arg, term *next, char *reason)
/* u/sqrt v < 0 => uv < 0 */
/* 0 > u/sqrt v => 0 > uv */
{ unsigned short f = FUNCTOR(ineq);
unsigned short n,k,j;
int i;
term left,right,u,v,w,denom,temp,q;
char *r;
if(f != '<' && f != '>')
return 1;
if(f == '<')
r = "$u/�v < 0 => uv < 0$";
else
r = "$0 > u/�v => 0 > uv$";
left = ARG(f == '<' ? 0 : 1, ineq);
right = ARG(f == '<' ? 1 : 0, ineq);
if(!ZERO(right))
return 1;
if(!FRACTION(left))
return 1;
denom = ARG(1, left);
if(FUNCTOR(denom) == SQRT)
{ v = ARG(0,denom);
HIGHLIGHT(v);
u = ARG(0,left);
w = product(u,v);
if(FUNCTOR(w) == '*')
sortargs(w);
if(f == '<')
*next = lessthan(w,zero);
else
*next = greaterthan(zero,w);
strcpy(reason,r);
return 0;
}
if(FUNCTOR(denom) == '*')
{ /* extract the sqrt term (or terms) */
n = ARITY(denom);
v = make_term('*',n);
q = make_term('*',n);
k = j = 0;
for(i=0;i<n;i++)
{ if(FUNCTOR(ARG(i,denom)) == SQRT)
{ ARGREP(v,k,ARG(0,ARG(i,denom)));
HIGHLIGHT(ARG(k,v));
++k;
}
else
{ ARGREP(q,j,ARG(i,denom));
++j;
}
}
if(k == 0)
return 1; /* no SQRT term */
else if(k == 1)
{ temp = ARG(0,v);
RELEASE(v);
v = temp;
}
else
SETFUNCTOR(v,'*',k);
if(j == 0)
{ RELEASE(q);
q = one;
}
else if(j == 1)
{ temp = ARG(0,q);
RELEASE(q);
q = temp;
}
else
SETFUNCTOR(q,'*',j);
u = ARG(0,left);
w = product(u,v);
if(f == '<')
*next = lessthan(ONE(q) ? w : make_fraction(w,q),zero);
else
*next = greaterthan(zero, ONE(q) ? w : make_fraction(w,q));
strcpy(reason,r);
return 0;
}
return 1;
}
/*________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt3(term ineq, term arg, term *next, char *reason)
/* 0 <= u/sqrt v => 0 <= uv */
/* u/sqrt v >= 0 => uv >= 0 */
{ unsigned short f = FUNCTOR(ineq);
unsigned short n,k,j;
int i;
term left,right,u,v,w,denom,temp,q;
char *r;
if(f != LE && f != GE)
return 1;
if(f == LE)
r = "$0 � u/�v => 0 � uv$";
else
r = "$u/�v � 0 => uv � 0$";
left = ARG(f == LE ? 0 : 1, ineq);
right = ARG(f == LE ? 1 : 0, ineq);
if(!ZERO(right))
return 1;
if(!FRACTION(left))
return 1;
denom = ARG(1, left);
if(FUNCTOR(denom) == SQRT)
{ v = ARG(0,denom);
HIGHLIGHT(v);
u = ARG(0,left);
w = product(u,v);
if(FUNCTOR(w) == '*')
sortargs(w);
if(f == LE)
*next = le(zero,w);
else
*next = ge(w,zero);
strcpy(reason,r);
return 0;
}
if(FUNCTOR(denom) == '*')
{ /* extract the sqrt term (or terms) */
n = ARITY(denom);
v = make_term('*',n);
q = make_term('*',n);
k = j = 0;
for(i=0;i<n;i++)
{ if(FUNCTOR(ARG(i,denom)) == SQRT)
{ ARGREP(v,k,ARG(0,ARG(i,denom)));
HIGHLIGHT(ARG(k,v));
++k;
}
else
{ ARGREP(q,j,ARG(i,denom));
++j;
}
}
if(k == 0)
return 1; /* no SQRT term */
else if(k == 1)
{ temp = ARG(0,v);
RELEASE(v);
v = temp;
}
else
SETFUNCTOR(v,'*',k);
if(j == 0)
{ RELEASE(q);
q = one;
}
else if(j == 1)
{ temp = ARG(0,q);
RELEASE(q);
q = temp;
}
else
SETFUNCTOR(q,'*',j);
u = ARG(0,left);
w = product(u,v);
if(f == LE)
*next = le(ONE(q) ? w : make_fraction(w,q),zero);
else
*next = ge(zero, ONE(q) ? w : make_fraction(w,q));
strcpy(reason,r);
return 0;
}
return 1;
}
/*______________________________________________________________________*/
MEXPORT_ALGEBRA int mulineqsqrt4(term ineq, term arg, term *next, char *reason)
/* u/sqrt v <= 0=> uv <= 0 */
/* 0 >= u/sqrt v => 0 >= uv */
{ unsigned short f = FUNCTOR(ineq);
unsigned short n,k,j;
int i;
term left,right,u,v,w,denom,temp,q;
char *r;
if(f != LE && f != GE)
return 1;
if(f == LE)
r = "$u/�v � 0 => uv � 0$";
else
r = "$0 � u/�v => 0 � uv$";
left = ARG(f == LE ? 0 : 1, ineq);
right = ARG(f == LE ? 1 : 0, ineq);
if(!ZERO(right))
return 1;
if(!FRACTION(left))
return 1;
denom = ARG(1, left);
if(FUNCTOR(denom) == SQRT)
{ v = ARG(0,denom);
HIGHLIGHT(v);
u = ARG(0,left);
w = product(u,v);
if(FUNCTOR(w) == '*')
sortargs(w);
if(f == LE)
*next = le(w,zero);
else
*next = ge(zero,w);
strcpy(reason,r);
return 0;
}
if(FUNCTOR(denom) == '*')
{ /* extract the sqrt term (or terms) */
n = ARITY(denom);
v = make_term('*',n);
q = make_term('*',n);
k = j = 0;
for(i=0;i<n;i++)
{ if(FUNCTOR(ARG(i,denom)) == SQRT)
{ ARGREP(v,k,ARG(0,ARG(i,denom)));
HIGHLIGHT(ARG(k,v));
++k;
}
else
{ ARGREP(q,j,ARG(i,denom));
++j;
}
}
if(k == 0)
return 1; /* no SQRT term */
else if(k == 1)
{ temp = ARG(0,v);
RELEASE(v);
v = temp;
}
else
SETFUNCTOR(v,'*',k);
if(j == 0)
{ RELEASE(q);
q = one;
}
else if(j == 1)
{ temp = ARG(0,q);
RELEASE(q);
q = temp;
}
else
SETFUNCTOR(q,'*',j);
u = ARG(0,left);
w = product(u,v);
if(f == LE)
*next = le(ONE(q) ? w : make_fraction(w,q),zero);
else
*next = ge(zero, ONE(q) ? w : make_fraction(w,q));
strcpy(reason,r);
return 0;
}
return 1;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists