Frobby  0.9.5
IOHandler.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 "IOHandler.h"
19 
20 #include "Scanner.h"
21 #include "VarNames.h"
22 #include "NameFactory.h"
23 #include "FrobbyStringStream.h"
24 #include "DataType.h"
25 #include "BigTermConsumer.h"
26 #include "CoefBigTermConsumer.h"
27 #include "CountingIOHandler.h"
28 #include "NewMonosIOHandler.h"
29 #include "MonosIOHandler.h"
30 #include "Macaulay2IOHandler.h"
31 #include "Fourti2IOHandler.h"
32 #include "NullIOHandler.h"
33 #include "CoCoA4IOHandler.h"
34 #include "SingularIOHandler.h"
35 #include "error.h"
36 #include "BigTermRecorder.h"
37 #include "InputConsumer.h"
38 
40 }
41 
43  doReadIdeal(in, consumer);
44 }
45 
47  doReadIdeals(in, consumer);
48 }
49 
51 (Scanner& in, const VarNames& names, vector<mpz_class>& term) {
52  InputConsumer consumer;
53  consumer.consumeRing(names);
54  consumer.beginIdeal();
55  doReadTerm(in, consumer);
56  consumer.endIdeal();
57  ASSERT(!consumer.empty());
58  auto_ptr<BigIdeal> ideal = consumer.releaseBigIdeal();
59  ASSERT(consumer.empty());
60  ASSERT(ideal->getGeneratorCount() == 1);
61  term = (*ideal)[0];
62 }
63 
65  doReadPolynomial(in, consumer);
66 }
67 
69  doReadSatBinomIdeal(in, consumer);
70 }
71 
72 void IOHandler::writeTerm(const vector<mpz_class>& term,
73  const VarNames& names, FILE* out) {
74  doWriteTerm(term, names, out);
75 }
76 
78  return doHasMoreInput(in);
79 }
80 
81 const char* IOHandler::getName() const {
82  return doGetName();
83 }
84 
85 const char* IOHandler::getDescription() const {
86  return doGetDescription();
87 }
88 
89 auto_ptr<BigTermConsumer> IOHandler::createIdealWriter(FILE* out) {
91  throwError<UnsupportedException>
92  ("The " + string(getName()) +
93  " format does not support output of a monomial ideal.");
94  }
95  return auto_ptr<BigTermConsumer>(doCreateIdealWriter(out));
96 }
97 
98 auto_ptr<BigTermConsumer> IOHandler::createIdealListWriter(FILE* out) {
100  throwError<UnsupportedException>
101  ("The " + string(getName()) +
102  " format does not support output of a list of monomial ideals.");
103  }
104  // This is the same kind of object as for a non-list ideal
105  // writer. The only difference is that we checked for support for
106  // output of lists above.
107  return auto_ptr<BigTermConsumer>(doCreateIdealWriter(out));
108 }
109 
110 auto_ptr<CoefBigTermConsumer> IOHandler::createPolynomialWriter(FILE* out) {
112  throwError<UnsupportedException>
113  ("The " + string(getName()) +
114  " format does not support output of a polynomial.");
115  }
116  return auto_ptr<CoefBigTermConsumer>(doCreatePolynomialWriter(out));
117 }
118 
119 bool IOHandler::supportsInput(const DataType& type) const {
120  return doSupportsInput(type);
121 }
122 
123 bool IOHandler::supportsOutput(const DataType& type) const {
124  return doSupportsOutput(type);
125 }
126 
127 namespace {
128  typedef NameFactory<IOHandler> IOHandlerFactory;
129  IOHandlerFactory getIOHandlerFactory() {
130  IOHandlerFactory factory("format");
131 
132  nameFactoryRegister<IO::Macaulay2IOHandler>(factory);
133  nameFactoryRegister<IO::CoCoA4IOHandler>(factory);
134  nameFactoryRegister<IO::SingularIOHandler>(factory);
135  nameFactoryRegister<IO::MonosIOHandler>(factory);
136  nameFactoryRegister<IO::NewMonosIOHandler>(factory);
137  nameFactoryRegister<IO::Fourti2IOHandler>(factory);
138  nameFactoryRegister<IO::NullIOHandler>(factory);
139  nameFactoryRegister<IO::CountingIOHandler>(factory);
140 
141  return factory;
142  }
143 }
144 
145 auto_ptr<IOHandler> createIOHandler(const string& prefix) {
146  return createWithPrefix(getIOHandlerFactory(), prefix);
147 }
148 
149 auto_ptr<IOHandler> createOHandler(const string& input, const string& output) {
151  return createIOHandler(input);
152  else
153  return createIOHandler(output);
154 }
155 
156 void getIOHandlerNames(vector<string>& names) {
157  getIOHandlerFactory().getNamesWithPrefix("", names);
158 }
159 
160 void readFrobeniusInstance(Scanner& in, vector<mpz_class>& numbers) {
161  numbers.clear();
162 
163  string number;
164  mpz_class n;
165  while (!in.matchEOF()) {
166  in.readInteger(n);
167 
168  if (n <= 1) {
169  FrobbyStringStream errorMsg;
170  errorMsg << "Read the number " << n
171  << " while reading Frobenius instance. "
172  << "Only integers strictly larger than 1 are valid.";
173  reportSyntaxError(in, errorMsg);
174  }
175 
176  numbers.push_back(n);
177  }
178 
179  if (numbers.empty())
181  (in, "Read empty Frobenius instance, which is not allowed.");
182 
183  mpz_class gcd = numbers[0];
184  for (size_t i = 1; i < numbers.size(); ++i)
185  mpz_gcd(gcd.get_mpz_t(), gcd.get_mpz_t(), numbers[i].get_mpz_t());
186 
187  if (gcd != 1) {
188  // Maybe not strictly speaking a syntax error, but that category
189  // of errors still fits best.
190  FrobbyStringStream errorMsg;
191  errorMsg << "The numbers in the Frobenius instance are not "
192  << "relatively prime. They are all divisible by "
193  << gcd << '.';
194  reportSyntaxError(in, errorMsg);
195  }
196 }
197 
199  // We guess based on the initial non-whitespace character. We detect
200  // more than the correct initial character to try to guess the
201  // intended format in the face of mistakes.
202  in.eatWhite();
203  switch (in.peek()) {
204  case 'U': // correct
205  case 'u': // incorrect
207 
208  case 'r': // correct
210 
211  case '(': // correct
212  case 'l': // incorrect
213  case ')': // incorrect
215 
216  case '0': case '1': case '2': case '3': case '4': // correct
217  case '5': case '6': case '7': case '8': case '9': // correct
218  case '+': case '-': // incorrect
220 
221  case 'v': // correct
223 
224  case 'R': // correct
225  default: // incorrect
227  }
228 }
229 
231  return "input";
232 }
233 
235  return "autodetect";
236 }
void readFrobeniusInstance(Scanner &in, vector< mpz_class > &numbers)
Definition: IOHandler.cpp:160
void getIOHandlerNames(vector< string > &names)
Add the name of each fomat to names.
Definition: IOHandler.cpp:156
string getFormatNameIndicatingToUseInputFormatAsOutputFormat()
Using the returned string in place of an (output) format name indicates to use the input format as th...
Definition: IOHandler.cpp:230
string getFormatNameIndicatingToGuessTheInputFormat()
Using the returned string in place of an (input) format name indicates to guess the format based on w...
Definition: IOHandler.cpp:234
auto_ptr< IOHandler > createIOHandler(const string &prefix)
Returns an IOHandler for the format whose name has the given prefix.
Definition: IOHandler.cpp:145
auto_ptr< IOHandler > createOHandler(const string &input, const string &output)
Returns an IOHandler for the output format.
Definition: IOHandler.cpp:149
string autoDetectFormat(Scanner &in)
Return the format of what in is reading based on the first non-whitespace character.
Definition: IOHandler.cpp:198
auto_ptr< AbstractProduct > createWithPrefix(const NameFactory< AbstractProduct > &factory, const string &prefix)
Creates the unique product that has the indicated prefix, or create the actual product that has name ...
Definition: NameFactory.h:154
The intention of this class is to describe the different kinds of mathematical structures that Frobby...
Definition: DataType.h:29
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.
virtual void doWriteTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)=0
virtual void doReadSatBinomIdeal(Scanner &in, SatBinomConsumer &consumer)=0
void readSatBinomIdeal(Scanner &in, SatBinomConsumer &consumer)
Definition: IOHandler.cpp:68
void readPolynomial(Scanner &in, CoefBigTermConsumer &consumer)
Definition: IOHandler.cpp:64
virtual bool doSupportsInput(const DataType &type) const =0
virtual void doReadIdeals(Scanner &in, InputConsumer &consumer)=0
void writeTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
Definition: IOHandler.cpp:72
virtual const char * doGetDescription() const =0
virtual void doReadPolynomial(Scanner &in, CoefBigTermConsumer &consumer)=0
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)=0
void readIdeal(Scanner &in, InputConsumer &consumer)
Read an ideal and feed it to the consumer.
Definition: IOHandler.cpp:42
bool supportsInput(const DataType &type) const
Definition: IOHandler.cpp:119
auto_ptr< BigTermConsumer > createIdealWriter(FILE *out)
Definition: IOHandler.cpp:89
const char * getName() const
Definition: IOHandler.cpp:81
virtual const char * doGetName() const =0
auto_ptr< CoefBigTermConsumer > createPolynomialWriter(FILE *out)
Definition: IOHandler.cpp:110
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)=0
virtual bool doSupportsOutput(const DataType &type) const =0
virtual void doReadIdeal(Scanner &in, InputConsumer &consumer)=0
auto_ptr< BigTermConsumer > createIdealListWriter(FILE *out)
Definition: IOHandler.cpp:98
const char * getDescription() const
Definition: IOHandler.cpp:85
virtual bool doHasMoreInput(Scanner &in) const =0
bool supportsOutput(const DataType &type) const
Definition: IOHandler.cpp:123
virtual void doReadTerm(Scanner &in, InputConsumer &consumer)=0
void readTerm(Scanner &in, const VarNames &names, vector< mpz_class > &term)
Definition: IOHandler.cpp:51
virtual ~IOHandler()
Definition: IOHandler.cpp:39
bool hasMoreInput(Scanner &in) const
Definition: IOHandler.cpp:77
void readIdeals(Scanner &in, InputConsumer &consumer)
Read a number of ideals and feed them to the consumer.
Definition: IOHandler.cpp:46
static const char * staticGetName()
static const char * staticGetName()
static const char * staticGetName()
static const char * staticGetName()
static const char * staticGetName()
static const char * staticGetName()
bool empty() const
Returns true if there are ideals stored.
Definition: InputConsumer.h:74
void beginIdeal()
Start consuming an ideal.
void consumeRing(const VarNames &names)
auto_ptr< BigIdeal > releaseBigIdeal()
Returns the least recently read ideal that has not been released.
void endIdeal()
Done reading an ideal.
A NameFactory takes a name and then creates an instance of a class that has been previously registere...
Definition: NameFactory.h:33
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 eatWhite()
Reads past any whitespace, where whitespace is defined by the standard function isspace().
Definition: Scanner.h:267
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
Defines the variables of a polynomial ring and facilities IO involving them.
Definition: VarNames.h:40
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition: error.cpp:44
void gcd(Word *res, const Word *resEnd, const Word *a, const Word *b)
#define ASSERT(X)
Definition: stdinc.h:86