Frobby  0.9.5
IOHandlerImpl.cpp
Go to the documentation of this file.
1 /* Frobby: Software for monomial ideal computations.
2  Copyright (C) 2007 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 "IOHandlerImpl.h"
19 
20 #include "Scanner.h"
21 #include "BigIdeal.h"
22 #include "TermTranslator.h"
23 #include "Term.h"
24 #include "TermConsumer.h"
25 #include "VarNames.h"
26 #include "CoefTermConsumer.h"
27 #include "Polynomial.h"
28 #include "BigPolynomial.h"
29 #include "FrobbyStringStream.h"
30 #include "BigTermConsumer.h"
31 #include "DataType.h"
32 #include "error.h"
33 #include "InputConsumer.h"
34 #include <algorithm>
35 
36 IO::IOHandlerImpl::IOHandlerImpl(const char* formatName,
37  const char* formatDescription):
38  _formatName(formatName),
39  _formatDescription(formatDescription) {
40 }
41 
44 }
45 
48 }
49 
51  return std::find(_supportedInputs.begin(), _supportedInputs.end(),
52  &type) != _supportedInputs.end();
53 }
54 
56  return std::find(_supportedOutputs.begin(), _supportedOutputs.end(),
57  &type) != _supportedOutputs.end();
58 }
59 
61  ASSERT(!type.isNull());
62  ASSERT(!supportsInput(type));
63 
64  _supportedInputs.push_back(&type);
65 }
66 
68  ASSERT(!type.isNull());
69  ASSERT(!supportsOutput(type));
70 
71  _supportedOutputs.push_back(&type);
72 }
73 
76 }
77 
80 }
81 
84 }
85 
87  CoefBigTermConsumer& consumer) {
89 }
90 
92  SatBinomConsumer& consumer) {
94 }
95 
97  return !in.matchEOF();
98 }
99 
100 const char* IO::IOHandlerImpl::doGetName() const {
101  return _formatName;
102 }
103 
105  return _formatDescription;
106 }
107 
109  const VarNames& names,
110  vector<mpz_class>& term) {
111  term.resize(names.getVarCount());
112  for (size_t var = 0; var < term.size(); ++var)
113  term[var] = 0;
114 
115  if (in.match('1'))
116  return;
117 
118  do {
119  readVarPower(term, names, in);
120  } while (in.match('*'));
121 }
122 
123 void IO::writeCoefTermProduct(const mpz_class& coef,
124  const Term& term,
125  const TermTranslator& translator,
126  bool hidePlus,
127  FILE* out) {
128  if (coef >= 0 && !hidePlus)
129  fputc('+', out);
130 
131  if (term.isIdentity()) {
132  gmp_fprintf(out, "%Zd", coef.get_mpz_t());
133  return;
134  }
135 
136  if (coef == -1)
137  fputc('-', out);
138  else if (coef != 1)
139  gmp_fprintf(out, "%Zd*", coef.get_mpz_t());
140 
141  writeTermProduct(term, translator, out);
142 }
143 
144 void IO::writeCoefTermProduct(const mpz_class& coef,
145  const vector<mpz_class>& term,
146  const VarNames& names,
147  bool hidePlus,
148  FILE* out) {
149  if (coef >= 0 && !hidePlus)
150  fputc('+', out);
151 
152  bool isIdentity = true;
153  for (size_t var = 0; var < term.size(); ++var)
154  if (term[var] != 0)
155  isIdentity = false;
156 
157  if (isIdentity) {
158  gmp_fprintf(out, "%Zd", coef.get_mpz_t());
159  return;
160  }
161 
162  if (coef == -1)
163  fputc('-', out);
164  else if (coef != 1)
165  gmp_fprintf(out, "%Zd*", coef.get_mpz_t());
166 
167  writeTermProduct(term, names, out);
168 }
169 
170 void IO::writeTermProduct(const Term& term,
171  const TermTranslator& translator,
172  FILE* out) {
173  bool seenNonZero = false;
174  size_t varCount = term.getVarCount();
175  for (size_t var = 0; var < varCount; ++var) {
176  const char* exp = translator.getVarExponentString(var, term[var]);
177  if (exp == 0)
178  continue;
179 
180  if (seenNonZero)
181  putc('*', out);
182  else
183  seenNonZero = true;
184 
185  fputs(exp, out);
186  }
187 
188  if (!seenNonZero)
189  fputc('1', out);
190 }
191 
192 void IO::writeTermProduct(const vector<mpz_class>& term,
193  const VarNames& names,
194  FILE* out) {
195  bool seenNonZero = false;
196  size_t varCount = term.size();
197  for (size_t var = 0; var < varCount; ++var) {
198  if (term[var] == 0)
199  continue;
200 
201  if (seenNonZero)
202  fputc('*', out);
203  else
204  seenNonZero = true;
205 
206  fputs(names.getName(var).c_str(), out);
207  if ((term[var]) != 1) {
208  fputc('^', out);
209  mpz_out_str(out, 10, term[var].get_mpz_t());
210  }
211  }
212 
213  if (!seenNonZero)
214  fputc('1', out);
215 }
216 
218  ideal.newLastTerm();
219 
220  if (in.match('1'))
221  return;
222 
223  do {
224  readVarPower(ideal.getLastTermRef(), ideal.getNames(), in);
225  } while (in.match('*'));
226 }
227 
228 void IO::readCoefTerm(mpz_class& coef,
229  vector<mpz_class>& term,
230  const VarNames& names,
231  bool firstTerm,
232  Scanner& in) {
233  term.resize(names.getVarCount());
234  for (size_t var = 0; var < term.size(); ++var)
235  term[var] = 0;
236 
237  bool positive = true;
238  if (!firstTerm && in.match('+'))
239  positive = !in.match('-');
240  else if (in.match('-'))
241  positive = false;
242  else if (!firstTerm) {
243  in.expect('+');
244  return;
245  }
246  if (in.match('+') || in.match('-'))
247  reportSyntaxError(in, "Too many adjacent signs.");
248 
249  if (in.peekIdentifier()) {
250  coef = 1;
251  readVarPower(term, names, in);
252  } else
253  in.readInteger(coef);
254 
255  while (in.match('*'))
256  readVarPower(term, names, in);
257 
258  if (!positive)
259  coef = -coef;
260 }
261 
263  bool firstTerm,
264  Scanner& in) {
265  polynomial.newLastTerm();
266  mpz_class& coef = polynomial.getLastCoef();
267  vector<mpz_class>& term = polynomial.getLastTerm();
268 
269  readCoefTerm(coef, term, polynomial.getNames(), firstTerm, in);
270 }
271 
272 void IO::readVarPower(vector<mpz_class>& term,
273  const VarNames& names,
274  Scanner& in) {
275  size_t var = in.readVariable(names);
276 
277  if (term[var] != 0) {
278  const string& name = names.getName(var);
279  reportSyntaxError(in, "The variable " +
280  name + " appears more than once in monomial.");
281  }
282 
283  if (in.match('^')) {
284  in.readInteger(term[var]);
285  if (term[var] <= 0) {
286  FrobbyStringStream errorMsg;
287  errorMsg << "Expected positive integer as exponent but got "
288  << term[var] << ".";
289  reportSyntaxError(in, errorMsg);
290  }
291  } else
292  term[var] = 1;
293 }
void newLastTerm()
Definition: BigIdeal.cpp:104
const VarNames & getNames() const
Definition: BigIdeal.cpp:253
vector< mpz_class > & getLastTermRef()
Definition: BigIdeal.h:133
mpz_class & getLastCoef()
vector< mpz_class > & getLastTerm()
const VarNames & getNames() const
The intention of this class is to describe the different kinds of mathematical structures that Frobby...
Definition: DataType.h:29
bool isNull() const
Returns true if this object was returned by getNullType().
Definition: DataType.cpp:28
A replacement for stringstream.
void registerInput(const DataType &type)
Specify that input of the argument type is supported.
virtual void doReadTerm(Scanner &in, InputConsumer &term)
virtual void doReadSatBinomIdeal(Scanner &in, SatBinomConsumer &consumer)
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)=0
virtual bool doSupportsInput(const DataType &type) const
virtual void doReadIdeal(Scanner &in, InputConsumer &consumer)
virtual const char * doGetDescription() const
virtual const char * doGetName() const
virtual bool doSupportsOutput(const DataType &type) const
IOHandlerImpl(const char *formatName, const char *formatDescription)
virtual bool doHasMoreInput(Scanner &in) const
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
virtual void doReadPolynomial(Scanner &in, CoefBigTermConsumer &consumer)
virtual void doReadIdeals(Scanner &in, InputConsumer &consumer)
void registerOutput(const DataType &type)
Specify that output of the argument type is supported.
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition: Scanner.h:50
void expect(char expected)
Require the next character to be equal to expected.
Definition: Scanner.h:231
bool peekIdentifier()
Skips whitespace and returns true if the next token is an identifier.
Definition: Scanner.h:257
size_t readVariable(const VarNames &names)
Reads an identifier and returns the index of that identifier as the index of a variable in names.
Definition: Scanner.h:201
bool matchEOF()
Return true if no more input.
Definition: Scanner.h:210
void readInteger(mpz_class &integer)
Read an arbitrary-precision integer.
Definition: Scanner.h:238
bool match(char c)
Return true if the next character is c, and in that case skip past it.
Definition: Scanner.h:215
TermTranslator handles translation between terms whose exponents are infinite precision integers and ...
const char * getVarExponentString(size_t variable, Exponent exponent) const
As getExponent, except the string "var^e" is returned or null if the exponent is zero,...
Term represents a product of variables which does not include a coefficient.
Definition: Term.h:49
size_t getVarCount() const
Definition: Term.h:85
static bool isIdentity(const Exponent *a, size_t varCount)
Returns whether a is 1, i.e. whether all entries of a are 0.
Definition: Term.h:316
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 reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition: error.cpp:44
#define INTERNAL_ERROR_UNIMPLEMENTED()
Definition: error.h:47
void writeCoefTermProduct(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool hidePlus, FILE *out)
void readVarPower(vector< mpz_class > &term, const VarNames &names, Scanner &in)
void readCoefTerm(BigPolynomial &polynomial, bool firstTerm, Scanner &in)
void readTermProduct(Scanner &in, const VarNames &names, vector< mpz_class > &term)
void writeTermProduct(const Term &term, const TermTranslator &translator, FILE *out)
bool isIdentity(const Word *a, Word *aEnd)
#define ASSERT(X)
Definition: stdinc.h:86