Macaulay2IOHandler.cpp
Go to the documentation of this file.
/* Frobby: Software for monomial ideal computations.
Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
*/
#include "stdinc.h"
#include "Macaulay2IOHandler.h"
#include "Scanner.h"
#include "VarNames.h"
#include "TermTranslator.h"
#include "DataType.h"
#include "Term.h"
#include "IdealWriter.h"
#include "PolyWriter.h"
#include "error.h"
#include "display.h"
#include "InputConsumer.h"
#include <cstdio>
namespace IO {
namespace {
string m2GetRingName(const VarNames& names);
void m2WriteRing(const VarNames& names, FILE* out);
}
class M2IdealWriter : public IdealWriter {
public:
M2IdealWriter(FILE* out): IdealWriter(out) {
}
private:
virtual void doWriteHeader(bool first) {
if (first)
m2WriteRing(getNames(), getFile());
fputs("I = monomialIdeal(", getFile());
}
virtual void doWriteTerm(const Term& term,
const TermTranslator& translator,
bool first) {
fputs(first ? "\n " : ",\n ", getFile());
writeTermProduct(term, translator, getFile());
const size_t varCount = translator.getVarCount();
for (size_t var = 0; var < varCount; ++var)
if (translator.getExponent(var, term) != 0)
return;
fputc('_', getFile());
fputs(m2GetRingName(translator.getNames()).c_str(), getFile());
}
virtual void doWriteTerm(const vector<mpz_class>& term,
bool first) {
fputs(first ? "\n " : ",\n ", getFile());
writeTermProduct(term, getNames(), getFile());
const size_t varCount = term.size();
for (size_t var = 0; var < varCount; ++var)
if (term[var] != 0)
return;
fputc('_', getFile());
fputs(m2GetRingName(getNames()).c_str(), getFile());
}
virtual void doWriteFooter(bool wasZeroIdeal) {
if (wasZeroIdeal) {
// Macaulay 2's monomialIdeal reports an error if we give it an
// empty list, so to get the zero ideal we have to explicitly
// specify zero as a generator.
fprintf(getFile(), "0_%s);\n", m2GetRingName(getNames()).c_str());
} else
fputs("\n);\n", getFile());
}
virtual void doWriteEmptyList() {
m2WriteRing(getNames(), getFile());
}
};
class M2PolyWriter : public PolyWriter {
public:
M2PolyWriter(FILE* out): PolyWriter(out) {
}
virtual void doWriteHeader() {
m2WriteRing(getNames(), getFile());
fputs("p =", getFile());
}
virtual void doWriteTerm(const mpz_class& coef,
const Term& term,
const TermTranslator& translator,
bool firstGenerator) {
if (firstGenerator)
fputs("\n ", getFile());
else
fputs(" +\n ", getFile());
writeCoefTermProduct(coef, term, translator, true, getFile());
}
virtual void doWriteTerm(const mpz_class& coef,
const vector<mpz_class>& term,
bool firstGenerator) {
if (firstGenerator)
fputs("\n ", getFile());
else
fputs(" +\n ", getFile());
writeCoefTermProduct(coef, term, getNames(), true, getFile());
}
virtual void doWriteFooter(bool wasZero) {
if (wasZero)
fputs("\n 0", getFile());
fputs(";\n", getFile());
}
};
Macaulay2IOHandler::Macaulay2IOHandler():
IOHandlerCommon(staticGetName(),
"Format understandable by the program Macaulay 2.") {
registerInput(DataType::getMonomialIdealType());
registerInput(DataType::getMonomialIdealListType());
registerInput(DataType::getPolynomialType());
registerOutput(DataType::getMonomialIdealType());
registerOutput(DataType::getMonomialIdealListType());
registerOutput(DataType::getPolynomialType());
}
const char* Macaulay2IOHandler::staticGetName() {
return "m2";
}
BigTermConsumer* Macaulay2IOHandler::doCreateIdealWriter(FILE* out) {
return new M2IdealWriter(out);
}
CoefBigTermConsumer* Macaulay2IOHandler::doCreatePolynomialWriter(FILE* out) {
return new M2PolyWriter(out);
}
void Macaulay2IOHandler::doWriteTerm(const vector<mpz_class>& term,
const VarNames& names,
FILE* out) {
writeTermProduct(term, names, out);
}
void Macaulay2IOHandler::doReadTerm(Scanner& in, InputConsumer& consumer) {
consumer.consumeTermProductNotation(in);
if (in.match('_'))
in.readIdentifier();
}
void Macaulay2IOHandler::doReadRing(Scanner& in, VarNames& names) {
names.clear();
const char* ringName = in.readIdentifier();
ASSERT(ringName != 0 && string(ringName) != "");
if (ringName[0] != 'R') {
reportSyntaxError
(in, "Expected name of ring to start with an upper case R.");
ASSERT(false); // shouldn't reach here.
}
in.expect('=');
in.eatWhite();
if (in.peek() == 'Z') {
displayNote("In the Macaulay 2 format, writing ZZ as the ground field "
"instead of QQ is deprecated and may not work in future "
"releases of Frobby.");
in.expect("ZZ");
} else
in.expect("QQ");
in.expect('[');
// The enclosing braces are optional, but if the start brace is
// there, then the end brace should be there too.
bool readBrace = in.match('{');
if (readBrace) {
displayNote("In the Macaulay 2 format, putting braces { } around the "
"variables is deprecated and may not work in future "
"releases of Frobby.");
}
if (in.peekIdentifier()) {
do {
names.addVarSyntaxCheckUnique(in, in.readIdentifier());
} while (in.match(','));
}
if (readBrace)
in.expect('}');
in.expect(']');
in.expect(';');
}
bool Macaulay2IOHandler::doPeekRing(Scanner& in) {
return in.peek('R') || in.peek('r');
}
void Macaulay2IOHandler::doReadBareIdeal
(Scanner& in, InputConsumer& consumer) {
consumer.beginIdeal();
in.expect('I');
in.expect('=');
in.expect("monomialIdeal");
in.expect('(');
if (in.match('0')) {
if (in.match('_'))
in.readIdentifier();
} else {
do {
consumer.consumeTermProductNotation(in);
if (in.match('_'))
in.readIdentifier();
} while (in.match(','));
}
in.expect(')');
in.expect(';');
consumer.endIdeal();
}
void Macaulay2IOHandler::doReadBarePolynomial(Scanner& in,
const VarNames& names,
CoefBigTermConsumer& consumer) {
consumer.consumeRing(names);
vector<mpz_class> term(names.getVarCount());
mpz_class coef;
in.expect('p');
in.expect('=');
consumer.beginConsuming();
bool first = true;
do {
readCoefTerm(coef, term, names, first, in);
consumer.consume(coef, term);
first = false;
} while (!in.match(';'));
consumer.doneConsuming();
}
namespace {
string m2GetRingName(const VarNames& names) {
string name = "R";
if (!names.contains(name))
return name;
for (mpz_class i = 1; true; ++i) {
name = "R" + i.get_str();
if (!names.contains(name))
return name;
}
}
void m2WriteRing(const VarNames& names, FILE* out) {
fputs(m2GetRingName(names).c_str(), out);
fputs(" = QQ[", out);
const char* pre = "";
for (unsigned int i = 0; i < names.getVarCount(); ++i) {
fputs(pre, out);
if (names.getName(i) == "R") {
string msg =
"The name of the ring in Macaulay 2 format is usually named R,\n"
"but in this case there is already a variable named R. Thus,\n"
"the ring has been renamed to " + m2GetRingName(names) + '.';
displayNote(msg);
}
fputs(names.getName(i).c_str(), out);
pre = ", ";
}
fputs("];\n", out);
}
}
}
DataType.h
IdealWriter.h
InputConsumer.h
Macaulay2IOHandler.h
PolyWriter.h
Scanner.h
TermTranslator.h
Term.h
VarNames.h
BigTermConsumer
Definition BigTermConsumer.h:29
CoefBigTermConsumer
Definition CoefBigTermConsumer.h:29
CoefBigTermConsumer::beginConsuming
virtual void beginConsuming()=0
CoefBigTermConsumer::consume
virtual void consume(const mpz_class &coef, const Term &term)
Definition CoefBigTermConsumer.cpp:25
CoefBigTermConsumer::doneConsuming
virtual void doneConsuming()=0
CoefBigTermConsumer::consumeRing
virtual void consumeRing(const VarNames &names)=0
DataType::getMonomialIdealListType
static const DataType & getMonomialIdealListType()
Returns the one and only instance for monomial ideal lists.
Definition DataType.cpp:54
DataType::getMonomialIdealType
static const DataType & getMonomialIdealType()
Returns the one and only instance for monomial ideals.
Definition DataType.cpp:45
DataType::getPolynomialType
static const DataType & getPolynomialType()
Returns the one and only instance for polynomials.
Definition DataType.cpp:50
IO::IOHandlerCommon::IOHandlerCommon
IOHandlerCommon(const char *formatName, const char *formatDescription)
Definition IOHandlerCommon.cpp:27
IO::IOHandlerImpl::registerInput
void registerInput(const DataType &type)
Specify that input of the argument type is supported.
Definition IOHandlerImpl.cpp:60
IO::IOHandlerImpl::registerOutput
void registerOutput(const DataType &type)
Specify that output of the argument type is supported.
Definition IOHandlerImpl.cpp:67
IO::IdealWriter::getFile
FILE * getFile()
Definition IdealWriter.h:43
IO::IdealWriter::IdealWriter
IdealWriter(FILE *out)
Definition IdealWriter.cpp:25
IO::IdealWriter::getNames
const VarNames & getNames()
Definition IdealWriter.h:44
IO::M2IdealWriter
Definition Macaulay2IOHandler.cpp:38
IO::M2IdealWriter::doWriteTerm
virtual void doWriteTerm(const vector< mpz_class > &term, bool first)
Definition Macaulay2IOHandler.cpp:65
IO::M2IdealWriter::M2IdealWriter
M2IdealWriter(FILE *out)
Definition Macaulay2IOHandler.cpp:40
IO::M2IdealWriter::doWriteFooter
virtual void doWriteFooter(bool wasZeroIdeal)
Definition Macaulay2IOHandler.cpp:79
IO::M2IdealWriter::doWriteTerm
virtual void doWriteTerm(const Term &term, const TermTranslator &translator, bool first)
Definition Macaulay2IOHandler.cpp:50
IO::M2IdealWriter::doWriteHeader
virtual void doWriteHeader(bool first)
Definition Macaulay2IOHandler.cpp:44
IO::M2IdealWriter::doWriteEmptyList
virtual void doWriteEmptyList()
Definition Macaulay2IOHandler.cpp:89
IO::M2PolyWriter
Definition Macaulay2IOHandler.cpp:94
IO::M2PolyWriter::M2PolyWriter
M2PolyWriter(FILE *out)
Definition Macaulay2IOHandler.cpp:96
IO::M2PolyWriter::doWriteFooter
virtual void doWriteFooter(bool wasZero)
Definition Macaulay2IOHandler.cpp:127
IO::M2PolyWriter::doWriteTerm
virtual void doWriteTerm(const mpz_class &coef, const vector< mpz_class > &term, bool firstGenerator)
Definition Macaulay2IOHandler.cpp:116
IO::M2PolyWriter::doWriteHeader
virtual void doWriteHeader()
Definition Macaulay2IOHandler.cpp:99
IO::M2PolyWriter::doWriteTerm
virtual void doWriteTerm(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool firstGenerator)
Definition Macaulay2IOHandler.cpp:104
IO::Macaulay2IOHandler::doPeekRing
virtual bool doPeekRing(Scanner &in)
Definition Macaulay2IOHandler.cpp:212
IO::Macaulay2IOHandler::Macaulay2IOHandler
Macaulay2IOHandler()
Definition Macaulay2IOHandler.cpp:134
IO::Macaulay2IOHandler::doReadBareIdeal
virtual void doReadBareIdeal(Scanner &in, InputConsumer &consumer)
Definition Macaulay2IOHandler.cpp:217
IO::Macaulay2IOHandler::doCreatePolynomialWriter
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
Definition Macaulay2IOHandler.cpp:153
IO::Macaulay2IOHandler::staticGetName
static const char * staticGetName()
Definition Macaulay2IOHandler.cpp:145
IO::Macaulay2IOHandler::doWriteTerm
virtual void doWriteTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
Definition Macaulay2IOHandler.cpp:157
IO::Macaulay2IOHandler::doReadRing
virtual void doReadRing(Scanner &in, VarNames &names)
Definition Macaulay2IOHandler.cpp:169
IO::Macaulay2IOHandler::doCreateIdealWriter
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)
Definition Macaulay2IOHandler.cpp:149
IO::Macaulay2IOHandler::doReadTerm
virtual void doReadTerm(Scanner &in, InputConsumer &consumer)
Definition Macaulay2IOHandler.cpp:163
IO::Macaulay2IOHandler::doReadBarePolynomial
virtual void doReadBarePolynomial(Scanner &in, const VarNames &names, CoefBigTermConsumer &consumer)
Definition Macaulay2IOHandler.cpp:240
IO::PolyWriter::PolyWriter
PolyWriter(FILE *out)
Definition PolyWriter.cpp:25
IO::PolyWriter::getFile
FILE * getFile()
Definition PolyWriter.h:40
IO::PolyWriter::getNames
const VarNames & getNames() const
Definition PolyWriter.h:41
InputConsumer
Definition InputConsumer.h:30
InputConsumer::beginIdeal
void beginIdeal()
Start consuming an ideal.
Definition InputConsumer.cpp:50
InputConsumer::consumeTermProductNotation
void consumeTermProductNotation(Scanner &in)
Reads a term in a format like "a^4*b*c^2".
Definition InputConsumer.cpp:148
InputConsumer::endIdeal
void endIdeal()
Done reading an ideal.
Definition InputConsumer.cpp:191
Scanner
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition Scanner.h:50
Scanner::peek
bool peek(char character)
Skips whitespace and returns true if the next character is equal to the parameter(s).
Definition Scanner.h:262
Scanner::eatWhite
void eatWhite()
Reads past any whitespace, where whitespace is defined by the standard function isspace().
Definition Scanner.h:267
Scanner::expect
void expect(char expected)
Require the next character to be equal to expected.
Definition Scanner.h:231
Scanner::readIdentifier
const char * readIdentifier()
The returned string is only valid until the next method on this object gets called.
Definition Scanner.cpp:255
Scanner::peekIdentifier
bool peekIdentifier()
Skips whitespace and returns true if the next token is an identifier.
Definition Scanner.h:257
Scanner::match
bool match(char c)
Return true if the next character is c, and in that case skip past it.
Definition Scanner.h:215
TermTranslator
TermTranslator handles translation between terms whose exponents are infinite precision integers and ...
Definition TermTranslator.h:41
TermTranslator::getExponent
const mpz_class & getExponent(size_t variable, Exponent exponent) const
This method translates from IDs to arbitrary precision integers.
Definition TermTranslator.cpp:392
TermTranslator::getVarCount
size_t getVarCount() const
Definition TermTranslator.cpp:447
TermTranslator::getNames
const VarNames & getNames() const
Definition TermTranslator.cpp:443
Term
Term represents a product of variables which does not include a coefficient.
Definition Term.h:49
VarNames
Defines the variables of a polynomial ring and facilities IO involving them.
Definition VarNames.h:40
VarNames::getVarCount
size_t getVarCount() const
Returns the current number of variables.
Definition VarNames.h:113
VarNames::getName
const string & getName(size_t index) const
The returned reference can become invalid next time addVar is called.
Definition VarNames.cpp:100
VarNames::clear
void clear()
Resets the number of variables to zero.
Definition VarNames.cpp:106
VarNames::addVarSyntaxCheckUnique
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
VarNames::contains
bool contains(const string &name) const
Returns true if name is the name of a variable.
Definition VarNames.cpp:91
displayNote
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
display.h
This file contains functions for printing strings to standard error.
reportSyntaxError
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition error.cpp:44
error.h
IO
Definition CoCoA4IOHandler.cpp:33
IO::writeCoefTermProduct
void writeCoefTermProduct(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool hidePlus, FILE *out)
Definition IOHandlerImpl.cpp:123
IO::readCoefTerm
void readCoefTerm(BigPolynomial &polynomial, bool firstTerm, Scanner &in)
Definition IOHandlerImpl.cpp:262
IO::writeTermProduct
void writeTermProduct(const Term &term, const TermTranslator &translator, FILE *out)
Definition IOHandlerImpl.cpp:170
stdinc.h
This header file includes common definitions and is included as the first line of code in every imple...
ASSERT
#define ASSERT(X)
Definition stdinc.h:86