Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/
Upload File :
Current File : /usr/home/beeson/MathXpert/terms.h

/* data structures for mathematical expressions ("terms") in c */
/* M. Beeson */
/* created April 1990 */
/* history in terms.his */
/* 10.25.05 added LARGPTR */
/* 8.19.07 added EULERGAMMA_DECIMAL */
/* 6.2.13 added SIGNEDINTEGERP   */

/* the data structure 'term' is not supposed to be manipulated except by
the macros in this file, which constitute the public interface to
the data structure.  */

#include <ctype.h>  /* for isalpha */
#include "heap.h"   /* malloc, calloc, and free */
#include "bignum.h"

#define MAXIMUM(a,b)   (((a) > (b)) ? (a) : (b))
#define PI_DECIMAL 3.141592653589793238462643383279
#define E_DECIMAL  2.71828182845904523536
#define EULERGAMMA_DECIMAL 0.577215664901532860606512090083

/*_______________________________________________________________________*/
/* THE DATA STRUCTURE 'TERM' */

#if 0
/* One can do it this way, but then one can't inspect the terms
conveniently */
typedef struct
   { unsigned short symbol;
     unsigned short arity;
     unsigned short info;
     void *args;
   } term;

#endif
/* Instead we make the void * more specific as shown below. */

typedef union argtag arg;

typedef struct
   { unsigned short symbol;
     unsigned short arity;
     unsigned short info;
     arg *args;
   } term;

union argtag
   { term t;
     long i;
     double d;
     bignum b;
   };

 /* For compound terms,  t.args is a dynamic array of terms, the
 arguments of t. Thus  the i-th argument of t is simply  t.args[i]
 (except for the casts required by ANSI C).  The most basic
 macros for manipulating terms are as follows: */

#define ARG(N,F)   (((term *)(F).args)[N])   /* the n-th argument itself */
                         /* use only for compound terms */
                         /* arguments are numbered starting from 0 */
#define ARGPTR(t) ((term *) ((t).args))  /* pointer to args of t */
#define LVARGPTR(t) (((t).args))         /* for use as an lvalue */
/* using ARGPTR(t) as an lvalue provokes an error in gcc 4.0.1 */
/* so ARGPTR(t) + i  will be a pointer to the i-th arg */

#define ARGREP(t,n,newarg)   ((term *) ((t).args))[n] = newarg
       /* gives compound term t a new n-th argument.
          Does not erase any old argument it may have had before. */
#define ARITY(F)   ((F).arity)
#define FUNCTOR(F) ((F).symbol)

/*  The args field is declared as arg*  instead of struct tm *,
because in the case of 'object' terms (numbers or polynomials of various kinds)
it is not a pointer to the base of a dynamic array of terms, but simply
to the 'object' data itself, which can be of various sizes.  Thus
terms themselves are always 8 bytes (2 bytes of functor, 2 bytes of info,
and one pointer)  but the data pointed to is of different sizes. */


#define ZEROINFO(x)  ((x).info = 0)

#include "functors.h"  /* definitions of predefined atoms and functors */
#include "maketerm.h"  /* prototypes of creator functions */


/*________________________________________________________________________*/
/* Meaning of the 'symbol' field:
     first byte is the 'functor byte':
         up to and including 20 means a predefined atom.
         21 to WEIERSTRASSP  means a predefined functor.
         We use up to 16 user-defined atoms
         and up to 16 user-defined functions, which occupy the last
         32 places out of 256, leaving 224.  The user-defined atoms
         must not overlap the predefined functors.
         Zero in the functor field means an 'object'.
*/
#define FIRST_DEFINED_ATOM  224
#define FIRST_DEFINED_FUNCTION 240
#define LAST_DEFINED_FUNCTION 255
#define DEFINED_FUNCTION(F)   ( (F) >= FIRST_DEFINED_FUNCTION && (F) <= LAST_DEFINED_FUNCTION)
#define DEFINED_ATOM(F)       ( (F) >= FIRST_DEFINED_ATOM && (F) < FIRST_DEFINED_ATOM + MAXATOMS)
#define DIRECT_ATOM(F)  ((F) < FIRST_DEFINED_ATOM)
#define INDEX(F)  ((F) - FIRST_DEFINED_FUNCTION)  /* offset into 'functors' array,
                           used to get the print name of a user-defined function */
