%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (C) 1996,1998 Joergen Backelin
%%
%% Bergman is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY.  No author or distributor
%% accepts responsibility to anyone for the consequences of using it
%% or for whether it serves any particular purpose or works at all,
%% unless (s)he says so in writing.  Refer to the Bergman General
%% Public License for full details.

%% Everyone is granted permission to copy, modify and redistribute
%% bergman, but only under the conditions described in the
%% Bergman General Public License.   A copy of this license is
%% supposed to have been given to you along with bergman so you
%% can know your rights and responsibilities.  It should be in a
%% file named copyright.  Among other things, the copyright notice
%% and this notice must be preserved on all copies.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


	Type specifications for bergman 1.0.

 Here we give an informal description of the "types" communicated
between the "modules" of bergman.  The actual 'recursive definitions'
are only suggestions, since the 'parts' of an object
should not be accessed directly, but only by means of the procedures
described in the protocol file and by the macros in macro.sl.

 One reason for the descring the types is to facilitate automatic
translation of bergman code into c code. In this contect, one
should watch out for "mode changing unions". Several procedures
often are defined ...

 We are not concerned about differences between 'objects' being
represented by pointers or not, here; however, in lisp we mostly
automatically have indirection.


 Several objects will be composed of others by recognised lisp
operations, forming lists or (other) dotted pairs. A special
such construct is the degree list. (This was introduced, since
bergman is handling quite a number of homogeneous objects, and
often has use of accessing them sorted by degree.)

 In lispish terms, a degree list DL (of type dlXXX) is an
association list, where the antecedents form an increasing
sequence of integers (the "degrees"). More precisely, the degree
list is a list of lists, say DL = (list_1 list_2 list_3 ...),
where for each i the car of list_i is an integer int_i, and
the rest of the elements on list_i are objects of type XXX;
i.e., list_i = (int_i . tail_i), where tail_i is of type lXXX.
The integers must fulfil int_1 < int_2 < int_3 < ... . The
XXX objects in Cdr(list_i) normally are said to have "degree
int_i". (In many cases, DL always will fulfil the extra property
that (as soon as any active change of the list is concluded)
each tail_i is non-NIL. Such a degree list is called pruned.)


 The prefix gen- always denotes: also NIL is a legal object.
dp- , l- , dl- denotes dotted pairs, lists, and degree lists,
repectively. (gen- should only be used together with a type
definition NOT allowing NIL as a legal object.) Thus we have
the following "type macros" (or "templates"):

	genXXX ::= <NIL | XXX>
	dpXXX ::= <XXX>.<XXX>
	lXXX ::= <NIL>|<XXX>.<lXXX>
	dlXXX ::= A special kind of l(<int>.<lXXX>)


	General Lisp types (abbreviated):
 atom ::= <id(ent(ifier)) | number | string |...>
 any ::= <atom | dpany>
 bool ::= any

 A dotted pair (A . D) with A of type foo and B of type bar
is of type foo.bar, or (foo.bar), if grouping need to be
indicated. dpfoo is the same type as foo.foo.

 For a complete description of Standard Lisp types, see
the Standard Lisp report. The type "any" above includes
all bergman types below, although the programmer should
treat all of these not prefixed by dp-, l-, or dl- as
undivisible units from the general Lisp procedures point
of view. In other words, access to parts of them should
be by appropriate funtions (or by macros defined in macro
files).

 bool denotes (quasi) boolean variables. The reserved
