IOHandlerImpl.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 "IOHandlerImpl.h"
#include "Scanner.h"
#include "BigIdeal.h"
#include "TermTranslator.h"
#include "Term.h"
#include "TermConsumer.h"
#include "VarNames.h"
#include "CoefTermConsumer.h"
#include "Polynomial.h"
#include "BigPolynomial.h"
#include "FrobbyStringStream.h"
#include "BigTermConsumer.h"
#include "DataType.h"
#include "error.h"
#include "InputConsumer.h"
#include <algorithm>
IO::IOHandlerImpl::IOHandlerImpl(const char* formatName,
const char* formatDescription):
_formatName(formatName),
_formatDescription(formatDescription) {
}
BigTermConsumer* IO::IOHandlerImpl::doCreateIdealWriter(FILE* out) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
CoefBigTermConsumer* IO::IOHandlerImpl::doCreatePolynomialWriter(FILE* out) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
bool IO::IOHandlerImpl::doSupportsInput(const DataType& type) const {
return std::find(_supportedInputs.begin(), _supportedInputs.end(),
&type) != _supportedInputs.end();
}
bool IO::IOHandlerImpl::doSupportsOutput(const DataType& type) const {
return std::find(_supportedOutputs.begin(), _supportedOutputs.end(),
&type) != _supportedOutputs.end();
}
void IO::IOHandlerImpl::registerInput(const DataType& type) {
ASSERT(!type.isNull());
ASSERT(!supportsInput(type));
_supportedInputs.push_back(&type);
}
void IO::IOHandlerImpl::registerOutput(const DataType& type) {
ASSERT(!type.isNull());
ASSERT(!supportsOutput(type));
_supportedOutputs.push_back(&type);
}
void IO::IOHandlerImpl::doReadTerm(Scanner& in, InputConsumer& consumer) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
void IO::IOHandlerImpl::doReadIdeal(Scanner& in, InputConsumer& consumer) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
void IO::IOHandlerImpl::doReadIdeals(Scanner& in, InputConsumer& consumer) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
void IO::IOHandlerImpl::doReadPolynomial(Scanner& in,
CoefBigTermConsumer& consumer) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
void IO::IOHandlerImpl::doReadSatBinomIdeal(Scanner& in,
SatBinomConsumer& consumer) {
INTERNAL_ERROR_UNIMPLEMENTED();
}
bool IO::IOHandlerImpl::doHasMoreInput(Scanner& in) const {
return !in.matchEOF();
}
const char* IO::IOHandlerImpl::doGetName() const {
return _formatName;
}
const char* IO::IOHandlerImpl::doGetDescription() const {
return _formatDescription;
}
void IO::readTermProduct(Scanner& in,
const VarNames& names,
vector<mpz_class>& term) {
term.resize(names.getVarCount());
for (size_t var = 0; var < term.size(); ++var)
term[var] = 0;
if (in.match('1'))
return;
do {
readVarPower(term, names, in);
} while (in.match('*'));
}
void IO::writeCoefTermProduct(const mpz_class& coef,
const Term& term,
const TermTranslator& translator,
bool hidePlus,
FILE* out) {
if (coef >= 0 && !hidePlus)
fputc('+', out);
if (term.isIdentity()) {
gmp_fprintf(out, "%Zd", coef.get_mpz_t());
return;
}
if (coef == -1)
fputc('-', out);
else if (coef != 1)
gmp_fprintf(out, "%Zd*", coef.get_mpz_t());
writeTermProduct(term, translator, out);
}
void IO::writeCoefTermProduct(const mpz_class& coef,
const vector<mpz_class>& term,
const VarNames& names,
bool hidePlus,
FILE* out) {
if (coef >= 0 && !hidePlus)
fputc('+', out);
bool isIdentity = true;
for (size_t var = 0; var < term.size(); ++var)
if (term[var] != 0)
isIdentity = false;
if (isIdentity) {
gmp_fprintf(out, "%Zd", coef.get_mpz_t());
return;
}
if (coef == -1)
fputc('-', out);
else if (coef != 1)
gmp_fprintf(out, "%Zd*", coef.get_mpz_t());
writeTermProduct(term, names, out);
}
void IO::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.getVarExponentString(var, term[var]);
if (exp == 0)
continue;
if (seenNonZero)
putc('*', out);
else
seenNonZero = true;
fputs(exp, out);
}
if (!seenNonZero)
fputc('1', out);
}
void IO::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;
if (seenNonZero)
fputc('*', out);
else
seenNonZero = true;
fputs(names.getName(var).c_str(), out);
if ((term[var]) != 1) {
fputc('^', out);
mpz_out_str(out, 10, term[var].get_mpz_t());
}
}
if (!seenNonZero)
fputc('1', out);
}
void IO::readTermProduct(BigIdeal& ideal, Scanner& in) {
ideal.newLastTerm();
if (in.match('1'))
return;
do {
readVarPower(ideal.getLastTermRef(), ideal.getNames(), in);
} while (in.match('*'));
}
void IO::readCoefTerm(mpz_class& coef,
vector<mpz_class>& term,
const VarNames& names,
bool firstTerm,
Scanner& in) {
term.resize(names.getVarCount());
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;
readVarPower(term, names, in);
} else
in.readInteger(coef);
while (in.match('*'))
readVarPower(term, names, in);
if (!positive)
coef = -coef;
}
void IO::readCoefTerm(BigPolynomial& polynomial,
bool firstTerm,
Scanner& in) {
polynomial.newLastTerm();
mpz_class& coef = polynomial.getLastCoef();
vector<mpz_class>& term = polynomial.getLastTerm();
readCoefTerm(coef, term, polynomial.getNames(), firstTerm, in);
}
void IO::readVarPower(vector<mpz_class>& term,
const VarNames& names,
Scanner& in) {
size_t var = in.readVariable(names);
if (term[var] != 0) {
const string& name = names.getName(var);
reportSyntaxError(in, "The variable " +
name + " appears more than once in monomial.");
}
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;
}
BigIdeal.h
BigPolynomial.h
BigTermConsumer.h
CoefTermConsumer.h
DataType.h
FrobbyStringStream.h
IOHandlerImpl.h
InputConsumer.h
Polynomial.h
Scanner.h
TermConsumer.h
TermTranslator.h
Term.h
VarNames.h
BigIdeal
Definition BigIdeal.h:27
BigIdeal::newLastTerm
void newLastTerm()
Definition BigIdeal.cpp:104
BigIdeal::getNames
const VarNames & getNames() const
Definition BigIdeal.cpp:253
BigIdeal::getLastTermRef
vector< mpz_class > & getLastTermRef()
Definition BigIdeal.h:133
BigPolynomial
Definition BigPolynomial.h:27
BigPolynomial::getLastCoef
mpz_class & getLastCoef()
Definition BigPolynomial.cpp:89
BigPolynomial::newLastTerm
void newLastTerm()
Definition BigPolynomial.cpp:78
BigPolynomial::getLastTerm
vector< mpz_class > & getLastTerm()
Definition BigPolynomial.cpp:83
BigPolynomial::getNames
const VarNames & getNames() const
Definition BigPolynomial.cpp:42
BigTermConsumer
Definition BigTermConsumer.h:29
CoefBigTermConsumer
Definition CoefBigTermConsumer.h:29
DataType
The intention of this class is to describe the different kinds of mathematical structures that Frobby...
Definition DataType.h:29
DataType::isNull
bool isNull() const
Returns true if this object was returned by getNullType().
Definition DataType.cpp:28
FrobbyStringStream
A replacement for stringstream.
Definition FrobbyStringStream.h:26
IOHandler::supportsInput
bool supportsInput(const DataType &type) const
Definition IOHandler.cpp:119
IOHandler::supportsOutput
bool supportsOutput(const DataType &type) const
Definition IOHandler.cpp:123
IO::IOHandlerImpl::registerInput
void registerInput(const DataType &type)
Specify that input of the argument type is supported.
Definition IOHandlerImpl.cpp:60
IO::IOHandlerImpl::doReadTerm
virtual void doReadTerm(Scanner &in, InputConsumer &term)
Definition IOHandlerImpl.cpp:74
IO::IOHandlerImpl::doReadSatBinomIdeal
virtual void doReadSatBinomIdeal(Scanner &in, SatBinomConsumer &consumer)
Definition IOHandlerImpl.cpp:91
IO::IOHandlerImpl::_formatDescription
const char * _formatDescription
Definition IOHandlerImpl.h:73
IO::IOHandlerImpl::doCreateIdealWriter
virtual BigTermConsumer * doCreateIdealWriter(FILE *out)=0
Definition IOHandlerImpl.cpp:42
IO::IOHandlerImpl::doSupportsInput
virtual bool doSupportsInput(const DataType &type) const
Definition IOHandlerImpl.cpp:50
IO::IOHandlerImpl::doReadIdeal
virtual void doReadIdeal(Scanner &in, InputConsumer &consumer)
Definition IOHandlerImpl.cpp:78
IO::IOHandlerImpl::doGetDescription
virtual const char * doGetDescription() const
Definition IOHandlerImpl.cpp:104
IO::IOHandlerImpl::doGetName
virtual const char * doGetName() const
Definition IOHandlerImpl.cpp:100
IO::IOHandlerImpl::doSupportsOutput
virtual bool doSupportsOutput(const DataType &type) const
Definition IOHandlerImpl.cpp:55
IO::IOHandlerImpl::IOHandlerImpl
IOHandlerImpl(const char *formatName, const char *formatDescription)
Definition IOHandlerImpl.cpp:36
IO::IOHandlerImpl::doHasMoreInput
virtual bool doHasMoreInput(Scanner &in) const
Definition IOHandlerImpl.cpp:96
IO::IOHandlerImpl::_supportedOutputs
vector< const DataType * > _supportedOutputs
Definition IOHandlerImpl.h:70
IO::IOHandlerImpl::doCreatePolynomialWriter
virtual CoefBigTermConsumer * doCreatePolynomialWriter(FILE *out)
Definition IOHandlerImpl.cpp:46
IO::IOHandlerImpl::doReadPolynomial
virtual void doReadPolynomial(Scanner &in, CoefBigTermConsumer &consumer)
Definition IOHandlerImpl.cpp:86
IO::IOHandlerImpl::doReadIdeals
virtual void doReadIdeals(Scanner &in, InputConsumer &consumer)
Definition IOHandlerImpl.cpp:82
IO::IOHandlerImpl::registerOutput
void registerOutput(const DataType &type)
Specify that output of the argument type is supported.
Definition IOHandlerImpl.cpp:67
IO::IOHandlerImpl::_formatName
const char * _formatName
Definition IOHandlerImpl.h:72
IO::IOHandlerImpl::_supportedInputs
vector< const DataType * > _supportedInputs
Definition IOHandlerImpl.h:69
InputConsumer
Definition InputConsumer.h:30
SatBinomConsumer
Definition SatBinomConsumer.h:25
Scanner
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition Scanner.h:50
Scanner::expect
void expect(char expected)
Require the next character to be equal to expected.
Definition Scanner.h:231
Scanner::peekIdentifier
bool peekIdentifier()
Skips whitespace and returns true if the next token is an identifier.
Definition Scanner.h:257
Scanner::readVariable
size_t readVariable(const VarNames &names)
Reads an identifier and returns the index of that identifier as the index of a variable in names.
Definition Scanner.h:201
Scanner::matchEOF
bool matchEOF()
Return true if no more input.
Definition Scanner.h:210
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::getVarExponentString
const char * getVarExponentString(size_t variable, Exponent exponent) const
As getExponent, except the string "var^e" is returned or null if the exponent is zero,...
Definition TermTranslator.cpp:400
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
reportSyntaxError
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition error.cpp:44
error.h
INTERNAL_ERROR_UNIMPLEMENTED
#define INTERNAL_ERROR_UNIMPLEMENTED()
Definition error.h:47
IO::writeCoefTermProduct
void writeCoefTermProduct(const mpz_class &coef, const Term &term, const TermTranslator &translator, bool hidePlus, FILE *out)
Definition IOHandlerImpl.cpp:123
IO::readVarPower
void readVarPower(vector< mpz_class > &term, const VarNames &names, Scanner &in)
Definition IOHandlerImpl.cpp:272
IO::readCoefTerm
void readCoefTerm(BigPolynomial &polynomial, bool firstTerm, Scanner &in)
Definition IOHandlerImpl.cpp:262
IO::readTermProduct
void readTermProduct(Scanner &in, const VarNames &names, vector< mpz_class > &term)
Definition IOHandlerImpl.cpp:108
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