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.

$type="TYPE";
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.
$temporary=BOOLEAN;
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.
The default is 0, i.e. a persistent property.
$accept=CODE;
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.
@upgrade=( VERSION => CODE, ... );
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.

$diff=CODE;
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.
$apply_diff{OTHER_PROPERTY}=CODE;
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 and declarations 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.