Commits

Volker Braun committed 9739d8c

updated polyhedron patches

Comments (0)

Files changed (6)

 trac_13638_ray_adjacency_fix.patch
 trac_11763-polyhedra_coercion_folded.2.patch
 trac_11763_fix_associahedron.patch
-trac_11763_relax_typechecks.patch
-trac_11763_remove_trailing_whitespace.patch
 trac_13312_polyhedral_neg_polar.patch
 trac12215_weak_cached_function.patch    #+SimonKing
 trac12215_segfault_fixes.patch          #+SimonKing

trac_11763-polyhedra_coercion_folded.2.patch

 # User Volker Braun <vbraun@stp.dias.ie>
 # Date 1315501129 14400
 # Node ID 72fa3dd63afb47e375297e85483bc1358eacf998
-# Parent 8be67663c8cacbbbec83d5f734a1850da478da3f
+# Parent 29434d3b8ee58b4beb9ca6a64334c6f766c9665e
 Trac #11763: Add ZZ as allowed base ring for polyhedra
 * * *
 Trac #11763: Parents for polyhedra
+* * *
+Trac #11763: relax typechecks
+
+Some plotting commands needlessly require that the
+input is a Python list. This patch relaxes typechecks
+to allow arbitrary iterables.
+* * *
+Trac #11763: remove trailing whitespace
 
 diff --git a/doc/en/reference/geometry.rst b/doc/en/reference/geometry.rst
 --- a/doc/en/reference/geometry.rst
 +++ b/doc/en/reference/geometry.rst
-@@ -25,6 +25,7 @@
+@@ -25,7 +25,9 @@
     sage/geometry/polyhedron/plot
     sage/geometry/polyhedron/base
     sage/geometry/polyhedron/base_QQ
 +   sage/geometry/polyhedron/base_ZZ
     sage/geometry/polyhedron/base_RDF
++   sage/geometry/polyhedron/face
     sage/geometry/polyhedron/backend_cdd
     sage/geometry/polyhedron/backend_ppl
+    sage/geometry/polyhedron/cdd_file_format
 diff --git a/sage/categories/all.py b/sage/categories/all.py
 --- a/sage/categories/all.py
 +++ b/sage/categories/all.py
  
  
  
-@@ -25,14 +19,12 @@
+@@ -25,22 +19,20 @@
      Base class for the cdd backend.
      """
  
          - ``vertices`` -- list of point. Each point can be specified
             as any iterable container of
             :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+-        
++
+         - ``rays`` -- list of rays. Each ray can be specified as any
+           iterable container of
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+-        
++
+         - ``lines`` -- list of lines. Each line can be specified as
+           any iterable container of
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
 @@ -51,7 +43,7 @@
          EXAMPLES::
  
              A 1-dimensional polyhedron in QQ^2 defined as the
              convex hull of 1 vertex and 1 ray
          """
-@@ -98,7 +88,7 @@
+@@ -97,8 +87,8 @@
+         computed during initialization.
  
          EXAMPLES::
-         
+-        
 -            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cddr')
++
 +            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cdd', base_ring=QQ)
              sage: '_H_adjacency_matrix' in p.__dict__
              False
              sage: p._init_facet_adjacency_matrix()
-@@ -118,7 +108,7 @@
+@@ -117,8 +107,8 @@
+         computed during initialization.
  
          EXAMPLES::
-         
+-        
 -            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cddr')
++
 +            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cdd', base_ring=QQ)
              sage: '_V_adjacency_matrix' in p.__dict__
              False
              sage: p._init_vertex_adjacency_matrix()
-@@ -138,7 +128,7 @@
+@@ -137,8 +127,8 @@
+         and initialize ourselves with the output.
  
          TESTS::
-         
+-        
 -            sage: p = Polyhedron(vertices = [[0,0,0],[1,0,0],[0,1,0],[0,0,1]], backend='cddr')
++
 +            sage: p = Polyhedron(vertices = [[0,0,0],[1,0,0],[0,1,0],[0,0,1]], backend='cdd', base_ring=QQ)
              sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation
              sage: s = cdd_Vrepresentation('rational', [[0,0,1],[0,1,0],[1,0,0]], [], [])
              sage: p._init_from_cdd_input(s)
