Each object property must be declared in a rule file using the following declaration block:
property NAME
$type="TYPE";
$temporary=BOOLEAN;
$accept=CODE;
@upgrade=( VERSION => CODE, ... );
$diff=CODE;
$apply_diff{OTHER_PROPERTY}=CODE;
The declaration looks like a piece of perl code, and this is indeed so, except that no other variables on the left hand side
than shown above are allowed, and no empty lines may occur between the code lines (comments are nevertheless allowed). All
elements but are optional.
Elements marked with CODE may be references to subroutines, anonymous subroutines, or strings with names of object methods.
In the last case, or if the subroutine has a : method attribute, it is called as a method of the object possessing
the property.
Now we describe each declaration element more precisely.
Should be one of the common data types described here. One nice day the type specification
will be mapped to an elaborated system of access methods, verification and conversion routines; as of now, this is used
primarily for documentation purposes.
Currently polymake distinguishes between scalar and array types, depending on what perl data type (scalar and array reference)
you get when the object property is accessed. Scalar types are boolean .. label, as well as list and array of scalar types and, finally, vector and set. All other types are array
references. Once again, this will change in the next releases.
User-defined types are not supported now. If you specify here something unknown to polymake, the property will be treated
just as an array of text lines.
If set to 1, the property will be never saved with the object in the data file. Moreover, in the interactive mode all
temporary properties are cleaned out at the end of each user cycle.
There are two reasons to declare a property as temporary: either it is quite trivial to recompute it, or its representation
eats up too much memory and disk space.
A special subroutine which checks, and possibly converts, the input representation of the property value.
It is called with a single argument - the property value read from the file or passed via the take
method. It should return its input argument if it is OK, some other value if some conversion took place, or raise an exception
if input was incorrect.
Contains a list of subroutines which convert an out-of-date representation of a property to the current one.
VERSION must be specified as a "dotted perl constant", e.g. v2.0. It denotes the last version where the old
representation was still used. If the property has undergone several format changes, the version-code pairs must be sorted in
increasing version order.
Like in accept, each subroutine takes a single argument - the property value in old format, and should return the
converted value.
The last two components are rather ugly attempts to manage the problem of properties having many possible representations.
They will disappear in the next polymake releases. Nevertheless we'll describe them briefly.
Defines a subroutine which compares two different values of the property. It takes two arguments, the old and the new value,
and should return something encoding the transformation between them if both values are equivalent. If they aren't, the
subroutine must raise an exception. For example, VERTICES and FACETS are allowed to occur in
arbitrary order. The comparison routine tries to find a permutation transforming the old vertex (or facet) set to the new one,
and returns it as an array of integer indices.
As a special case the subroutine is allowed to return undef, which means that both values are really equal and no
transformation is needed at all.
The diff routine is used in the verification mode, as well as in seldom cases when a
production rule called in order to produce some other lacking property tries to overwrite this property as its by-product.
If no diff routine is defined, the property is considered to have a unique representation. Then in the verification mode
the values are compared verbatim.
This declaration states that the value of this property depends on the (non-unique) representation of OTHER_PROPERTY. As
soon as the value of the latte changes, the value of this property must be accordingly transformed. The subroutine takes two
arguments: the old property value and the result of OTHER_PROPERTY's diff routine. It should return the new property
value.
There can be multiple apply_diff routines if the representation depends on several other properties.
For example, the vertex-facet incidence matrix is encoded using the facet numbers as row
indices and vertex numbers as column indices. As soon as one of those get permuted, the rows or columns of the incidence
matrix must be permuted too. Therefore this property has two conversion routines, $apply_diff{VERTICES} and
$apply_diff{FACETS}.
The apply_diff routine is allowed to raise an exception if it estimates that performing the transformation of the value
will not be less expensive that recomputing it anew. In this case the property is simply removed from the object.
The anddeclarations sometimes influence the choice of the production rule chain. polymake rule
scheduler takes greatest care to avoid violation of object description consistency. When it is going to schedule a rule producing
(among others) a property with diff routine, it checks whether this property already exists (or would exist to that moment) in
the object, and if not, whether there will be other properties depending on it. If so, the rule will be discarded, since there
will be no means to provide the consistency between the existing dependent properties with the new created one.
As already mentioned before, this mechanism is far from being perfect. It will be replaced by a more flexible solution as soon as
hierarchical objects are implemented.
Property aliases
An object property can have several names assigned to it. The primary ("canonical") name is given in the declaration as described above.
Alternative names can be introduced using the following alias declaration:
property ALIAS_NAME = NAME
NAME can be the canonical property name or another alias introduced earlier. The property being aliased must belong to the
current object type or to one of its ancestors in the inheritance hierarchy.
The alias names can be used everywhere a property name is expected, that is, in the data files, in the polymake script command
line, as access method name in a perl script, as an argument of the Poly::give and Poly::take client functions, in the
production rule headers, etc.
The only asymmetry concerns data files: The property will be always stored under its canonical name, even if it was originally
created using an alias.