scripting:start

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revisionBoth sides next revision
scripting:start [2012/02/28 23:49] – [ObjectType] gawrilowscripting:start [2019/01/25 09:27] – ↷ Links adapted because of a move operation oroehrig
Line 65: Line 65:
  
 Special variables residing in the global package such as ''$_'', ''@_'', ''@ARGV'', ''@INC'', ''%ENV'', ''%SIG'', etc. don't need to be declared.  The package inheritance list ''@ISA'' and sort placeholders ''$a'' and ''$b'' are also exempt from declaration. Special variables residing in the global package such as ''$_'', ''@_'', ''@ARGV'', ''@INC'', ''%ENV'', ''%SIG'', etc. don't need to be declared.  The package inheritance list ''@ISA'' and sort placeholders ''$a'' and ''$b'' are also exempt from declaration.
 +
 +Variables can also be declared temporarily in scripts loaded by operator ''do'':
 +<code>declare local $bla=123;</code>
 +After the script has been executed, the variable disappears as if it were never declared, so that this script or other ones reusing the same variable name can safely be loaded again.  However, if the variable was already declared persistently beforehand, the effect of such local declaration is equivalent to a standard perl ''local'' operator, that is, its value will be temporarily changed but not the declaration status.  Please beware that this is a quite exotic feature introduced primarily for testing purposes.  In most cases, one-shot scripts should only create lexical variables and avoid injecting new names in namespaces.
  
 === Name lookup === === Name lookup ===
Line 89: Line 93:
 === Extending lookup scope === === Extending lookup scope ===
  
-Each package compiled from polymake source code possesses its own lookup list.  By default it consists of all enclosing packages, but can be easily extended by arbitrary further packages.  This is accomplished with a statement <code>using namespaces "OTHER_PACKAGE", ...;</code> put somewhere in the package being extended.  Please note that this a real function call, not a pragma, therefore it must be executed early enough to have effect on the package code.  The extension relation is transitive.+Each package compiled from polymake source code possesses its own lookup list.  By default it consists of all enclosing packages, but can be easily extended by arbitrary further packages.  This is accomplished with a statement <code>using namespaces "OTHER_PACKAGE", ...;</code> put somewhere in the package being extended.  Please note that this is a real function call, not a pragma, therefore it must be executed early enough to have effect on the package code.  The extension relation is transitive.
  
 This extension mechanism is involved, for example, in the process of importing applications: the application polytope imports everything from applications graph and common, so the lookup list for the package ''Polymake::polytope'' contains ''Polymake:::graph'' and ''Polymake::common'' along with the enclosing ''Polymake'' If some other application would import the application polytope, it would automatically inherit its entire lookup list. This extension mechanism is involved, for example, in the process of importing applications: the application polytope imports everything from applications graph and common, so the lookup list for the package ''Polymake::polytope'' contains ''Polymake:::graph'' and ''Polymake::common'' along with the enclosing ''Polymake'' If some other application would import the application polytope, it would automatically inherit its entire lookup list.
Line 129: Line 133:
 The standard ''local'' operator is very useful as it allows to make exception-safe temporary changes.  polymake enhances this functionality in two aspects: The standard ''local'' operator is very useful as it allows to make exception-safe temporary changes.  polymake enhances this functionality in two aspects:
    -- ''local'' works with package variables only.  Using new functions ''local_scalar'', ''local_array'', ''local_hash'', and ''local_sub'', you can temporarily modify each data type passed by reference too:\\ ''$a=[1,2];''\\ ''local_array($a, [3,4]);''    -- ''local'' works with package variables only.  Using new functions ''local_scalar'', ''local_array'', ''local_hash'', and ''local_sub'', you can temporarily modify each data type passed by reference too:\\ ''$a=[1,2];''\\ ''local_array($a, [3,4]);''