Lisp identifier NIL is considered as standing for "false".
Any other Lisp item stands for "true". (This follows
ordinary Lisp conventions; which means that bool output
behaves as one might expect with logical Standard Lisp
procedures such as AND, COND, OR, and NOT. Likewise, it
is permitted to treat an object of type genXXX as a bool,
employing the fact that it is "false" if and only if it
is NIL, and hence is "true" if and only if it is of type
XXX.)



	Coefficient types:
 Primitive: redandcoeff, redorcoeff, in_form_coefficient,
	    out_form_coefficient.
 coeff ::= <redandcoeff | redorcoeff | ratcoeff>
 ratcoeff ::= <redandcoeff> <redandcoeff>
 genredandcoeff ::= <redandcoeff | NIL>
 genredorcoeff ::= <redorcoeff | NIL>

	Implementations of internal coefficients (at present):

 redandcoeff ::= <inum | bignum | unsigned inum | unsigned bignum
		  | Standard_Form>
 redorcoeff ::= <inum | bignum | unsigned inum | unsigned bignum
		  | Standard_Form>
 in_form_coefficient ::= <fixnum | Standard_Form>
 out_form_coefficient ::= <fixnum | Standard_Form>


	Monomial types:
 Primitive: revlexpuremon, lexpuremon, ncpuremon, revlexmonquot,
	    lexmonquot, ncmonquot, ... .
 puremon ::= <revlexpuremon | lexpuremon | ncpuremon | ...>
 monquot ::= <revlexmonquot | lexmonquot | ncmonquot | ...>
 augmon ::= <monptr> <monaugplist> <puremon>
 monptr ::= <reductdata | spdata>
 monaugplist ::= <any>
 mon_factor_data ::= bool
 exptno ::= <unsigned int>
 varno ::= <unsigned int>
 degree ::= <int>
 spdata ::= <spdatum> | <lspdatum>
 spdatum ::= any
 reductdata ::= <genaugredor> | <reductsignature>


	Reduction data types (at present: 2006-08-14)
#rgbitem ::= <augmon> <degno> <reductsignature>
#reductsignature ::= <gendegno> <dlrgbitem>
rgbitem ::= laugmon
reductsignature ::= <gendegno> <degno> <dldprgbitem>

 The puremon and quotmon types might be radically different
for different ring set ups. When the ring set up modes are
changed, no conversion of existing monomial structures is
performed; but the access procedures for such structures are.
Thus, e.g. performing MONLESSP on a pair of monomials formed
when in another monomial mode yields unpredicted and
potentially damaging results.

 Similarly, mon_factor_data depends on monomial modes. However,
it also is of boolean type, whence tests for being NIL or
not are safe.

 

    (Used internally in hseries:)
 hsflag ::= <bool>
 hsmon ::= <exptno> <lexptno>
 hsflagmon ::= <hsflag> <hsmon>
 hsmonid ::= <lhsflagmon>
 hsredmonid ::= <hsmonid>
 hsmoniddata ::= <varno> <lhsredmonid>
 hsmask ::= <hsmon>
 hscoeff ::= <bignum>
 hsterm ::= <hscoeff> <degno>
 hsnum ::= <lhsterm>
 hsdendeg ::= <degno>
 (gen)hsnumdendeg ::= <hsnum> <hsdendeg>
 hssplitnum ::= <hsnum> <hsdendeg>

 The monomial (augmented) property list procedures should be hand-set.
I only access them by means of LGET, LPUT, and LPUT!-LGET.
 Probably in c we should have one flag field separately.


	Term ( = Coefficient-Monomial) types:

 redandterm ::= <redandcoeff> <augmon>
 redorterm ::= <redorcoeff> <augmon>
 ratterm ::= <ratcoeff> <augmon>
 term ::= <coeff> <augmon>, == <redandterm | redorterm | ratterm>


	Polynomial types:

 pureredand ::= <NIL>|<redandterm><pureredand>
 pureredor ::= <NIL>|<redorterm><pureredor>
 purepol ::= <pureredand | pureredor>
 (gen)augredand ::= <polhead> <pureredand>
 (gen)augredor ::= <polhead> <pureredor>
 (gen)qpol ::= <polhead> <pureredand>
 (gen)augpol ::= <polhead> <purepol> , == <augredand | augredor | qpol>
 redandposition ::= <augredand>|<qpol>|<pureredand>
 redorposition ::= <augredor>|<pureredor>
 polposition ::= <redandposition | redorposition>

 The redandpositions (redorpositions) are intended to be the
(non-NIL) results of zero or more successive PolTails on an
augredand or a qpol (an augredor, respectively). A term "at"
a polposition is the Lt of the PPol part of the polposition.

 An augpol is incomplete if its purepol part is NIL.
 In most cases, the zero polynomial should be represented by NIL.
Thus, if some (destructive) algebraic operations on a polynomial
might yield a zero result, one should check whether or not the
purepol part is NIL; and if so, return NIL rather than the
corresponding incomplete augpol. The test preferrably should be
done by means of the macro PPol0!?.

 polheads may be implemented in some smarter way in c. I use it for
polpriorities in augredors and for ratcoeffs in qpols. I do not
access these with the same macros, so there should be no trouble.
 The polpriorities type suggested below has the weakness that it is
