Frobby 0.9.5
InputConsumer.cpp
Go to the documentation of this file.
1/* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2011 Bjarke Hammersholt Roune (www.broune.com)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see http://www.gnu.org/licenses/.
16*/
17#include "stdinc.h"
18#include "InputConsumer.h"
19
20#include "Scanner.h"
21#include "FrobbyStringStream.h"
22#include "error.h"
23#include "RawSquareFreeTerm.h"
24
25#include <iostream>
26
28 _idealsDeleter(_ideals),
29 _inIdeal(false),
30 _requireSquareFree(false) {
31}
32
34 VarNames nameCopy(names); // exception safety: copy and swap
35 if (_inIdeal) {
36 ASSERT(names.getVarCount() == _names.getVarCount());
37 if (_sqfIdeal.get() != 0)
38 _sqfIdeal->renameVars(names);
39 else
40 _bigIdeal->renameVars(names);
41 }
43}
44
49
52 _inIdeal = true;
54 _term.resize(_names.getVarCount());
55}
56
61
64 ASSERT(_term.size() == _names.getVarCount());
65#ifdef DEBUG
66 for (size_t var = 0; var < _term.size(); ++var) {
67 ASSERT(_term[var].empty());
68 }
69#endif
70 if (_sqfIdeal.get() != 0)
71 _sqfIdeal->insertIdentity();
72 else
73 _bigIdeal->newLastTerm();
74}
75
78
79 size_t var;
80 in.readSizeT(var);
81
82 if (var == 0 || var > _names.getVarCount()) {
84 errorMsg << "There is no variable number " << var << '.';
86 }
87 return var - 1;
88}
89
92 in.readIdentifier(_tmpString);
93 size_t var = _names.getIndex(_tmpString);
94 if (var == VarNames::invalidIndex) {
96 errorMsg << "Unknown variable \"" << _tmpString << "\". Maybe you forgot a *.";
98 }
99 return var;
100}
101
104 ASSERT(var < _names.getVarCount());
105
106 if (_sqfIdeal.get() != 0) {
107 Word* back = _sqfIdeal->back();
108 if (!SquareFreeTermOps::getExponent(back, var)) {
109 SquareFreeTermOps::setExponent(back, var, true);
110 return;
111 }
112 } else {
113 mpz_class& exponent = _bigIdeal->getLastTermExponentRef(var);
114 if (exponent == 0) {
115 exponent = 1;
116 return;
117 }
118 }
120}
121
124 ASSERT(var < _names.getVarCount());
125
126 if (_sqfIdeal.get() != 0) {
127 in.readIntegerNoSign(_tmpString);
128 Word* back = _sqfIdeal->back();
129 if (!SquareFreeTermOps::getExponent(back, var)) {
130 if (_tmpString == "1")
131 SquareFreeTermOps::setExponent(back, var, true);
132 else if (_tmpString != "0") {
134 _bigIdeal->getLastTermExponentRef(var) = _tmpString;
135 }
136 return;
137 }
138 } else {
139 mpz_class& exponent = _bigIdeal->getLastTermExponentRef(var);
140 if (exponent == 0) {
141 in.readIntegerNoSign(exponent);
142 return;
143 }
144 }
146}
147
150
151 beginTerm();
152 if (!in.match('1')) {
153 do {
154 const size_t var = consumeVar(in);
155 if (in.match('^'))
157 else
159 } while (in.match('*'));
160 }
161 endTerm();
162}
163
166/* const size_t varCount = _names.getVarCount();
167 if (_sqfIdeal.get() != 0) {
168 if (_sqfIdeal->insert(_term)) {
169 for (size_t var = 0; var < varCount; ++var)
170 _term[var].clear();
171 return;
172 }
173 if (_requireSquareFree)
174 reportError("Expected square free term.");
175 toBigIdeal(_sqfIdeal, _bigIdeal);
176 }
177 ASSERT(!_requireSquareFree);
178
179 ASSERT(_bigIdeal.get() != 0);
180 _bigIdeal->newLastTerm();
181 for (size_t var = 0; var < varCount; ++var) {
182 std::string& str = _term[var];
183 if (str.empty())
184 continue;
185 mpz_class& integer = _bigIdeal->getLastTermExponentRef(var);
186 mpz_set_str(integer.get_mpz_t(), str.c_str(), 10);
187 str.clear();
188 }*/
189}
190
193 _inIdeal = false;
195 entry->_big = _bigIdeal;
196 entry->_sqf = _sqfIdeal;
198}
199
208
217
220 ASSERT(!empty());
221 ASSERT(_ideals.front()->_sqf.get() != 0);
222 Entry entry;
224 return entry._sqf;
225}
226
229 ASSERT(!empty());
230 entry = *_ideals.front();
231 _ideals.pop_front();
232}
233
236 errorMsg << "The variable " << _names.getName(var)
237 << " appears twice in the same monomial.";
239}
240
243 reportError("Expected square free term.");
245}
246
247void InputConsumer::toBigIdeal(std::auto_ptr<SquareFreeIdeal>& sqf, std::auto_ptr<BigIdeal>& big) {
248 if (big.get() != 0)
249 return;
250 ASSERT(sqf.get() != 0);
251 big.reset(new BigIdeal(sqf->getNames()));
252 big->insert(*sqf);
253 sqf.reset(0);
254}
void exceptionSafePushBack(Container &container, auto_ptr< Element > pointer)
void nameFactoryRegister(NameFactory< AbstractProduct > &factory)
Registers the string returned by ConcreteProduct::getStaticName() to a function that default-construc...
A replacement for stringstream.
void requireSquareFree()
void errorVariableAppearsTwice(const Scanner &in, size_t var)
auto_ptr< SquareFreeIdeal > releaseSquareFreeIdeal()
Returns the least recently read ideal that has not been released.
bool empty() const
Returns true if there are ideals stored.
size_t consumeVarNumber(Scanner &in)
Reads variable as a number so that the first variable is 1.
void idealNotSquareFree()
void releaseIdeal(auto_ptr< SquareFreeIdeal > &sqf, auto_ptr< BigIdeal > &big)
Struct that keeps either a BigIdeal or a SquareFreeIdeal.
void beginTerm()
Start consuming a term.
void beginIdeal()
Start consuming an ideal.
size_t consumeVar(Scanner &in)
Reads variable and returns id.
std::list< Entry * > _ideals
void consumeTermProductNotation(Scanner &in)
Reads a term in a format like "a^4*b*c^2".
static void toBigIdeal(auto_ptr< SquareFreeIdeal > &sqf, auto_ptr< BigIdeal > &big)
void consumeRing(const VarNames &names)
void consumeVarExponent(size_t var, Scanner &in)
Consumes var raised to an exponent read from in.
void hintGenCount(size_t hintGenCount)
Suggest that the current ideal will have the given number of generators.
auto_ptr< BigIdeal > releaseBigIdeal()
Returns the least recently read ideal that has not been released.
auto_ptr< SquareFreeIdeal > _sqfIdeal
void consumeVarExponentOne(size_t var, const Scanner &in)
Consumes var raised to the exponent 1.
auto_ptr< BigIdeal > _bigIdeal
void endIdeal()
Done reading an ideal.
vector< string > _term
void endTerm()
Done reading a term.
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition Scanner.h:50
Defines the variables of a polynomial ring and facilities IO involving them.
Definition VarNames.h:40
size_t getVarCount() const
Returns the current number of variables.
Definition VarNames.h:113
const string & getName(size_t index) const
The returned reference can become invalid next time addVar is called.
Definition VarNames.cpp:100
void swap(VarNames &names)
Definition VarNames.cpp:190
static const size_t invalidIndex
Returns a fixed variable offset that is always invalid.
Definition VarNames.h:100
size_t getIndex(const string &name) const
Returns VarNames::invalidIndex() if name is not known.
Definition VarNames.cpp:83
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition error.cpp:44
void reportError(const string &errorMsg)
Definition error.cpp:23
void setExponent(Word *a, size_t var, bool value)
bool getExponent(const Word *a, size_t var)
returns true if var divides a and false otherwise.
unsigned long Word
The native unsigned type for the CPU.
Definition stdinc.h:93
#define ASSERT(X)
Definition stdinc.h:86