#define ATOMINDEX(F)  ((F) - FIRST_DEFINED_ATOM)
   /* this is an offset into the 'symbols' array, used
   to get the print name of a user-defined atom */
#define INDEX_TO_FUNCTOR(F)   ((F) + FIRST_DEFINED_FUNCTION)
#define PREDEFINED_FUNCTOR(F)  ((F) <= WEIERSTRASSP && !isalpha(F))
#define SUBSCRIPT(F)  ((F) >> 8)  /* upper 8 bits of functor */
#define VARNAME(F)  (unsigned short)((F) & 0x00ff)    /* lower 8 bits of functor */
#define SUBSCRIPTEDFUNCTOR(x,n)   ((x) | ((n+1) << 8))
    /* This makes a functor appropriate for the variable x sub n */
#define MAXSUBSCRIPT   254   /* 8 bits can be used for the subscript */
/*___________________________________________________________________*/
/* Meaning of the .arity field:
         number of arguments of a compound functor;
         1 for an 'object' (that is, a number)
         0 for an atom
   The following macros enable us to determine whether a term
   is an object, an atom, or a compound term:  */

#define OBJECT(F)  ( FUNCTOR(F) == 0 && ARITY(F) == 1 )
#define ISATOM(F)    (ARITY(F) == 0)
#define COMPOUND(F) (! ISATOM(F) && !OBJECT(F))
#define ATOMIC(F)  (ISATOM(F) || OBJECT(F))

/* The following macros enable us to set the symbol and arity fields: */

#define SETFUNCTOR(t,f,n)     (((t).symbol = f),((t).arity = n))
#define SETSYMBOL(t,f)        ((t).symbol = f)
#define SETARITY(t,n)         ((t).arity = n)

/* This macro makes a 'raw' atom  */
#define MAKE_ATOM(F)  make_term(F,0)  /* F is a short int coding an atom */
/*___________________________________________________________________*/
/* Types.  Once we know a term is an object, we still don't know whether
it is an integer, a double, or what.  Objects have types.  Variables
also have types.  The type info of an object is kept with the term,
in bits 0-3 of the info field.  The type info of variables may sometimes
be kept there too, but not always.  */

/* Bits 0-3 of the info field are used for type information
   according to the following scheme:

             bit 0:   quotients? (for non-floating types, i.e. bit 3 zero)
             bit 1:   bignums?
             bit 2:   complex number?
             bit 3:   floating point?
             all bits 0, by this convention, means an int (a long really)

  With this convention, the  'common type' of two terms is
  found by just taking the bitwise 'or'.  Isn't that neat?
  However, it isn't quite that simple in reality, because
  in MATHPERT, bigfloats and bigcomplexes are not implemented,
  so COMMONTYPE(DOUBLE,BIGNUM) = DOUBLE, not BIGFLOAT.  That is,
  if bits 3 and 1 are both on when the 'or' is taken, bit 1 should be
  turned off.  Moreover,  fractions of doubles aren't used, so if
  bit 3 is on, bit 0 should be off too.

In MATHPERT, only nonnegative bignums, integers, and doubles actually are
treated as atomic objects.  Negative numbers are terms with functor '-';
rationals and bigrats are terms with functor '/'.   Such terms can still
carry type info if they are in standard form; but e.g. 1/200000000000 would
not qualify as a BIGRAT unless 1 is represented as a BIGRAT.  If a term is
not typed, or not typed yet, the type info slot will contain NOTYPE.
*/

