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
72void 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
81const char* IOHandler::getName() const {
82 return doGetName();
83}
84
85const char* IOHandler::getDescription() const {
86 return doGetDescription();
87}
88
89auto_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
98auto_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
110auto_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
119bool IOHandler::supportsInput(const DataType& type) const {
120 return doSupportsInput(type);
121}
122
123bool IOHandler::supportsOutput(const DataType& type) const {
124 return doSupportsOutput(type);
125}
126
127namespace {
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
145auto_ptr<IOHandler> createIOHandler(const string& prefix) {
146 return createWithPrefix(getIOHandlerFactory(), prefix);
147}
148
149auto_ptr<IOHandler> createOHandler(const string& input, const string& output) {
151 return createIOHandler(input);
152 else
153 return createIOHandler(output);
154}
155
156void getIOHandlerNames(vector<string>& names) {
157 getIOHandlerFactory().getNamesWithPrefix("", names);
158}
159
160void 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}
auto_ptr< IOHandler > createIOHandler(const string &prefix)
Returns an IOHandler for the format whose name has the given prefix.
Definition: IOHandler.cpp:145
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 > 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
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)=0
void writeTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
Definition: IOHandler.cpp:72
virtual void doReadPolynomial(Scanner &in, CoefBigTermConsumer &consumer)=0
virtual const char * doGetDescription() const =0
virtual BigTermConsumer * doCreateIdealWriter(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
auto_ptr< CoefBigTermConsumer > createPolynomialWriter(FILE *out)
Definition: IOHandler.cpp:110
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
virtual const char * doGetName() const =0
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