In this section we list the C implementation of the product function for monomials together with all type definitions and renamings that are necessary for SPP . In the Figures 2 to 4 we show how these blocks of code are distributed among source files, header files, and coercion units.
#define coefficient( m) FIRST( m) #define power_product( m) SECOND( m) #define monomial( c, pp) LIST2( c, pp) typedef Word Mon; typedef RN Coef; /* Coefficient Domain = Rational Numbers */ typedef EL PP; /* Power Product Domain = Exponent List */ #define product_coef product_rn /* Renaming */ #define product_pp product_el /* Renaming */ Mon product_mon( Mon m1, Mon m2) { Coef c1, c2; PP pp1, pp2; c1 = coefficient( m1); c2 = coefficient( m2); pp1 = power_product( m1); pp2 = power_product( m2); return monomial( product_coef( c1, c2), product_pp( pp1, pp2)); } RN product_rn( RN r1, RN r2) { /* Here goes the implementation of the product function for rational numbers */ } EL product_el( EL el1, EL el2) { /* Here goes the implementation of the product function for exponent lists */ }
Figure 2 shows how virtual data types and calls to virtual domains are used. The dashed lines indicate, where a function call leads to.
Figure 2: Communication between Domain and its Subdomains
Figure 3: The Central Header File groebner.h
Figure 4: Communication between Coercion Unit and Subdomain
GRÖBNER has one central header file, groebner.h , which is included from every source file. In this header file the inclusion of all other header files and the inclusion of the appropriate coercion units is organized. This mechanism is depicted in Figure 3. One can see that for changing the coefficient domain or the power product representation only the lines marked by (*) need to be adjusted.
In fact, in the actual implementation we also distributed the lines marked by (*) together with the following activation of the appropriate coercion unit among several files, the setup-files , in order to enable a more accurate check which part of the setup has actually been changed. When using make (or a similar tool) for managing the compilation of the library, we can thus avoid superfluous re-compilation of files that are not influenced by recent changes. (We did not include this into Figure 3 in order not to distract the reader by these details.)
Finally, in Figure 4 the mapping from a virtual domain call to an implemented function and from a virtual type to an existing data type is visualized. We see that both mappings are nothing but renamings done by the coercion unit.