#define COMMONTYPE(type1,type2)  ( ((((type1) | (type2)) & 0x0008) == 0x0008) ? \
        (((type1) | (type2)) & 0xfffc) : ((type1) | (type2))  )

/*           Here are the fifteen basic types  : */

#define  INTEGER     0U     /* also the type of integer variables */
#define  RATIONAL    1U
#define  BIGNUM      2U
#define  BIGRAT      3U
#define  GAUSSIAN    4U
#define  CRAT        5U
#define  BIGGAUSSIAN 6U
#define  BIGCRAT     7U
#define  DOUBLE      8U
/*  9 would be quotients of doubles, which is useless */
#define  NATNUM      9U     /* a variable might in principle have this type,
                             but actually no such variables are ever created.*/
#define  BIGFLOAT    10U
#define  R           10U    /* variables have types too, and this is used
                              for real variables */
/*  11 would be quotients of bigfloats, which is useless */
#define  DCOMPLEX   12U     /* with double real and imaginary parts */
                           /* also used as the type of complex variables */
/*  13  would be quotients of complexes, which is useless */
#define  BIGCOMPLEX 14U     /* complex numbers with bigfloat parts */
#define NOTYPE 15U
/*  15  would otherwise be quotients of bigcomplex, which is useless */
/*   etc. */

#define TYPE(F)    (((F).info) & (unsigned short) 0x000f)   /* bits 0-3 */
#define SETTYPE(F,TYPE)   ((F).info = (unsigned short)(((F).info & 0xfff0) | (TYPE)))
#define ISINTEGER(F) (TYPE(F)==INTEGER && OBJECT(F))
#define INTEGERP(F)  (OBJECT(F) && (TYPE(F) == INTEGER || TYPE(F) == BIGNUM))
#define SIGNEDINTEGERP(F) (INTEGERP(F) || (FUNCTOR(F) == '-' && INTEGERP(ARG(0,F))))
#define RATIONALP(F) (FUNCTOR(F)== '/' && INTEGERP(ARG(0,F)) && INTEGERP(ARG(1,F)))
#define SIGNEDRATIONAL(F) (RATIONALP(F) || (NEGATIVE(F) && RATIONALP(ARG(0,F))))
#define POSNUMBER(x) (OBJECT(x) || RATIONALP(x))
#define NUMBER(x)   (POSNUMBER(x) || (NEGATIVE(x) && POSNUMBER(ARG(0,x))))

/* The next five macros extract data from atomic objects */
#define INTDATA(F)   ( * ((long *) ((F).args)) )
#define DOUBLEDATA(F)  (*((double *)((F).args)) )
#define REALDATA(F)  DOUBLEDATA(F)
#define IMAGDATA(F) (*((double *)((F).args)+1) )
#define BIGNUMDATA(F)  (*((bignum *)((F).args)) )

#define NEGATIVE(F)  (FUNCTOR(F) == '-' )
#define FRACTION(F)  (FUNCTOR(F) == '/' )
#define SIGNEDFRACTION(t)  (FUNCTOR(t) == '/' || (FUNCTOR(t) == '-' && FUNCTOR(ARG(0,t))=='/'))
#define ZERO(F)   (OBJECT(F) && ((TYPE(F) == INTEGER && INTDATA(F)== 0) || (TYPE(F) == BIGNUM && BIGNUMDATA(F).ln == 1 && BIGNUMDATA(F).val[0] == 0)))
#define ISZERO(x)  (ZERO(x) || (OBJECT (x) && TYPE(x)==DOUBLE && fabs(DOUBLEDATA(x)) < 1.0e-15))
/* ZERO(x) only checks for ints and bignums */

#define ISONE(x)  ((TYPE(x)==INTEGER && OBJECT(x) && INTDATA(x)==1) || (OBJECT(x) && TYPE(x)==DOUBLE && fabs(DOUBLEDATA(x)-1.0) < 1.0e-15))
#define ONE(F)       (OBJECT(F) && TYPE(F) == INTEGER && INTDATA(F)== 1)
#define ONEHALF(t) (FRACTION(t) && ONE(ARG(0,t)) && ISINTEGER(ARG(1,t)) && INTDATA(ARG(1,t))==2)

