source: git/factory/ftest/fbinops.m4 @ bc82d6

spielwiese
Last change on this file since bc82d6 was bc82d6, checked in by Jens Schmidt <schmidt@…>, 26 years ago
***** merge from branch `factory-gcd' to main trunk git-svn-id: file:///usr/local/Singular/svn/trunk@1292 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: fbinops.m4,v 1.4 1998-03-31 10:23:59 schmidt Exp $ */
3
4ftestSetNameOfGame( fbinops, `"
5Usage: fbinops [<options>] [<envSpec>] <f> <operator> <g>
6  executes operator an canonical forms f, g.
7
8  The following operators (with aliases) are recognized:
9  `+', `-', `*' (= `mul'), `/', `div', `%', `mod': return a canonicalform;
10  `==', `!=', `<' (= `lt'), `>' (= `gt'): return an integer (i.e. boolean)
11"'`' )
12
13//{{{ docu
14//
15// ftestAlgorithm.m4 - ftestAlgorithm test program.
16//
17// To create ftestAlgorithm.cc, run m4 using the ftest_util.m4 library in
18// the following way:
19//
20// m4 ftest_util.m4 ftestAlgorithm.m4 > ftestAlgorithm.cc
21//
22//}}}
23
24ftestPreprocInit();
25
26ftestGlobalInit();
27
28//{{{ typedef binOpCFT, binOpBoolT, binOpCFTestT
29//{{{ docu
30//
31// typedef binOpCFT, binOpBoolT, binOpCFTestT -
32//   pointer to functions types.
33//
34// binOpCFT, binOpBoolT: pointers to binary operators getting two
35//   CanonicalForms and returning a CanonicalForm or a bool, resp.
36// binOpCFTestT: pointers to test functions getting three
37//   CanonicalForms and returning a ftestStatusT.
38//
39//}}}
40typedef CanonicalForm (* binOpCFT)( const CanonicalForm &, const CanonicalForm & );
41typedef bool (* binOpBoolT)( const CanonicalForm &, const CanonicalForm & );
42typedef ftestStatusT (* binOpCFTestT)( const CanonicalForm &, const CanonicalForm &, const CanonicalForm & );
43//}}}
44
45//{{{ struct binOpCFSpecT, binOpBoolSpecT
46//{{{ docu
47//
48// struct binOpCFSpecT, struct binOpBoolSpecT - types describing a binary
49//   operator.
50//
51// binOpCFSpecT describes binary operators returning a CanonicalForm.
52// binOpBoolSpecT describes binary operators returning a bool.
53//
54// op: pointer to operator
55// test: test function
56// operatorName: symbolic name, used as a key
57// operatorTag: tag to print result
58//
59//}}}
60struct binOpCFSpecT
61{
62    binOpCFT op;
63    binOpCFTestT test;
64    const char * operatorName;
65    const char * operatorTag;
66};
67
68struct binOpBoolSpecT
69{
70    binOpBoolT op;
71    const char * operatorName;
72    const char * operatorTag;
73};
74//}}}
75
76//{{{ comparison functions, tests
77static inline bool
78ftestBoolEquiv ( bool a, bool b )
79{
80    return ( ( !a || b ) && ( !b || a ) );
81}
82
83static inline bool
84ftestCheckImplementation ( const CanonicalForm & f, const CanonicalForm & g )
85{
86    return ( ftestBoolEquiv( f == g, !(f != g) )
87             && ftestBoolEquiv( f < g, g > f )
88             && ftestBoolEquiv( f != g, (f < g) || (f > g) ) );
89}
90
91static inline bool
92ftestCheckTrichotomy ( const CanonicalForm & f, const CanonicalForm & g )
93{
94    if ( f == g ) {
95        if ( f < g ) return false;
96        if ( g < f ) return false;
97        return true;
98    } else if ( f < g ) {
99        if ( f == g ) return false;
100        if ( g < f ) return false;
101        return true;
102    } else if ( g < f ) {
103        if ( f == g ) return false;
104        if ( f < g ) return false;
105        return true;
106    } else
107        return false;
108}
109
110static ftestStatusT
111ftestRelOpTest ( const CanonicalForm & f, const CanonicalForm & g )
112{
113    // check reflexivity
114    if ( ! ( f == f ) ) {
115        ftestError( CheckError, "reflexivity check (f) failed\n" );
116        return Failed;
117    }
118    // check reflexivity
119    if ( ! ( g == g ) ) {
120        ftestError( CheckError, "reflexivity check (g) failed\n" );
121        return Failed;
122    }
123    // check symmetry
124    if ( ! ftestBoolEquiv( f == g, g == f ) ) {
125        ftestError( CheckError, "symmetry check failed\n" );
126        return Failed;
127    }
128    // check implementation of operators
129    if ( ! ftestCheckImplementation( f, g ) ) {
130        ftestError( CheckError, "implementation check (f, g) failed\n" );
131        return Failed;
132    }
133    // check implementation of operators
134    if ( ! ftestCheckImplementation( g, f ) ) {
135        ftestError( CheckError, "implementation check (g, f) failed\n" );
136        return Failed;
137    }
138    // check trichotomy
139    if ( ! ftestCheckTrichotomy( f, g ) ) {
140        ftestError( CheckError, "trichotomy check (f, g) failed\n" );
141        return Failed;
142    }
143    // check trichotomy
144    if ( ! ftestCheckTrichotomy( g, f ) ) {
145        ftestError( CheckError, "trichotomy check (g, f) failed\n" );
146        return Failed;
147    }
148
149    return Passed;
150}
151//}}}
152
153//{{{ arithmetic functions, tests
154static ftestStatusT
155ftestArithTest( const CanonicalForm &, const CanonicalForm &, const CanonicalForm & )
156{
157    return UndefinedResult;
158}
159
160static ftestStatusT
161ftestDivideTest( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm & quot )
162{
163    if ( ! ((quot*g)+(f%g)-f).isZero() ) {
164        ftestError( CheckError, "f != (f/g)*g+(f%%g)\n" );
165        return Failed;
166    } else
167        return Passed;
168}
169
170static ftestStatusT
171ftestDivTest( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm & quot )
172{
173    if ( ! (f%g).isZero() ) {
174        ftestError( CheckError, "g does not divide f\n" );
175        return Failed;
176    } else if ( f != (quot*g) ) {
177        ftestError( CheckError, "f != (div(f, g)*g)\n" );
178        return Failed;
179    } else
180        return Passed;
181}
182
183static ftestStatusT
184ftestModuloTest( const CanonicalForm & f, const CanonicalForm & g, const CanonicalForm & rem )
185{
186    if ( ! (((f/g)*g)+(rem)-f).isZero() ) {
187        ftestError( CheckError, "f != (f/g)*g+(f%%g)\n" );
188        return Failed;
189    } else
190        return Passed;
191}
192//}}}
193
194//{{{ binOpCFSpecArray, binOpBoolSpecArray
195//{{{ docu
196//
197// binOpCFSpec, binOpBoolSpec - arrays of operator descriptions.
198//
199//}}}
200binOpCFSpecT binOpCFSpecArray[] =
201{
202    { &operator+, ftestArithTest, "+", "f+g" },
203    { &operator-, ftestArithTest, "-", "f-g" },
204    { &operator*, ftestArithTest, "*", "f*g" },
205    { &operator*, ftestArithTest, "mul", "f*g" },
206    { &operator/, ftestDivideTest, "/", "f/g" },
207    { &div, ftestDivTest, "div", "div(f,g)" },
208    { &operator%, ftestModuloTest, "%", "f%g" },
209    { &mod, ftestModuloTest, "mod", "mod(f,g)" },
210    { 0, 0, 0, 0 }
211};
212
213binOpBoolSpecT binOpBoolSpecArray[] =
214{
215    { &operator==, "==", "f==g" },
216    { &operator!=, "!=", "f!=g" },
217    { &operator>, ">", "f>g" },
218    { &operator>, "gt", "f>g" },
219    { &operator<, "<", "f<g" },
220    { &operator<, "lt", "f<g" },
221    { 0, 0, 0 }
222};
223//}}}
224
225//
226// - main program.
227//
228int
229main ( int argc, char ** argv )
230{
231    // initialization
232    ftestMainInit();
233
234    // declare input and output variables
235    ftestOutVar( CanonicalForm, resultCF );
236    ftestOutVar( bool, resultBool );
237    ftestInVar( CanonicalForm, f );
238    ftestInVar( CanonicalForm, g );
239
240    // process argument list and set environment
241    ftestGetOpts();
242    ftestGetEnv();
243
244    // read first operand
245    ftestGetInVar( f );
246
247    // declarations to search operator
248    const char * operatorName = 0;
249    const char * operatorTag = 0;
250    binOpCFT binOpCF = 0;
251    binOpBoolT binOpBool = 0;
252    binOpCFTestT binOpCFTest = 0;
253
254    // get and search operator
255    if ( argv[ optind ] ) {
256        operatorName = ftestSkipBlancs( argv[ optind++ ] );
257    } else
258        ftestError( CommandlineError,
259                    "expected operator specification at position %d in commandline\n",
260                    optind );
261
262    // search through binOpCFSpecArray
263    int i = 0;
264    while ( binOpCFSpecArray[i].operatorName ) {
265        if ( strcmp( binOpCFSpecArray[i].operatorName, operatorName ) == 0 ) {
266            binOpCF = binOpCFSpecArray[i].op;
267            binOpCFTest = binOpCFSpecArray[i].test;
268            operatorTag = binOpCFSpecArray[i].operatorTag;
269            break;
270        }
271        i++;
272    }
273
274    // search through binOpBoolSpecArray
275    i = 0;
276    if ( ! binOpCF )
277        while ( binOpBoolSpecArray[i].operatorName ) {
278            if ( strcmp( binOpBoolSpecArray[i].operatorName, operatorName ) == 0 ) {
279                binOpBool = binOpBoolSpecArray[i].op;
280                operatorTag = binOpBoolSpecArray[i].operatorTag;
281                break;
282            }
283            i++;
284        }
285
286    // check whether operator has been found
287    if ( binOpCF == 0 && binOpBool == 0 )
288        ftestError( CommandlineError,
289                    "unknown operator `%s'\n", operatorName );
290
291    // read second operand
292    ftestGetInVar( g );
293
294    // do the test!
295    if ( binOpCF ) {
296        ftestRun(
297            resultCF = binOpCF( f, g ); );
298        ftestCheck(
299            binOpCFTest( f, g, resultCF ) );
300    } else {
301        ftestRun(
302            resultBool = binOpBool( f, g ); );
303        ftestCheck(
304            ftestRelOpTest( f, g ) );
305    }
306
307    // print results
308    if ( binOpCF ) {
309        ftestOutput( operatorTag, resultCF );
310    } else {
311        ftestOutput( operatorTag, resultBool );
312    }
313
314    // clean up
315    ftestMainExit();
316}
Note: See TracBrowser for help on using the repository browser.