CoCoA4IOHandler.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 "CoCoA4IOHandler.h"
#include "Scanner.h"
#include "VarNames.h"
#include "Term.h"
#include "TermTranslator.h"
#include "FrobbyStringStream.h"
#include "DataType.h"
#include "IdealWriter.h"
#include "PolyWriter.h"
#include "error.h"
#include "InputConsumer.h"
#include <cstdio>
namespace IO {
namespace CoCoA4 {
void writeRing(const VarNames& names, FILE* out);
void writeTermProduct(const Term& term,
const TermTranslator& translator,
FILE* out);
void writeTermProduct(const vector<mpz_class>& term,
const VarNames& names,
FILE* out);
void readTerm(Scanner& in, vector<mpz_class>& term);
void readTerm(Scanner& in, InputConsumer& consumer);
void readVarPower(vector<mpz_class>& term, Scanner& in);
void readVarPower(Scanner& in, InputConsumer& consumer);
void readCoefTerm(mpz_class& coef,
vector<mpz_class>& term,
bool firstTerm,
Scanner& in);
}
namespace C = CoCoA4;
class CoCoA4IdealWriter : public IdealWriter {
public:
CoCoA4IdealWriter(FILE* out): IdealWriter(out) {
}
private:
virtual void doWriteHeader(bool first) {
C::writeRing(getNames(), getFile());
fputs("I := Ideal(", getFile());
}
virtual void doWriteTerm(const Term& term,
const TermTranslator& translator,
bool first) {
fputs(first ? "\n " : ",\n ", getFile());
C::writeTermProduct(term, translator, getFile());
}
virtual void doWriteTerm(const vector<mpz_class>& term,
bool first) {
fputs(first ? "\n " : ",\n ", getFile());
C::writeTermProduct(term, getNames(), getFile());
}
virtual void doWriteFooter(bool wasZeroIdeal) {
fputs("\n);\n", getFile());
}
virtual void doWriteEmptyList() {
C::writeRing(getNames(), getFile());
}
};
class CoCoA4PolyWriter : public PolyWriter {
public:
CoCoA4PolyWriter(FILE* out): PolyWriter(out) {
}
virtual void doWriteHeader() {
C::writeRing(getNames(), getFile());
fputs("p :=", getFile());
}
virtual void doWriteTerm(const mpz_class& coef,
const Term& term,
const TermTranslator& translator,
bool firstGenerator) {
fputs("\n ", getFile());
if (coef >= 0 && !firstGenerator)
fputc('+', getFile());
if (term.isIdentity()) {
gmp_fprintf(getFile(), "%Zd", coef.get_mpz_t());
return;
}
if (coef == -1)
fputc('-', getFile());
else if (coef != 1)
gmp_fprintf(getFile(), "%Zd", coef.get_mpz_t());
C::writeTermProduct(term, translator, getFile());
}
virtual void doWriteTerm(const mpz_class& coef,
const vector<mpz_class>& term,
bool firstGenerator) {
fputs("\n ", getFile());
if (coef >= 0 && !firstGenerator)
fputc('+', getFile());
bool isIdentity = true;
for (size_t var = 0; var < term.size(); ++var)
if (term[var] != 0)
isIdentity = false;
if (isIdentity) {
gmp_fprintf(getFile(), "%Zd", coef.get_mpz_t());
return;
}
if (coef == -1)
fputc('-', getFile());
else if (coef != 1)
gmp_fprintf(getFile(), "%Zd", coef.get_mpz_t());
C::writeTermProduct(term, getNames(), getFile());
}
virtual void doWriteFooter(bool wasZero) {
if (wasZero)
fputs("\n 0", getFile());
fputs(";\n", getFile());
}
};
IO::CoCoA4IOHandler::CoCoA4IOHandler():
IOHandlerCommon(staticGetName(),
"Format understandable by the program CoCoA 4.") {
registerInput(DataType::getMonomialIdealType());
registerInput(DataType::getMonomialIdealListType());
registerInput(DataType::getPolynomialType());
registerOutput(DataType::getMonomialIdealType());
registerOutput(DataType::getPolynomialType());
}
const char* CoCoA4IOHandler::staticGetName() {
return "cocoa4";
}
BigTermConsumer* CoCoA4IOHandler::doCreateIdealWriter(FILE* out) {
return new CoCoA4IdealWriter(out);
}
CoefBigTermConsumer* CoCoA4IOHandler::doCreatePolynomialWriter(FILE* out) {
return new CoCoA4PolyWriter(out);
}
void CoCoA4IOHandler::doWriteTerm(const vector<mpz_class>& term,
const VarNames& names,
FILE* out) {
C::writeTermProduct(term, names, out);
}
void CoCoA4IOHandler::doReadTerm(Scanner& in, InputConsumer& consumer) {
C::readTerm(in, consumer);
}
void CoCoA4IOHandler::doReadRing(Scanner& in, VarNames& names) {
names.clear();
in.expect("Use");
in.expect('R');
in.expect("::=");
in.expect('Q');
in.expect('[');
in.expect('x');
size_t varCount = 0;
if (in.match('[')) {
in.expect('1');
in.expect("..");
in.readSizeT(varCount);
in.expect(']');
}
in.expect(']');
in.expect(';');
in.expect("Names");
in.expect(":=");
in.expect('[');
for (size_t var = 0; var < varCount; ++var) {
in.expect('\"');
if (in.peekWhite())
reportSyntaxError(in, "Variable name contains space.");
names.addVarSyntaxCheckUnique(in, in.readIdentifier());
if (in.peekWhite())
reportSyntaxError(in, "Variable name contains space.");
in.expect('\"');
if (var < varCount - 1)
in.expect(',');
}
in.expect(']');
in.expect(';');
}
bool CoCoA4IOHandler::doPeekRing(Scanner& in) {
return in.peek('U') || in.peek('u');
}
void CoCoA4IOHandler::doReadBareIdeal
(Scanner& in, InputConsumer& consumer) {
consumer.beginIdeal();
in.expect('I');
in.expect(":=");
in.expect("Ideal");
in.expect('(');
if (!in.match(')')) {
do {
C::readTerm(in, consumer);
} while (in.match(','));
in.expect(')');
}
in.match(';');
consumer.endIdeal();
}
void CoCoA4IOHandler::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 {
C::readCoefTerm(coef, term, first, in);
consumer.consume(coef, term);
first = false;
} while (!in.match(';'));
consumer.doneConsuming();
}
void C::writeRing(const VarNames& names, FILE* out) {
if (names.getVarCount() == 0) {
fputs("Use R ::= Q[x];\nNames := [];\n", out);
return;
}
fprintf(out, "Use R ::= Q[x[1..%lu]];\n",
(unsigned long)names.getVarCount());
fputs("Names := [", out);
const char* pre = "\"";
for (size_t i = 0; i < names.getVarCount(); ++i) {
fputs(pre, out);
fputs(names.getName(i).c_str(), out);
pre = "\", \"";
}
fputs("\"];\n", out);
}
void C::writeTermProduct(const Term& term,
const TermTranslator& translator,
FILE* out) {
bool seenNonZero = false;
size_t varCount = term.getVarCount();
for (size_t var = 0; var < varCount; ++var) {
const char* exp = translator.getExponentString(var, term[var]);
if (exp == 0)
continue;
seenNonZero = true;
fprintf(out, "x[%lu]", (unsigned long)(var + 1));
if (exp[0] != '1' || exp[1] != '\0') {
fputc('^', out);
fputs(exp, out);
}
}
if (!seenNonZero)
fputc('1', out);
}
void C::writeTermProduct(const vector<mpz_class>& term,
const VarNames& names,
FILE* out) {
bool seenNonZero = false;
size_t varCount = term.size();
for (size_t var = 0; var < varCount; ++var) {
if (term[var] == 0)
continue;
seenNonZero = true;
fprintf(out, "x[%lu]", (unsigned long)(var + 1));
if (term[var] != 1) {
fputc('^', out);
mpz_out_str(out, 10, term[var].get_mpz_t());
}
}
if (!seenNonZero)
fputc('1', out);
}
void C::readTerm(Scanner& in, vector<mpz_class>& term) {
for (size_t var = 0; var < term.size(); ++var)
term[var] = 0;
if (in.match('1'))
return;
do {
C::readVarPower(term, in);
in.eatWhite();
} while (in.peek() == 'x');
}
void C::readTerm(Scanner& in, InputConsumer& consumer) {
consumer.beginTerm();
if (!in.match('1')) {
do {
C::readVarPower(in, consumer);
in.eatWhite();
} while (in.peek() == 'x');
}
consumer.endTerm();
}
void C::readVarPower(vector<mpz_class>& term, Scanner& in) {
in.expect('x');
in.expect('[');
size_t var;
in.readSizeT(var);
if (var == 0 || var > term.size()) {
FrobbyStringStream errorMsg;
errorMsg << "There is no variable x[" << var << "].";
reportSyntaxError(in, errorMsg);
}
--var;
in.expect(']');
if (term[var] != 0) {
FrobbyStringStream errorMsg;
errorMsg << "The variable x["
<< (var + 1)
<< "] appears twice in the same monomial.";
reportSyntaxError(in, errorMsg);
}
if (in.match('^')) {
in.readInteger(term[var]);
if (term[var] <= 0) {
FrobbyStringStream errorMsg;
errorMsg << "Expected positive integer as exponent but got "
<< term[var] << '.';
reportSyntaxError(in, errorMsg);
}
} else
term[var] = 1;
}
void C::readVarPower(Scanner& in, InputConsumer& consumer) {
in.expect('x');
in.expect('[');
size_t var = consumer.consumeVarNumber(in);
in.expect(']');
if (in.match('^'))
consumer.consumeVarExponent(var, in);
else
consumer.consumeVarExponentOne(var, in);
}
void C::readCoefTerm(mpz_class& coef,
vector<mpz_class>& term,
bool firstTerm,
Scanner& in) {
for (size_t var = 0; var < term.size(); ++var)
term[var] = 0;
bool positive = true;
if (!firstTerm && in.match('+'))
positive = !in.match('-');
else if (in.match('-'))
positive = false;
else if (!firstTerm) {
in.expect('+');
return;
}
if (in.match('+') || in.match('-'))
reportSyntaxError(in, "Too many adjacent signs.");
if (in.peekIdentifier()) {
coef = 1;
C::readVarPower(term, in);
} else
in.readInteger(coef);
in.eatWhite();
while (in.peek() == 'x') {
C::readVarPower(term, in);
in.eatWhite();
}
if (!positive)
coef = -coef;
}
}
CoCoA4IOHandler.h
DataType.h
FrobbyStringStream.h
IdealWriter.h
InputConsumer.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
FrobbyStringStream
A replacement for stringstream.
Definition FrobbyStringStream.h:26
IO::CoCoA4IOHandler::doCreateIdealWriter
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)
Definition CoCoA4IOHandler.cpp:164
IO::CoCoA4IOHandler::doReadBarePolynomial
virtual void doReadBarePolynomial(Scanner &in, const VarNames &names, CoefBigTermConsumer &consumer)
Definition CoCoA4IOHandler.cpp:249
IO::CoCoA4IOHandler::doReadBareIdeal
virtual void doReadBareIdeal(Scanner &in, InputConsumer &consumer)
Definition CoCoA4IOHandler.cpp:230
IO::CoCoA4IOHandler::doReadRing
virtual void doReadRing(Scanner &in, VarNames &names)
Definition CoCoA4IOHandler.cpp:182
IO::CoCoA4IOHandler::CoCoA4IOHandler
CoCoA4IOHandler()
Definition CoCoA4IOHandler.cpp:150
IO::CoCoA4IOHandler::doCreatePolynomialWriter
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
Definition CoCoA4IOHandler.cpp:168
IO::CoCoA4IOHandler::doReadTerm
virtual void doReadTerm(Scanner &in, InputConsumer &consumer)
Definition CoCoA4IOHandler.cpp:178
IO::CoCoA4IOHandler::staticGetName
static const char * staticGetName()
Definition CoCoA4IOHandler.cpp:160
IO::CoCoA4IOHandler::doPeekRing
virtual bool doPeekRing(Scanner &in)
Definition CoCoA4IOHandler.cpp:225
IO::CoCoA4IOHandler::doWriteTerm
virtual void doWriteTerm(const vector< mpz_class > &term, const VarNames &names, FILE *out)
Definition CoCoA4IOHandler.cpp:172
IO::CoCoA4IdealWriter
Definition CoCoA4IOHandler.cpp:53
IO::CoCoA4IdealWriter::CoCoA4IdealWriter
CoCoA4IdealWriter(FILE *out)
Definition CoCoA4IOHandler.cpp:55
IO::CoCoA4IdealWriter::doWriteEmptyList
virtual void doWriteEmptyList()
Definition CoCoA4IOHandler.cpp:81
IO::CoCoA4IdealWriter::doWriteTerm
virtual void doWriteTerm(const Term &term, const TermTranslator &translator, bool first)
Definition CoCoA4IOHandler.cpp:64
IO::CoCoA4IdealWriter::doWriteFooter
virtual void doWriteFooter(bool wasZeroIdeal)
Definition CoCoA4IOHandler.cpp:77
IO::CoCoA4IdealWriter::doWriteHeader
virtual void doWriteHeader(bool first)
Definition CoCoA4IOHandler.cpp:59
IO::CoCoA4IdealWriter::doWriteTerm
virtual void doWriteTerm(const vector< mpz_class > &term, bool first)
Definition CoCoA4IOHandler.cpp:71
IO::CoCoA4PolyWriter
Definition CoCoA4IOHandler.cpp:86
IO::CoCoA4PolyWriter::doWriteTerm
virtual void doWriteTerm(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool firstGenerator)
Definition CoCoA4IOHandler.cpp:96
IO::CoCoA4PolyWriter::doWriteHeader
virtual void doWriteHeader()
Definition CoCoA4IOHandler.cpp:91
IO::CoCoA4PolyWriter::doWriteFooter
virtual void doWriteFooter(bool wasZero)
Definition CoCoA4IOHandler.cpp:143
IO::CoCoA4PolyWriter::CoCoA4PolyWriter
CoCoA4PolyWriter(FILE *out)
Definition CoCoA4IOHandler.cpp:88
IO::CoCoA4PolyWriter::doWriteTerm
virtual void doWriteTerm(const mpz_class &coef, const vector< mpz_class > &term, bool firstGenerator)
Definition CoCoA4IOHandler.cpp:118
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::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::consumeVarNumber
size_t consumeVarNumber(Scanner &in)
Reads variable as a number so that the first variable is 1.
Definition InputConsumer.cpp:76
InputConsumer::beginTerm
void beginTerm()
Start consuming a term.
Definition InputConsumer.cpp:62
InputConsumer::beginIdeal
void beginIdeal()
Start consuming an ideal.
Definition InputConsumer.cpp:50
InputConsumer::consumeVarExponent
void consumeVarExponent(size_t var, Scanner &in)
Consumes var raised to an exponent read from in.
Definition InputConsumer.cpp:122
InputConsumer::consumeVarExponentOne
void consumeVarExponentOne(size_t var, const Scanner &in)
Consumes var raised to the exponent 1.
Definition InputConsumer.cpp:102
InputConsumer::endIdeal
void endIdeal()
Done reading an ideal.
Definition InputConsumer.cpp:191
InputConsumer::endTerm
void endTerm()
Done reading a term.
Definition InputConsumer.cpp:164
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::peekWhite
bool peekWhite()
Returns true if the next character is whitespace.
Definition Scanner.h:137
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::readSizeT
void readSizeT(size_t &size)
Reads a size_t, where the representable range of that type determines when the number is too big.
Definition Scanner.cpp:205
Scanner::readInteger
void readInteger(mpz_class &integer)
Read an arbitrary-precision integer.
Definition Scanner.h:238
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::getExponentString
const char * getExponentString(size_t variable, Exponent exponent) const
as getExponent, except the string "e" is returned, where e is the exponent.
Definition TermTranslator.cpp:410
Term
Term represents a product of variables which does not include a coefficient.
Definition Term.h:49
Term::getVarCount
size_t getVarCount() const
Definition Term.h:85
Term::isIdentity
static bool isIdentity(const Exponent *a, size_t varCount)
Returns whether a is 1, i.e. whether all entries of a are 0.
Definition Term.h:316
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
reportSyntaxError
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition error.cpp:44
error.h
IO::CoCoA4
Definition CoCoA4IOHandler.cpp:34
IO::CoCoA4::writeTermProduct
void writeTermProduct(const Term &term, const TermTranslator &translator, FILE *out)
Definition CoCoA4IOHandler.cpp:289
IO::CoCoA4::readCoefTerm
void readCoefTerm(mpz_class &coef, vector< mpz_class > &term, bool firstTerm, Scanner &in)
Definition CoCoA4IOHandler.cpp:402
IO::CoCoA4::readTerm
void readTerm(Scanner &in, vector< mpz_class > &term)
Definition CoCoA4IOHandler.cpp:332
IO::CoCoA4::readVarPower
void readVarPower(vector< mpz_class > &term, Scanner &in)
Definition CoCoA4IOHandler.cpp:356
IO::CoCoA4::writeRing
void writeRing(const VarNames &names, FILE *out)
Definition CoCoA4IOHandler.cpp:269
IO
Definition CoCoA4IOHandler.cpp:33
stdinc.h
This header file includes common definitions and is included as the first line of code in every imple...