-   .. There are further functions doing temporary changes, which are reverted on leaving the block scope:\\ ''local_incr($scalar, number)'' -- add a number\\ ''local_shift(\@array)'' -- hide the first element\\ ''local_pop(\@array)'' -- hide the last element \\ ''local_shorten(\@array, n)'' -- hide abs(n) elements at the front (n>0) or back (n<0) end\\ ''local_unshift(\@array, list)'' -- prepend elements\\ ''local_push(\@array, list)'' -- append elements \\ ''local_swap(\@array, i1, i2)'' -- exchange two elements with given indices+   .. There are further functions doing temporary changes, which are reverted on leaving the block scope:\\ ''local_incr($scalar, number)'' -- add a number\\ ''local_shift(\@array)'' -- hide the first element\\ ''local_pop(\@array)'' -- hide the last element \\ ''local_clip_front(\@array, n)'' -- hide elements at the front so that the element [n] becomes the first one\\ ''local_clip_back(\@array, n)'' -- hide elements at the end so that the element [n] becomes the last one\\ ''local_unshift(\@array, list)'' -- prepend elements\\ ''local_push(\@array, list)'' -- append elements \\ ''local_swap(\@array, i1, i2)'' -- exchange two elements with given indices\\ ''%%local_bless($object, "Package" or \%Package::)%%'' -- change the type of an object
    -- You can postpone the reverting actions to an outer enclosing block scope, even located in a different subroutine.  You create a special guard object in the outer scope and pass it to other subroutines.  All temporary modifications remain in effect until the guard object is destroyed:    -- You can postpone the reverting actions to an outer enclosing block scope, even located in a different subroutine.  You create a special guard object in the outer scope and pass it to other subroutines.  All temporary modifications remain in effect until the guard object is destroyed:
    .. <code>    .. <code>
