Prerequisits

#include <Poly.h>

using namespace polymake; 

Introduction

class Poly : public std::iostream 

An object of this class encapsulates a communication channel to the polymake server. Each channel can be bound to exactly one data file. Therefore, a client program computing properties of a polyhedron or constructing it from scratch normally needs a single Poly object, while a client transforming a polyhedron to a new one will need two or more such objects.

explicit Poly(const char *filename, ios::openmode mode=ios::in, const char *opt=0);
Establish the connection to the server. filename should be either a data file (when the client is called directly from the command line) or a socket created by the server (when the client is called via the rules.) In the most cases, it is simply one of the argv elements of the main() function.
mode parameter controls the creation of new files and imposes constraints on the possible operations on the object. The following values would make sense:
ios::in Data file must exist and is opened read-only: existing properties may be read.
ios::in | ios::out Data file must exist; properties can be read, written, or deleted.
ios::out Data file can exist; new properties can be added.
ios::out | ios::trunc Data file is created empty or truncated to zero length; new properties can be added.
ios::in | ios::out | ios::trunc Data file is created empty or truncated to zero length; new properties can be added, and later read or deleted.
opt can be used to pass additional options to the polymake server. If the variable POLYMAKE_SWITCHES was already set in the client's environment, both option sets are merged. But if the client program is itself called by the server via the rules, opt has no effect.
~Poly();
The destructor flushes the output buffers, closes the transaction, and shuts down the connection to the server. The current transaction is positively committed only if no (uncleared) read errors have encountered and no unfinished output sections are pending.

Reading properties

void read (const char* request, ...);
void vread (va_list requests);
Ask the server to prepare the given properties. The last argument in the ... variant must be a zero pointer (0).
The request syntax is the same as in the user's command line. The contents of the first property are available as an ASCII input stream immediately after this method returns.
To obtain the data, you can use all the standard formatted input operators and std::iostream methods. PTL defines also constructors and input operators for all top-level PTL container classes, as well as input operators for the most popular STL containers: std::vector, std::list, std_ext::hash_set, and std_ext::hash_map.
If the client makes several read() calls, each next call "forgets" the properties requested by the previous one and makes the input stream empty before new data arrive.
const std::string& name() const;
Tell the exact name of the property being currently read. An empty name ("") signals that the server could not create the requested property (due to lacking data, failed rules, etc.) or that there exists a negated property contradicting the requested one.
int lines();
Tell the total number of lines in the property being currently read. 0 would mean an empty section.
int get_size(int d);
Tell the number of d-dimensional data items that can be read from the input stream. Scalar elements, such as int, double, or Rational, are treated as having dimension 0.
void next();
This method is necessary if the prior read() call has contained more than one request. After the data of a property are completely read in, the input stream switches to the eof() state, so that any further attempts to read anything will fail. next() makes the data of the next input property free and clears the eof() state.
This method can be called prematurely, while the current property is still not completely parsed; in fact, it is a most efficient way to skip the rest and go directly to the next property.

Writing properties

void write (const char* property_name, ...);
void vwrite (va_list property_names);
Announce the creation of properties to the server. The last argument in the ... variant must be a zero pointer (0).
The contents are written to the output stream using all the standard formatted output operators and std::ostream methods. PTL defines also output operators for all top-level PTL container classes, as well as for the most popular STL containers: std::vector, std::list, std_ext::hash_set, and std_ext::hash_map.
The output of each property must be concluded with an empty line (an extra endl.) The number of empty lines written out must exactly match the number of arguments in the prior write call. The check is made in every but the first write call, as well as in each commit call.
read and write operations don't interfere each other. Unlike in the standard file-oriented IO, the input and output data streams are fully independent.
void remove (const char* property_name, ...);
void vremove (va_list sections);
Ask the server to delete the properties immediately. The last argument in the ... variant must be a zero pointer (0).
This operation does not interfere with read and write streams, unless you are trying to delete just the same property that you have requested to read former.

Transaction handling

The data exchange between the server and the client runs under transaction control: all changes made by the client remain tentative unless committed explicitly. A communication error of any kind reverts the data file to the last permanent state: either immediately before the client has started, or after the last successful commitment, if any.

void commit();
Commit the transaction positively, make all changes permanent. However, if the state of the Poly object is any other than good(), this call is equivalent to rollback().
The Poly destructor calls always commit, so that this method is really needed only if the client perfroms complex, multi-step operations.
void rollback();
Discard all changes made to the data file since the last successful commit or client start.

Error handling

There are two kinds of error conditions that can arise during the lifetime of a Poly object. The first are those inherent to all input/output streams, such as a non-existing file name, or a parse error in the input data. They are reported via the standard ios::setstate() method. You can check them either using standard methods good(), fail(), etc, or let the object raise an exception std::iostream::failure using the exceptions() method. Note that the constructors of PTL container classes also raise this exception if they can't parse the input data.

The second kind are errors specific to the communication with the polymake server. They are signaled by throwing an exception of one of the following types.

class Poly::error : public runtime_error
A common base for all polymake-specific exception classes.
class Poly::garbage_error : public Poly::error
Is raised by write, commit, and Poly destructor if there are pending output properties (that is, less sections have been written out than announced in the last write call). Is raised after std::endl if more properties have been written out than announced.
Usually this occurs due to logical errors in the client prorgam, or when an empty line has stolen in in the data stream. Recall that the output data blocks are separated by empty lines.
class Poly::illegal_error : public Poly::error
Is raised if the requested operation is not permitted by the current open mode, e.g. an attempt to write while the Poly object was opened read-only. It's always a programming error.
class Poly::commfail_error : public Poly::error
Is raised if the polymake server can't be started or connected to, or the connection suddenly breaks down. The client program can safely terminate, since there is no much action it could perform after such an error.