/* Complex terms can represented as sums x+iy just as in mathematics,
   and there can also be complex numbers as objects, whose arg field points
   to two doubles (in other words, a dcomplex)  */

#define COMPLEX(F)     ((((F).info) & 0x0004U)  && TYPE(F) != NOTYPE)
#define SETCOMPLEX(F)   ( (((F).info & 0x000fU) ==  (unsigned short) 0x000fU) ? ((F).info = (((F).info & (unsigned short) 0xfff0U) | (unsigned short) 0x0004U)) : (((F).info = (F).info | (unsigned short) 0x0004U)))
#define UNSETCOMPLEX(F) ((F).info &= 0xfffb)
#define REAL(F)        (!(((F).info) & 0x0004))
/* next two macros get real and imaginary parts of x+iy or of iy */
#define RE(F)   ( FUNCTOR(F) == '+' ? ARG(0,(F)) : zero);
#define IM(F)   ( (FUNCTOR(F) == '+') ? ARG(1,ARG(1,(F))) : ARG(1,(F)) )


/* Ordinary (first-order, mathematical) variables are represented as
atoms.  Metavariables, that is, variables ranging over first-order terms,
are represented as atoms with functor VAR.  Thus all metavariables
have the same functor.
Then bits 0-11 of the .info field are used to
give the subscript of the variable, i.e. the index
i such that this term is the i-th metavariable.
A global array of terms, metavariables, holds the current value
of the metavariables.   */

/*______________________________________________________________________*/
#define METAVARIABLE(x)   (ARITY(x) == 0 && ((x).info & 0x2000))  /* bit 13 */
#define META(x)          ((x).info |= 0x2000)  /* set bit 13 */
#define UNMETA(x)        ((x).info &= 0xdfff)  /* 1 everywhere but bit 13 */
#define METASUBSCRIPT(t)  ((t).info & 0x0fff)
#define SET_METASUBSCRIPT(t,k)   ((t).info = (unsigned short) ((t).info & (unsigned short) 0xf000) | (k))



