Frobby 0.9.5
Macaulay2IOHandler.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 "Macaulay2IOHandler.h"
19
20#include "Scanner.h"
21#include "VarNames.h"
22#include "TermTranslator.h"
23#include "DataType.h"
24#include "Term.h"
25#include "IdealWriter.h"
26#include "PolyWriter.h"
27#include "error.h"
28#include "display.h"
29#include "InputConsumer.h"
30#include <cstdio>
31
32namespace IO {
33 namespace {
34 string m2GetRingName(const VarNames& names);
35 void m2WriteRing(const VarNames& names, FILE* out);
36 }
37
38 class M2IdealWriter : public IdealWriter {
39 public:
42
43 private:
44 virtual void doWriteHeader(bool first) {
45 if (first)
47 fputs("I = monomialIdeal(", getFile());
48 }
49
50 virtual void doWriteTerm(const Term& term,
52 bool first) {
53 fputs(first ? "\n " : ",\n ", getFile());
55
56 const size_t varCount = translator.getVarCount();
57 for (size_t var = 0; var < varCount; ++var)
58 if (translator.getExponent(var, term) != 0)
59 return;
60
61 fputc('_', getFile());
62 fputs(m2GetRingName(translator.getNames()).c_str(), getFile());
63 }
64
65 virtual void doWriteTerm(const vector<mpz_class>& term,
66 bool first) {
67 fputs(first ? "\n " : ",\n ", getFile());
69
70 const size_t varCount = term.size();
71 for (size_t var = 0; var < varCount; ++var)
72 if (term[var] != 0)
73 return;
74
75 fputc('_', getFile());
77 }
78
79 virtual void doWriteFooter(bool wasZeroIdeal) {
80 if (wasZeroIdeal) {
81 // Macaulay 2's monomialIdeal reports an error if we give it an
82 // empty list, so to get the zero ideal we have to explicitly
83 // specify zero as a generator.
84 fprintf(getFile(), "0_%s);\n", m2GetRingName(getNames()).c_str());
85 } else
86 fputs("\n);\n", getFile());
87 }
88
89 virtual void doWriteEmptyList() {
91 }
92 };
93
94 class M2PolyWriter : public PolyWriter {
95 public:
98
99 virtual void doWriteHeader() {
101 fputs("p =", getFile());
102 }
103
104 virtual void doWriteTerm(const mpz_class& coef,
105 const Term& term,
107 bool firstGenerator) {
108 if (firstGenerator)
109 fputs("\n ", getFile());
110 else
111 fputs(" +\n ", getFile());
112
113 writeCoefTermProduct(coef, term, translator, true, getFile());
114 }
115
116 virtual void doWriteTerm(const mpz_class& coef,
117 const vector<mpz_class>& term,
118 bool firstGenerator) {
119 if (firstGenerator)
120 fputs("\n ", getFile());
121 else
122 fputs(" +\n ", getFile());
123
124 writeCoefTermProduct(coef, term, getNames(), true, getFile());
125 }
126
127 virtual void doWriteFooter(bool wasZero) {
128 if (wasZero)
129 fputs("\n 0", getFile());
130 fputs(";\n", getFile());
131 }
132 };
133
144
146 return "m2";
147 }
148
152
156
157 void Macaulay2IOHandler::doWriteTerm(const vector<mpz_class>& term,
158 const VarNames& names,
159 FILE* out) {
160 writeTermProduct(term, names, out);
161 }
162
164 consumer.consumeTermProductNotation(in);
165 if (in.match('_'))
166 in.readIdentifier();
167 }
168
170 names.clear();
171 const char* ringName = in.readIdentifier();
172 ASSERT(ringName != 0 && string(ringName) != "");
173 if (ringName[0] != 'R') {
175 (in, "Expected name of ring to start with an upper case R.");
176 ASSERT(false); // shouldn't reach here.
177 }
178
179 in.expect('=');
180
181 in.eatWhite();
182 if (in.peek() == 'Z') {
183 displayNote("In the Macaulay 2 format, writing ZZ as the ground field "
184 "instead of QQ is deprecated and may not work in future "
185 "releases of Frobby.");
186 in.expect("ZZ");
187 } else
188 in.expect("QQ");
189 in.expect('[');
190
191 // The enclosing braces are optional, but if the start brace is
192 // there, then the end brace should be there too.
193 bool readBrace = in.match('{');
194 if (readBrace) {
195 displayNote("In the Macaulay 2 format, putting braces { } around the "
196 "variables is deprecated and may not work in future "
197 "releases of Frobby.");
198 }
199
200 if (in.peekIdentifier()) {
201 do {
202 names.addVarSyntaxCheckUnique(in, in.readIdentifier());
203 } while (in.match(','));
204 }
205
206 if (readBrace)
207 in.expect('}');
208 in.expect(']');
209 in.expect(';');
210 }
211
213 return in.peek('R') || in.peek('r');
214 }
215
218 consumer.beginIdeal();
219
220 in.expect('I');
221 in.expect('=');
222 in.expect("monomialIdeal");
223 in.expect('(');
224
225 if (in.match('0')) {
226 if (in.match('_'))
227 in.readIdentifier();
228 } else {
229 do {
230 consumer.consumeTermProductNotation(in);
231 if (in.match('_'))
232 in.readIdentifier();
233 } while (in.match(','));
234 }
235 in.expect(')');
236 in.expect(';');
237 consumer.endIdeal();
238 }
239
241 const VarNames& names,
243 consumer.consumeRing(names);
244 vector<mpz_class> term(names.getVarCount());
245 mpz_class coef;
246
247 in.expect('p');
248 in.expect('=');
249
250 consumer.beginConsuming();
251 bool first = true;
252 do {
253 readCoefTerm(coef, term, names, first, in);
254 consumer.consume(coef, term);
255 first = false;
256 } while (!in.match(';'));
257 consumer.doneConsuming();
258 }
259
260 namespace {
261 string m2GetRingName(const VarNames& names) {
262 string name = "R";
263 if (!names.contains(name))
264 return name;
265
266 for (mpz_class i = 1; true; ++i) {
267 name = "R" + i.get_str();
268 if (!names.contains(name))
269 return name;
270 }
271 }
272
273 void m2WriteRing(const VarNames& names, FILE* out) {
275 fputs(" = QQ[", out);
276
277 const char* pre = "";
278 for (unsigned int i = 0; i < names.getVarCount(); ++i) {
279 fputs(pre, out);
280 if (names.getName(i) == "R") {
281 string msg =
282 "The name of the ring in Macaulay 2 format is usually named R,\n"
283 "but in this case there is already a variable named R. Thus,\n"
284 "the ring has been renamed to " + m2GetRingName(names) + '.';
286 }
287 fputs(names.getName(i).c_str(), out);
288 pre = ", ";
289 }
290 fputs("];\n", out);
291 }
292 }
293}
void nameFactoryRegister(NameFactory< AbstractProduct > &factory)
Registers the string returned by ConcreteProduct::getStaticName() to a function that default-construc...
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
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
virtual void doWriteTerm(const vector< mpz_class > &term, bool first)
virtual void doWriteFooter(bool wasZeroIdeal)
virtual void doWriteTerm(const Term &term, const TermTranslator &translator, bool first)
virtual void doWriteHeader(bool first)
virtual void doWriteEmptyList()
virtual void doWriteFooter(bool wasZero)
virtual void doWriteTerm(const mpz_class &coef, const vector< mpz_class > &term, bool firstGenerator)
virtual void doWriteHeader()
virtual void doWriteTerm(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool firstGenerator)
virtual bool doPeekRing(Scanner &in)
virtual void doReadBareIdeal(Scanner &in, InputConsumer &consumer)
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
static const char * staticGetName()
virtual void doWriteTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
virtual void doReadRing(Scanner &in, VarNames &names)
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)
virtual void doReadTerm(Scanner &in, InputConsumer &consumer)
virtual void doReadBarePolynomial(Scanner &in, const VarNames &names, CoefBigTermConsumer &consumer)
FILE * getFile()
Definition PolyWriter.h:40
const VarNames & getNames() const
Definition PolyWriter.h:41
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition Scanner.h:50
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
void displayNote(const string &msg)
Display msg to standard error in a way that indicates that this is something that the user should tak...
Definition display.cpp:135
This file contains functions for printing strings to standard error.
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition error.cpp:44
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 writeTermProduct(const Term &term, const TermTranslator &translator, FILE *out)
#define ASSERT(X)
Definition stdinc.h:86