-@@ -168,13 +158,14 @@
+@@ -162,19 +152,20 @@
+         Initialize ourselves with the output from cdd.
+ 
+         TESTS::
+- 
++
+             sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation
+             sage: s = cdd_Vrepresentation('rational',[[0,0],[1,0],[0,1],[1,1]], [], [])
              sage: from subprocess import Popen, PIPE
              sage: cdd_proc = Popen(['cdd_both_reps_gmp', '--all'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
              sage: ans, err = cdd_proc.communicate(input=s)
  
          # nested function
          def expect_in_cddout(expected_string):
-@@ -219,22 +210,22 @@
+@@ -219,37 +210,37 @@
              lines = cdd_linearities()
              expect_in_cddout('begin')
              l = cddout.pop(0).split()
 +                parent._make_Vertex(self, [0] * self.ambient_dim())
              self._Vrepresentation = tuple(self._Vrepresentation)
              expect_in_cddout('end')
-         
-@@ -243,13 +234,13 @@
+-        
++
+         if find_in_cddout('H-representation'):
+             self._Hrepresentation = []
              equations = cdd_linearities()
              expect_in_cddout('begin')
              l = cddout.pop(0).split()
              self._Hrepresentation = tuple(self._Hrepresentation)
              expect_in_cddout('end')
  
+@@ -258,7 +249,7 @@
+             l = cddout.pop(0).split()
+             assert l[2] == ':', "Not a line of the adjacency data?"
+             return [int(i)-1 for i in l[3:]]
+-        
++
+         if find_in_cddout('Vertex graph'):
+             n = len(self._Vrepresentation);
+             if suppressed_vertex:
+@@ -285,7 +276,7 @@
+                     self._V_adjacency_matrix[n-1,i] = 1
+             self._V_adjacency_matrix.set_immutable()
+             expect_in_cddout('end')
+-    
++
+         if find_in_cddout('Facet graph'):
+             n = len(self._Hrepresentation);
+             self._H_adjacency_matrix = matrix(ZZ, n, n, 0)
 @@ -306,16 +297,19 @@
  
      INPUT:
 +      :class:`~sage.geometry.polyhedron.parent.Polyhedra`.
  
 -    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
+-        
+-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
 +    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
-         
--    - ``Hrep`` -- a list ``[ieqs, eqns]``.
++
 +    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
  
      EXAMPLES::
          """
          The Python constructor.
  
-@@ -332,12 +326,12 @@
+@@ -331,14 +325,14 @@
+         data.
  
          TESTS::
-         
+-        
 -            sage: p = Polyhedron(backend='cddr')
++
 +            sage: p = Polyhedron(backend='cdd', base_ring=QQ)
              sage: type(p)
 -            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedron_QQ_cdd'>
              sage: TestSuite(p).run()
          """
 -        Polyhedron_cdd.__init__(self, ambient_dim, Vrep, Hrep, **kwds)
+-    
 +        Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
-     
++
  
  #########################################################################
+ class Polyhedron_RDF_cdd(Polyhedron_cdd, Polyhedron_RDF):
 @@ -349,21 +343,23 @@
  
      - ``ambient_dim`` -- integer. The dimension of the ambient space.
  
 -    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
+-        
+-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
 +    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
-         
--    - ``Hrep`` -- a list ``[ieqs, eqns]``.
++
 +    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
  
      EXAMPLES::
          A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 3 vertices
      """
      _cdd_type = 'real'
-     
+-    
++
      _cdd_executable = 'cdd_both_reps'
  
 -    def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
          """
          The Python constructor.
  
-@@ -372,10 +368,10 @@
+@@ -371,11 +367,11 @@
+         data.
  
          TESTS::
-         
+-        
 -            sage: p = Polyhedron(backend='cddf')
++
 +            sage: p = Polyhedron(backend='cdd', base_ring=RDF)
              sage: type(p)
 -            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedron_RDF_cdd'>
              sage: TestSuite(p).run()
          """
 -        Polyhedron_cdd.__init__(self, ambient_dim, Vrep, Hrep, **kwds)
+-    
 +        Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
-     
++
 diff --git a/sage/geometry/polyhedron/backend_ppl.py b/sage/geometry/polyhedron/backend_ppl.py
 --- a/sage/geometry/polyhedron/backend_ppl.py
 +++ b/sage/geometry/polyhedron/backend_ppl.py
      INPUT:
  
 -    - ``ambient_dim`` -- integer. The dimension of the ambient space.
--
++    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
+ 
 -    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
-+    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
-         
+-        
 -    - ``Hrep`` -- a list ``[ieqs, eqns]``.
 +    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
  
      EXAMPLES::
  
-@@ -40,14 +33,12 @@
+@@ -40,22 +33,20 @@
          sage: TestSuite(p).run()
      """
  
          - ``vertices`` -- list of point. Each point can be specified
             as any iterable container of
             :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
-@@ -63,37 +54,46 @@
+-        
++
+         - ``rays`` -- list of rays. Each ray can be specified as any
+           iterable container of
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+-        
++
+         - ``lines`` -- list of lines. Each line can be specified as
+           any iterable container of
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+@@ -63,38 +54,47 @@
          EXAMPLES::
  
              sage: p = Polyhedron(backend='ppl')
          Construct polyhedron from H-representation data.
  
          INPUT:
--
+ 
 -        - ``ambient_dim`` -- integer. The dimension of the ambient space.
-         
+-        
          - ``ieqs`` -- list of inequalities. Each line can be specified
            as any iterable container of
-@@ -106,29 +106,31 @@
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+@@ -106,33 +106,35 @@
          EXAMPLES::
  
              sage: p = Polyhedron(backend='ppl')
      def _init_Vrepresentation_from_ppl(self, minimize):
          """
          Create the Vrepresentation objects from the ppl polyhedron.
+-        
++
+         EXAMPLES::
+ 
+             sage: p = Polyhedron(vertices=[(0,1/2),(2,0),(4,5/6)],
 @@ -150,23 +152,26 @@
          """
          self._Vrepresentation = []
  
  
  #########################################################################
-@@ -83,13 +78,14 @@
+@@ -83,18 +78,19 @@
  
  
  #########################################################################
  
      - ``Vrep`` -- a list `[vertices, rays, lines]`` or ``None``. The
        V-representation of the polyhedron. If ``None``, the polyhedron
+       is determined by the H-representation.
+-        
++
+     - ``Hrep`` -- a list `[ieqs, eqns]`` or ``None``. The
+       H-representation of the polyhedron. If ``None``, the polyhedron
+       is determined by the V-representation.
 @@ -107,7 +103,7 @@
          sage: TestSuite(p).run()
      """
          """
          Initializes the polyhedron.
  
-@@ -118,27 +114,23 @@
+@@ -118,35 +114,31 @@
  
              sage: p = Polyhedron()    # indirect doctests
          """
          - ``vertices`` -- list of point. Each point can be specified
             as any iterable container of
             :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+-        
++
+         - ``rays`` -- list of rays. Each ray can be specified as any
+           iterable container of
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
+-        
++
+         - ``lines`` -- list of lines. Each line can be specified as
+           any iterable container of
+           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
 @@ -155,7 +147,7 @@
  
              sage: p = Polyhedron()
          - ``ieqs`` -- list of inequalities. Each line can be specified
            as any iterable container of
            :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
-@@ -183,48 +173,47 @@
+@@ -183,59 +173,55 @@
  
              sage: p = Polyhedron()
              sage: from sage.geometry.polyhedron.base import Polyhedron_base
          """
          Compute the facet adjacency matrix in case it has not been
          computed during initialization.
-@@ -232,10 +221,7 @@
+ 
          EXAMPLES::
-         
+-        
++
              sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
 -            sage: '_H_adjacency_matrix' in p.__dict__
 -            False
              [0 1 1]
              [1 0 1]
              [1 1 0]
-@@ -256,11 +242,9 @@
+@@ -256,22 +242,17 @@
              Hrep = face.element.ambient_Hrepresentation()
              if len(Hrep) == 2:
                  set_adjacent(Hrep[0], Hrep[1])
          """
          Compute the vertex adjacency matrix in case it has not been
          computed during initialization.
-@@ -268,10 +252,7 @@
+ 
          EXAMPLES::
-         
+-        
++
              sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
 -            sage: '_V_adjacency_matrix' in p.__dict__
 -            False
              [0 1 1]
              [1 0 1]
              [1 1 0]
-@@ -313,168 +294,112 @@
+@@ -321,168 +302,112 @@
              Vrep = face.element.ambient_Vrepresentation()
              if len(Vrep) == 2:
                  set_adjacent(Vrep[0], Vrep[1])
      def _is_subpolyhedron(self, other):
          """
          Test whether ``self`` is a (not necessarily strict)
-@@ -497,12 +422,9 @@
+@@ -505,19 +430,16 @@
              sage: Q._is_subpolyhedron(P)
              True
          """
  
      def plot(self, **kwds):
          """
-@@ -533,10 +455,8 @@
+         Return a graphical representation.
+ 
+         INPUT:
+-        
++
+         - ``**kwds`` -- optional keyword parameters.
+ 
+         See :func:`render_2d`, :func:`render_3d`, :func:`render_4d`
+@@ -541,10 +463,8 @@
          raise NotImplementedError('Plotting of '+str(self.ambient_dim())+
                                    '-dimensional polyhedra not implemented')
  
      def _repr_(self):
          """
          Return a description of the polyhedron.
-@@ -545,10 +465,10 @@
+@@ -553,10 +473,10 @@
  
              sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]])
              sage: poly_test._repr_()
          """
          desc = ''
          if self.n_vertices()==0:
-@@ -556,8 +476,10 @@
+@@ -564,8 +484,10 @@
          else:
              desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron'
          desc += ' in '
          desc += '^' + repr(self.ambient_dim())
  
          if self.n_vertices()>0:
-@@ -582,7 +504,6 @@
+@@ -573,14 +495,14 @@
+             desc += repr(self.n_vertices())
+             if self.n_vertices()==1: desc += ' vertex'
+             else:                    desc += ' vertices'
+-            
++
+             if self.n_rays()>0:
+                 if self.n_lines()>0: desc += ", "
+                 else:                desc += " and "
+                 desc += repr(self.n_rays())
+                 if self.n_rays()==1: desc += ' ray'
+                 else:                desc += ' rays'
+-                
++
+             if self.n_lines()>0:
+                 if self.n_rays()>0: desc += ", "
+                 else:               desc += " and "
+@@ -590,7 +512,6 @@
  
          return desc
  
      def cdd_Hrepresentation(self):
          """
          Write the inequalities/equations data of the polyhedron in
-@@ -610,13 +531,16 @@
+@@ -618,18 +539,21 @@
          try:
              cdd_type = self._cdd_type
          except AttributeError:
      def cdd_Vrepresentation(self):
          """
          Write the vertices/rays/lines data of the polyhedron in cdd's
-@@ -644,14 +568,18 @@
+         V-representation format.
+-        
++
+         OUTPUT:
+ 
+         A string. If you save the output to filename.ext then you can
+@@ -652,14 +576,18 @@
          try:
              cdd_type = self._cdd_type
          except AttributeError:
      def n_equations(self):
          """
          Return the number of equations. The representation will
-@@ -664,13 +592,9 @@
+@@ -672,13 +600,9 @@
              sage: p.n_equations()
              1
          """
      def n_inequalities(self):
          """
          Return the number of inequalities. The representation will
-@@ -682,29 +606,16 @@
+@@ -690,29 +614,16 @@
              sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]])
              sage: p.n_inequalities()
              3
      def n_vertices(self):
          """
          Return the number of vertices. The representation will
-@@ -716,14 +627,9 @@
+@@ -724,14 +635,9 @@
              sage: p.n_vertices()
              2
          """
      def n_rays(self):
          """
          Return the number of rays. The representation will
-@@ -735,14 +641,9 @@
+@@ -743,14 +649,9 @@
              sage: p.n_rays()
              1
          """
      def n_lines(self):
          """
          Return the number of lines. The representation will
-@@ -754,12 +655,7 @@
+@@ -762,12 +663,7 @@
              sage: p.n_lines()
              1
          """
  
      def Hrepresentation(self, index=None):
          """
-@@ -785,7 +681,7 @@
+@@ -775,29 +671,29 @@
+         either an inequality or a equation.
+ 
+         INPUT:
+-        
++
+         - ``index`` -- either an integer or ``None``.
+ 
+         OUTPUT:
+-        
++
+         The optional argument is an index in
+         `0...n_Hrepresentations()`. If present, the H-representation
+         object at the given index will be returned. Without an
+         argument, returns the list of all H-representation objects.
+ 
+         EXAMPLES::
+-        
++
+             sage: p = polytopes.n_cube(3)
+             sage: p.Hrepresentation(0)
+             An inequality (0, 0, -1) x + 1 >= 0
              sage: p.Hrepresentation(0) == p.Hrepresentation() [0]
              True
          """
              return self._Hrepresentation
          else:
              return self._Hrepresentation[index]
+-            
++
+ 
+     def Hrep_generator(self):
+         """
 @@ -805,7 +701,7 @@
+         (inequalities or equations).
+ 
+         EXAMPLES::
+-        
++
+             sage: p = polytopes.n_cube(3)
+             sage: p.Hrep_generator().next()
+             An inequality (0, 0, -1) x + 1 >= 0
+@@ -813,7 +709,7 @@
          for H in self.Hrepresentation():
              yield H
  
      def n_Hrepresentation(self):
          """
          Return the number of objects that make up the
-@@ -825,7 +721,6 @@
+@@ -833,18 +729,17 @@
          """
          return len(self.Hrepresentation())
  
      def Vrepresentation(self, index=None):
          """
          Return the objects of the V-representation. Each entry is
-@@ -850,12 +745,12 @@
+         either a vertex, a ray, or a line.
+ 
+         INPUT:
+-        
++
+         - ``index`` -- either an integer or ``None``.
+ 
+         OUTPUT:
+-        
++
+         The optional argument is an index in
+         `0...n_Vrepresentation()`. If present, the V-representation
+         object at the given index will be returned. Without an
+@@ -858,12 +753,12 @@
              sage: p.Vrepresentation(0) == p.Vrepresentation() [0]
              True
          """
      def n_Vrepresentation(self):
          """
          Return the number of objects that make up the
-@@ -875,7 +770,6 @@
+@@ -883,7 +778,6 @@
          """
          return len(self.Vrepresentation())
  
      def Vrep_generator(self):
          """
          Returns an iterator over the objects of the V-representation
-@@ -893,9 +787,8 @@
+@@ -901,9 +795,8 @@
          for V in self.Vrepresentation():
              yield V
  
          Return the list of face indices (i.e. indices of
          H-representation objects) and the indices of faces adjacent to
          them.
-@@ -910,6 +803,10 @@
+@@ -918,6 +811,10 @@
  
              sage: p = polytopes.permutahedron(4)
              sage: p.facial_adjacencies()[0:3]
              [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]]
              sage: f0 = p.Hrepresentation(0)
              sage: f0.index() == 0
-@@ -918,6 +815,8 @@
+@@ -926,6 +823,8 @@
              sage: p.facial_adjacencies()[0] == f0_adjacencies
              True
          """
          try:
              return self._facial_adjacencies
          except AttributeError:
-@@ -927,7 +826,6 @@
+@@ -935,11 +834,10 @@
                    ] for h in self.Hrepresentation() ]
              return self._facial_adjacencies
  
      def facial_incidences(self):
          """
          Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`.
-@@ -949,6 +847,9 @@
+-        
++
+         .. NOTE::
+ 
+             Instead of working with face/vertex indices, it is
+@@ -957,6 +855,9 @@
  
              sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]])
              sage: p.facial_incidences()
              [[0, [0, 1, 3, 4]],
               [1, [0, 1, 2]],
               [2, [0, 2, 3]],
-@@ -973,6 +874,8 @@
+@@ -981,6 +882,8 @@
              sage: p.incidence_matrix().column(4)
              (0, 1, 1, 0, 1)
          """
          try:
              return self._facial_incidences
          except AttributeError:
