Frobby  0.9.5
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) {
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() {
71  }
72  };
73 
74  class SingularPolyWriter : public PolyWriter {
75  public:
76  SingularPolyWriter(FILE* out): PolyWriter(out) {
77  }
78 
79  virtual void doWriteHeader() {
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 
125  doCreatePolynomialWriter(FILE* out) {
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 }
virtual void consume(const vector< mpz_class > &term)=0
virtual void doneConsuming()=0
Must be called once after each time beginConsuming has been called.
virtual void beginConsuming()=0
Tell the consumer to begin consuming an ideal.
virtual void beginConsuming()=0
virtual void consume(const mpz_class &coef, const Term &term)
virtual void doneConsuming()=0
virtual void consumeRing(const VarNames &names)=0
static const DataType & getMonomialIdealListType()
Returns the one and only instance for monomial ideal lists.
Definition: DataType.cpp:54
static const DataType & getMonomialIdealType()
Returns the one and only instance for monomial ideals.
Definition: DataType.cpp:45
static const DataType & getPolynomialType()
Returns the one and only instance for polynomials.
Definition: DataType.cpp:50
A replacement for stringstream.
void readTerm(Scanner &in, const VarNames &names, vector< mpz_class > &term)
Definition: IOHandler.cpp:51
This class contains further functionality that makes it more convenient to derive from than IOHandler...
void registerInput(const DataType &type)
Specify that input of the argument type is supported.
void registerOutput(const DataType &type)
Specify that output of the argument type is supported.
FILE * getFile()
Definition: IdealWriter.h:43
const VarNames & getNames()
Definition: IdealWriter.h:44
FILE * getFile()
Definition: PolyWriter.h:40
const VarNames & getNames() const
Definition: PolyWriter.h:41
virtual void doReadBarePolynomial(Scanner &in, const VarNames &names, CoefBigTermConsumer &consumer)
virtual void doReadBareIdeal(Scanner &in, const VarNames &names, BigTermConsumer &consumer)
virtual bool doPeekRing(Scanner &in)
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)
virtual void doReadRing(Scanner &in, VarNames &names)
virtual void doReadTerm(Scanner &in, const VarNames &names, vector< mpz_class > &term)
virtual void doWriteTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
static const char * staticGetName()
virtual void doWriteFooter(bool wasZeroIdeal)
virtual void doWriteTerm(const vector< mpz_class > &term, bool first)
virtual void doWriteTerm(const Term &term, const TermTranslator &translator, bool first)
virtual void doWriteHeader(bool first)
virtual void doWriteTerm(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool firstGenerator)
virtual void doWriteTerm(const mpz_class &coef, const vector< mpz_class > &term, bool firstGenerator)
virtual void doWriteFooter(bool wasZero)
void beginIdeal()
Start consuming an ideal.
void consumeTermProductNotation(Scanner &in)
Reads a term in a format like "a^4*b*c^2".
void endIdeal()
Done reading an ideal.
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition: Scanner.h:50
bool peek(char character)
Skips whitespace and returns true if the next character is equal to the parameter(s).
Definition: Scanner.h:262
void expect(char expected)
Require the next character to be equal to expected.
Definition: Scanner.h:231
const char * readIdentifier()
The returned string is only valid until the next method on this object gets called.
Definition: Scanner.cpp:255
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 ...
Term represents a product of variables which does not include a coefficient.
Definition: Term.h:49
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 clear()
Resets the number of variables to zero.
Definition: VarNames.cpp:106
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
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition: error.cpp:44
void writeRing(const VarNames &names, FILE *out)
void writeCoefTermProduct(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool hidePlus, FILE *out)
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)