{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial on Properties and Rules\n",
    "\n",
    "\n",
    "### Properties\n",
    "\n",
    "Each object has a list of properties of various types.  When an object is 'born' it comes with an initial list of properties, and all other properties will be derived from those.  Here we discuss an example from the `polytope` application.  The following creates a 3-dimensional cube.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$c=cube(3);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "The object is defined by calling some function, but how does one find out what the initial set of properties is?  Of course, one could look at the source code, but the following is the direct way from the interpreter.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AMBIENT_DIM, DIM, FACETS, VERTICES_IN_FACETS, BOUNDED\n",
       "\n"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print join(\", \", $c->list_properties);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "The relevant method, which is defined for any `polymake` object, is called `list_properties`.  It returns an array of strings.  The extra code is just there to print this list nicely.  The object is changed if we ask for a property which has not been computed before.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1 -1 -1 -1\n",
       "1 1 -1 -1\n",
       "1 -1 1 -1\n",
       "1 1 1 -1\n",
       "1 -1 -1 1\n",
       "1 1 -1 1\n",
       "1 -1 1 1\n",
       "1 1 1 1\n",
       "    \n"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print $c->VERTICES;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AMBIENT_DIM, DIM, FACETS, VERTICES_IN_FACETS, BOUNDED, N_VERTICES, FEASIBLE, SIMPLE, SIMPLE_POLYHEDRON, AFFINE_HULL, VERTICES\n",
       "\n"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print join(\", \", $c->list_properties);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "The property `VERTICES` was added, but also a few others.  These were computed on the way.  Which properties show up after some computation depends on the rules applied.  What is the set of properties that *can* be computed for a given object?  This depends on your set of rule valid for the object in question.  Here is a short sequence of commands which lets you find out.  The properties listed come in alphabetical ordering.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "$t=$c->type;\n",
    "print join(\", \", sorted_uniq(sort { $a cmp $b } map { keys %{$_->properties} } $t, @{$t->super}));"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "Instead of showing the (lengthy) enumeration have a look at the [documentation](release_docs/latest/polytope.html) for a complete list of properties known for objects of the application `polytope`.\n",
    "\n",
    "\n",
    "### Schedules\n",
    "\n",
    "[beware: output from branch \"cones\"]\n",
    "\n",
    "Let us restart with our cube from scratch.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "POLYTOPE_AMBIENT_DIM, POLYTOPE_DIM, FACETS, VERTICES_IN_FACETS, BOUNDED\n",
       "\n"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$c=cube(3);\n",
    "print join(\", \", $c->list_properties);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Suppose we want to see which sequence of rules leads to the computation of the F_VECTOR.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "HASSE_DIAGRAM : RAYS_IN_FACETS\n",
       "F_VECTOR : HASSE_DIAGRAM\n",
       "\n"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$schedule=$c->get_schedule(\"F_VECTOR\");\n",
    "print join(\"\\n\", $schedule->list);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Applying the schedule to the object yields the same as asking for the property right away.\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "POLYTOPE_AMBIENT_DIM, POLYTOPE_DIM, FACETS, VERTICES_IN_FACETS, BOUNDED, HASSE_DIAGRAM, F_VECTOR\n",
       "\n"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "$schedule->apply($c);\n",
    "print join(\", \", $c->list_properties);"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is possible to apply the same schedule to several polytopes.  This is useful for a slight speed up in the total time of the computation.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "polymake",
   "language": "polymake",
   "name": "polymake"
  },
  "language_info": {
   "codemirror_mode": "perl",
   "file_extension": ".pm",
   "mimetype": "text/x-polymake",
   "name": "polymake"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}