"name" | the prototype with the given name will be searched in your favorite applications
"application:name" | the prototype in the given application
"application:default" | the default type of the given application

std::ios::in | the object must exist; the client reads its properties
std::ios::in | std::ios::out | the object must exist; the client reads some existing properties and creates new ones
std::ios::out | the client creates a new object or add new properties to the existing one
std::ios::out | std::ios::trunc | the client creates a new object or cleans the existing one, removing all its properties; then it fills it with a new set of properties
std::ios::in | std::ios::out | std::ios::trunc | as above, but the client may later read some of properties

### Prerequisits

    #include <Poly.h>
    using namespace polymake;

### Introduction

A client program gets the data from the `polymake` server. The class Poly plays the central role in the communication between them. Each object of this class corresponds to a `polymake` object (a polyhedron, simplicial complex, etc.) In almost all cases everything the client needs for its computations is available as the object properties.

### Constructors

In the next `polymake` releases the client will obtain ready-to-use Poly objects created by the core system. You will need to use the constructors described below only as long as the clients are separate programs. According to the client coding scheme suggested in the tutorial, the Poly objects should be created in the main() function of a client.

Poly();
Create a void object, not bound to any `polymake` object. Must be actived later using init().
Poly(const char *object_ref, std::ios::openmode mode=std::ios::in, const char *object_type=0); Poly(const char *object_ref, std::ios::openmode mode, const std::string& object_type);
Bind to a `polymake` object. object_ref must be an appropriate argument of the client program (argv[...]) or 0 for a temporary object.
When the client is called directly from the shell command line, this argument must be a name of the file where the object is stored. When it is called by `polymake` via Modules::client function, it will be a special string generated by the script.
mode puts a constraint on the set of access operations allowed for this client.
object_type specifies a name of a `polymake` object. If used in the input (std::ios::in) mode, it poses the requirement that the object passed to the client must be of the given type or derived from it. If used in the creation (std::ios::trunc) mode, it sets the type of the new object.
When object_type is omitted, no type check is performed; for the new objects the default type of the application is assumed.
void init(const char *object_ref, std::ios::openmode mode=std::ios::in, const char *=0);
Bind the void object created by the default constructor to a `polymake` object. Arguments are the same as above.
std::string type();
Return the type of the connected `polymake` object. It is the pure prototype name, without application prefix.
bool isa(const char *object_type);
Return true if the connected `polymake` object is of the given type or derived from it. object_type should be a prototype name defined in the same application as this object.

### Property access

GenericInput give(const char *property_name); GenericInput lookup(const char *property_name);
Read the value of the named property. give() is used if the property is necessary for the client. If it does not exist so far, it will be created be the `polymake` server using the production rules. lookup() asks whether the property exists, and if yes, delivers its value, otherwise the input stream has an eof state.
property_name may contain a list of alternative properties connected by | signs, e.g. "VERTICES | FACETS" , if the client can go with each of them equally well.
The GenericInput object returned by these methods is a source of the data. The client writer may consider it as a magic black box which can be converted to almost each C++ data type or class. (This is true for the standard STL containers and PTL classes. If you are going to store the object property in a different C++ class, please read the details how to make it cooperate with the GenericInput and GenericOutput layers.)
The possible uses are:
p.give("PROPERTY") >> X; stores the property value in the variable X;
Type X=p.give("PROPERTY"); combines the contruction and reading operations; especially useful for introducing const variables;
if (p.lookup("PROPERTY") >> X) { ... } checks the existance of the property and reads its value in the positive case.
const std::string& given() const;
Return the name of the last property obtained by Poly:give() or Poly::lookup(), for the case the request contained alternatives.
GenericOutput take(const char *property_name);
Prepare the setting of a property. As for give(), GenericOutput is a black box which accepts a variable or expression of almost any data type. This method is used as follows:
p.take("PROPERTY") << X;
If you want to assign the undefined value to the property, you must use the special expression:
p.take("PROPERTY") << Poly::undefined();

### Other requests

Besides of property reading and setting, a client can make several other requests about the `polymake` object. They are, however, much more seldom used.

bool exists(const char *property_name);
Return true if the property already exists.
bool defined(const char *property_name);
Return true if the property exists and has a defined value. An attempt to read a property with undefined value with Poly::give() raises an exception, therefore you need this special method.
bool provide (const char* property_name, ...);
Announce that the client is going to read the given properties. The server gets the chance to find a set of rules providing all these properties with less total costs as when they were to compute one by one. Return false if it is not possible, e.g. due to the lacking initial information.
This methods accepts an arbitrary list of arguments, the last must be 0.
void remove (const char* property_name, ...);
Delete the properties of the object. This methods accepts an arbitrary list of arguments, the last must be 0.

### Exceptions

The methods of class Poly can raise a std::runtime_error exception if following occurs:

- communication error:
  unable to start the `polymake` script or connect to it; the data file does not exist
- logical error:
  the requested operation does not match the open mode of the Poly object (e.g. Poly::take() in std::ios::in mode)
- data error:
  the requested property does not exist or could not be created; the property value contains invalid data which don't match the property type

The last sort of errors is detected by the GenericIO layer or even deeper, in the formatted input routines of the C++ runtime library. The message stored in the exception object in this case is not very informative. Depending on the C++ compiler version, it looks like "basic_ios::clear".

The two most possible reasons for this kind of error are:

1. the user made a mistake (typo) when editing the data file manually
2. the client is called from a production rule, but the property it wants to read is not listed among the rule sources