/*  Meaning of the remaining 12 bits of the info field:

     bit  4
               for fractions (of whatever type)
               if set means already in lowest terms
               For integers:  means it's prime
               For polynomials: means it's irreducible.  See bit 12,
                  which is used to indicate Mathpert's inability to
                  factor.
               For products: means the factors are prime or prime powers,
                  or irreducible, at least as far as Mathpert can tell;
                  if this bit is set on a product, arithmetic won't
                  multiply it out in auto mode, to prevent
                  undoing a complicated factoring process; but this
                  way it can still be checked in menu mode.
               For equations or inequalities:  means already processed by reduce_ineq
               for atoms:  means it depends on some other atom (so
                 its derivative is not automatically zero).  This bit
                 is set when an atom is let-defined, or when the user
                 answers yes to "Does y depend on x" in ask_user_about_parameters.
               for AND terms--means it is an interval and so should not be
               flattened with other AND terms.
               for integrals: means integration by substitution
               has already been tried.
                 for series: means it has been proved convergent or divergent,
               so don't try any more convergence tests.

     bit 5     if set,  it means t is an arithmetic expression, so its
               value can be calculated; thus 0 in the type info means
               it's an integer, not that it has no type.
               for a bignum term, means the arg points to a display string
               rather than a bignum, i.e. this is a "fake bignum"
     bit 6     Set by make_term, means the args of t can be freed.
               Set to zero by destroy_term.  See SETARGS and HASARGS
     bit 7     if set means the term is 'protected',  e.g. if in factoring
               we write everything as a function of 3*x, then 3*x will be
               'protected', and order_terms won't touch 2*(3*x)
               See PROTECT, UNPROTECT, PROTECTED;
     bit 8     the "ALREADY" bit.
               For non-logical terms (except POLY terms),
               it means "already processed by polyval".
               For POLY terms, it means "known to be primitive"
                  (checked and set by pp in polynoms.c)
               For logical terms, it means "already processed by lpt".
               (Since lpt calls polyval on non-logical terms, this is
               consistent usage.)
               See macros ALREADY and SET_ALREADY.
     bit 9     the "ALREADYARITH" bit.  Set indicate
               "already processed by arith()";  arith() checks this bit and
               exits immediately if it is set.
               See macros ALREADYARITH and SET_ALREADYARITH.
     bit 10    means it's a complex arithmetical expression, i.e. an
               arithmetical expression containing 'i' somewhere.  See
               macros CE and SETCE.
     bit 11    For products and sums:
               If set, means do NOT re-order the args of this term.
               Also used to mark an assumption PROVISIONAL.  No conflict
               arises because sums and products can't be propositions,
               and assumptions must be propositions.  For atoms: it
               means "put me last in additive order regardless of orderflag".
               Used for constants of integration and limit variables.
               For an integral, means the integrand may not be defined
               on the closed interval of integration.  Used to mark
               improper integrals.
     bit 12    is set for a sum to indicate that Mathpert can't factor it,
               and also can't prove it is irreducible,
               whether or not it is really irreducible.  Bit 4 is used
               only to indicate that it is truly irreducible.
               For an integral, it means similarly that Mathpert can't
               integrate it. Bit 4 in this case is used to mean that
               integration by substitution doesn't work on that integral.
               For equations:  means it's already been checked in the
               original equation.  For inequalities, ANDs or ORs, it means
               it was the output of explicitdomain, so explicitdomain
               shouldn't be called on it again.
                  For atoms:  is set by getnewintvar, to indicate that
               this is an EXISTENTIAL variable of type INTEGER, introduced
               by the domain-finder.  Setting this bit enables the grapher
               to check for such variables without needing to access varinfo.
     bit  13   used on an equation or inequality to indicate it is the
               currently selected equation, i.e. should be displayed instead
               of history[currentline] which is an AND or OR of equations/ineqs.
                 Also used to indicate a metavariable, and on an AND is
               used to indicate that a system of equations should be displayed
               with variables lined up.
                 Also used on an infinite series to indicate that coefficients
               before ... should be displayed as doubles.
     bit  14   used to indicate that the argument(s) should be printed as
               subscripts.  On a sum, this bit begs "factor me, even if
               factoring is turned off."
                  Also used on an infinite series to indicate that coefficients
               before ... should be displayed with factorials evaluated.
     bits 15   is set to specify 'highlight this term', so that if the term
               is displayed, it will be displayed in the document's
               highlight color.
*/
#define META_BIT 0x2000  /* bit 13 */
#define AE_BIT 0x0020
#define AE(F)  (((F).info) & AE_BIT)        /* arithmetic expression:
                                               bit 5, set or not? */
#define SETAE(F)  ((F).info |=  AE_BIT)     /* set bit 5 */
#define CE_BIT 0x0400                       /* used in constant.c */
#define CE(F)  (((F).info) & CE_BIT)        /* complex arithmetical expression:
                                               bit 10, set or not? */
