Frobby  0.9.0
SingularIOHandler.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 "SingularIOHandler.h"
19 
20 #include "Scanner.h"
21 #include "VarNames.h"
22 #include "BigTermConsumer.h"
23 #include "FrobbyStringStream.h"
24 #include "DataType.h"
25 #include "CoefBigTermConsumer.h"
26 #include "IdealWriter.h"
27 #include "PolyWriter.h"
28 #include "error.h"
29 #include "InputConsumer.h"
30 
31 #include <cstdio>
32 
33 namespace IO {
34  namespace Singular {
35  void writeRing(const VarNames& names, FILE* out);
36  }
37  namespace S = Singular;
38 
40  public:
41  SingularIdealWriter(FILE* out): IdealWriter(out) {
42  }
43 
44  private:
45  virtual void doWriteHeader(bool first) {
46  S::writeRing(getNames(), getFile());
47  fputs("ideal I =", getFile());
48  }
49 
50  virtual void doWriteTerm(const Term& term,
51  const TermTranslator& translator,
52  bool first) {
53  fputs(first ? "\n " : ",\n ", getFile());
54  IO::writeTermProduct(term, translator, getFile());
55  }
56 
57  virtual void doWriteTerm(const vector<mpz_class>& term,
58  bool first) {
59  fputs(first ? "\n " : ",\n ", getFile());
60  writeTermProduct(term, getNames(), getFile());
61  }
62 
63  virtual void doWriteFooter(bool wasZeroIdeal) {
64  if (wasZeroIdeal)
65  fputs("\n 0", getFile());
66  fputs(";\n", getFile());
67  }
68 
69  virtual void doWriteEmptyList() {
70  S::writeRing(getNames(), getFile());
71  }
72  };
73 
74  class SingularPolyWriter : public PolyWriter {
75  public:
76  SingularPolyWriter(FILE* out): PolyWriter(out) {
77  }
78 
79  virtual void doWriteHeader() {
80  S::writeRing(getNames(), getFile());
81  fputs("poly p =", getFile());
82  }
83 
84  virtual void doWriteTerm(const mpz_class& coef,
85  const Term& term,
86  const TermTranslator& translator,
87  bool firstGenerator) {
88  fputs("\n ", getFile());
89  writeCoefTermProduct(coef, term, translator, firstGenerator, getFile());
90  }
91 
92  virtual void doWriteTerm(const mpz_class& coef,
93  const vector<mpz_class>& term,
94  bool firstGenerator) {
95  fputs("\n ", getFile());
96  writeCoefTermProduct(coef, term, getNames(), firstGenerator, getFile());
97  }
98 
99  virtual void doWriteFooter(bool wasZero) {
100  if (wasZero)
101  fputs("\n 0", getFile());
102  fputs(";\n", getFile());
103  }
104  };
105 
107  IOHandlerCommon(staticGetName(),
108  "Format understandable by the program Singular.") {
114  }
115 
117  return "singular";
118  }
119 
121  return new SingularIdealWriter(out);
122  }
123 
126  return new SingularPolyWriter(out);
127  }
128 
129  void SingularIOHandler::doWriteTerm(const vector<mpz_class>& term,
130  const VarNames& names,
131  FILE* out) {
132  writeTermProduct(term, names, out);
133  }
134 
136  const VarNames& names,
137  vector<mpz_class>& term) {
138  readTermProduct(in, names, term);
139  }
140 
142  consumer.consumeTermProductNotation(in);
143  }
144 
146  names.clear();
147 
148  in.expect("ring");
149  in.expect('R');
150  in.expect('=');
151  in.expect('0');
152  in.expect(',');
153  in.expect('(');
154 
155  do {
156  names.addVarSyntaxCheckUnique(in, in.readIdentifier());
157  } while (in.match(','));
158 
159  in.expect(')');
160  in.expect(',');
161  in.expect("lp");
162  in.expect(';');
163 
164  in.expect("int");
165  in.expect("noVars");
166  in.expect("=");
167  if (in.match('1')) {
168  if (names.getVarCount() != 1 ||
169  names.getName(0) != string("dummy")) {
170  FrobbyStringStream errorMsg;
171  errorMsg <<
172  "A singular ring with no actual variables must have a single "
173  "place-holder variable named \"dummy\", and in this case ";
174  if (names.getVarCount() != 1)
175  errorMsg << "there are " << names.getVarCount()
176  << " place-holder variables.";
177  else
178  errorMsg << "it has the name \"" << names.getName(0) << "\".";
179 
180  reportSyntaxError(in, errorMsg);
181  }
182  names.clear();
183  } else if (!in.match('0')) {
184  // TODO: Replace following line with: in.expect('0', '1');
185  reportSyntaxError(in, "noVars must be either 0 or 1.");
186  }
187 
188  in.expect(';');
189  }
190 
192  return in.peek('r') || in.peek('R');
193  }
194 
196  BigTermConsumer& consumer) {
197  consumer.beginConsuming(names);
198  vector<mpz_class> term(names.getVarCount());
199 
200  in.expect("ideal");
201  in.expect('I');
202  in.expect('=');
203 
204  if (!in.match('0')) {
205  do {
206  readTerm(in, names, term);
207  consumer.consume(term);
208  } while (in.match(','));
209  }
210  in.expect(';');
211 
212  consumer.doneConsuming();
213  }
214 
216  (Scanner& in, InputConsumer& consumer) {
217  consumer.beginIdeal();
218 
219  in.expect("ideal");
220  in.expect('I');
221  in.expect('=');
222 
223  if (!in.match('0')) {
224  do {
225  consumer.consumeTermProductNotation(in);
226  } while (in.match(','));
227  }
228  in.expect(';');
229 
230  consumer.endIdeal();
231  }
232 
234  const VarNames& names,
235  CoefBigTermConsumer& consumer) {
236  consumer.consumeRing(names);
237  vector<mpz_class> term(names.getVarCount());
238  mpz_class coef;
239 
240  in.expect("poly");
241  in.expect('p');
242  in.expect('=');
243 
244  consumer.beginConsuming();
245  bool first = true;
246  do {
247  readCoefTerm(coef, term, names, first, in);
248  consumer.consume(coef, term);
249  first = false;
250  } while (!in.match(';'));
251  consumer.doneConsuming();
252  }
253 
254  void S::writeRing(const VarNames& names, FILE* out) {
255  if (names.getVarCount() == 0)
256  fputs("ring R = 0, (dummy), lp;\nint noVars = 1;\n", out);
257  else {
258  fputs("ring R = 0, (", out);
259 
260  const char* pre = "";
261  for (unsigned int i = 0; i < names.getVarCount(); ++i) {
262  fputs(pre, out);
263  fputs(names.getName(i).c_str(), out);
264  pre = ", ";
265  }
266  fputs("), lp;\nint noVars = 0;\n", out);
267  }
268  }
269 }
static const DataType & getPolynomialType()
Returns the one and only instance for polynomials.
Definition: DataType.cpp:50
This class contains further functionality that makes it more convenient to derive from than IOHandler...
virtual void consume(const vector< mpz_class > &term)=0
void readCoefTerm(BigPolynomial &polynomial, bool firstTerm, Scanner &in)
virtual void consumeRing(const VarNames &names)=0
void writeRing(const VarNames &names, FILE *out)
virtual void doWriteHeader(bool first)
virtual void doWriteTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
virtual void beginConsuming()=0
Tell the consumer to begin consuming an ideal.
virtual void doWriteFooter(bool wasZeroIdeal)
static const DataType & getMonomialIdealListType()
Returns the one and only instance for monomial ideal lists.
Definition: DataType.cpp:54
virtual void doWriteTerm(const vector< mpz_class > &term, bool first)
void clear()
Resets the number of variables to zero.
Definition: VarNames.cpp:106
void registerOutput(const DataType &type)
Specify that output of the argument type is supported.
virtual void consume(const mpz_class &coef, const Term &term)
virtual void doWriteTerm(const mpz_class &coef, const vector< mpz_class > &term, bool firstGenerator)
void readTermProduct(Scanner &in, const VarNames &names, vector< mpz_class > &term)
virtual void doReadBareIdeal(Scanner &in, const VarNames &names, BigTermConsumer &consumer)
void endIdeal()
Done reading an ideal.
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
Defines the variables of a polynomial ring and facilities IO involving them.
Definition: VarNames.h:40
virtual void doReadTerm(Scanner &in, const VarNames &names, vector< mpz_class > &term)
void consumeTermProductNotation(Scanner &in)
Reads a term in a format like "a^4*b*c^2".
virtual void doneConsuming()=0
Must be called once after each time beginConsuming has been called.
void addVarSyntaxCheckUnique(const Scanner &in, const string &name)
As addvar, except it reports a syntax error if name is already a variable.
Definition: VarNames.cpp:68
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition: Scanner.h:50
void writeCoefTermProduct(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool hidePlus, FILE *out)
virtual void doWriteFooter(bool wasZero)
static const char * staticGetName()
void registerInput(const DataType &type)
Specify that input of the argument type is supported.
virtual bool doPeekRing(Scanner &in)
virtual void doWriteTerm(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool firstGenerator)
bool peek(char character)
Skips whitespace and returns true if the next character is equal to the parameter(s).
Definition: Scanner.h:262
const char * readIdentifier()
The returned string is only valid until the next method on this object gets called.
Definition: Scanner.cpp:255
virtual void doWriteTerm(const Term &term, const TermTranslator &translator, bool first)
void readTerm(Scanner &in, const VarNames &names, vector< mpz_class > &term)
Definition: IOHandler.cpp:51
void beginIdeal()
Start consuming an ideal.
TermTranslator handles translation between terms whose exponents are infinite precision integers and ...
void expect(char expected)
Require the next character to be equal to expected.
Definition: Scanner.h:231
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition: error.cpp:44
static const DataType & getMonomialIdealType()
Returns the one and only instance for monomial ideals.
Definition: DataType.cpp:45
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)
void writeTermProduct(const Term &term, const TermTranslator &translator, FILE *out)
virtual void doReadRing(Scanner &in, VarNames &names)
size_t getVarCount() const
Returns the current number of variables.
Definition: VarNames.h:112
const string & getName(size_t index) const
The returned reference can become invalid next time addVar is called.
Definition: VarNames.cpp:100
A replacement for stringstream.
Term represents a product of variables which does not include a coefficient.
Definition: Term.h:49
virtual void beginConsuming()=0
bool match(char c)
Return true if the next character is c, and in that case skip past it.
Definition: Scanner.h:215
virtual void doneConsuming()=0
virtual void doReadBarePolynomial(Scanner &in, const VarNames &names, CoefBigTermConsumer &consumer)