-@@ -982,7 +885,6 @@
+@@ -990,7 +893,6 @@
                    ] for h in self.Hrepresentation() ]
              return self._facial_incidences
  
      def vertex_adjacencies(self):
          """
          Return a list of vertex indices and their adjacent vertices.
-@@ -1007,6 +909,9 @@
+@@ -1015,6 +917,9 @@
  
              sage: permuta3 = Polyhedron(vertices = permutations([1,2,3,4]))
              sage: permuta3.vertex_adjacencies()[0:3]
              [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]]
              sage: v0 = permuta3.Vrepresentation(0)
              sage: v0.index() == 0
-@@ -1017,6 +922,8 @@
+@@ -1025,6 +930,8 @@
              sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies
              True
          """
          try:
              return self._vertex_adjacencies
          except AttributeError:
-@@ -1026,7 +933,6 @@
+@@ -1034,11 +941,10 @@
                    ] for v in self.Vrepresentation() ]
              return self._vertex_adjacencies
  
      def vertex_incidences(self):
          """
          Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`.
-@@ -1041,6 +947,9 @@
+-        
++
+         .. NOTE::
+ 
+             Instead of working with face/vertex indices, you can use
+@@ -1049,6 +955,9 @@
  
              sage: p = polytopes.n_simplex(3)
              sage: p.vertex_incidences()
              [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
              sage: v0 = p.Vrepresentation(0)
              sage: v0.index() == 0
-@@ -1048,6 +957,8 @@
+@@ -1056,6 +965,8 @@
              sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ]
              True
          """
          try:
              return self._vertex_incidences
          except AttributeError:
-@@ -1057,7 +968,6 @@
+@@ -1065,14 +976,13 @@
                    ] for v in self.Vrepresentation() ]
              return self._vertex_incidences
  
      def inequality_generator(self):
          """
          Return  a generator for the defining inequalities of the
-@@ -1085,24 +995,48 @@
+         polyhedron.
+ 
+         OUTPUT:
+-        
++
+         A generator of the inequality Hrepresentation objects.
+ 
+         EXAMPLES::
+@@ -1093,24 +1003,48 @@
              if H.is_inequality():
                  yield H
  
 +    @cached_method
      def inequalities(self):
          """
+-        Return a list of inequalities as coefficient lists.
+-
+-        .. NOTE::
+-        
+-            It is recommended to use :meth:`inequality_generator`
+-            instead to iterate over the list of :class:`Inequality`
+-            objects.
 +        Return all inequalities.
 +
 +        OUTPUT:
 +
 +        A tuple of inequalities.
-+
-+        EXAMPLES::
-+
-+            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
-+            sage: p.inequalities()[0:3]
+ 
+         EXAMPLES::
+ 
+             sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
+             sage: p.inequalities()[0:3]
 +            (An inequality (1, 0, 0) x + 0 >= 0,
 +             An inequality (0, 1, 0) x + 0 >= 0,
 +             An inequality (0, 0, 1) x + 0 >= 0)
 +
 +    def inequalities_list(self):
 +        """
-         Return a list of inequalities as coefficient lists.
- 
-         .. NOTE::
-         
--            It is recommended to use :meth:`inequality_generator`
--            instead to iterate over the list of :class:`Inequality`
--            objects.
++        Return a list of inequalities as coefficient lists.
++
++        .. NOTE::
++
 +            It is recommended to use :meth:`inequalities` or
 +            :meth:`inequality_generator` instead to iterate over the
 +            list of :class:`Inequality` objects.
- 
-         EXAMPLES::
- 
-             sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
--            sage: p.inequalities()[0:3]
++
++        EXAMPLES::
++
++            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
 +            sage: p.inequalities_list()[0:3]
              [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
              sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
              sage: ieqs[0]
              [-6, 0, 1, 1, 1]
              sage: ieqs[-1]
-@@ -1110,12 +1044,7 @@
+@@ -1118,26 +1052,25 @@
              sage: ieqs == [list(x) for x in p3.inequality_generator()]
              True
          """
  
      def ieqs(self):
          """
-@@ -1125,11 +1054,15 @@
-          
+         Deprecated. Alias for inequalities()
+ 
+         EXAMPLES::
+-         
++
              sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
              sage: p3.ieqs() == p3.inequalities()
 +            doctest:...: DeprecationWarning:
      def equation_generator(self):
          """
          Return a generator for the linear equations satisfied by the
-@@ -1146,9 +1079,25 @@
+@@ -1154,31 +1087,45 @@
              if H.is_equation():
                  yield H
  
          Return the linear constraints of the polyhedron. As with
          inequalities, each constraint is given as [b -a1 -a2 ... an]
          where for variables x1, x2,..., xn, the polyhedron satisfies
-@@ -1156,21 +1105,19 @@
+         the equation b = a1*x1 + a2*x2 + ... + an*xn.
  
          .. NOTE::
-         
+-        
 -            It is recommended to use :meth:`equation_generator()` instead
 -            to iterate over the list of :class:`Equation` objects.
++
 +            It is recommended to use :meth:`equations` or
 +            :meth:`equation_generator()` instead to iterate over the
 +            list of
  
      def linearities(self):
          """
-@@ -1184,14 +1131,18 @@
+@@ -1192,42 +1139,41 @@
  
              sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
              sage: test_p.linearities()
          """
          Return a list of vertices of the polyhedron.
  
-@@ -1203,22 +1154,17 @@
+         .. NOTE::
+-        
++
+             It is recommended to use :meth:`vertex_generator` instead to
+             iterate over the list of :class:`Vertex` objects.
+ 
          EXAMPLES::
  
              sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
 -            self._vertices = [list(x) for x in self.vertex_generator()]
 -            return self._vertices
 -
+-        
 +        return [list(x) for x in self.vertex_generator()]
-         
++
      def vertex_generator(self):
          """
-@@ -1249,7 +1195,68 @@
+         Return a generator for the vertices of the polyhedron.
+@@ -1257,7 +1203,68 @@
          for V in self.Vrepresentation():
              if V.is_vertex():
                  yield V
+-        
 +
 +    @cached_method
 +    def vertices(self):
 +        Return the coordinates of the vertices as the columns of a matrix.
 +
 +        INPUT:
-         
++
 +        - ``base_ring`` -- A ring or ``None`` (default). The base ring
 +          of the returned matrix. If not specified, the base ring of
 +          the polyhedron is used.
  
      def ray_generator(self):
          """
-@@ -1266,15 +1273,34 @@
+@@ -1274,34 +1281,48 @@
              if V.is_ray():
                  yield V
  
 +    @cached_method
      def rays(self):
          """
-         Return a list of rays as coefficient lists.
- 
-+        OUTPUT:
-+
+-        Return a list of rays as coefficient lists.
+-
+-        .. NOTE::
+-        
+-            It is recommended to use :meth:`ray_generator` instead to
+-            iterate over the list of :class:`Ray` objects.
++        Return a list of rays of the polyhedron.
+ 
+         OUTPUT:
+ 
+-        A list of rays as lists of coordinates.
 +        A tuple of rays.
-+
-+        EXAMPLES::
-+
-+            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
-+            sage: p.rays()
+ 
+         EXAMPLES::
+ 
+             sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
+             sage: p.rays()
 +            (A ray in the direction (1, 0, 0),
 +             A ray in the direction (0, 1, 0),
 +             A ray in the direction (0, 0, 1))
 +        """
 +        Return a list of rays as coefficient lists.
 +
-         .. NOTE::
-         
--            It is recommended to use :meth:`ray_generator` instead to
--            iterate over the list of :class:`Ray` objects.
++        .. NOTE::
++
 +            It is recommended to use :meth:`rays` or
 +            :meth:`ray_generator` instead to iterate over the list of
 +            :class:`Ray` objects.