#define SETCE(F)  ((F).info |= CE_BIT)                /* set bit 10 */
/* Note:  'COMPLEX' means, has the form a+bi with a real (or bi, or i) */
/* CE means, evaluates to that form.  Both must be numerical except for i */
#define HASARGS(F)  (((F).info) & 0x0040)             /* see if bit 6 is set */
#define SETARGS(F)  ((F).info |= 0x0040)              /* set bit 6 */
#define KILLARGS(F) ((F).info &=  0xffbf)             /* set bit 6 to 0 */
#define PROTECTED(F)  (((F).info) & 0x0080)           /* see if bit 7 is set */
#define PROTECT(F)  ((F).info |= 0x0080)              /* set bit 7 */
#define UNPROTECT(F) ((F).info &=  0xff7f)            /* set bit 7 to 0 */
#define ALREADY(F)   ((F).info & 0x0100)              /* see if bit 8 is set */
#define SET_ALREADY(F) ((F).info |= 0x0100)           /* set bit 8 */
#define UNSET_ALREADY(F) ((F).info &=  0xfeff)        /* set bit 8 to 0 */
#define ALREADYARITH(F) ((F).info & 0x0200)           /* see if bit 9 is set */
#define SET_ALREADYARITH(F) ((F).info |= 0x0200)      /* set bit 9 */
#define UNSET_ALREADYARITH(F) ((F).info &=  0xfdff)   /* set bit 9 to 0 */
#define SET_SELECTED(F) ((F).info |=  0x2000)         /* set bit 13 */
#define SET_DEVALCOEF(F) ((F).info |=  0x2000)        /* set bit 13 */
#define SELECTED(F) ((F).info & 0x2000)               /* see if bit 13 is set */
#define DEVALCOEF(F) ((F).info & 0x2000)               /* see if bit 13 is set */
#define UNSELECT(F) ((F).info &= 0xdfff)              /* set bit 13 to zero */
#define UNSET_DEVALCOEF(F) ((F).info &= 0xdfff)      /* set bit 13 to zero */
#define LINEUP(F)  SELECTED(F)
#define SET_LINEUP(F) SET_SELECTED(F)
#define UNLINEUP(F)  UNSELECT(F)
#define SUBSCRIPTARGS(F)  ((F).info & 0x4000)         /* see if bit 14 is set */
#define FACTORME(F)  ((F).info & 0x4000)              /* see if bit 14 is set */
#define EVALFACTORIAL(F) ((F).info & 0x4000)          /* see if bit 14 is set */
#define SET_EVALFACTORIAL(F) ((F).info |= 0x4000)     /* set bit 14         */
#define SET_SUBSCRIPTARGS(F) ((F).info |= 0x4000)     /* set bit 14         */
#define SET_FACTORME(F)  ((F).info |= 0x4000)         /* set bit 14         */
#define UNSET_FACTORME(F) ((F).info &= 0xbfff)        /* set bit 14 to zero */
#define UNSET_EVALFACTORIAL(F) ((F).info &= 0xbfff)    /* set bit 14 to zero */
#define SETDIVERGENT(F) ((F).info |= 0x4000)         /* set bit 14, used for infinite series  */
#define DIVERGENT(F) ((F).info & 0x4000)              /* see if bit 14 is set */
/* One bit can be used to specify that a term should be
   highlighted.  This bit is set with SETCOLOR or HIGHLIGHT.  The
   parameter of SETCOLOR is only meaningful in that it is
   zero or not.  */
#define COLOR(F)  ((char) ((F).info >>15))    /* bit 15 */
#define HIGHLIGHT(F) ((F).info |= 0x8000)     /* set bit 15 */
#define SETCOLOR(F,color)  ((F).info = (unsigned short) (((color) ? (((F).info & (unsigned short) 0x7fff) | (unsigned short) 0x8000) : ((F).info & (unsigned short) 0x7fff))))
#define YELLOW 6U   /* SETCOLOR(f,YELLOW) is used throughout Mathpert to highlight terms */

/*  function prototypes for functions that make objects of various types */
/*  the functions are in terms.c */

#define RELEASE(x)  free2((x).args)   /* undoes make_term */

void destroy_term(term);
void destroy_bblocked_term( term);
term make_atom_from_string( char *);
term make_imag(term);
term make_complex(term,term);

/* macros for looking at bit 4  of the info field */