Line 147: Line 151:
    .. All ''local_XXX'' functions described above can be used in the block ''begin_locals'' .. ''end_locals'' too.    .. All ''local_XXX'' functions described above can be used in the block ''begin_locals'' .. ''end_locals'' too.
    .. There is one session-scope guard dwelling in the variable ''$Polymake::Scope'' (aka ''$Scope'' due to namespace lookup rules).  Its lifetime ends with the complete interpretation of the current input line in the interactive shell, or complete execution of the script started in [[#calling|batch mode]].  This guard is used, among others, by [[:general#preferences|prefer_now]] commands, as well as for purging temporary properties from the objects.    .. There is one session-scope guard dwelling in the variable ''$Polymake::Scope'' (aka ''$Scope'' due to namespace lookup rules).  Its lifetime ends with the complete interpretation of the current input line in the interactive shell, or complete execution of the script started in [[#calling|batch mode]].  This guard is used, among others, by [[:general#preferences|prefer_now]] commands, as well as for purging temporary properties from the objects.
- 
-=== Classes === 
  
 ===== Most important interfaces ===== ===== Most important interfaces =====
Line 195: Line 197:
 === Name and Description === === Name and Description ===
  
-The name is supposed to be a short string distinguishing the object from all others, but its uniqueness is neither enforced nor checked.  The name appears in the drawings, where appropriate, as part of drawable object identifiers (in visualization engines supporting it, e.g. povray or javaview).  The name is also included as the stem into the default file name if the object is to be stored in a file.+The name is supposed to be a short string distinguishing the object from all others, but its uniqueness is only required for multiple subobjects (described further below).  The name appears in the drawings, where appropriate, as part of drawable object identifiers (in visualization engines supporting it, e.g. povray or javaview).  The name is also included as the stem into the default file name if the object is to be stored in a file.
  
 The name is optional; however, if a unnamed new object is assigned to a non-local variable (like this: ''$p=new Polytope(...);'' or ''$c=cube(3);'' then the variable name is used as the object name too. The name is optional; however, if a unnamed new object is assigned to a non-local variable (like this: ''$p=new Polytope(...);'' or ''$c=cube(3);'' then the variable name is used as the object name too.
Line 243: Line 245:
   ? ''%%$p->take("FACETS_THRU_VERTICES", temporary, $F);%%''   ? ''%%$p->take("FACETS_THRU_VERTICES", temporary, $F);%%''
   :: creates a property temporarily.  It survives until the end of the execution cycle.  In the interactive mode, the cycle ends after the complete evaluation of the last input line; in scripting mode it is the termination of the script.  Under no circumstances can temporary values be stored in the XML file; an explicit ''save'' of the object discards the temporary values instantly.  However, please note the difference to older versions of polymake: now it's a concrete value that can be declared as temporary, while earlier it was an inherent attribute of a property.   :: creates a property temporarily.  It survives until the end of the execution cycle.  In the interactive mode, the cycle ends after the complete evaluation of the last input line; in scripting mode it is the termination of the script.  Under no circumstances can temporary values be stored in the XML file; an explicit ''save'' of the object discards the temporary values instantly.  However, please note the difference to older versions of polymake: now it's a concrete value that can be declared as temporary, while earlier it was an inherent attribute of a property.
-  ? ''%%$p->remove("POINTS_IN_FACETS");%%'' +  ? ''%%$p->remove("POINTS_IN_FACETS", ...);%%'' 
-  :: removes a property from the object.  A //mutable// property can be removed at any time.  A normal property may be removed only if the object contains enough data to reconstruct this property later.  A production rule may remove a property only if it is one of its sources.+  :: removes one or more properties from the object.  A //mutable// property can be removed at any time.  A normal property may be removed only if the object contains enough data to reconstruct this property later.  A production rule may remove a property only if it is one of its sources.
  
 Methods ''give'' and ''take'' do exactly the same as the operations using the unquoted property name as a method.  The only difference lies in small additional costs for the former caused by property name lookup performed in each call.  Thus you should generally prefer the direct property-named methods unless your code must handle flexible property names. Methods ''give'' and ''take'' do exactly the same as the operations using the unquoted property name as a method.  The only difference lies in small additional costs for the former caused by property name lookup performed in each call.  Thus you should generally prefer the direct property-named methods unless your code must handle flexible property names.
Line 265: Line 267:
   ? ''%%$p->GRAPH->ADJACENCY=$a;%%''   ? ''%%$p->GRAPH->ADJACENCY=$a;%%''
   ? ''%%$p->take("GRAPH.ADJACENCY", $a);%%''   ? ''%%$p->take("GRAPH.ADJACENCY", $a);%%''
-  :: creates a property in a subobject; the same constrains apply as in the simple case above.+  :: creates a property in a subobject; the same constraints apply as in the simple case above.
   ? ''%%$p->GRAPH->remove("NODE_DEGREES");%%''   ? ''%%$p->GRAPH->remove("NODE_DEGREES");%%''
   ? ''%%$p->remove("GRAPH.NODE_DEGREES");%%''   ? ''%%$p->remove("GRAPH.NODE_DEGREES");%%''
-  :: removes a property in a subobject.+  :: removes a property in a subobject.  The same restriction apply here: either the property must be //mutable//, or the object must have enough data to reconstruct it later. 
 +  ? ''%%$p->remove("GRAPH")%%'' 
 +  :: removes the complete subobject.  The restriction about being mutable or reconstructible applies to all properties of this subobject, also recursively to all deeper subobjects.
  
 One can also create a subobject property from a complete object like this: One can also create a subobject property from a complete object like this:
Line 278: Line 282:
 === Multiple subobjects === === Multiple subobjects ===
  
-While normal (singular) subobjects are treated much like other properties, multiple subobjects require special methods capable of choosing the desired instance or iterating over them all.+While normal (singular) subobjects are treated much like other properties, multiple subobjects require special methods capable of choosing the desired instance or iterating over them all.  Multiple subobject instances must have non-empty, unique names; uniqueness (among all instances of the same property in one parent object) is enforced. 
 + 
 +== Construction of multiple subobjects ==
  
 The method ''add'' is used for creating and/or attaching multiple subobjects to the parent.  It has several flavors, resembling the construction modes of top-level objects: The method ''add'' is used for creating and/or attaching multiple subobjects to the parent.  It has several flavors, resembling the construction modes of top-level objects:
  
   ? ''%%$lp=$p->add("LP");%%''   ? ''%%$lp=$p->add("LP");%%''
-  :: creates a new empty subobject to be consequently filled with initial properties+  :: creates a new empty subobject to be consequently filled with initial properties.  Its name will be of the form "unnamed#NN".
   ? ''%%$lp=$p->add("LP", LINEAR_OBJECTIVE => Vector, ...);%%''   ? ''%%$lp=$p->add("LP", LINEAR_OBJECTIVE => Vector, ...);%%''
   :: creates a new subobject and initializes it with given properties. No further immutable properties can be added to it afterwards.   :: creates a new subobject and initializes it with given properties. No further immutable properties can be added to it afterwards.
 +  ? ''%%$lp=$p->add("LP", "name", ...);%%''
 +  :: creates a new subobject with a desired name.  If there is already another sibling subobject with identical name, the name will be amended with a suffix #NN in order to ensure its uniqueness.
   ? ''%%$my_tr=$p->add("TRIANGULATION", $tr);%%''   ? ''%%$my_tr=$p->add("TRIANGULATION", $tr);%%''
   :: takes an existing object ''$tr'' and attach it as a subobject.  Usually, the object ''$tr'' itself will become a property of ''$p'', but in some cases, as explained above, a copy will be created.  The return value is always the child subobject of ''$p''.   :: takes an existing object ''$tr'' and attach it as a subobject.  Usually, the object ''$tr'' itself will become a property of ''$p'', but in some cases, as explained above, a copy will be created.  The return value is always the child subobject of ''$p''.
Line 293: Line 301:
 In any flavor, you can add an option ''temporary'' directly after the name of the property, specifying that the subobject is to be added temporarily. In any flavor, you can add an option ''temporary'' directly after the name of the property, specifying that the subobject is to be added temporarily.
  
-Having added a subobject, you can retrieve it later using numerous search criteria.  Some of the retrieval methods can even create new subobject on the fly, as described in the corresponding remarks:+**Note:** For the sake of convenience, the very first instance of multiple subobject may be created in the same manner as singular subobjects, that is, using ''take()'', providing initial property values in the constructor list, or assigning values to property access methods during the initialization phase. 
  
 +== Examining multiple subobjects ==
 +
 +Having added a subobject instance, you can retrieve it later using numerous search criteria.  Some of the retrieval methods can even create a new subobject on the fly, as described in the corresponding remarks:
 +
 +  ? ''%%$p->LP%%''
 +  ? ''%%$p->give("LP.MAXIMAL_VALUE")%%''
 +  :: access the default subobject instance, that is, a subobject with ordinal number 0.  If no subobject of the requested type exists and there are production rules creating new instances, plans the cheapest rule chain and returns a new instance.
   ? ''%%$p->LP->[$i]%%''   ? ''%%$p->LP->[$i]%%''
-  :: select the subobject by its ordinal number+  ? ''%%$p->give("LP")->[$i]%%'' 
 +  :: select the subobject instance by its ordinal number
   ? ''%%$p->LP("name")%%''   ? ''%%$p->LP("name")%%''
   ? ''%%$p->give("LP", "name")%%''   ? ''%%$p->give("LP", "name")%%''
   :: select the subobject by its name; if no match found, returns ''undef''   :: select the subobject by its name; if no match found, returns ''undef''
 +  ? ''%%$p->LP(sub { $_->MAXIMAL_VALUE >= 0 })%%''
 +  ? ''%%$p->give("LP", sub { $_->MAXIMAL_VALUE >= 0 })%%''
 +  :: select the first subobject satisfying the filter expression; if none satisfies the criteria, returns ''undef''. The subobject under test is passed in the variable ''$_'' .
   ? ''%%$p->SCHLEGEL_DIAGRAM(FACET => 1, ...)%%''   ? ''%%$p->SCHLEGEL_DIAGRAM(FACET => 1, ...)%%''
   ? ''%%$p->give("SCHLEGEL_DIAGRAM", FACET => 1)%%''   ? ''%%$p->give("SCHLEGEL_DIAGRAM", FACET => 1)%%''
Line 305: Line 324:
   ? ''%%$p->give("SCHLEGEL_DIAGRAM", FACET => 1, temporary)%%''   ? ''%%$p->give("SCHLEGEL_DIAGRAM", FACET => 1, temporary)%%''
   :: the same as above, but in the non-match case the new subobject will be created temporarily   :: the same as above, but in the non-match case the new subobject will be created temporarily
-  ? ''%%$p->SCHLEGEL_DIAGRAM%%'' 
-  ? ''%%$p->give("SCHLEGEL_DIAGRAM")%%'' 
-  :: if there are many instances, retrieves a random one; if none exists and there are suitable production rules, a new subobject will be created. 
   ? ''%%foreach $lp (@{$p->LP}) { ... }%%''   ? ''%%foreach $lp (@{$p->LP}) { ... }%%''
-  :: iterates over all subobjects +  :: iterates over all existing instances 
-  ? ''%%$p->remove($lp);%%'' +  ? ''%%$p->LP->list_names%%'' 
-  :: removes the given instance of a multiple subobject.  Please note the difference to the operation ''%%$p->remove("LP")%%'', which would remove //all// subobjects attached as a LP property.+  :: returns the list of names of all existing instances 
 +  ? ''%%$p->LP(...)->select_as_default%%'' 
 +  :: permanently makes the selected instance the default one, which simply means moving it at the front of the instance list 
 +  ? ''%%$p->LP(...)->select_as_default_now%%'' 
 +  :: temporarily makes the selected instance the default one; the change is reverted at the end of the current user cycle 
 + 
 +== Removing multiple subobjects == 
 + 
 +  ? ''%%$p->remove($lp, ...);%%'' 
 +  :: removes the given instance of a multiple subobject.  Several instances may be removed at once. 
 +  ? ''%%$p->remove("LP");%%'' 
 +  .. removes //all// subobjects attached as a LP property.
  
 === Rule planning === === Rule planning ===
Line 360: Line 387:
   :: gets a type of an Object   :: gets a type of an Object
   ? ''%%$t=typeof Polytope<Rational>;%%''   ? ''%%$t=typeof Polytope<Rational>;%%''
-  :: constructs a literally specified type+  :: constructs a literally specified type; it must be known in the current application.
   ? ''%%$t=Polytope->type($t2->type);%%''   ? ''%%$t=Polytope->type($t2->type);%%''
   :: constructs a type with dynamic parameters   :: constructs a type with dynamic parameters
 +  ? ''%%$t=application->eval_type($string);%%''
 +  :: constructs a type specified by its full name in string form, e.g. ''%%$string="Polytope<Rational>";%%''
 +  .. The type must be known in the current application.
 +  ? ''%%$t=application("appname")->eval_type($string);%%''
 +  :: constructs a type defined in the specified application.
   ? ''%%$t->isa("Polytope")%%''   ? ''%%$t->isa("Polytope")%%''
   ? ''%%$t->isa($t2)%%''   ? ''%%$t->isa($t2)%%''
Line 390: Line 422:
   print map { "$_\n" } $s->list;   print map { "$_\n" } $s->list;
  
-==== Visualization ==== 
  
 ===== Using C++ objects ===== ===== Using C++ objects =====
  
 +For many C++ classes from polymake template library, as well as for some classes from STL and third-party libraries bundled with polymake, convenient perl wrappers are provided, allowing to work with the objects directly from perl code.  The following gives a rough overview of the most common use cases; to get the complete picture, please refer to the release documentation and study the rulefiles, especially common::basic_types and other ones included there.  Starting with this examples, you will be able to easily define further wrappers for your favorite C++ classes and functions in your own extensions.
 +
 +The first and most important common design principle of all wrappers for C++ objects which you should always keep in mind is that they appear as references on the perl side.  This means in particular that an assignment of two perl variables ''$a=$b;'' does not involve copying of C++ objects: you still have a single object, just now hanging on two references.  If you change the object via ''$a'', you will see these changes via ''$b'' too.  However, this does not apply to //all// changes.  For classes with overloaded arithmetic operators like ++ or +=, perl automagically (it's not a typo, this word indeed occurs in the perl documentation) clones the object to be changed prior to executing the operator.  Thus be careful and watch out.  If in doubt, you can always create an explicit copy calling the copy constructor: ''$a=new TYPE($b);''
 +
 +==== Construction ====
 +
 +Except for few special cases, all wrappers for C++ classes are equipped with a set of standard constructors.  Besides the already mentioned copy constructor, these are the default constructor ''new TYPE()'' and the parsing constructor ''%%new TYPE("string")%%''
 +taking a printable representation of the value.  Container types like Array or Vector also have a list constructor ''%%new TYPE([ value, value, ... ])%%'' taking an arbitrary list of elements.  If you definitely know that more than one element is going to be passed, you can also omit the square brackets.  The same applies for composite types like Pair, they always have a constructor taking the list of initializers of their members.  Furthermore, type-specific constructors may be defined in the [[reference:rulefiles#property_type_scope_definitions|rulefiles]].
 +
 +==== Common operations ====
 +
 +Almost all C++ classes wrapped in polymake have an automatic conversion to character strings, allowing to print them directly to the screen or write into text files.  Also almost all classes have comparison operators ''%%== !=%%'' , and if they support full ordering, all other comparison operators ''%%< > <= >=%%'' as well.
 +
 +==== Numbers ====
 +
 +The GMP-based classes Integer and Rational behave much like normal numeric scalars.  All possible arithmetic operators are overloaded, as well as the most common operations like ''gcd'' and ''lcm''.
 +
 +Literal integer constants having more digits than fit into a normal scalar (18 on a 64-bit platform) are automatically converted to Integer objects; a fraction of two literal integers like ''1/2'' is automatically converted to a Rational object.  The special //infinite// values can be obtained by calling static functions ''Integer::inf()'' and ''Rational::inf()''.
 +
 +==== Vectors ====
 +
 +Container classes like Array or Vector support iteration in a loop:
 +  foreach my $elem (@{$v}) {
 +    ...
 +  }
 +and in all iterating functions like ''map'' and ''grep''.
 +
 +As far as the underlying C++ class supports random access to its elements, it is available as a normal array access in both flavors, scalar and list:
 +  $v->[$i]
 +  @{$v}[$i..$j]
 +
 +Unless the C++ objects are write-protected (which normally happens to properties of "big" objects), the elements retrieved via random access may also be modified by assignment, overloaded operators, etc.
 +
 +Sparse containers like SparseVector behave like dense containers when iterated this way, that is, they expose all implicit zeroes in the gaps as if they were physically stored there.  If you want to iterate over non-zero elements only, you must create an iterator object and dereference it like a normal scalar reference.  Here is an excerpt from an interactive session:
 +
 +  > $v=new SparseVector<Rational>([0, 1/2, 0, 0, 3/4, -5/6, 0]);
 +  > print $v->dim;   # dimension
 +  7
 +  > print $v->size;  # number of non-zero elements
 +  3
 +  > print "@{$v}"    # pretends to be dense here
 +  0 1/2 0 0 3/4 -5/6 0
 +  > for ($iter = entire($v); $iter; ++$iter) { print "[", $iter->index, "]=", $$iter, "\n" }
 +  [1]=1/2
 +  [4]=3/4
 +  [5]=-5/6
 +  > print $v->[2];   # an implicit zero element
 +  0
 +  > ++$v->[2];       # now it becomes a physical 1
 +  > print "@{$v}"
 +  0 1/2 1 0 3/4 -5/6 0
 +
 +Classes Vector and SparseVector should only be used with numerical element types, because they overload all possible arithmetic operators.  Class Array is a normal random-access container, which does not impose any requirements on the type of its elements.
 +
 +==== Matrices ====
 +
 +Matrix<Element> and SparseMatrix<Element> behave like two-dimensional arrays, stored in the column-changes-first order.  They can be constructed from a two-dimensional list of elements, or from a list of vectors (taken as rows), or from a multi-line text string, or even from a file input iterator delivering the rows in printable form:
 +  $m=new Matrix<Rational>([[11, 12], [21, 22]]);
 +  $m=new Matrix<Rational>($vec1, $vec2);
 +  $m=new Matrix<Rational>(<<"_END_");
 +  11 12
 +  21 22
 +  _END_
 +  open F, "<file.txt";
 +  $m=new Matrix(<F>);
 +
 +Single elements can be accessed and, if permitted, modified via ''%%$m->($i, $j)%%'' .  Single rows and columns can be dealt with like Vectors: ''%%$m->row($i); $m->col($j);%%''  To iterate over all rows and columns, use functions:
 +  foreach (@{rows($m)}) { ... }
 +  foreach (@{cols($m)}) { ... }
 +
 +Method ''%%$m->minor(row_set, column_set)%%'' allows to work with a minor like with a separate matrix object.  As arguments for selecting rows and columns you can pass any containers with integer indices (including plain perl arrays), their complements (use a prefix operator ''~'' for this), or a special constant ''All''.
 +
 +Block matrices can be built together from several matrix and vector objects using operator ''/'' for row-wise concatenation, operator ''|'' for column-wise concatenation, and function ''diag(x,y)'' for block-diagonal matrices.
 +
 +Basic linear algebra operations are available as functions ''transpose'', ''inv'', ''det'', ''lin_solve'', ''basis'', etc.
 +
 +==== Associative Containers ====
 +
 +Class Map<Key,Value> behaves much like a hash table.  You can retrieve and modify its elements:
 +  $m->{$key}=$value;
 +  exists $m->{$key}
 +  delete $m->{$key}
 +and iterate over it using ''each'', ''keys'', and ''values''.
 +
 +Class Set<Element> also supports ''exists'' and ''delete'' operators, but otherwise behaves like a normal one-dimensional container without random access.  It also offers set-theoretic operations like union, intersection, difference, and symmetric difference, masqueraded as overloaded operators.
 +
 +Class IncidenceMatrix behaves like a two-dimensional sparse matrix.  It supports the same access patterns as if it were a SparseMatrix<Bool>, while its rows and columns have the Set-like interface.
 +
 +==== Complex objects ====
 +
 +Some more complex objects like Graphs or Polynomials are also wrapped for directed use from perl code.  Please refer to the release documentation and the [[user_guide:start|tutorials]] for more details.
 ===== Debugging ===== ===== Debugging =====
  
-You can use the perl debugger to debug your scripts.  The only problem is how to set the initial breakpoint into your script: When you start polymake under the debugger <code>perl -dS polymake</code> not only your script, but also all the applications and even a part of the polymake core modules are still not loaded.  Stepping through polymake bootstrap is **very** tedious.  A much more convenient way is to insert a call to ''stop_here();'' at the very beginning of your script.  This little function does nothing but prints its arguments to STDOUT.  And it has a big advantage to be defined directly in the polymake main script, so you can just enter+You can use the perl debugger to debug your scripts.  The only problem is how to set the initial breakpoint into your script: When you start polymake under the debugger <code>perl -dS polymake</code> not only your script, but also all the applications and even some of the polymake core modules are still not loaded.  Stepping through polymake bootstrap is **very** tedious.  A much more convenient way is to insert a call to ''stop_here();'' at the very beginning of your script.  This little function does nothing but prints its arguments to STDOUT.  And it has a big advantage to be defined directly in the polymake main script, so you can just enter
   b stop_here   b stop_here
   c   c