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) {
37 if (_sqfIdeal.get() != 0)
38 _sqfIdeal->renameVars(names);
39 else
40 _bigIdeal->renameVars(names);
41 }
42 _names.swap(nameCopy);
43}
44
47 _requireSquareFree = true;
48}
49
52 _inIdeal = true;
54 _term.resize(_names.getVarCount());
55}
56
57void InputConsumer::hintGenCount(size_t hintGenCountParam) {
59 _bigIdeal->reserve(hintGenCountParam);
60}
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()) {
83 FrobbyStringStream errorMsg;
84 errorMsg << "There is no variable number " << var << '.';
85 reportSyntaxError(in, errorMsg);
86 }
87 return var - 1;
88}
89
93 size_t var = _names.getIndex(_tmpString);
94 if (var == VarNames::invalidIndex) {
95 FrobbyStringStream errorMsg;
96 errorMsg << "Unknown variable \"" << _tmpString << "\". Maybe you forgot a *.";
97 reportSyntaxError(in, errorMsg);
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) {
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('^'))
156 consumeVarExponent(var, in);
157 else
158 consumeVarExponentOne(var, in);
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;
194 auto_ptr<Entry> entry(new Entry());
195 entry->_big = _bigIdeal;
196 entry->_sqf = _sqfIdeal;
198}
199
200void InputConsumer::releaseIdeal(auto_ptr<SquareFreeIdeal>& sqf, auto_ptr<BigIdeal>& big) {
202 ASSERT(!empty());
203 Entry entry;
204 releaseIdeal(entry);
205 sqf = entry._sqf;
206 big = entry._big;
207}
208
209auto_ptr<BigIdeal> InputConsumer::releaseBigIdeal() {
211 ASSERT(!empty());
212 Entry entry;
213 releaseIdeal(entry);
214 toBigIdeal(entry._sqf, entry._big);
215 return entry._big;
216}
217
218auto_ptr<SquareFreeIdeal> InputConsumer::releaseSquareFreeIdeal() {
220 ASSERT(!empty());
221 ASSERT(_ideals.front()->_sqf.get() != 0);
222 Entry entry;
223 releaseIdeal(entry);
224 return entry._sqf;
225}
226
229 ASSERT(!empty());
230 entry = *_ideals.front();
231 _ideals.pop_front();
232}
233
235 FrobbyStringStream errorMsg;
236 errorMsg << "The variable " << _names.getName(var)
237 << " appears twice in the same monomial.";
238 reportSyntaxError(in, errorMsg);
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)
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.
Definition: InputConsumer.h:74
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.
bool _requireSquareFree
VarNames _names
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
void readIntegerNoSign(string &str)
Read an arbitrary-precision integer.
Definition: Scanner.h:252
const char * readIdentifier()
The returned string is only valid until the next method on this object gets called.
Definition: Scanner.cpp:255
void readSizeT(size_t &size)
Reads a size_t, where the representable range of that type determines when the number is too big.
Definition: Scanner.cpp:205
bool match(char c)
Return true if the next character is c, and in that case skip past it.
Definition: Scanner.h:215
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
auto_ptr< SquareFreeIdeal > _sqf
Definition: InputConsumer.h:96
auto_ptr< BigIdeal > _big
Definition: InputConsumer.h:95