#define FACTORED(F)       (((F).info) & 0x0010)
#define REDUCED(F)        (((F).info) & 0x0010)
#define PRIME(F)          (((F).info) & 0x0010)
#define CONVERGENT(F)     (((F).info) & 0x0010)
#define IRREDUCIBLE(F)    (((F).info) & 0x0010)
#define SETREDUCED(F)     (((F).info) |= 0x0010)
#define SETPRIME(F)       (((F).info) |= 0x0010)
#define SETCONVERGENT(F)  (((F).info) |= 0x0010)
#define UNSETPRIME(F)     (((F).info)  &= 0xffef)
#define UNSETCONVERGENT(F)(((F).info)  &= 0xffef)
#define SETINTERVAL(F)    SETPRIME(F)
#define ISINTERVAL(F)     PRIME(F)
  /* SETPRIME is also used to label an inequality or equation
      as processed by reduce_ineq */
#define SETFACTORED(F)      SETPRIME(F)
#define SETDEPENDENT(F)     SETPRIME(F)  /* for an atom, means it depends on another variable */
#define DEPENDENT(F)        PRIME(F)
#define ORDERED(F)          (((F).info) & 0x0800)  /* is bit 11 set? */
#define IMPROPER(F)          (((F).info) & 0x0800) /* is bit 11 set? */
#define PROVISIONAL(F)      (((F).info) & 0x0800)  /* is bit 11 set? */
#define SETORDERED(F)       (((F).info) |= 0x0800) /* set bit 11     */
#define UNSETORDERED(F)     (((F).info) &= 0xf7ff) /* unset bit 11   */
#define SETPROVISIONAL(F)   (((F).info) |= 0x0800) /* set bit 11     */
#define UNSETPROVISIONAL(F) (((F).info) &= 0xf7ff) /* unset bit 11   */
#define SETIMPROPER(F)   (((F).info) |= 0x0800)    /* set bit 11     */
#define ISEXISTENTIALVAR(F) (((F).info) & 0x1000)  /* is bit 12 set? */
#define SETEXISTENTIALVAR(F) (((F).info) |= 0x1000)/* set bit 12     */
#define CANTFACTOR(F)       (((F).info) & 0x1000)  /* is bit 12 set? */
#define SETCANTFACTOR(F)    (((F).info) |= 0x1000) /* set bit 12     */
#define CHECKED(F)       (((F).info) & 0x1000)  /* bit 12 set? for equations */
#define SETCHECKED(F)  (((F).info) |= 0x1000) /* set bit 12 for equations */

/* bits 11 and 12 are used in terms with zero denominators to stand for
positive or negative infinitesimals respectively in the denominator,
i.e. the limit from which the
zero denominator came has a limitand which is positive or negative in
the neighborhoods involved in the limit. These macros are used to
mark the fractions, not the num or denom.   */

/* Bit 11 is used on INTEGRAL terms to mark improper integrals */

#define SETPOSITIVE(F)  SETORDERED(F)
#define POSITIVE_INFINITESIMAL(F)  (ORDERED(F) && !CANTFACTOR(F))
#define SETNEGATIVE(F)  SETCANTFACTOR(F)
#define NEGATIVE_INFINITESIMAL(F)  (!ORDERED(F) && CANTFACTOR(F))
#define SETINFINITESIMAL(F)  (((F).info) |= 0x1800) /* set bits 11 and 12 both */
#define UNSIGNED_INFINITESIMAL(F)  (ORDERED(F) && CANTFACTOR(F))
#define SOME_INFINITESIMAL(F)  (ORDERED(F) || CANTFACTOR(F))

/* possible values of the 'where' parameter in functor_string */
#define PROLOG 0
#define SCREEN 1


/* macros dealing with values of atoms */
#define VALUE(t)   (* ((double *) (t).args))  /* t must be an atom */
#define CHANGE_VALUE(t,newval)    *( (double *) t.args) = (double) (newval);
#define SETVALUE(t,newval) CHANGE_VALUE(t,newval)

int equalstructures(void *, void *, int);  /* terms.c */
int equals(term,term);              /* var.c */
int contains(term, unsigned short); /* var.c */
int subst(term,term,term, term *);  /* var.c */
void copy(term, term *);             /* var.c */

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists