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
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.
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
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.
This header file includes common definitions and is included as the first line of code in every imple...
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
auto_ptr< BigIdeal > _big