Production rules are the crucial information source for polymake. They bring in the semantics to the properties.
TARGET [ , ... ] : SOURCE [ , ... ]
(Whitespaces are not mandatory.)
Sources are properties the rule algorithm needs as its input. The rule can expect all its input properties to already exist at the moment the rule is starting to run. It is the job of the polymake server to provide it. If for some reason a source property will be nevertheless lacking, the rule will most probably fail.
A source can be also given as a list of alternatives:
property1 | property2 ...Another variation has the form ?property, which means that
the property should be created by other rules if possible, but this rule
can cope without it too. Such source is called weak.
Targets are properties produced by the rule algorithm. More exactly, these are the properties the rule is expected to produce. If some property is "forgotten", it will be automatically created as negated after the rule finishes.
The rule header states also an access restriction: only those properties can be read or created by the rule that are declared as its sources rsp. targets. Violation of this restriction leads to the abnormal termination of the rule.
The source access list of the rule can be expanded with following clause:
may read(property [ , ... ])It contains optional rule characteristics and a piece of perl code which actually makes the whole job. Characteristics are placed on separate lines at the beginning of the body.
| 0 | constant time, trivial operation |
| 1 | linear time |
| 2 | quadratic time |
| 3 | polynomial time of degree > 2 |
| 4 | exponential time |
| >= 5 | artificial weights for rules that should be applied only when explicitly called for, and pseudo-targets |
The rest of the body is interpreted as an usual perl code, but with following restrictions:
sub
and the enclosing braces are added automatically during rule file parsing, so they must be omitted.
Empty lines must not occur in the code, since they would be treated as rule delimiters.
Perl comments (starting with a #) can be inserted at will.package Rules; use strict;package main
except for the standard perl library routines.
my variables should be used whenever possible.
undef return value means failure and forces polymake to revert the data
to the state they had before the execution of the rule. Then it seeks for an alternative rule chain or
gives up to build the targets.
die instead of returning
a zero value. The message specified in die will
be printed on stderr.
An error-handling routine can be supplied for the rule. Similarly to the
catch clauses in C++, it is called if the rule
terminates prematurely with die or a signal. The perl code of the error
handler is separated from the rule body by ON ERROR on a separate line.
Such a handler might delete temporary files created by the rule and do
some other clean-up.
If we treat a polyhedron as an object in the sense of object-oriented programming languages, then the production rules will correspond to const access methods.
Why const? Let's consider the life cycle of a polyhedral object in polymake. Once created with an initial set of known properties, it doesn't change them during his whole lifetime. Though the main and only purpose of the production rules is to compute new properties, they aren't allowed to change the already known ones, and this means, that the polyhedron remains the same. More precisely, the object in polymake always models the same well-defined equivalence class of geometric objects, such as all polytopes with the same f-vector, with the same combinatorial structure, or with the same vertex coordinates in Qd. (The notion of equivalence classes will be mapped more directly in the future versions of polymake. Currently it is given only implicitly by the initially known properties.)
Thus, applying production rules to the polyhedral object only reveals some of its properties having been "invisible" so far. This way the rules implement the well-known principle of lazy evaluation: creation of new properties is delayed until they are really needed. But with respect to a geometric object being modeled it is the same as if all properties were computed at once by its birth and never touched since then.
There is an important consequence from this design scheme: the properties are considered invariant to the rules they are created by. Therefore, if some property is created repeatedly by several rules, the second and following "versions" of it are in the most cases simply discarded. (By the way, it differs from the treatment in previous polymake versions, where all properties were always updated). But sometimes the property rewriting can be forced by the user (via pseudo-targets). If the property concerned doesn't have a natural canonical (invariant) representation, there arises a problem how to maintain the consistency between the rewritten version and other properties computed from the old version. It is solved by the synchronization mechanism.
Probably we'll introduce in the future a concept for non-const methods too, and we are going to decrease the granularity of polyhedral objects in order to allow to change some parts of an object. But now you have to submit to the fact that there are only const methods in polymake.