supposed to be user implementable. In the present implementation, it
is set to the number of terms in the polynomial (whence it is
unsigned and does not exceed the length of the longest polynomial;
this length however often is greater than 256 and probably might
exceed 65536 as well).
 The user might wish to use negative integers, too!

 CAUTION: I sometimes use that 'polpriorities' is an atom in order
to deduce that an item is a polynomial. This is efficient; but might
rebound, if users define different types of priorities.

 polheads ::= <NIL | ratcoeff | polpriorities>
 polpriorities ::= <unsigned long>


	Strategic types:
 critpairs ::= <any>
 binno ::= <unsigned char>
 (gen)degno ::= <unsigned int>
 bgsize ::= <unsigned int>


	SUGGESTED EXTENSIONS:

	Environment types:
 modestate ::= (keyword . lmodestates) | any
	       (Full or partial mode information, including
	       variables setting.)
 calcstate ::= .... (full info of how far (salvagable) calculation has
               proceeded, so that it may be continued later. As general
	       as possible!)
 gbasis ::= .... (The gbasis saved in a form that allows restoration,
               even if internal unique  monomial representation was
	       changed in between.)
       
 fullstate ::= <modestate> <gbasis> ....

 field-descriptor ::= <prime number | SF> .... (The field-descriptor
	       should be some way to denote what to use for new
	       coefficient field. Legal values right now are: NIl or
	       0 (denoting the field Q of rational numbers); and a
	       prime p (denoting the Galois field with p elements).
	       If bergman is running under Reduce, the identifier SF
	       also is a legal value; denoting that Reduce "Standard
	       Forms" be considered as representing the coefficient
	       domain elements.)

   OR, SHOULD WE RATHER CONNECT THEM TO MATHEMATICAL ENTITIES?
 E.g., ideals; free rings; quotient rings; matrices; coefficient
fields or domains; ...?

	Series types
 seriespol ::= <lint> | <ldpint>
 ratseries ::= <seriespol> <seriespol>
 truncseries ::= <seriespol> <degree>

	TYPING DOCUMENTATION IN RUNNING TEXT:

 Such documentation should always be on the following format:

%# <fnname> (<typelist>) : <type | -> ; <comment>

where the different parts are as explained below:

%# should stand first in the line, and in this position should be
reserved for typing (and other c parser?) information. If the type
information is too long, it could be spread out on several successive
lines, each beginning with %# . However, the <comment> must be on the
same line as the preceeding ; .

Blank signs (not preceeded by !) are ignorable whence optional.

<fnname> should be the name of a function later set by PUTD or some
of the procedures calling PUTD, i.e., DE, DF, DM, COPYD, and DMaybe.
Its typing is documented "as if it were an EXPR", as closely as
possible. This means some troubles for FEXPRs (and potentially for
MACROs, but these ar mostly not written in such a way that there
would be any trouble in writing an EXPR variant).

 typelist ::= <emptytypelist> | <nonemptytypelist> | <...>
 nonemptytypelist ::= <type> | <type><,><nonemptytypelist>
 emptytypelist ::= <>
where <type> stands for any legal type (includig these formed by
means of one or several prefixes gen- , l- , and/or dp- ).
(In new style c declarations, emptytypelist and - correspond to
void; ... stands eliptically for a variable number of arguments
of type any; and nonemptytypelists could be taken verbatim.  The
return type is given between : and ; .)
The type any is a union of all legal types. &<type> is used in some
macros in order to indicate that the input, not just its members,
is changed.
(In e.g. c rendering, there ought to be quite some indirection; I
do not try to represent this here, since there is some inbuilt
indirection in lisp, anyhow.)

 comments may include

 FEXPR or MACRO : The function is of this type, and it is not so
easy to supplant it with something else.

 RESET : The function definition is changed (dynamically) by COPYD's
at mode changes. (Could be c implemented as "function pointers".)

 ALIAS : The function name is an alias for another name, for the
convenience of the user, or in order to provide some backward
versions compatibility.

 DESTRUCTIVE: One or several of the arguments are modified. May
be followed by a strictly increasing list of positive integers
within a pair of parentheses, denoting which argument(s) in order
are destroyed. The last integer should be less than or equal to
the number of arguments. If such a list is not given, then all
arguments may be modified.