- 
-         OUTPUT:
- 
-@@ -1283,17 +1309,12 @@
-         EXAMPLES::
- 
-             sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
--            sage: p.rays()
++
++        OUTPUT:
++
++        A list of rays as lists of coordinates.
++
++        EXAMPLES::
++
++            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
 +            sage: p.rays_list()
              [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
 -            sage: p.rays() == [list(r) for r in p.ray_generator()]
  
      def line_generator(self):
          """
-@@ -1309,9 +1330,25 @@
+@@ -1317,36 +1338,47 @@
              if V.is_line():
                  yield V
  
          Return a list of lines of the polyhedron.  The line data is given
          as a list of coordinates rather than as a Hrepresentation object.
  
-@@ -1323,17 +1360,12 @@
+         .. NOTE::
+-        
++
+             It is recommended to use :meth:`line_generator` instead to
+             iterate over the list of :class:`Line` objects.
+ 
          EXAMPLES::
  
              sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
 -            self._lines = [list(x) for x in self.line_generator()]
 -            return self._lines
 -
+-                
 +        return [list(x) for x in self.line_generator()]
-                 
++
      def bounded_edges(self):
          """
-@@ -1360,9 +1392,7 @@
+         Return the bounded edges (excluding rays and lines).
+-        
++
+         OUTPUT:
+ 
+         A generator for pairs of vertices, one pair per edge.
+@@ -1368,45 +1400,41 @@
                  if self.vertex_adjacency_matrix()[i,j] == 0: continue
                  yield (obj[i], obj[j])
  
 +    def Vrepresentation_space(self):
          r"""
          Return the ambient vector space.
-         
-@@ -1373,15 +1403,15 @@
+-        
++
+         OUTPUT:
+-        
++
+         A free module over the base ring of dimension :meth:`ambient_dim`.
+-        
++
          EXAMPLES::
  
              sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
      def Hrepresentation_space(self):
          r"""
          Return the linear space containing the H-representation vectors.
-@@ -1393,12 +1423,10 @@
+ 
+         OUTPUT:
+-        
++
+         A free module over the base ring of dimension :meth:`ambient_dim` + 1.
+-        
++
          EXAMPLES::
-         
+-        
++
              sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
 -            sage: poly_test.ambient_space()
 -            Vector space of dimension 4 over Rational Field
  
      def ambient_dim(self):
          r"""
-@@ -1410,8 +1438,7 @@
+@@ -1418,9 +1446,8 @@
              sage: poly_test.ambient_dim()
              4
          """
 -        return self._ambient_dim
 -
+-            
 +        return self.parent().ambient_dim()
-             
++
      def dim(self):
          """
-@@ -1427,26 +1454,7 @@
-        """
+         Return the dimension of the polyhedron.
+@@ -1432,29 +1459,10 @@
+             3
+             sage: simplex.ambient_dim()
+             4
+-       """
++        """
          return self.ambient_dim() - self.n_equations()
  
 -
      def vertex_adjacency_matrix(self):
          """
          Return the binary matrix of vertex adjacencies.
-@@ -1460,11 +1468,11 @@
+@@ -1468,11 +1476,11 @@
              [1 1 1 0 1]
              [1 1 1 1 0]
          """
      def facet_adjacency_matrix(self):
          """
          Return the adjacency matrix for the facets and hyperplanes.
-@@ -1478,11 +1486,9 @@
+@@ -1486,11 +1494,9 @@
              [1 1 1 0 1]
              [1 1 1 1 0]
          """
      def incidence_matrix(self):
          """
          Return the incidence matrix.
-@@ -1527,18 +1533,13 @@
+@@ -1503,7 +1509,7 @@
+             :meth:`Vrepresentation`
+ 
+         EXAMPLES::
+-        
++
+             sage: p = polytopes.cuboctahedron()
+             sage: p.incidence_matrix()
+             [0 0 1 1 0 1 0 0 0 0 1 0 0 0]
+@@ -1535,18 +1541,13 @@
              sage: p.incidence_matrix() [2,0]   # note: not symmetric
              0
          """
  
      def base_ring(self):
          """
-@@ -1552,84 +1553,13 @@
+@@ -1560,84 +1561,13 @@
          EXAMPLES::
  
              sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]])
      @cached_method
      def center(self):
          """
-@@ -1693,7 +1623,6 @@
+@@ -1694,14 +1624,13 @@
+         distance measure.
+ 
+         EXAMPLES::
+-        
++
+             sage: p = polytopes.n_cube(4)
+             sage: p.radius()
+             2
          """
          return sqrt(self.radius_square())
  
      def is_compact(self):
          """
          Test for boundedness of the polytope.
-@@ -1709,7 +1638,6 @@
+@@ -1717,7 +1646,6 @@
          """
          return self.n_rays()==0 and self.n_lines()==0
  
      def is_simple(self):
          """
          Test for simplicity of a polytope.
-@@ -1733,9 +1661,9 @@
+@@ -1741,9 +1669,9 @@
              adj = [a for a in v.neighbors()]
              if len(adj) != self.dim():
                  return False
          """
          Return the Gale transform of a polytope as described in the
 @@ -1763,7 +1691,7 @@
+             sage: p2 = p.prism()
+             sage: p2.gale_transform()
+             [(1, 0), (0, 1), (-1, -1), (-1, 0), (0, -1), (1, 1)]
+-        
++
+         REFERENCES:
+ 
+             Lectures in Geometric Combinatorics, R.R.Thomas, 2006, AMS Press.
+@@ -1771,7 +1699,7 @@
          if not self.is_compact(): raise ValueError('Not a polytope.')
  
          A = matrix(self.n_vertices(),
          A = A.transpose()
          A_ker = A.right_kernel()
          return A_ker.basis_matrix().transpose().rows()
-@@ -1833,7 +1761,7 @@
+@@ -1800,14 +1728,14 @@
+         - ``fine`` -- boolean (default: ``False``). Whether the
+           triangulations must be fine, that is, make use of all points
+           of the configuration.
+-    
++
+         - ``regular`` -- boolean or ``None`` (default:
+           ``None``). Whether the triangulations must be regular. A
+           regular triangulation is one that is induced by a
+           piecewise-linear convex support function. In other words,
+           the shadows of the faces of a polyhedron in one higher
+           dimension.
+-      
++
+           * ``True``: Only regular triangulations.
+ 
+           * ``False``: Only non-regular triangulations.
+@@ -1826,7 +1754,7 @@
+         :class:`~sage.geometry.triangulation.point_configuration.Triangulation`. The
+         indices in the triangulation correspond to the
+         :meth:`Vrepresentation` objects.
+-        
++
+         EXAMPLES::
+ 
+             sage: cube = polytopes.n_cube(3)
+@@ -1841,7 +1769,7 @@
              [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1),
               A vertex at (-1, 1, -1), A vertex at (1, 1, 1)]
              sage: Polyhedron(simplex_vertices)
          """
          if not self.is_compact():
              raise NotImplementedError('I can only triangulate compact polytopes.')
-@@ -1862,18 +1790,24 @@
+@@ -1870,18 +1798,24 @@
  
              sage: Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[2,2,5]]
              ...             ).triangulated_facial_incidences()
 +            This method is deprecated. Use self.Hrepresentation(i).incident() instead.
 +            See http://trac.sagemath.org/11763 for details.
              [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
-                              
+-                             
++
          Otherwise some faces get split up to triangles::
  
              sage: Polyhedron(vertices = [[2,0,0],[4,1,0],[0,5,0],[5,5,0],
              [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]],
               [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]]
          """
-@@ -1928,7 +1862,6 @@
+@@ -1936,7 +1870,6 @@
          self._triangulated_facial_incidences = t_fac_incs
          return t_fac_incs
  
      def simplicial_complex(self):
          """
          Return a simplicial complex from a triangulation of the polytope.
-@@ -1960,56 +1893,134 @@
+@@ -1968,56 +1901,134 @@
          return SimplicialComplex(vertex_set = self.n_vertices(),
                                   maximal_faces = [x[1] for x in self.triangulated_facial_incidences()])
  
  
          OUTPUT:
  
-@@ -2022,66 +2033,68 @@
+@@ -2030,66 +2041,68 @@
               sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
               sage: p.vertex_generator().next()
               A vertex at (2, 4, 8)
      def convex_hull(self, other):
          """
          Return the convex hull of the set-theoretic union of the two
-@@ -2108,12 +2121,9 @@
+@@ -2116,12 +2129,9 @@
          hull_vertices = self.vertices() + other.vertices()
          hull_rays = self.rays() + other.rays()
          hull_lines = self.lines() + other.lines()
      def intersection(self, other):
          """
          Return the intersection of one polyhedron with another.
-@@ -2126,27 +2136,39 @@
+@@ -2134,42 +2144,54 @@
  
          The intersection.
  
  
      def edge_truncation(self, cut_frac = Integer(1)/3):
          r"""
-@@ -2182,7 +2204,7 @@
+         Return a new polyhedron formed from two points on each edge
+         between two vertices.
+-        
++
+         INPUT:
+-        
++
+         - ``cut_frac`` -- integer. how deeply to cut into the edge.
+             Default is `\frac{1}{3}`.
+-            
++
+         OUTPUT:
+ 
+         A Polyhedron object, truncated as described above.
+-            
++
+         EXAMPLES::
+ 
+             sage: cube = polytopes.n_cube(3)
+@@ -2190,7 +2212,7 @@
  
          return Polyhedron(vertices=new_vertices, rays=new_rays,
                            lines=new_lines,
  
  
      def _make_polyhedron_face(self, Vindices, Hindices):
-@@ -2211,7 +2233,7 @@
-         """
-         return PolyhedronFace_base(self, Vindices, Hindices)
- 
--
+@@ -2207,8 +2229,8 @@
+           face.
+ 
+         OUTPUT:
+-        
+-        A new :class:`PolyhedronFace_base` instance. It is not checked
++
++        A new :class:`~sage.geometry.polyhedron.face.PolyhedronFace` instance. It is not checked
+         whether the input data actually defines a face.
+ 
+         EXAMPLES::
+@@ -2217,18 +2239,19 @@
+             sage: square._make_polyhedron_face((0,2), (1,))
+             <0,2>
+         """
+-        return PolyhedronFace_base(self, Vindices, Hindices)
+-
+-
++        from sage.geometry.polyhedron.face import PolyhedronFace
++        return PolyhedronFace(self, Vindices, Hindices)
++
 +    @cached_method
      def face_lattice(self):
          """
          Return the face-lattice poset.
-@@ -2356,11 +2378,6 @@
+ 
+         OUTPUT:
+-        
++
+         A :class:`~sage.combinat.posets.posets.FinitePoset`. Elements
+         are given as
+-        :class:`~sage.geometry.polyhedron.PolyhedronFace_base`.
++        :class:`~sage.geometry.polyhedron.face.PolyhedronFace`.
+ 
+         In the case of a full-dimensional polytope, the faces are
+         pairs (vertices, inequalities) of the spanning vertices and
+@@ -2263,7 +2286,7 @@
+         * Lines are removed before calling
+           :func:`Hasse_diagram_from_incidences`, and then added back
+           to each face V-representation except for the "empty face".
+-        
++
+         * Equations are removed before calling
+           :func:`Hasse_diagram_from_incidences`, and then added back
+           to each face H-representation.
+@@ -2299,14 +2322,14 @@
+             (A vertex at (-1, -1), A vertex at (1, -1))
+             sage: a_face.ambient_Hrepresentation()
+             (An inequality (0, 1) x + 1 >= 0,)
+-            
++
+         A more complicated example::
+ 
+             sage: c5_10 = Polyhedron(vertices = [[i,i^2,i^3,i^4,i^5] for i in range(1,11)])
+             sage: c5_10_fl = c5_10.face_lattice()
+             sage: [len(x) for x in c5_10_fl.level_sets()]
+             [1, 10, 45, 100, 105, 42, 1]
+-            
++
+         Note that if the polyhedron contains lines then there is a
+         dimension gap between the empty face and the first non-empty
+         face in the face lattice::
+@@ -2356,7 +2379,7 @@
+         REFERENCES:
+ 
+         ..  [KP2002]
+-        
++
+             Volker Kaibel and Marc E. Pfetsch, "Computing the Face
+             Lattice of a Polytope from its Vertex-Facet Incidences",
+             Computational Geometry: Theory and Applications, Volume
+@@ -2364,29 +2387,24 @@
              http://portal.acm.org/citation.cfm?id=763203 and free of
              charge at http://arxiv.org/abs/math/0106043
          """
          coatom_to_Hindex = [ h.index() for h in self.inequality_generator() ]
          Hindex_to_coatom = [None] * self.n_Hrepresentation()
          for i in range(0,len(coatom_to_Hindex)):
-@@ -2392,12 +2409,12 @@
+             Hindex_to_coatom[ coatom_to_Hindex[i] ] = i
+-            
++
+         atom_to_Vindex = [ v.index() for v in self.Vrep_generator() if not v.is_line() ]
+         Vindex_to_atom = [None] * self.n_Vrepresentation()
+         for i in range(0,len(atom_to_Vindex)):
+                         Vindex_to_atom[ atom_to_Vindex[i] ] = i
+-            
++
+         atoms_incidences   = [ tuple([ Hindex_to_coatom[h.index()]
+                                        for h in v.incident() if h.is_inequality() ])
+                                for v in self.Vrepresentation() if not v.is_line() ]
+-        
++
+         coatoms_incidences = [ tuple([ Vindex_to_atom[v.index()]
+                                        for v in h.incident() if not v.is_line() ])
+                                for h in self.Hrepresentation() if h.is_inequality() ]
+-        
++
+         atoms_vertices = [ Vindex_to_atom[v.index()] for v in self.vertex_generator() ]
+         equations = [ e.index() for e in self.equation_generator() ]
+         lines     = [ l.index() for l in self.line_generator() ]
+@@ -2400,18 +2418,96 @@
              return self._make_polyhedron_face(Vindices, Hindices)
  
          from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
 -
 -
 +
++    def faces(self, face_dimension):
++        """
++        Return the faces of given dimension
++
++        INPUT:
++
++        - ``face_dimension`` -- integer.
++        
++        OUTPUT: 
++        
++        A tuple of
++        :class:`~sage.geometry.polyhedron.face.PolyhedronFace`. See
++        :mod:`~sage.geometry.polyhedron.face` for details. The order
++        random but fixed.
++
++        EXAMPLES:
++
++        Here we find the vertex and face indices of the eight three-dimensional
++        facets of the four-dimensional hypercube::
++
++            sage: p = polytopes.n_cube(4)
++            sage: p.faces(3)
++            (<0,1,2,3,4,5,6,7>, <0,1,2,3,8,9,10,11>, <0,1,4,5,8,9,12,13>, 
++             <0,2,4,6,8,10,12,14>, <2,3,6,7,10,11,14,15>, <8,9,10,11,12,13,14,15>, 
++             <4,5,6,7,12,13,14,15>, <1,3,5,7,9,11,13,15>)
++
++            sage: face = p.faces(3)[0]
++            sage: face.ambient_Hrepresentation()
++            (An inequality (1, 0, 0, 0) x + 1 >= 0,)
++            sage: face.vertices()
++            (A vertex at (-1, -1, -1, -1), A vertex at (-1, -1, -1, 1), 
++             A vertex at (-1, -1, 1, -1), A vertex at (-1, -1, 1, 1), 
++             A vertex at (-1, 1, -1, -1), A vertex at (-1, 1, -1, 1), 
++             A vertex at (-1, 1, 1, -1), A vertex at (-1, 1, 1, 1))
++
++        You can use the
++        :meth:`~sage.geometry.polyhedron.representation.PolyhedronRepresentation.index`
++        method to enumerate vertices and inequalities::
++
++            sage: def get_idx(rep): return rep.index()
++            sage: map(get_idx, face.ambient_Hrepresentation())
++            [4]
++            sage: map(get_idx, face.ambient_Vrepresentation())
++            [0, 1, 2, 3, 4, 5, 6, 7]
++
++            sage: [ (map(get_idx, face.ambient_Vrepresentation()), map(get_idx, face.ambient_Hrepresentation()))
++            ...     for face in p.faces(3) ]
++            [([0, 1, 2, 3, 4, 5, 6, 7], [4]), 
++             ([0, 1, 2, 3, 8, 9, 10, 11], [5]), 
++             ([0, 1, 4, 5, 8, 9, 12, 13], [6]), 
++             ([0, 2, 4, 6, 8, 10, 12, 14], [7]),
++             ([2, 3, 6, 7, 10, 11, 14, 15], [2]),
++             ([8, 9, 10, 11, 12, 13, 14, 15], [0]),
++             ([4, 5, 6, 7, 12, 13, 14, 15], [1]), 
++             ([1, 3, 5, 7, 9, 11, 13, 15], [3])]
++            
++        TESTS::
++
++            sage: pr = Polyhedron(rays = [[1,0,0],[-1,0,0],[0,1,0]], vertices = [[-1,-1,-1]], lines=[(0,0,1)])
++            sage: pr.faces(4)
++            ()
++            sage: pr.faces(3)
++            (<0,1,2,3>,)
++            sage: pr.faces(2)
++            (<0,1,2>,)
++            sage: pr.faces(1)
++            ()
++            sage: pr.faces(0)
++            ()
++            sage: pr.faces(-1)
++            ()
++        """
++        fl = self.face_lattice().level_sets()
++        codim = self.dim() - face_dimension
++        index = len(fl) - 1 - codim
++        if index>=len(fl) or index<1:
++            return tuple()
++        return tuple(face.element for face in fl[index])
 +
 +    @cached_method
      def f_vector(self):
          r"""
          Return the f-vector.
-@@ -2414,13 +2431,9 @@
+ 
+         OUTPUT:
+-        
++
+         Returns a vector whose ``i``-th entry is the number of
+         ``i``-dimensional faces of the polytope.
+ 
+@@ -2422,13 +2518,9 @@
              sage: p.f_vector()
              (1, 7, 12, 7, 1)
          """
      def vertex_graph(self):
          """
          Return a graph in which the vertices correspond to vertices
-@@ -2435,25 +2448,21 @@
+@@ -2443,25 +2535,21 @@
              sage: s4.is_eulerian()
              True
          """
              sage: p
              A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices
              sage: p.polar()
-@@ -2461,10 +2470,9 @@
+@@ -2469,10 +2557,9 @@
          """
          assert self.is_compact(), "Not a polytope."
  
  
      def pyramid(self):
          """
-@@ -2472,8 +2480,10 @@
+@@ -2480,8 +2567,10 @@
  
          EXAMPLES::
  
              sage: egyptian_pyramid.n_vertices()
              5
              sage: for v in egyptian_pyramid.vertex_generator(): print v
-@@ -2484,11 +2494,9 @@
+@@ -2492,11 +2581,9 @@
              A vertex at (1, 0, 0)
          """
          new_verts = \
  
      def bipyramid(self):
          """
-@@ -2523,9 +2531,7 @@
+@@ -2518,7 +2605,7 @@
+              [0, 0, 1, 0],
+              [0, 1, 0, 0],
+              [1, 0, 0, 0]]
+-        
++
+         Now check that bipyramids of cross-polytopes are cross-polytopes::
+ 
+             sage: q2 = [list(v) for v in polytopes.cross_polytope(4).vertex_generator()]
+@@ -2531,9 +2618,7 @@
              [[-1] + list(self.center())]
          new_rays = [[0] + r for r in self.rays()]
          new_lines = [[0] + list(l) for l in self.lines()]
  
      def prism(self):
          """
-@@ -2536,7 +2542,7 @@
+@@ -2544,7 +2629,7 @@
              sage: square = polytopes.n_cube(2)
              sage: cube = square.prism()
              sage: cube
              sage: hypercube = cube.prism()
              sage: hypercube.n_vertices()
              16
-@@ -2545,10 +2551,9 @@
+@@ -2553,10 +2638,9 @@
          new_verts.extend( [ [0] + v for v in self.vertices()] )
          new_verts.extend( [ [1] + v for v in self.vertices()] )
          new_rays =        [ [0] + r for r in self.rays()]
  
      def projection(self):
          """
-@@ -2565,7 +2570,6 @@
+@@ -2573,7 +2657,6 @@
          self.projection = Projection(self)
          return self.projection
  
      def render_solid(self, **kwds):
          """
          Return a solid rendering of a 2- or 3-d polytope.
-@@ -2584,7 +2588,6 @@
+@@ -2592,7 +2675,6 @@
              return proj.render_fill_2d(**kwds)
          raise ValueError, "render_solid is only defined for 2 and 3 dimensional polyhedra."
  
      def render_wireframe(self, **kwds):
          """
          For polytopes in 2 or 3 dimensions, return the edges
-@@ -2604,7 +2607,6 @@
+@@ -2612,7 +2694,6 @@
              return proj.render_outline_2d(**kwds)
          raise ValueError, "render_wireframe is only defined for 2 and 3 dimensional polyhedra."
  
      def schlegel_projection(self, projection_dir = None, height = 1.1):
          """
          Returns a projection object whose transformed coordinates are
-@@ -2621,13 +2623,13 @@
+@@ -2629,12 +2710,12 @@
          """
          proj = self.projection()
          if projection_dir == None:
 +            projection_dir = [sum([vertices[f0[i]][j]/len(f0) for i in range(len(f0))])
 +                              for j in range(self.ambient_dim())]
          return proj.schlegel(projection_direction = projection_dir, height = height)
-         
--
+-        
+ 
      def lrs_volume(self, verbose = False):
          """
-         Computes the volume of a polytope.
-@@ -2678,7 +2680,6 @@
+@@ -2655,7 +2736,7 @@
+             2.0
+ 
+         REFERENCES:
+-        
++
+              David Avis's lrs program.
+         """
+         if is_package_installed('lrs') != True:
+@@ -2686,7 +2767,6 @@
  
          raise ValueError, "lrs did not return a volume"
  
      def contains(self, point):
          """
          Test whether the polyhedron contains the given ``point``.
-@@ -2720,13 +2721,13 @@
+@@ -2703,7 +2783,7 @@
+         Boolean.
+ 
+         EXAMPLES::
+-        
++
+             sage: P = Polyhedron(vertices=[[1,1],[1,-1],[0,0]])
+             sage: P.contains( [1,0] )
+             True
+@@ -2724,17 +2804,17 @@
+             True
+             sage: ray.contains(['hello', 'kitty'])   # no common ring for coordinates
+             False
+-            
++
          The empty polyhedron needs extra care, see trac #10238::
  
              sage: empty = Polyhedron(); empty
              sage: full.contains([])
              True
              sage: full.contains([0])
-@@ -2738,7 +2739,7 @@
+@@ -2746,17 +2826,16 @@
              if len(point)>0:
                  return False
              else:
  
          if len(p)!=self.ambient_dim():
              return False
-@@ -2748,7 +2749,6 @@
+-        
++
+         for H in self.Hrep_generator():
+             if not H.contains(p):
                  return False
          return True
  
      def interior_contains(self, point):
          """
          Test whether the interior of the polyhedron contains the
-@@ -2785,7 +2785,7 @@
+@@ -2766,15 +2845,15 @@
+         :meth:`relative_interior_contains`.
+ 
+         INPUT:
+-        
++
+         - ``point`` -- coordinates of a point.
+ 
+         OUTPUT:
+-        
++
+         ``True`` or ``False``.
+ 
+         EXAMPLES::
+-        
++
+             sage: P = Polyhedron(vertices=[[0,0],[1,1],[1,-1]])
+             sage: P.contains( [1,0] )
+             True
+@@ -2793,7 +2872,7 @@
          The empty polyhedron needs extra care, see trac #10238::
  
              sage: empty = Polyhedron(); empty
              sage: empty.interior_contains([])
              False
          """
-@@ -2795,7 +2795,7 @@
+@@ -2803,17 +2882,16 @@
              if len(point)>0:
                  return False
              else:
  
          if len(p)!=self.ambient_dim():
              return False
-@@ -2805,7 +2805,6 @@
+-        
++
+         for H in self.Hrep_generator():
+             if not H.interior_contains(p):
                  return False
          return True
  
      def relative_interior_contains(self, point):
          """
          Test whether the relative interior of the polyhedron
-@@ -2836,7 +2835,7 @@
+@@ -2822,15 +2900,15 @@
+         See also :meth:`contains` and :meth:`interior_contains`.
+ 
+         INPUT:
+-        
++
+         - ``point`` -- coordinates of a point.
+ 
+         OUTPUT:
+-        
++
+         ``True`` or ``False``.
+ 
+         EXAMPLES::
+-        
++
+             sage: P = Polyhedron(vertices=[(1,0), (-1,0)])
+             sage: P.contains( (0,0) )
+             True
+@@ -2844,7 +2922,7 @@
          The empty polyhedron needs extra care, see trac #10238::
  
              sage: empty = Polyhedron(); empty
              sage: empty.relative_interior_contains([])
              False
          """
-@@ -2846,7 +2845,7 @@
+@@ -2854,11 +2932,11 @@
              if len(point)>0:
                  return False
              else:
  
          if len(p)!=self.ambient_dim():
              return False
-@@ -2876,6 +2875,7 @@
+-         
++
+         for eq in self.equation_generator():
+             if not eq.contains(p):
+                 return False
+@@ -2872,7 +2950,7 @@
+     def is_simplex(self):
+         r"""
+         Return whether the polyhedron is a simplex.
+-        
++
+         EXAMPLES::
+ 
+             sage: Polyhedron([(0,0,0), (1,0,0), (0,1,0)]).is_simplex()
+@@ -2884,34 +2962,34 @@
          """
          return self.is_compact() and (self.dim()+1==self.n_vertices())
  
      def is_lattice_polytope(self):
          r"""
          Return whether the polyhedron is a lattice polytope.
-@@ -2892,14 +2892,13 @@
+-        
++
+         OUTPUT:
+ 
+         ``True`` if the polyhedron is compact and has only integral
+         vertices, ``False`` otherwise.
+-        
++
+         EXAMPLES::
+-        
++
+             sage: polytopes.cross_polytope(3).is_lattice_polytope()
+             True
              sage: polytopes.regular_polygon(5).is_lattice_polytope()
              False
          """
 -        self._is_lattice_polytope = self.is_compact() and \
 -            all(v.is_integral() for v in self.vertex_generator())
 -        return self._is_lattice_polytope
+-        
 +        if not self.is_compact():
 +            return False
 +        if self.base_ring() is ZZ:
 +            return True
 +        return all(v.is_integral() for v in self.vertex_generator())
-         
++
 +    @cached_method
      def lattice_polytope(self, envelope=False):
          r"""
          Return an encompassing lattice polytope.
-@@ -2962,33 +2961,13 @@
+-        
++
+         INPUT:
+ 
+         - ``envelope`` -- boolean (default: ``False``). If the
+@@ -2942,7 +3020,7 @@
+         is returned.
+ 
+         EXAMPLES:
+-        
++
+         First, a polyhedron with integral vertices::
+ 
+             sage: P = Polyhedron( vertices = [(1, 0), (0, 1), (-1, 0), (0, -1)])
+@@ -2970,33 +3048,13 @@
          if not self.is_compact():
              raise NotImplementedError, 'Only compact lattice polytopes are allowed.'
  
              vertices = []
              for v in self.vertex_generator():
                  vbox = [ set([floor(x),ceil(x)]) for x in v ]
-@@ -2997,8 +2976,7 @@
+@@ -3005,8 +3063,7 @@
  
          # construct the (enveloping) lattice polytope
          from sage.geometry.lattice_polytope import LatticePolytope
  
      def _integral_points_PALP(self):
          r"""
-@@ -3066,8 +3044,10 @@
+@@ -3015,12 +3072,12 @@
+         This method is for testing purposes and will eventually be removed.
+ 
+         OUTPUT:
+-        
++
+         The list of integral points in the polyhedron. If the
+         polyhedron is not compact, a ``ValueError`` is raised.
+ 
+         EXAMPLES::
+-        
++
+             sage: Polyhedron(vertices=[(-1,-1),(1,0),(1,1),(0,1)])._integral_points_PALP()
+             [(-1, -1), (0, 1), (1, 0), (1, 1), (0, 0)]
+             sage: Polyhedron(vertices=[(-1/2,-1/2),(1,0),(1,1),(0,1)]).lattice_polytope(True).points()
+@@ -3053,7 +3110,7 @@
+ 
+         - ``integral`` -- Boolean (default: ``False``). Whether to
+           only allow integral coordinates in the bounding box.
+-        
++
+         OUTPUT:
+ 
+         A pair of tuples ``(box_min, box_max)`` where ``box_min`` are