source: git/factory/variable.cc @ 1bd66a

spielwiese
Last change on this file since 1bd66a was 0b55585, checked in by Martin Lee <martinlee84@…>, 11 years ago
fix: wrong assertions
  • Property mode set to 100644
File size: 7.1 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2
3#ifdef HAVE_CONFIG_H
4#include "config.h"
5#endif /* HAVE_CONFIG_H */
6
7#include <string.h>
8
9#include "cf_assert.h"
10
11#include "cf_defs.h"
12#include "variable.h"
13#include "canonicalform.h"
14#include "cf_factory.h"
15#include "int_poly.h"
16#include "cf_iter.h"
17
18class ext_entry
19{
20private:
21    InternalPoly * _mipo;
22    bool _reduce;
23public:
24    ext_entry () : _mipo(0), _reduce(false) {}
25    ext_entry ( InternalPoly * mipoly, bool reduce ) : _mipo(mipoly), _reduce(reduce) {};
26    ext_entry ( const ext_entry & e ) : _mipo(e._mipo), _reduce(e._reduce) {}
27    ~ext_entry () {};
28    ext_entry & operator= ( const ext_entry & e )
29    {
30        if ( this != &e ) {
31            _mipo = e._mipo;
32            _reduce = e._reduce;
33        }
34        return *this;
35    }
36    InternalPoly * mipo () { return _mipo; }
37    void setmipo( InternalPoly * p ) { _mipo = p; }
38    bool & reduce () { return _reduce; }
39};
40
41static ext_entry * algextensions = 0;
42static char * var_names = 0;
43static char * var_names_ext = 0;
44static char default_name = 'v';
45static char default_name_ext = 'a';
46
47Variable::Variable( int l, bool flag ) : _level(l)
48{
49    ASSERT( flag, "illegal level" );
50}
51
52Variable::Variable( int l ) : _level(l)
53{
54    //ASSERT( l > 0 && l != LEVELQUOT, "illegal level" );
55}
56
57Variable::Variable( char name )
58{
59    bool isext = false;
60    int n, i;
61    if ( var_names_ext != 0 ) {
62        n = strlen( var_names_ext );
63        i = 1;
64        while ( i < n && var_names_ext[i] != name ) i++;
65        if ( i < n ) {
66            _level = -i;
67            isext = true;
68        }
69    }
70    if ( ! isext ) {
71        if ( var_names == 0 ) {
72            var_names = new char [3];
73            var_names[0] = '@';
74            var_names[1] = name;
75            var_names[2] = '\0';
76            _level = 1;
77        }
78        else {
79            n = strlen( var_names );
80            i = 1;
81            while ( i < n && var_names[i] != name ) i++;
82            if ( i < n )
83                _level = i;
84            else {
85                ASSERT( name != '@', "illegal variable name" );
86                char * newvarnames = new char [n+2];
87                for ( i = 0; i < n; i++ )
88                    newvarnames[i] = var_names[i];
89                newvarnames[n] = name;
90                newvarnames[n+1] = 0;
91                delete [] var_names;
92                var_names = newvarnames;
93                _level = n;
94            }
95        }
96    }
97}
98
99Variable::Variable( int l, char name ) : _level(l)
100{
101    ASSERT( l > 0 && l != LEVELQUOT, "illegal level" );
102    int n;
103    if ( (n = (var_names == 0 ? 0 : strlen( var_names ))) <= l ) {
104        char * newvarnames = new char [l+2];
105        int i;
106        for ( i = 0; i < n; i++ )
107            newvarnames[i] = var_names[i];
108        for ( i = n; i < l; i++ )
109            newvarnames[i] = '@';
110        newvarnames[l] = name;
111        newvarnames[l+1] = 0;
112        delete [] var_names;
113        var_names = newvarnames;
114    }
115    else {
116        ASSERT( var_names[l] == '@', "illegal name" );
117        var_names[l] = name;
118    }
119}
120
121char
122Variable::name() const
123{
124    if ( _level > 0 && _level < (int)strlen( var_names ) )
125        return( var_names[_level] );
126    else if ( _level < 0 && -_level < (int)strlen( var_names_ext ) )
127        return( var_names_ext[-_level] );
128    else
129        return '@';
130}
131
132#ifndef NOSTREAMIO
133OSTREAM & operator << ( OSTREAM & os, const Variable & v )
134{
135    if ( v._level == LEVELBASE )
136        os << "1";
137    else {
138        char * vn = ( v._level > 0 ) ? var_names : var_names_ext;
139        char dn = ( v._level > 0 ) ? default_name : default_name_ext;
140        int l = v._level;
141
142        if ( l < 0 ) l = -l;
143        if ( (vn == 0) || ((int)strlen( vn ) <= l) )
144            os << dn << "_" << l;
145        else  if ( vn[l] == '@' )
146            os << dn << "_" << l;
147        else
148            os << vn[l];
149    }
150    return os;
151}
152#endif /* NOSTREAMIO */
153
154static CanonicalForm conv2mipo ( const CanonicalForm & mipo, const Variable alpha )
155{
156    CanonicalForm result;
157    for ( CFIterator i = mipo; i.hasTerms(); i++ )
158        result += i.coeff() * power( alpha, i.exp() );
159    return result;
160}
161
162Variable rootOf( const CanonicalForm & mipo, char name )
163{
164    ASSERT (mipo.isUnivariate(), "not a legal extension");
165
166    int l;
167    if ( var_names_ext == 0 ) {
168        var_names_ext = new char [3];
169        var_names_ext[0] = '@';
170        var_names_ext[1] = name;
171        var_names_ext[2] = '\0';
172        l = 1;
173        Variable result( -l, true );
174        algextensions = new ext_entry [2];
175        algextensions[1] = ext_entry( 0, false );
176        algextensions[1] = ext_entry( (InternalPoly*)(conv2mipo( mipo, result ).getval()), true );
177        return result;
178    }
179    else {
180        int i, n = strlen( var_names_ext );
181        char * newvarnames = new char [n+2];
182        for ( i = 0; i < n; i++ )
183            newvarnames[i] = var_names_ext[i];
184        newvarnames[n] = name;
185        newvarnames[n+1] = 0;
186        delete [] var_names_ext;
187        var_names_ext = newvarnames;
188        l = n;
189        Variable result( -l, true );
190        ext_entry * newalgext = new ext_entry [n+1];
191        for ( i = 0; i < n; i++ )
192            newalgext[i] = algextensions[i];
193        newalgext[n] = ext_entry( 0, false );
194        delete [] algextensions;
195        algextensions = newalgext;
196        algextensions[n] = ext_entry( (InternalPoly*)(conv2mipo( mipo, result ).getval()), true );
197        return result;
198    }
199}
200
201InternalPoly * getInternalMipo ( const Variable & alpha )
202{
203    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
204    return algextensions[-alpha.level()].mipo();
205}
206
207CanonicalForm getMipo( const Variable & alpha, const Variable & x )
208{
209    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
210    return CanonicalForm( algextensions[-alpha.level()].mipo()->copyObject() )(x,alpha);
211}
212
213CanonicalForm getMipo( const Variable & alpha )
214{
215    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
216    return CanonicalForm( algextensions[-alpha.level()].mipo()->copyObject() );
217}
218
219void setMipo ( const Variable & alpha, const CanonicalForm & mipo)
220{
221    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
222    algextensions[-alpha.level()]= ext_entry((InternalPoly*)(conv2mipo( mipo, alpha ).getval()), true );
223}
224
225bool hasMipo( const Variable & alpha )
226{
227    ASSERT( alpha.level() < 0, "illegal extension" );
228    return (alpha.level() != LEVELBASE && (algextensions!=NULL) && getReduce(alpha) );
229}
230
231bool getReduce( const Variable & alpha )
232{
233    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
234    return algextensions[-alpha.level()].reduce();
235}
236
237void setReduce( const Variable & alpha, bool reduce )
238{
239    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
240    algextensions[-alpha.level()].reduce() = reduce;
241}
242
243char getDefaultVarName()
244{
245    return default_name;
246}
247
248char getDefaultExtName()
249{
250    return default_name_ext;
251}
252
253int ExtensionLevel()
254{
255  if( var_names_ext == 0)
256    return 0;
257  return strlen( var_names_ext )-1;
258}
259
260void Reduce( bool on)
261{
262  int i;
263  for (i=ExtensionLevel(); i>0;i--)
264  {
265    Variable l(-i);
266    setReduce(l,on);
267  }
268}
Note: See TracBrowser for help on using the repository browser.