Ticket #11763: trac_11763_parents_for_polyhedron.py

File trac_11763_parents_for_polyhedron.py, 174.0 KB (added by vbraun, 8 years ago)

Initial patch

Line 
1# HG changeset patch
2# User Volker Braun <vbraun@stp.dias.ie>
3# Date 1315501165 14400
4# Node ID f4a242b69ccdbb084a06b8f53776d89d6bc88041
5# Parent  234c3b73241018880fc3598bf9e868002350dcec
6Trac #11763: Parents for polyhedra
7
8diff --git a/sage/categories/all.py b/sage/categories/all.py
9--- a/sage/categories/all.py
10+++ b/sage/categories/all.py
11@@ -118,3 +118,6 @@
12 from highest_weight_crystals import HighestWeightCrystals
13 from finite_crystals import FiniteCrystals
14 from classical_crystals import ClassicalCrystals
15+
16+# polyhedra
17+from polyhedra import PolyhedralSets
18diff --git a/sage/categories/polyhedra.py b/sage/categories/polyhedra.py
19new file mode 100644
20--- /dev/null
21+++ b/sage/categories/polyhedra.py
22@@ -0,0 +1,75 @@
23+r"""
24+Polyhedral subsets of free ZZ, QQ or RR-modules.
25+"""
26+#*****************************************************************************
27+#       Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
28+#
29+#  Distributed under the terms of the GNU General Public License (GPL)
30+#                  http://www.gnu.org/licenses/
31+#******************************************************************************
32+
33+from sage.structure.element_wrapper import ElementWrapper
34+from sage.categories.category_types import Category_over_base_ring
35+from sage.misc.cachefunc import cached_method
36+from sage.categories.category import HomCategory
37+
38+
39+
40+class PolyhedralSets(Category_over_base_ring):
41+    r"""
42+    The category of Polyhedra over a ring.
43+
44+    EXAMPLES:
45+
46+    We create the category of polyhedra over `\QQ`::
47+
48+        sage: PolyhedralSets(QQ)
49+        Category of Polyhedra over Rational Field
50+
51+    TESTS::
52+
53+        sage: TestSuite(PolyhedralSets(RDF)).run()
54+
55+        sage: P = Polyhedron()
56+        sage: P.parent().category().element_class
57+        <class 'sage.categories.category.PolyhedralSets.element_class'>
58+        sage: P.parent().category().element_class.mro()
59+        [<class 'sage.categories.category.PolyhedralSets.element_class'>,
60+         <class 'sage.categories.magmas.Magmas.element_class'>,
61+         <class 'sage.categories.additive_magmas.AdditiveMagmas.element_class'>,
62+         <class 'sage.categories.sets_cat.Sets.element_class'>,
63+         <class 'sage.categories.category.SetsWithPartialMaps.element_class'>,
64+         <class 'sage.categories.objects.Objects.element_class'>,
65+         <type 'object'>]
66+        sage: isinstance(P, P.parent().category().element_class)
67+        True
68+    """
69+   
70+    def __init__(self, R):
71+        """
72+        TESTS::
73+
74+            sage: PolyhedralSets((1,2,3))
75+            Traceback (most recent call last):
76+            ...
77+            TypeError: base ring R (=(1, 2, 3)) must be ZZ, QQ, or RDF.
78+        """
79+        from sage.rings.all import ZZ, QQ, RDF
80+        if R not in [ZZ, QQ, RDF]:
81+            raise TypeError, 'base ring R (='+str(R)+') must be ZZ, QQ, or RDF.'
82+        Category_over_base_ring.__init__(self, R, 'Polyhedra')
83+
84+    @cached_method
85+    def super_categories(self):
86+        """
87+        EXAMPLES::
88+
89+            sage: PolyhedralSets(QQ).super_categories()
90+            [Category of magmas, Category of additive magmas]
91+        """
92+        from sage.categories.all import Magmas, AdditiveMagmas
93+        return [Magmas(), AdditiveMagmas()]
94+
95+
96+
97+
98diff --git a/sage/geometry/cone.py b/sage/geometry/cone.py
99--- a/sage/geometry/cone.py
100+++ b/sage/geometry/cone.py
101@@ -144,7 +144,7 @@
102     sage: four_rays.lattice_polytope()
103     A lattice polytope: 3-dimensional, 5 vertices.
104     sage: four_rays.polyhedron()
105-    A 3-dimensional polyhedron in QQ^3 defined as
106+    A 3-dimensional polyhedron in ZZ^3 defined as
107     the convex hull of 1 vertex and 4 rays
108 
109 And of course you are always welcome to suggest new features that should be
110@@ -532,7 +532,10 @@
111         V = lattice.base_extend(QQ)
112         for n, ray in enumerate(rays):
113             try:
114-                ray = V(ray)
115+                if isinstance(ray, (list, tuple, V._element_class)):
116+                    ray = V(ray)
117+                else:
118+                    ray = V(list(ray))
119             except TypeError:
120                 raise TypeError("cannot convert %s to %s!" % (ray, V))
121             if ray.is_zero():
122@@ -2832,18 +2835,18 @@
123 
124             sage: quadrant = Cone([(1,0), (0,1)])
125             sage: quadrant.polyhedron()
126-            A 2-dimensional polyhedron in QQ^2 defined as the convex hull
127+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull
128             of 1 vertex and 2 rays
129             sage: line = Cone([(1,0), (-1,0)])
130             sage: line.polyhedron()
131-            A 1-dimensional polyhedron in QQ^2 defined as the convex hull
132+            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull
133             of 1 vertex and 1 line
134             
135         Here is an example of a trivial cone (see Trac #10237)::
136         
137             sage: origin = Cone([], lattice=ZZ^2)
138             sage: origin.polyhedron()
139-            A 0-dimensional polyhedron in QQ^2 defined as the convex hull
140+            A 0-dimensional polyhedron in ZZ^2 defined as the convex hull
141             of 1 vertex
142         """
143         if "_polyhedron" not in self.__dict__:
144diff --git a/sage/geometry/integral_points.pyx b/sage/geometry/integral_points.pyx
145--- a/sage/geometry/integral_points.pyx
146+++ b/sage/geometry/integral_points.pyx
147@@ -266,7 +266,7 @@
148     
149         sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
150         sage: simplex = Polyhedron(v); simplex
151-        A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
152+        A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
153         sage: pts = simplex_points(simplex.Vrepresentation())
154         sage: len(pts)
155         49
156@@ -279,7 +279,7 @@
157         
158         sage: v = [(4,-1,-1,-1), (-1,4,-1,-1), (-1,-1,4,-1), (-1,-1,-1,4), (-1,-1,-1,-1)]
159         sage: P4mirror = Polyhedron(v); P4mirror
160-        A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
161+        A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
162         sage: len( simplex_points(P4mirror.Vrepresentation()) )
163         126
164     """
165@@ -897,7 +897,7 @@
166         max_abs_coordinates = permutation.action(max_abs_coordinates)
167         self.ineqs_int = []
168         self.ineqs_generic = []
169-        if not polyhedron:
170+        if polyhedron is None:
171             return
172         for Hrep_obj in polyhedron.inequality_generator():
173             A, b = self._make_A_b(Hrep_obj, permutation)
174diff --git a/sage/geometry/polyhedron/backend_cdd.py b/sage/geometry/polyhedron/backend_cdd.py
175--- a/sage/geometry/polyhedron/backend_cdd.py
176+++ b/sage/geometry/polyhedron/backend_cdd.py
177@@ -10,12 +10,6 @@
178 from base import Polyhedron_base
179 from base_QQ import Polyhedron_QQ
180 from base_RDF import Polyhedron_RDF
181-from representation import (
182-    PolyhedronRepresentation, 
183-    Hrepresentation, 
184-    Inequality, Equation,
185-    Vrepresentation,
186-    Vertex, Ray, Line )
187 
188 
189 
190@@ -25,14 +19,12 @@
191     Base class for the cdd backend.
192     """
193 
194-    def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, verbose=False):
195+    def _init_from_Vrepresentation(self, vertices, rays, lines, verbose=False):
196         """
197         Construct polyhedron from V-representation data.
198 
199         INPUT:
200 
201-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
202-       
203         - ``vertices`` -- list of point. Each point can be specified
204            as any iterable container of
205            :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
206@@ -51,7 +43,7 @@
207         EXAMPLES::
208 
209             sage: Polyhedron(vertices=[(0,0)], rays=[(1,1)], 
210-            ...              lines=[(1,-1)], backend='cddr')  # indirect doctest
211+            ...              lines=[(1,-1)], backend='cdd', base_ring=QQ)  # indirect doctest
212             A 2-dimensional polyhedron in QQ^2 defined as the
213             convex hull of 1 vertex, 1 ray, 1 line
214         """
215@@ -60,14 +52,12 @@
216         self._init_from_cdd_input(s, '--reps', verbose)
217 
218 
219-    def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, verbose=False):
220+    def _init_from_Hrepresentation(self, ieqs, eqns, verbose=False):
221         """
222         Construct polyhedron from H-representation data.
223 
224         INPUT:
225 
226-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
227-       
228         - ``ieqs`` -- list of inequalities. Each line can be specified
229           as any iterable container of
230           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
231@@ -82,7 +72,7 @@
232         EXAMPLES::
233 
234             sage: Polyhedron(ieqs=[(0,1,1)], eqns=[(0,1,-1)],
235-            ...              backend='cddr')  # indirect doctest
236+            ...              backend='cdd', base_ring=QQ)  # indirect doctest
237             A 1-dimensional polyhedron in QQ^2 defined as the
238             convex hull of 1 vertex and 1 ray
239         """
240@@ -98,7 +88,7 @@
241 
242         EXAMPLES::
243         
244-            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cddr')
245+            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cdd', base_ring=QQ)
246             sage: '_H_adjacency_matrix' in p.__dict__
247             False
248             sage: p._init_facet_adjacency_matrix()
249@@ -118,7 +108,7 @@
250 
251         EXAMPLES::
252         
253-            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cddr')
254+            sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)], backend='cdd', base_ring=QQ)
255             sage: '_V_adjacency_matrix' in p.__dict__
256             False
257             sage: p._init_vertex_adjacency_matrix()
258@@ -138,7 +128,7 @@
259 
260         TESTS::
261         
262-            sage: p = Polyhedron(vertices = [[0,0,0],[1,0,0],[0,1,0],[0,0,1]], backend='cddr')
263+            sage: p = Polyhedron(vertices = [[0,0,0],[1,0,0],[0,1,0],[0,0,1]], backend='cdd', base_ring=QQ)
264             sage: from sage.geometry.polyhedron.cdd_file_format import cdd_Vrepresentation
265             sage: s = cdd_Vrepresentation('rational', [[0,0,1],[0,1,0],[1,0,0]], [], [])
266             sage: p._init_from_cdd_input(s)
267@@ -168,13 +158,14 @@
268             sage: from subprocess import Popen, PIPE
269             sage: cdd_proc = Popen(['cdd_both_reps_gmp', '--all'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
270             sage: ans, err = cdd_proc.communicate(input=s)
271-            sage: p = Polyhedron(vertices = [[0,0],[1,0],[0,1],[1,1]], backend='cddr')
272+            sage: p = Polyhedron(vertices = [[0,0],[1,0],[0,1],[1,1]], backend='cdd', base_ring=QQ)
273             sage: p._init_from_cdd_output(ans)
274             sage: p.vertices()
275-            [[0, 0], [1, 0], [0, 1], [1, 1]]
276+            (A vertex at (0, 0), A vertex at (1, 0), A vertex at (0, 1), A vertex at (1, 1))
277         """
278         cddout=cdd_output_string.splitlines()
279         suppressed_vertex = False   # whether cdd suppressed the vertex in output
280+        parent = self.parent()
281 
282         # nested function           
283         def expect_in_cddout(expected_string):
284@@ -219,22 +210,22 @@
285             lines = cdd_linearities()
286             expect_in_cddout('begin')
287             l = cddout.pop(0).split()
288-            assert self._ambient_dim == int(l[1])-1,  "Different ambient dimension?"
289+            assert self.ambient_dim() == int(l[1])-1,  "Different ambient dimension?"
290             suppressed_vertex = True
291             for i in range(int(l[0])):
292                 l = cddout.pop(0).strip()
293                 l_type = l[0]
294                 l = l[1:]
295                 if i in lines:
296-                    Line(self, cdd_convert(l));
297+                    parent._make_Line(self, cdd_convert(l));
298                 elif l_type == '0':
299-                    Ray(self, cdd_convert(l));
300+                    parent._make_Ray(self, cdd_convert(l));
301                 else:
302-                    Vertex(self, cdd_convert(l));
303+                    parent._make_Vertex(self, cdd_convert(l));
304                     suppressed_vertex = False
305             if suppressed_vertex and self.n_Vrepresentation()>0:
306                 # cdd does not output the vertex if it is only the origin
307-                Vertex(self, [0] * self._ambient_dim)
308+                parent._make_Vertex(self, [0] * self.ambient_dim())
309             self._Vrepresentation = tuple(self._Vrepresentation)
310             expect_in_cddout('end')
311         
312@@ -243,13 +234,13 @@
313             equations = cdd_linearities()
314             expect_in_cddout('begin')
315             l = cddout.pop(0).split()
316-            assert self._ambient_dim == int(l[1])-1, "Different ambient dimension?"
317+            assert self.ambient_dim() == int(l[1])-1, "Different ambient dimension?"
318             for i in range(int(l[0])):
319                 l = cddout.pop(0)
320                 if i in equations:
321-                    Equation(self, cdd_convert(l));
322+                    parent._make_Equation(self, cdd_convert(l));
323                 else:
324-                    Inequality(self, cdd_convert(l));
325+                    parent._make_Inequality(self, cdd_convert(l));
326             self._Hrepresentation = tuple(self._Hrepresentation)
327             expect_in_cddout('end')
328 
329@@ -306,16 +297,19 @@
330 
331     INPUT:
332 
333-    - ``ambient_dim`` -- integer. The dimension of the ambient space.
334+    - ``parent`` -- the parent, an instance of
335+      :class:`~sage.geometry.polyhedron.parent.Polyhedra`.
336 
337-    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
338+    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
339         
340-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
341+    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
342 
343     EXAMPLES::
344 
345+        sage: from sage.geometry.polyhedron.parent import Polyhedra
346+        sage: parent = Polyhedra(QQ, 2, backend='cdd')
347         sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd
348-        sage: Polyhedron_QQ_cdd(2, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
349+        sage: Polyhedron_QQ_cdd(parent, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
350         A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
351     """
352 
353@@ -323,7 +317,7 @@
354 
355     _cdd_executable = 'cdd_both_reps_gmp'
356 
357-    def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
358+    def __init__(self, parent, Vrep, Hrep, **kwds):
359         """
360         The Python constructor.
361 
362@@ -332,12 +326,12 @@
363 
364         TESTS::
365         
366-            sage: p = Polyhedron(backend='cddr')
367+            sage: p = Polyhedron(backend='cdd', base_ring=QQ)
368             sage: type(p)
369-            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedron_QQ_cdd'>
370+            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedra_QQ_cdd_with_category.element_class'>
371             sage: TestSuite(p).run()
372         """
373-        Polyhedron_cdd.__init__(self, ambient_dim, Vrep, Hrep, **kwds)
374+        Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
375     
376 
377 #########################################################################
378@@ -349,21 +343,23 @@
379 
380     - ``ambient_dim`` -- integer. The dimension of the ambient space.
381 
382-    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
383+    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
384         
385-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
386+    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
387 
388     EXAMPLES::
389 
390+        sage: from sage.geometry.polyhedron.parent import Polyhedra
391+        sage: parent = Polyhedra(RDF, 2, backend='cdd')
392         sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_RDF_cdd
393-        sage: Polyhedron_RDF_cdd(2, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
394+        sage: Polyhedron_RDF_cdd(parent, [ [(1,0),(0,1),(0,0)], [], []], None, verbose=False)
395         A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 3 vertices
396     """
397     _cdd_type = 'real'
398     
399     _cdd_executable = 'cdd_both_reps'
400 
401-    def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
402+    def __init__(self, parent, Vrep, Hrep, **kwds):
403         """
404         The Python constructor.
405 
406@@ -372,10 +368,10 @@
407 
408         TESTS::
409         
410-            sage: p = Polyhedron(backend='cddf')
411+            sage: p = Polyhedron(backend='cdd', base_ring=RDF)
412             sage: type(p)
413-            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedron_RDF_cdd'>
414+            <class 'sage.geometry.polyhedron.backend_cdd.Polyhedra_RDF_cdd_with_category.element_class'>
415             sage: TestSuite(p).run()
416         """
417-        Polyhedron_cdd.__init__(self, ambient_dim, Vrep, Hrep, **kwds)
418+        Polyhedron_cdd.__init__(self, parent, Vrep, Hrep, **kwds)
419     
420diff --git a/sage/geometry/polyhedron/backend_ppl.py b/sage/geometry/polyhedron/backend_ppl.py
421--- a/sage/geometry/polyhedron/backend_ppl.py
422+++ b/sage/geometry/polyhedron/backend_ppl.py
423@@ -3,7 +3,7 @@
424 """
425 
426 from sage.rings.all import ZZ, QQ
427-from sage.rings.arith import lcm
428+from sage.rings.integer import LCM_list
429 from sage.misc.functional import denominator
430 from sage.matrix.constructor import matrix
431 from sage.libs.ppl import (
432@@ -14,13 +14,6 @@
433 from base import Polyhedron_base
434 from base_QQ import Polyhedron_QQ
435 from base_ZZ import Polyhedron_ZZ
436-from representation import (
437-    PolyhedronRepresentation,
438-    Hrepresentation,
439-    Inequality, Equation,
440-    Vrepresentation,
441-    Vertex, Ray, Line )
442-
443 
444 
445 #########################################################################
446@@ -30,11 +23,9 @@
447 
448     INPUT:
449 
450-    - ``ambient_dim`` -- integer. The dimension of the ambient space.
451-
452-    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
453+    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
454         
455-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
456+    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
457 
458     EXAMPLES::
459 
460@@ -42,14 +33,12 @@
461         sage: TestSuite(p).run()
462     """
463 
464-    def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, minimize=True):
465+    def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True):
466         """
467         Construct polyhedron from V-representation data.
468 
469         INPUT:
470 
471-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
472-       
473         - ``vertices`` -- list of point. Each point can be specified
474            as any iterable container of
475            :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
476@@ -66,36 +55,45 @@
477 
478             sage: p = Polyhedron(backend='ppl')
479             sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl
480-            sage: Polyhedron_ppl._init_from_Vrepresentation(p, 2, [], [], [])
481+            sage: Polyhedron_ppl._init_from_Vrepresentation(p, [], [], [])
482         """
483         gs = Generator_System()
484         if vertices is None: vertices = []
485         for v in vertices:
486-            d = lcm([denominator(v_i) for v_i in v])
487-            dv = [ ZZ(d*v_i) for v_i in v ]
488-            gs.insert(point(Linear_Expression(dv, 0), d))
489+            d = LCM_list([denominator(v_i) for v_i in v])
490+            if d.is_one():
491+                gs.insert(point(Linear_Expression(v, 0)))
492+            else:
493+                dv = [ d*v_i for v_i in v ]
494+                gs.insert(point(Linear_Expression(dv, 0), d))
495         if rays is None: rays = []
496         for r in rays:
497-            d = lcm([denominator(r_i) for r_i in r])
498-            dr = [ ZZ(d*r_i) for r_i in r ]
499-            gs.insert(ray(Linear_Expression(dr, 0)))
500+            d = LCM_list([denominator(r_i) for r_i in r])
501+            if d.is_one():
502+                gs.insert(ray(Linear_Expression(r, 0)))
503+            else:
504+                dr = [ d*r_i for r_i in r ]
505+                gs.insert(ray(Linear_Expression(dr, 0)))
506         if lines is None: lines = []
507         for l in lines:
508-            d = lcm([denominator(l_i) for l_i in l])
509-            dl = [ ZZ(d*l_i) for l_i in l ]
510-            gs.insert(line(Linear_Expression(dl, 0)))
511-        self._ppl_polyhedron = C_Polyhedron(gs)
512+            d = LCM_list([denominator(l_i) for l_i in l])
513+            if d.is_one():
514+                gs.insert(line(Linear_Expression(l, 0)))
515+            else:
516+                dl = [ d*l_i for l_i in l ]
517+                gs.insert(line(Linear_Expression(dl, 0)))
518+        if gs.empty():
519+            self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty')
520+        else:
521+            self._ppl_polyhedron = C_Polyhedron(gs)
522         self._init_Vrepresentation_from_ppl(minimize)
523         self._init_Hrepresentation_from_ppl(minimize)
524 
525-
526-    def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, minimize=True):
527+    def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True):
528         """
529         Construct polyhedron from H-representation data.
530 
531         INPUT:
532-
533-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
534         
535         - ``ieqs`` -- list of inequalities. Each line can be specified
536           as any iterable container of
537@@ -109,28 +107,30 @@
538 
539             sage: p = Polyhedron(backend='ppl')
540             sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl
541-            sage: Polyhedron_ppl._init_from_Hrepresentation(p, 2, [], [])
542+            sage: Polyhedron_ppl._init_from_Hrepresentation(p, [], [])
543         """
544         cs = Constraint_System()
545         if ieqs is None: ieqs = []
546         for ieq in ieqs:
547-            d = lcm([denominator(ieq_i) for ieq_i in ieq])
548+            d = LCM_list([denominator(ieq_i) for ieq_i in ieq])
549             dieq = [ ZZ(d*ieq_i) for ieq_i in ieq ]
550             b = dieq[0]
551             A = dieq[1:]
552             cs.insert(Linear_Expression(A, b) >= 0)
553         if eqns is None: eqns = []
554         for eqn in eqns:
555-            d = lcm([denominator(eqn_i) for eqn_i in eqn])
556+            d = LCM_list([denominator(eqn_i) for eqn_i in eqn])
557             deqn = [ ZZ(d*eqn_i) for eqn_i in eqn ]
558             b = deqn[0]
559             A = deqn[1:]
560             cs.insert(Linear_Expression(A, b) == 0)
561-        self._ppl_polyhedron = C_Polyhedron(cs)
562+        if cs.empty():
563+            self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'universe')
564+        else:
565+            self._ppl_polyhedron = C_Polyhedron(cs)
566         self._init_Vrepresentation_from_ppl(minimize)
567         self._init_Hrepresentation_from_ppl(minimize)
568 
569-       
570     def _init_Vrepresentation_from_ppl(self, minimize):
571         """
572         Create the Vrepresentation objects from the ppl polyhedron.
573@@ -152,19 +152,22 @@
574         """
575         self._Vrepresentation = []
576         gs = self._ppl_polyhedron.minimized_generators()
577+        parent = self.parent()
578         for g in gs:
579             if g.is_point():
580                 d = g.divisor()
581-                Vertex(self, [x/d for x in g.coefficients()])
582+                if d.is_one():
583+                    parent._make_Vertex(self, g.coefficients())
584+                else:
585+                    parent._make_Vertex(self, [x/d for x in g.coefficients()])
586             elif g.is_ray():
587-                Ray(self, g.coefficients())
588+                parent._make_Ray(self, g.coefficients())
589             elif g.is_line():
590-                Line(self, g.coefficients())
591+                parent._make_Line(self, g.coefficients())
592             else:
593                 assert False 
594         self._Vrepresentation = tuple(self._Vrepresentation)
595         
596-
597     def _init_Hrepresentation_from_ppl(self, minimize):
598         """
599         Create the Vrepresentation objects from the ppl polyhedron.
600@@ -186,37 +189,32 @@
601         """
602         self._Hrepresentation = []
603         cs = self._ppl_polyhedron.minimized_constraints()
604+        parent = self.parent()
605         for c in cs:
606             if c.is_inequality():
607-                Inequality(self, (c.inhomogeneous_term(),) + c.coefficients())
608+                parent._make_Inequality(self, (c.inhomogeneous_term(),) + c.coefficients())
609             elif c.is_equality():
610-                Equation(self, (c.inhomogeneous_term(),) + c.coefficients())
611+                parent._make_Equation(self, (c.inhomogeneous_term(),) + c.coefficients())
612         self._Hrepresentation = tuple(self._Hrepresentation)
613-       
614 
615-    def _init_empty_polyhedron(self, ambient_dim):
616+    def _init_empty_polyhedron(self):
617         """
618         Initializes an empty polyhedron.
619 
620-        INPUT:
621-
622-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
623-
624         TESTS::
625 
626             sage: empty = Polyhedron(backend='ppl'); empty
627-            The empty polyhedron in QQ^0
628+            The empty polyhedron in ZZ^0
629             sage: empty.Vrepresentation()
630             ()
631             sage: empty.Hrepresentation()
632             (An equation -1 == 0,)
633             sage: Polyhedron(vertices = [], backend='ppl')
634-            The empty polyhedron in QQ^0
635-            sage: Polyhedron(backend='ppl')._init_empty_polyhedron(0)
636+            The empty polyhedron in ZZ^0
637+            sage: Polyhedron(backend='ppl')._init_empty_polyhedron()
638         """
639-        super(Polyhedron_ppl, self)._init_empty_polyhedron(ambient_dim)
640-        self._ppl_polyhedron = C_Polyhedron(ambient_dim, 'empty')
641-
642+        super(Polyhedron_ppl, self)._init_empty_polyhedron()
643+        self._ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty')
644 
645 
646 
647@@ -227,11 +225,9 @@
648 
649     INPUT:
650 
651-    - ``ambient_dim`` -- integer. The dimension of the ambient space.
652-
653-    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
654+    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
655         
656-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
657+    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
658 
659     EXAMPLES::
660 
661@@ -249,11 +245,9 @@
662 
663     INPUT:
664 
665-    - ``ambient_dim`` -- integer. The dimension of the ambient space.
666-
667-    - ``Vrep`` -- a list ``[vertices, rays, lines]``.
668+    - ``Vrep`` -- a list ``[vertices, rays, lines]`` or ``None``.
669         
670-    - ``Hrep`` -- a list ``[ieqs, eqns]``.
671+    - ``Hrep`` -- a list ``[ieqs, eqns]`` or ``None``.
672 
673     EXAMPLES::
674 
675diff --git a/sage/geometry/polyhedron/base.py b/sage/geometry/polyhedron/base.py
676--- a/sage/geometry/polyhedron/base.py
677+++ b/sage/geometry/polyhedron/base.py
678@@ -13,7 +13,7 @@
679 ########################################################################
680 
681 
682-from sage.structure.sage_object import SageObject
683+from sage.structure.element import Element, coerce_binop, is_Vector
684 
685 from sage.misc.all import union, cached_method, prod
686 from sage.misc.package import is_package_installed
687@@ -33,12 +33,6 @@
688 from sage.groups.perm_gps.permgroup_named import AlternatingGroup
689 
690 from constructor import Polyhedron
691-from representation import (
692-    PolyhedronRepresentation, 
693-    Hrepresentation, 
694-    Inequality, Equation,
695-    Vrepresentation,
696-    Vertex, Ray, Line )
697 
698 
699 #########################################################################
700@@ -55,6 +49,7 @@
701 #
702 #  * You can of course also override any other method for which you
703 #    have a faster implementation.
704+#########################################################################
705 
706 
707 #########################################################################
708@@ -83,13 +78,14 @@
709 
710 
711 #########################################################################
712-class Polyhedron_base(SageObject):
713+class Polyhedron_base(Element):
714     """
715     Base class for Polyhedron objects
716 
717     INPUT:
718 
719-    - ``ambient_dim`` -- integer. The dimension of the ambient space.
720+    - ``parent`` -- the parent, an instance of
721+      :class:`~sage.geometry.polyhedron.parent.Polyhedra`.
722 
723     - ``Vrep`` -- a list `[vertices, rays, lines]``.
724         
725@@ -101,7 +97,7 @@
726         sage: TestSuite(p).run()
727     """
728 
729-    def __init__(self, ambient_dim, Vrep, Hrep, **kwds):
730+    def __init__(self, parent, Vrep, Hrep, **kwds):
731         """
732         Initializes the polyhedron.
733 
734@@ -112,27 +108,22 @@
735 
736             sage: p = Polyhedron()    # indirect doctests
737         """
738-        self._ambient_dim = ambient_dim
739+        Element.__init__(self, parent=parent)
740         if Vrep is not None:
741             vertices, rays, lines = Vrep
742-            if len(vertices)==0:
743-                vertices = [[0] * ambient_dim]
744-            self._init_from_Vrepresentation(ambient_dim, vertices, rays, lines, **kwds)
745+            self._init_from_Vrepresentation(vertices, rays, lines, **kwds)
746         elif Hrep is not None:
747             ieqs, eqns = Hrep
748-            self._init_from_Hrepresentation(ambient_dim, ieqs, eqns, **kwds)
749+            self._init_from_Hrepresentation(ieqs, eqns, **kwds)
750         else:
751-            self._init_empty_polyhedron(ambient_dim)
752-
753-
754-    def _init_from_Vrepresentation(self, ambient_dim, vertices, rays, lines, **kwds):
755+            self._init_empty_polyhedron()
756+
757+    def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds):
758         """
759         Construct polyhedron from V-representation data.
760 
761         INPUT:
762 
763-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
764-       
765         - ``vertices`` -- list of point. Each point can be specified
766            as any iterable container of
767            :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
768@@ -149,22 +140,19 @@
769 
770             sage: p = Polyhedron()
771             sage: from sage.geometry.polyhedron.base import Polyhedron_base
772-            sage: Polyhedron_base._init_from_Vrepresentation(p, 2, [], [], [])
773+            sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], [])
774             Traceback (most recent call last):
775             ...
776             NotImplementedError: A derived class must implement this method.
777         """
778         raise NotImplementedError('A derived class must implement this method.')
779 
780-
781-    def _init_from_Hrepresentation(self, ambient_dim, ieqs, eqns, **kwds):
782+    def _init_from_Hrepresentation(self, ieqs, eqns, **kwds):
783         """
784         Construct polyhedron from H-representation data.
785 
786         INPUT:
787 
788-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
789-       
790         - ``ieqs`` -- list of inequalities. Each line can be specified
791           as any iterable container of
792           :meth:`~sage.geometry.polyhedron.base.base_ring` elements.
793@@ -177,48 +165,47 @@
794 
795             sage: p = Polyhedron()
796             sage: from sage.geometry.polyhedron.base import Polyhedron_base
797-            sage: Polyhedron_base._init_from_Hrepresentation(p, 2, [], [])
798+            sage: Polyhedron_base._init_from_Hrepresentation(p, [], [])
799             Traceback (most recent call last):
800             ...
801             NotImplementedError: A derived class must implement this method.
802         """
803         raise NotImplementedError('A derived class must implement this method.')
804 
805-
806-    def _init_empty_polyhedron(self, ambient_dim):
807+    def _init_empty_polyhedron(self):
808         """
809         Initializes an empty polyhedron.
810 
811-        INPUT:
812-
813-        - ``ambient_dim`` -- integer. The dimension of the ambient space.
814-
815         TESTS::
816 
817             sage: empty = Polyhedron(); empty
818-            The empty polyhedron in QQ^0
819+            The empty polyhedron in ZZ^0
820             sage: empty.Vrepresentation()
821             ()
822             sage: empty.Hrepresentation()
823             (An equation -1 == 0,)
824             sage: Polyhedron(vertices = [])
825-            The empty polyhedron in QQ^0
826-            sage: Polyhedron()._init_empty_polyhedron(0)
827+            The empty polyhedron in ZZ^0
828+            sage: Polyhedron(vertices = [])._init_empty_polyhedron()
829+            sage: from sage.geometry.polyhedron.parent import Polyhedra
830+            sage: Polyhedra(QQ,7)()
831+            A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex
832         """
833         self._Vrepresentation = []
834         self._Hrepresentation = []
835-        Equation(self, [-1] + [0]*ambient_dim);
836+        self.parent()._make_Equation(self, [-1] + [0]*self.ambient_dim());
837         self._Vrepresentation = tuple(self._Vrepresentation)
838         self._Hrepresentation = tuple(self._Hrepresentation)
839 
840-        self._V_adjacency_matrix = matrix(ZZ, 0, 0, 0)
841-        self._V_adjacency_matrix.set_immutable()
842-
843-        self._H_adjacency_matrix = matrix(ZZ, 1, 1, 0)
844-        self._H_adjacency_matrix.set_immutable()
845-
846-
847-    def _init_facet_adjacency_matrix(self):
848+        V_matrix = matrix(ZZ, 0, 0, 0)
849+        V_matrix.set_immutable()
850+        self.vertex_adjacency_matrix.set_cache(V_matrix)
851+
852+        H_matrix = matrix(ZZ, 1, 1, 0)
853+        H_matrix.set_immutable()
854+        self.facet_adjacency_matrix.set_cache(H_matrix)
855+
856+    def _facet_adjacency_matrix(self):
857         """
858         Compute the facet adjacency matrix in case it has not been
859         computed during initialization.
860@@ -226,10 +213,7 @@
861         EXAMPLES::
862         
863             sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
864-            sage: '_H_adjacency_matrix' in p.__dict__
865-            False
866-            sage: p._init_facet_adjacency_matrix()
867-            sage: p._H_adjacency_matrix
868+            sage: p._facet_adjacency_matrix()
869             [0 1 1]
870             [1 0 1]
871             [1 1 0]
872@@ -250,11 +234,9 @@
873             Hrep = face.element.ambient_Hrepresentation()
874             if len(Hrep) == 2:
875                 set_adjacent(Hrep[0], Hrep[1])
876-
877-        self._H_adjacency_matrix = M
878-
879-
880-    def _init_vertex_adjacency_matrix(self):
881+        return M
882+
883+    def _vertex_adjacency_matrix(self):
884         """
885         Compute the vertex adjacency matrix in case it has not been
886         computed during initialization.
887@@ -262,10 +244,7 @@
888         EXAMPLES::
889         
890             sage: p = Polyhedron(vertices=[(0,0),(1,0),(0,1)])
891-            sage: '_V_adjacency_matrix' in p.__dict__
892-            False
893-            sage: p._init_vertex_adjacency_matrix()
894-            sage: p._V_adjacency_matrix
895+            sage: p._vertex_adjacency_matrix()
896             [0 1 1]
897             [1 0 1]
898             [1 1 0]
899@@ -293,168 +272,105 @@
900         for r in self.ray_generator():
901             for vrep in self.Vrep_generator():
902                 set_adjacent(r, vrep)
903-               
904-        self._V_adjacency_matrix = M
905-
906-
907-    def __lt__(self, other):
908+        return M
909+
910+    def delete(self):
911         """
912-        Test whether ``self`` is a strict sub-polyhedron of ``other``.
913+        Delete this polyhedron.
914+       
915+        This speeds up creation of new polyhedra by reusing
916+        objects. After recycling a polyhedron object, it is not in a
917+        consistent state any more and neither the polyhedron nor its
918+        H/V-representation objects may be used any more.
919+
920+        .. seealso:: :meth:`~sage.geometry.polyhedron.Polyhedra_base.recycle`
921+
922+
923+        EXAMPLES::
924+
925+            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
926+            sage: p.delete()
927+
928+            sage: def loop_polyhedra():
929+            ...       for i in range(0,100):
930+            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
931+
932+            sage: timeit('loop_polyhedra()', repeat=25)                   # random output
933+            5 loops, best of 25: 44.2 ms per loop
934+
935+            sage: def loop_polyhedra_with_recycling():
936+            ...       for i in range(0,100):
937+            ...           p = Polyhedron([(0,0),(1,0),(0,1),(1,1)])
938+            ...           p.delete()
939+
940+            sage: timeit('loop_polyhedra_with_recycling()', repeat=25)    # random output
941+            25 loops, best of 25: 36.3 ms per loop
942+        """
943+        self.parent().recycle(self)
944+        self._Hrepresentation = None
945+        self._Vrepresentation = None
946+
947+    def base_extend(self, base_ring, backend=None):
948+        """
949+        EXAMPLES::
950+           
951+            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ);  P
952+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray
953+            sage: P.base_extend(QQ)
954+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray
955+        """
956+        new_parent = self.parent().base_extend(base_ring, backend)
957+        return new_parent(self)
958+
959+    def __cmp__(self, other):
960+        """
961+        Compare ``self`` and ``other``.
962 
963         INPUT:
964-
965-        - ``other`` -- a :class:`Polyhedron`.
966+       
967+        - ``other`` -- anything.
968 
969         OUTPUT:
970-
971-        Boolean.
972+       
973+        `-1, 0, +1` depending on how ``self`` and ``other``
974+        compare. If ``other`` is a polyhedron, then the comparison
975+        operator "less or equal than" means "is contained in", and
976+        "less than" means "is strictly contained in".
977 
978         EXAMPLES::
979 
980             sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
981             sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
982-            sage: P < Q   # indirect doctest
983+            sage: cmp(P,Q)
984+            1
985+            sage: cmp(Q,P)
986+            -1
987+            sage: cmp(P,P)
988+            0
989+            sage: cmp(P, 'anything')
990+            -1
991+
992+       The polytope ``Q`` is contained in ``P``::
993+           
994+            sage: P > Q
995+            True
996+            sage: P < Q
997             False
998-            sage: P < P   # indirect doctest
999-            False
1000-            sage: Q < P   # indirect doctest
1001-            True
1002-        """
1003-        return self._is_subpolyhedron(other) and not other._is_subpolyhedron(self)
1004-
1005-
1006-    def __le__(self, other):
1007-        """
1008-        Test whether ``self`` is a (not necessarily strict)
1009-        sub-polyhedron of ``other``.
1010-
1011-        INPUT:
1012-
1013-        - ``other`` -- a :class:`Polyhedron`.
1014-
1015-        OUTPUT:
1016-
1017-        Boolean.
1018-
1019-        EXAMPLES::
1020-
1021-            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
1022-            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
1023-            sage: P <= Q   # indirect doctest
1024-            False
1025-            sage: P <= P   # indirect doctest
1026-            True
1027-            sage: Q <= P   # indirect doctest
1028-            True
1029-        """
1030-        return self._is_subpolyhedron(other)
1031-       
1032-
1033-    def __eq__(self, other):
1034-        """
1035-        Test whether ``self`` is a strict sub-polyhedron of ``other``.
1036-
1037-        INPUT:
1038-
1039-        - ``other`` -- a :class:`Polyhedron`.
1040-
1041-        OUTPUT:
1042-
1043-        Boolean.
1044-
1045-        EXAMPLES::
1046-
1047-            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
1048-            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
1049-            sage: P == Q   # indirect doctest
1050-            False
1051-            sage: P == P   # indirect doctest
1052-            True
1053-            sage: Q == P   # indirect doctest
1054+            sage: P == Q
1055             False
1056         """
1057-        return self._is_subpolyhedron(other) and other._is_subpolyhedron(self)
1058-
1059-
1060-    def __ne__(self, other):
1061-        """
1062-        Test whether ``self`` is not equal to ``other``.
1063-
1064-        INPUT:
1065-
1066-        - ``other`` -- a :class:`Polyhedron`.
1067-
1068-        OUTPUT:
1069-
1070-        Boolean.
1071-
1072-        EXAMPLES::
1073-
1074-            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
1075-            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
1076-            sage: P != Q   # indirect doctest
1077-            True
1078-            sage: P != P   # indirect doctest
1079-            False
1080-            sage: Q != P   # indirect doctest
1081-            True
1082-        """
1083-        return not self.__eq__(other)
1084-
1085-
1086-    def __gt__(self, other):
1087-        """
1088-        Test whether ``self`` is a strict super-polyhedron of ``other``.
1089-
1090-        INPUT:
1091-
1092-        - ``other`` -- a :class:`Polyhedron`.
1093-
1094-        OUTPUT:
1095-
1096-        Boolean.
1097-
1098-        EXAMPLES::
1099-
1100-            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
1101-            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
1102-            sage: P > Q   # indirect doctest
1103-            True
1104-            sage: P > P   # indirect doctest
1105-            False
1106-            sage: Q > P   # indirect doctest
1107-            False
1108-        """
1109-        return other._is_subpolyhedron(self) and not self._is_subpolyhedron(other)
1110-
1111-
1112-    def __ge__(self, other):
1113-        """
1114-        Test whether ``self`` is a (not necessarily strict)
1115-        super-polyhedron of ``other``.
1116-
1117-        INPUT:
1118-
1119-        - ``other`` -- a :class:`Polyhedron`.
1120-
1121-        OUTPUT:
1122-
1123-        Boolean.
1124-
1125-        EXAMPLES::
1126-
1127-            sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)])
1128-            sage: Q = Polyhedron(vertices=[(1,0), (0,1)])
1129-            sage: P >= Q   # indirect doctest
1130-            True
1131-            sage: P >= P   # indirect doctest
1132-            True
1133-            sage: Q >= P   # indirect doctest
1134-            False
1135-        """
1136-        return other._is_subpolyhedron(self)
1137-
1138-
1139+        c = cmp(self.ambient_dim(), other.ambient_dim())
1140+        if c != 0: return c
1141+        c0 = self._is_subpolyhedron(other)
1142+        c1 = other._is_subpolyhedron(self)
1143+        if c0 and c1: 
1144+            return 0
1145+        if c0: 
1146+            return -1
1147+        else:
1148+            return +1
1149+           
1150+    @coerce_binop
1151     def _is_subpolyhedron(self, other):
1152         """
1153         Test whether ``self`` is a (not necessarily strict)
1154@@ -477,12 +393,9 @@
1155             sage: Q._is_subpolyhedron(P)
1156             True
1157         """
1158-        if not is_Polyhedron(other):
1159-            raise ValueError('Can only compare Polyhedron objects.')
1160         return all( other_H.contains(self_V)
1161                     for other_H, self_V in 
1162                     CartesianProduct(other.Hrep_generator(), self.Vrep_generator()) )
1163-       
1164 
1165     def plot(self, **kwds):
1166         """
1167@@ -513,10 +426,8 @@
1168         raise NotImplementedError('Plotting of '+str(self.ambient_dim())+
1169                                   '-dimensional polyhedra not implemented')
1170 
1171-
1172     show = plot
1173 
1174-
1175     def _repr_(self):
1176         """
1177         Return a description of the polyhedron.
1178@@ -525,10 +436,10 @@
1179 
1180             sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]])
1181             sage: poly_test._repr_()
1182-            'A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices'
1183+            'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices'
1184             sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]])
1185             sage: grammar_test._repr_()
1186-            'A 0-dimensional polyhedron in QQ^6 defined as the convex hull of 1 vertex'
1187+            'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex'
1188         """
1189         desc = ''
1190         if self.n_vertices()==0:
1191@@ -564,7 +475,6 @@
1192 
1193         return desc
1194 
1195-
1196     def cdd_Hrepresentation(self):
1197         """
1198         Write the inequalities/equations data of the polyhedron in
1199@@ -592,13 +502,16 @@
1200         try: 
1201             cdd_type = self._cdd_type
1202         except AttributeError:
1203-            ring_to_cdd = { QQ:'rational', RDF:'real' }
1204-            cdd_type = ring_to_cdd[self.base_ring()]
1205+            if self.base_ring() is ZZ or self.base_ring() is QQ:
1206+                cdd_type = 'rational'
1207+            elif self.base_ring() is RDF:
1208+                cdd_type = 'real'
1209+            else:
1210+                raise TypeError('The base ring must be ZZ, QQ, or RDF')
1211         return cdd_Hrepresentation(cdd_type, 
1212                                    list(self.inequality_generator()),
1213                                    list(self.equation_generator()) )
1214 
1215-
1216     def cdd_Vrepresentation(self):
1217         """
1218         Write the vertices/rays/lines data of the polyhedron in cdd's
1219@@ -626,14 +539,18 @@
1220         try:
1221             cdd_type = self._cdd_type
1222         except AttributeError:
1223-            ring_to_cdd = { QQ:'rational', RDF:'real' }
1224-            cdd_type = ring_to_cdd[self.base_ring()]
1225+            if self.base_ring() is ZZ or self.base_ring() is QQ:
1226+                cdd_type = 'rational'
1227+            elif self.base_ring() is RDF:
1228+                cdd_type = 'real'
1229+            else:
1230+                raise TypeError('The base ring must be ZZ, QQ, or RDF')
1231         return cdd_Vrepresentation(cdd_type,
1232                                    list(self.vertex_generator()),
1233                                    list(self.ray_generator()),
1234                                    list(self.line_generator()) )
1235-
1236-
1237+   
1238+    @cached_method
1239     def n_equations(self):
1240         """ 
1241         Return the number of equations. The representation will
1242@@ -646,13 +563,9 @@
1243             sage: p.n_equations()
1244             1
1245         """
1246-        try:
1247-            return self._n_equations
1248-        except AttributeError:
1249-            self._n_equations = len(self.equations())
1250-            return self._n_equations
1251-
1252-
1253+        return len(self.equations())
1254+
1255+    @cached_method
1256     def n_inequalities(self):
1257         """ 
1258         Return the number of inequalities. The representation will
1259@@ -664,29 +577,16 @@
1260             sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]])
1261             sage: p.n_inequalities()
1262             3
1263-        """
1264-        try:
1265-            return self._n_inequalities
1266-        except AttributeError:
1267-            self._n_inequalities = 0
1268-            for i in self.inequalities(): self._n_inequalities += 1
1269-            return self._n_inequalities
1270-
1271-
1272-    def n_facets(self):
1273-        """
1274-        Return the number of facets in the polyhedron.  This is the
1275-        same as the n_inequalities function.
1276-
1277-        EXAMPLES::
1278 
1279             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)])
1280             sage: p.n_facets()
1281             8
1282         """
1283-        return self.n_inequalities()
1284-
1285-
1286+        return len(self.inequalities())
1287+
1288+    n_facets = n_inequalities
1289+
1290+    @cached_method
1291     def n_vertices(self):
1292         """ 
1293         Return the number of vertices. The representation will
1294@@ -698,14 +598,9 @@
1295             sage: p.n_vertices()
1296             2
1297         """
1298-        try:
1299-            return self._n_vertices
1300-        except AttributeError:
1301-            self._n_vertices = 0
1302-            for v in self.vertex_generator(): self._n_vertices += 1
1303-            return self._n_vertices
1304-
1305-
1306+        return len(self.vertices())
1307+
1308+    @cached_method
1309     def n_rays(self):
1310         """ 
1311         Return the number of rays. The representation will
1312@@ -717,14 +612,9 @@
1313             sage: p.n_rays()
1314             1
1315         """
1316-        try:
1317-            return self._n_rays
1318-        except AttributeError:
1319-            self._n_rays = 0
1320-            for r in self.rays(): self._n_rays += 1
1321-            return self._n_rays
1322-
1323-
1324+        return len(self.rays())
1325+
1326+    @cached_method
1327     def n_lines(self):
1328         """ 
1329         Return the number of lines. The representation will
1330@@ -736,12 +626,7 @@
1331             sage: p.n_lines()
1332             1
1333         """
1334-        try:
1335-            return self._n_lines
1336-        except AttributeError:
1337-            self._n_lines = len(self.lines())
1338-            return self._n_lines
1339-
1340+        return len(self.lines())
1341 
1342     def Hrepresentation(self, index=None):
1343         """
1344@@ -767,11 +652,10 @@
1345             sage: p.Hrepresentation(0) == p.Hrepresentation() [0]
1346             True
1347         """
1348-        if index==None:
1349+        if index is None:
1350             return self._Hrepresentation
1351         else:
1352             return self._Hrepresentation[index]
1353-           
1354 
1355     def Hrep_generator(self):
1356         """
1357@@ -787,7 +671,7 @@
1358         for H in self.Hrepresentation():
1359             yield H
1360 
1361-
1362+    @cached_method
1363     def n_Hrepresentation(self):
1364         """
1365         Return the number of objects that make up the
1366@@ -807,7 +691,6 @@
1367         """
1368         return len(self.Hrepresentation())
1369 
1370-
1371     def Vrepresentation(self, index=None):
1372         """
1373         Return the objects of the V-representation. Each entry is
1374@@ -832,12 +715,12 @@
1375             sage: p.Vrepresentation(0) == p.Vrepresentation() [0]
1376             True
1377         """
1378-        if index==None: 
1379+        if index is None: 
1380             return self._Vrepresentation
1381         else:
1382             return self._Vrepresentation[index]
1383 
1384-
1385+    @cached_method
1386     def n_Vrepresentation(self):
1387         """
1388         Return the number of objects that make up the
1389@@ -857,7 +740,6 @@
1390         """
1391         return len(self.Vrepresentation())
1392 
1393-
1394     def Vrep_generator(self):
1395         """
1396         Returns an iterator over the objects of the V-representation
1397@@ -875,9 +757,8 @@
1398         for V in self.Vrepresentation():
1399             yield V
1400 
1401-
1402     def facial_adjacencies(self):
1403-        """
1404+        r"""
1405         Return the list of face indices (i.e. indices of
1406         H-representation objects) and the indices of faces adjacent to
1407         them.
1408@@ -892,6 +773,8 @@
1409 
1410             sage: p = polytopes.permutahedron(4)
1411             sage: p.facial_adjacencies()[0:3]
1412+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is deprecated.
1413+            Use self.Hrepresentation(i).neighbors() instead.
1414             [[0, [1, 2, 5, 10, 12, 13]], [1, [0, 2, 5, 7, 9, 11]], [2, [0, 1, 10, 11]]]
1415             sage: f0 = p.Hrepresentation(0)
1416             sage: f0.index() == 0
1417@@ -900,6 +783,9 @@
1418             sage: p.facial_adjacencies()[0] == f0_adjacencies
1419             True
1420         """
1421+        from sage.misc.misc import deprecation
1422+        deprecation('This method is deprecated. Use self.Hrepresentation(i).neighbors() instead.', 
1423+                    'Sage Version 4.7.2')
1424         try:
1425             return self._facial_adjacencies
1426         except AttributeError:
1427@@ -909,7 +795,6 @@
1428                   ] for h in self.Hrepresentation() ]
1429             return self._facial_adjacencies
1430 
1431-
1432     def facial_incidences(self):
1433         """
1434         Return the face-vertex incidences in the form `[f_i, [v_{i_0}, v_{i_1},\dots ,v_{i_2}]]`.
1435@@ -931,6 +816,8 @@
1436 
1437             sage: p = Polyhedron(vertices = [[5,0,0],[0,5,0],[5,5,0],[0,0,0],[2,2,5]])
1438             sage: p.facial_incidences()
1439+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
1440+            deprecated. Use self.Hrepresentation(i).incident() instead.
1441             [[0, [0, 1, 3, 4]],
1442              [1, [0, 1, 2]],
1443              [2, [0, 2, 3]],
1444@@ -955,6 +842,9 @@
1445             sage: p.incidence_matrix().column(4)
1446             (0, 1, 1, 0, 1)
1447         """
1448+        from sage.misc.misc import deprecation
1449+        deprecation('This method is deprecated. Use self.Hrepresentation(i).incident() instead.', 
1450+                    'Sage Version 4.7.2')
1451         try:
1452             return self._facial_incidences
1453         except AttributeError:
1454@@ -964,7 +854,6 @@
1455                   ] for h in self.Hrepresentation() ]
1456             return self._facial_incidences
1457 
1458-
1459     def vertex_adjacencies(self):
1460         """
1461         Return a list of vertex indices and their adjacent vertices.
1462@@ -983,6 +872,8 @@
1463 
1464             sage: permuta3 = Polyhedron(vertices = permutations([1,2,3,4]))
1465             sage: permuta3.vertex_adjacencies()[0:3]
1466+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
1467+            deprecated. Use self.Vrepresentation(i).neighbors() instead.
1468             [[0, [1, 2, 6]], [1, [0, 3, 7]], [2, [0, 4, 8]]]
1469             sage: v0 = permuta3.Vrepresentation(0)
1470             sage: v0.index() == 0
1471@@ -993,6 +884,9 @@
1472             sage: permuta3.vertex_adjacencies()[0] == v0_adjacencies
1473             True
1474         """
1475+        from sage.misc.misc import deprecation
1476+        deprecation('This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.', 
1477+                    'Sage Version 4.7.2')
1478         try:
1479             return self._vertex_adjacencies
1480         except AttributeError:
1481@@ -1002,7 +896,6 @@
1482                   ] for v in self.Vrepresentation() ]
1483             return self._vertex_adjacencies
1484 
1485-
1486     def vertex_incidences(self):
1487         """
1488         Return the vertex-face incidences in the form `[v_i, [f_{i_0}, f_{i_1},\dots ,f_{i_2}]]`.
1489@@ -1017,6 +910,8 @@
1490 
1491             sage: p = polytopes.n_simplex(3)
1492             sage: p.vertex_incidences()
1493+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
1494+            deprecated. Use self.Vrepresentation(i).incident() instead.
1495             [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
1496             sage: v0 = p.Vrepresentation(0)
1497             sage: v0.index() == 0
1498@@ -1024,6 +919,9 @@
1499             sage: p.vertex_incidences()[0] == [ v0.index(), [h.index() for h in v0.incident()] ]
1500             True
1501         """
1502+        from sage.misc.misc import deprecation
1503+        deprecation('This method is deprecated. Use self.Vrepresentation(i).incident() instead.', 
1504+                    'Sage Version 4.7.2')
1505         try:
1506             return self._vertex_incidences
1507         except AttributeError:
1508@@ -1033,7 +931,6 @@
1509                   ] for v in self.Vrepresentation() ]
1510             return self._vertex_incidences
1511 
1512-
1513     def inequality_generator(self):
1514         """
1515         Return  a generator for the defining inequalities of the
1516@@ -1061,24 +958,48 @@
1517             if H.is_inequality():
1518                 yield H
1519 
1520-
1521+    @cached_method
1522     def inequalities(self):
1523         """
1524+        Return all inequalities.
1525+
1526+        OUTPUT:
1527+
1528+        A tuple of inequalities.
1529+
1530+        EXAMPLES::
1531+
1532+            sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
1533+            sage: p.inequalities()[0:3]
1534+            (An inequality (1, 0, 0) x + 0 >= 0, 
1535+             An inequality (0, 1, 0) x + 0 >= 0, 
1536+             An inequality (0, 0, 1) x + 0 >= 0)
1537+            sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
1538+            sage: ieqs = p3.inequalities()
1539+            sage: ieqs[0]
1540+            An inequality (0, 1, 1, 1) x - 6 >= 0
1541+            sage: list(_)
1542+            [-6, 0, 1, 1, 1]
1543+        """
1544+        return tuple(self.inequality_generator())
1545+   
1546+    def inequalities_list(self):
1547+        """
1548         Return a list of inequalities as coefficient lists.
1549 
1550         .. NOTE::
1551         
1552-            It is recommended to use :meth:`inequality_generator`
1553-            instead to iterate over the list of :class:`Inequality`
1554-            objects.
1555+            It is recommended to use :meth:`inequalities` or
1556+            :meth:`inequality_generator` instead to iterate over the
1557+            list of :class:`Inequality` objects.
1558 
1559         EXAMPLES::
1560 
1561             sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]])
1562-            sage: p.inequalities()[0:3]
1563+            sage: p.inequalities_list()[0:3]
1564             [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
1565             sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
1566-            sage: ieqs = p3.inequalities()
1567+            sage: ieqs = p3.inequalities_list()
1568             sage: ieqs[0]
1569             [-6, 0, 1, 1, 1]
1570             sage: ieqs[-1]
1571@@ -1086,12 +1007,7 @@
1572             sage: ieqs == [list(x) for x in p3.inequality_generator()]
1573             True
1574         """
1575-        try:
1576-            return self._inequalities
1577-        except AttributeError:
1578-            self._ieqs = [list(x) for x in self.inequality_generator()]
1579-            return self._ieqs
1580-
1581+        return [list(x) for x in self.inequality_generator()]
1582 
1583     def ieqs(self):
1584         """
1585@@ -1101,11 +1017,15 @@
1586         
1587             sage: p3 = Polyhedron(vertices = permutations([1,2,3,4]))
1588             sage: p3.ieqs() == p3.inequalities()
1589+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is 
1590+            deprecated. Use inequalities() instead.
1591             True
1592         """
1593+        from sage.misc.misc import deprecation
1594+        deprecation('This method is deprecated. Use inequalities() instead.',
1595+                    'Sage Version 4.7.2')
1596         return self.inequalities()
1597 
1598-
1599     def equation_generator(self):
1600         """
1601         Return a generator for the linear equations satisfied by the
1602@@ -1122,9 +1042,25 @@
1603             if H.is_equation():
1604                 yield H
1605 
1606-
1607+    @cached_method
1608     def equations(self):
1609         """
1610+        Return all linear constraints of the polyhedron.
1611+
1612+        OUTPUT:
1613+
1614+        A tuple of equations.
1615+
1616+        EXAMPLES::
1617+
1618+            sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
1619+            sage: test_p.equations()
1620+            (An equation (1, 1, 1, 1) x - 10 == 0,)
1621+        """
1622+        return tuple(self.equation_generator())
1623+
1624+    def equations_list(self):
1625+        """
1626         Return the linear constraints of the polyhedron. As with
1627         inequalities, each constraint is given as [b -a1 -a2 ... an]
1628         where for variables x1, x2,..., xn, the polyhedron satisfies
1629@@ -1132,21 +1068,19 @@
1630 
1631         .. NOTE::
1632         
1633-            It is recommended to use :meth:`equation_generator()` instead
1634-            to iterate over the list of :class:`Equation` objects.
1635+            It is recommended to use :meth:`equations` or
1636+            :meth:`equation_generator()` instead to iterate over the
1637+            list of
1638+            :class:`~sage.geometry.polyhedron.representation.Equation`
1639+            objects.
1640 
1641         EXAMPLES::
1642 
1643             sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
1644-            sage: test_p.equations()
1645+            sage: test_p.equations_list()
1646             [[-10, 1, 1, 1, 1]]
1647         """
1648-        try:
1649-            return self._equations
1650-        except: 
1651-            self._equations = [list(eq) for eq in self.equation_generator()]
1652-            return self._equations
1653-
1654+        return [list(eq) for eq in self.equation_generator()]
1655 
1656     def linearities(self):
1657         """
1658@@ -1160,14 +1094,18 @@
1659 
1660             sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]])
1661             sage: test_p.linearities()
1662+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2) This method is
1663+            deprecated. Use equations_list() instead.
1664             [[-10, 1, 1, 1, 1]]
1665-            sage: test_p.linearities() == test_p.equations()
1666+            sage: test_p.linearities() == test_p.equations_list()
1667             True
1668         """
1669-        return self.equations()
1670-
1671-
1672-    def vertices(self):
1673+        from sage.misc.misc import deprecation
1674+        deprecation('This method is deprecated. Use equations_list() instead.', 
1675+                    'Sage Version 4.7.2')
1676+        return self.equations_list()
1677+
1678+    def vertices_list(self):
1679         """
1680         Return a list of vertices of the polyhedron.
1681 
1682@@ -1179,22 +1117,17 @@
1683         EXAMPLES::
1684 
1685             sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
1686-            sage: triangle.vertices()
1687+            sage: triangle.vertices_list()
1688             [[0, 1], [1, 0], [1, 1]]
1689             sage: a_simplex = Polyhedron(ieqs = [
1690             ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
1691             ...        ], eqns = [[1,-1,-1,-1,-1]])
1692-            sage: a_simplex.vertices()
1693+            sage: a_simplex.vertices_list()
1694             [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
1695-            sage: a_simplex.vertices() == [list(v) for v in a_simplex.vertex_generator()]
1696+            sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()]
1697             True
1698         """
1699-        try:
1700-            return self._vertices
1701-        except:
1702-            self._vertices = [list(x) for x in self.vertex_generator()]
1703-            return self._vertices
1704-
1705+        return [list(x) for x in self.vertex_generator()]
1706         
1707     def vertex_generator(self):
1708         """
1709@@ -1225,8 +1158,69 @@
1710         for V in self.Vrepresentation():
1711             if V.is_vertex():
1712                 yield V
1713+
1714+    @cached_method
1715+    def vertices(self):
1716+        """
1717+        Return all vertices of the polyhedron.
1718+
1719+        OUTPUT:
1720+
1721+        A tuple of vertices.
1722+
1723+        EXAMPLES::
1724+
1725+            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
1726+            sage: triangle.vertices()
1727+            (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1))
1728+            sage: a_simplex = Polyhedron(ieqs = [
1729+            ...            [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]
1730+            ...        ], eqns = [[1,-1,-1,-1,-1]])
1731+            sage: a_simplex.vertices()
1732+            (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0), 
1733+             A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1))
1734+        """
1735+        return tuple(self.vertex_generator())       
1736+
1737+    @cached_method
1738+    def vertices_matrix(self, base_ring=None):
1739+        """
1740+        Return the coordinates of the vertices as the columns of a matrix.
1741+
1742+        INPUT:
1743         
1744-
1745+        - ``base_ring`` -- A ring or ``None`` (default). The base ring
1746+          of the returned matrix. If not specified, the base ring of
1747+          the polyhedron is used.
1748+
1749+        OUTPUT:
1750+
1751+        A matrix over ``base_ring`` whose columns are the coordinates
1752+        of the vertices. A ``TypeError`` is raised if the coordinates
1753+        cannot be converted to ``base_ring``.
1754+
1755+        EXAMPLES::
1756+
1757+            sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]])
1758+            sage: triangle.vertices_matrix()
1759+            [0 1 1]
1760+            [1 0 1]
1761+            sage: (triangle/2).vertices_matrix()
1762+            [  0 1/2 1/2]
1763+            [1/2   0 1/2]
1764+            sage: (triangle/2).vertices_matrix(ZZ)
1765+            Traceback (most recent call last):
1766+            ...
1767+            TypeError: no conversion of this rational to integer
1768+        """
1769+        if base_ring is None:
1770+            base_ring = self.base_ring()
1771+        m = matrix(base_ring, self.ambient_dim(), self.n_vertices())
1772+        for i,v in enumerate(self.vertices()):
1773+            for j in range(0,self.ambient_dim()):
1774+                m[j,i] = v[j]
1775+        return m
1776+       
1777     def ray_generator(self):
1778         """
1779         Return a generator for the rays of the polyhedron.
1780@@ -1242,15 +1236,34 @@
1781             if V.is_ray():
1782                 yield V
1783 
1784-
1785+    @cached_method
1786     def rays(self):
1787         """
1788         Return a list of rays as coefficient lists.
1789 
1790+        OUTPUT:
1791+
1792+        A tuple of rays.
1793+
1794+        EXAMPLES::
1795+
1796+            sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
1797+            sage: p.rays()
1798+            (A ray in the direction (1, 0, 0),
1799+             A ray in the direction (0, 1, 0),
1800+             A ray in the direction (0, 0, 1))
1801+        """
1802+        return tuple(self.ray_generator())
1803+
1804+    def rays_list(self):
1805+        """
1806+        Return a list of rays as coefficient lists.
1807+
1808         .. NOTE::
1809         
1810-            It is recommended to use :meth:`ray_generator` instead to
1811-            iterate over the list of :class:`Ray` objects.
1812+            It is recommended to use :meth:`rays` or
1813+            :meth:`ray_generator` instead to iterate over the list of
1814+            :class:`Ray` objects.
1815 
1816         OUTPUT:
1817 
1818@@ -1259,17 +1272,12 @@
1819         EXAMPLES::
1820 
1821             sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]])
1822-            sage: p.rays()
1823+            sage: p.rays_list()
1824             [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
1825-            sage: p.rays() == [list(r) for r in p.ray_generator()]
1826+            sage: p.rays_list() == [list(r) for r in p.ray_generator()]
1827             True
1828         """
1829-        try:
1830-            return self._rays
1831-        except:
1832-            self._rays = [list(x) for x in self.ray_generator()]
1833-            return self._rays
1834-
1835+        return [list(x) for x in self.ray_generator()]
1836 
1837     def line_generator(self):
1838         """
1839@@ -1285,9 +1293,25 @@
1840             if V.is_line():
1841                 yield V
1842 
1843-
1844+    @cached_method
1845     def lines(self):
1846         """
1847+        Return all lines of the polyhedron.
1848+       
1849+        OUTPUT:
1850+
1851+        A tuple of lines.
1852+
1853+        EXAMPLES::
1854+
1855+            sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
1856+            sage: p.lines()
1857+            (A line in the direction (1, 0),)
1858+        """
1859+        return tuple(self.line_generator())
1860+
1861+    def lines_list(self):
1862+        """
1863         Return a list of lines of the polyhedron.  The line data is given
1864         as a list of coordinates rather than as a Hrepresentation object.
1865 
1866@@ -1299,17 +1323,12 @@
1867         EXAMPLES::
1868 
1869             sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]])
1870-            sage: p.lines()
1871+            sage: p.lines_list()
1872             [[1, 0]]
1873-            sage: p.lines() == [list(x) for x in p.line_generator()]
1874+            sage: p.lines_list() == [list(x) for x in p.line_generator()]
1875             True
1876         """
1877-        try:
1878-            return self._lines
1879-        except:
1880-            self._lines = [list(x) for x in self.line_generator()]
1881-            return self._lines   
1882-
1883+        return [list(x) for x in self.line_generator()]
1884                 
1885     def bounded_edges(self):
1886         """
1887@@ -1336,9 +1355,7 @@
1888                 if self.vertex_adjacency_matrix()[i,j] == 0: continue
1889                 yield (obj[i], obj[j])
1890 
1891-
1892-    @cached_method
1893-    def ambient_space(self):
1894+    def Vrepresentation_space(self):
1895         r"""
1896         Return the ambient vector space.
1897         
1898@@ -1349,15 +1366,15 @@
1899         EXAMPLES::
1900 
1901             sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
1902-            sage: poly_test.ambient_space()
1903-            Vector space of dimension 4 over Rational Field
1904+            sage: poly_test.Vrepresentation_space()
1905+            Ambient free module of rank 4 over the principal ideal domain Integer Ring
1906+            sage: poly_test.ambient_space() is poly_test.Vrepresentation_space()
1907+            True
1908         """
1909-        from sage.modules.free_module import FreeModule
1910-        return FreeModule(self.base_ring(), self.ambient_dim())
1911-
1912-    Vrepresentation_space = ambient_space
1913-
1914-    @cached_method
1915+        return self.parent().Vrepresentation_space()
1916+
1917+    ambient_space = Vrepresentation_space
1918+
1919     def Hrepresentation_space(self):
1920         r"""
1921         Return the linear space containing the H-representation vectors.
1922@@ -1369,12 +1386,10 @@
1923         EXAMPLES::
1924         
1925             sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]])
1926-            sage: poly_test.ambient_space()
1927-            Vector space of dimension 4 over Rational Field
1928+            sage: poly_test.Hrepresentation_space()
1929+            Ambient free module of rank 5 over the principal ideal domain Integer Ring
1930         """
1931-        from sage.modules.free_module import VectorSpace
1932-        return VectorSpace(self.base_ring(), self.ambient_dim()+1)
1933-
1934+        return self.parent().Hrepresentation_space()
1935 
1936     def ambient_dim(self):
1937         r"""
1938@@ -1386,9 +1401,8 @@
1939             sage: poly_test.ambient_dim()
1940             4
1941         """
1942-        return self._ambient_dim
1943-
1944-           
1945+        return self.parent().ambient_dim()
1946+
1947     def dim(self):
1948         """
1949         Return the dimension of the polyhedron.
1950@@ -1403,26 +1417,7 @@
1951        """
1952         return self.ambient_dim() - self.n_equations()
1953 
1954-
1955-    def adjacency_matrix(self):
1956-        """
1957-        This is an alias for :meth:`vertex_adjacency_matrix`
1958-
1959-        EXAMPLES::
1960-
1961-            sage: polytopes.n_cube(3).adjacency_matrix()
1962-            [0 1 1 0 1 0 0 0]
1963-            [1 0 0 1 0 1 0 0]
1964-            [1 0 0 1 0 0 1 0]
1965-            [0 1 1 0 0 0 0 1]
1966-            [1 0 0 0 0 1 1 0]
1967-            [0 1 0 0 1 0 0 1]
1968-            [0 0 1 0 1 0 0 1]
1969-            [0 0 0 1 0 1 1 0]
1970-        """
1971-        return self.vertex_adjacency_matrix()
1972-
1973-
1974+    @cached_method
1975     def vertex_adjacency_matrix(self):
1976         """
1977         Return the binary matrix of vertex adjacencies.
1978@@ -1436,11 +1431,11 @@
1979             [1 1 1 0 1]
1980             [1 1 1 1 0]
1981         """
1982-        if '_V_adjacency_matrix' not in self.__dict__:
1983-            self._init_vertex_adjacency_matrix()
1984-        return self._V_adjacency_matrix;
1985-
1986-
1987+        return self._vertex_adjacency_matrix()
1988+
1989+    adjacency_matrix = vertex_adjacency_matrix
1990+
1991+    @cached_method
1992     def facet_adjacency_matrix(self):
1993         """
1994         Return the adjacency matrix for the facets and hyperplanes.
1995@@ -1454,11 +1449,9 @@
1996             [1 1 1 0 1]
1997             [1 1 1 1 0]
1998         """
1999-        if '_H_adjacency_matrix' not in self.__dict__:
2000-            self._init_facet_adjacency_matrix()
2001-        return self._H_adjacency_matrix;
2002-
2003-
2004+        return self._facet_adjacency_matrix()
2005+
2006+    @cached_method
2007     def incidence_matrix(self):
2008         """
2009         Return the incidence matrix.
2010@@ -1503,18 +1496,13 @@
2011             sage: p.incidence_matrix() [2,0]   # note: not symmetric
2012             0
2013         """
2014-        try: 
2015-            return self._incidence_matrix
2016-        except AttributeError:
2017-            self._incidence_matrix = matrix(ZZ, len(self.Vrepresentation()), 
2018-                                                len(self.Hrepresentation()), 0)
2019-            for V in self.Vrep_generator():
2020-                for H in self.Hrep_generator():
2021-                    if self._is_zero(H*V):
2022-                        self._incidence_matrix[V.index(),H.index()] = 1
2023-
2024-            return self._incidence_matrix
2025-
2026+        incidence_matrix = matrix(ZZ, self.n_Vrepresentation(), 
2027+                                  self.n_Hrepresentation(), 0)
2028+        for V in self.Vrep_generator():
2029+            for H in self.Hrep_generator():
2030+                if self._is_zero(H*V):
2031+                    incidence_matrix[V.index(),H.index()] = 1
2032+        return incidence_matrix
2033 
2034     def base_ring(self):
2035         """
2036@@ -1528,84 +1516,14 @@
2037         EXAMPLES::
2038 
2039             sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]])
2040-            sage: triangle.base_ring() == QQ
2041+            sage: triangle.base_ring() == ZZ
2042             True
2043         """
2044-        return self._base_ring
2045+        return self.parent().base_ring()
2046 
2047     field = base_ring
2048 
2049-
2050-    def coerce_field(self, other):
2051-        """
2052-        Return the common field for both ``self`` and ``other``.
2053-
2054-        INPUT:
2055-
2056-        - ``other`` -- must be either:
2057-       
2058-            * another ``Polyhedron`` object
2059-       
2060-            * `\QQ` or `RDF`
2061-       
2062-            * a constant that can be coerced to `\QQ` or `RDF`
2063-
2064-        OUTPUT:
2065-
2066-        Either `\QQ` or `RDF`. Raises ``TypeError`` if ``other`` is not a
2067-        suitable input.
2068-
2069-        .. NOTE::
2070-       
2071-            "Real" numbers in sage are not necessarily elements of
2072-            `RDF`. For example, the literal `1.0` is not.
2073-
2074-        EXAMPLES::
2075-
2076-            sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ)
2077-            sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF)
2078-            sage: triangle_QQ.coerce_field(QQ)
2079-            Rational Field
2080-            sage: triangle_QQ.coerce_field(triangle_RDF)
2081-            Real Double Field
2082-            sage: triangle_RDF.coerce_field(triangle_QQ)
2083-            Real Double Field
2084-            sage: triangle_QQ.coerce_field(RDF)
2085-            Real Double Field
2086-            sage: triangle_QQ.coerce_field(ZZ)
2087-            Rational Field
2088-            sage: triangle_QQ.coerce_field(1/2)
2089-            Rational Field
2090-            sage: triangle_QQ.coerce_field(0.5)
2091-            Real Double Field
2092-        """
2093-        try:
2094-            # other is a Polyhedron object?
2095-            other_field = other.field()
2096-        except AttributeError:
2097-
2098-            try:
2099-                # other is a constant?
2100-                other_parent = other.parent()
2101-            except AttributeError:
2102-                other_parent = other
2103-
2104-            # other is a field?
2105-            if QQ.coerce_map_from(other_parent) != None:
2106-                other_field = QQ
2107-            elif RDF.coerce_map_from(other_parent) != None:
2108-                other_field = RDF
2109-            else:
2110-                raise TypeError("cannot determine field from %s!" % other)
2111-
2112-        assert other_field==QQ or other_field==RDF
2113-           
2114-        if self.field()==RDF or other_field==RDF:
2115-            return RDF
2116-        else:
2117-            return QQ
2118-
2119-
2120+    @cached_method
2121     def center(self):
2122         """
2123         Return the average of the vertices.
2124@@ -1623,15 +1541,12 @@
2125             sage: p.center()
2126             (1, 0, 0)
2127         """
2128-        try: 
2129-            return self._center
2130-        except AttributeError:
2131-            self._center = vector(ZZ, [0]*self.ambient_dim())
2132-            for v in self.vertex_generator(): self._center += v.vector()
2133-            self._center /= self.n_vertices()
2134-            return self._center
2135-
2136-
2137+        center = vector(self.base_ring(), [0]*self.ambient_dim())
2138+        for v in self.vertex_generator(): center += v.vector()
2139+        center /= self.n_vertices()
2140+        return center
2141+
2142+    @cached_method
2143     def radius_square(self):
2144         """
2145         Return the square of the maximal distance from the center to
2146@@ -1647,15 +1562,12 @@
2147             sage: p.radius_square()
2148             720
2149         """
2150-        try: 
2151-            return self._radius_2
2152-        except AttributeError:
2153-            self._radius_2 = 0
2154-            for v in self.vertex_generator(): 
2155-                self._radius_2 += v.vector()*v.vector()
2156-            return self._radius_2
2157-
2158-
2159+        radius_2 = 0
2160+        for v in self.vertex_generator(): 
2161+            radius_2 += v.vector()*v.vector()
2162+        return radius_2
2163+
2164+    @cached_method
2165     def radius(self):
2166         """
2167         Return the maximal distance from the center to a vertex. All
2168@@ -1675,7 +1587,6 @@
2169         """
2170         return sqrt(self.radius_square())
2171 
2172-
2173     def is_compact(self):
2174         """
2175         Test for boundedness of the polytope.
2176@@ -1691,7 +1602,6 @@
2177         """
2178         return self.n_rays()==0 and self.n_lines()==0
2179 
2180-
2181     def is_simple(self):
2182         """
2183         Test for simplicity of a polytope.
2184@@ -1715,9 +1625,9 @@
2185             adj = [a for a in v.neighbors()]
2186             if len(adj) != self.dim():
2187                 return False
2188-
2189         return True
2190 
2191+    @cached_method
2192     def gale_transform(self):
2193         """
2194         Return the Gale transform of a polytope as described in the
2195@@ -1745,7 +1655,7 @@
2196         if not self.is_compact(): raise ValueError('Not a polytope.')
2197 
2198         A = matrix(self.n_vertices(), 
2199-                   [ [1]+list(x) for x in self.vertex_generator()])
2200+                   [ [1]+x for x in self.vertex_generator()])
2201         A = A.transpose()
2202         A_ker = A.right_kernel()
2203         return A_ker.basis_matrix().transpose().rows()
2204@@ -1815,7 +1725,7 @@
2205             [A vertex at (-1, -1, -1), A vertex at (-1, -1, 1), 
2206              A vertex at (-1, 1, -1), A vertex at (1, -1, -1)]
2207             sage: Polyhedron(simplex_vertices)
2208-            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
2209+            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
2210         """
2211         if not self.is_compact():
2212             raise NotImplementedError('I can only triangulate compact polytopes.')
2213@@ -1846,6 +1756,8 @@
2214             ...             ).triangulated_facial_incidences()
2215             doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
2216             This method is deprecated. Use triangulate() instead.
2217+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
2218+            This method is deprecated. Use self.Hrepresentation(i).incident() instead.
2219             [[0, [0, 1, 2]], [1, [0, 1, 3]], [2, [0, 2, 3]], [3, [1, 2, 3]]]
2220                             
2221         Otherwise some faces get split up to triangles::
2222@@ -1854,6 +1766,8 @@
2223             ...       [1,1,0],[0,0,1]]).triangulated_facial_incidences()
2224             doctest:...: DeprecationWarning: (Since Sage Version 4.7.1)
2225             This method is deprecated. Use triangulate() instead.
2226+            doctest:...: DeprecationWarning: (Since Sage Version 4.7.2)
2227+            This method is deprecated. Use self.Vrepresentation(i).neighbors() instead.
2228             [[0, [1, 2, 5]], [0, [2, 5, 3]], [0, [5, 3, 4]], [1, [0, 1, 2]],
2229              [2, [0, 2, 3]], [3, [0, 3, 4]], [4, [0, 4, 5]], [5, [0, 1, 5]]]
2230         """
2231@@ -1908,7 +1822,6 @@
2232         self._triangulated_facial_incidences = t_fac_incs
2233         return t_fac_incs
2234 
2235-
2236     def simplicial_complex(self):
2237         """
2238         Return a simplicial complex from a triangulation of the polytope.
2239@@ -1939,56 +1852,134 @@
2240         return SimplicialComplex(vertex_set = self.n_vertices(),
2241                                  maximal_faces = [x[1] for x in self.triangulated_facial_incidences()])
2242 
2243-    def __add__(self, other):
2244+    @coerce_binop
2245+    def Minkowski_sum(self, other):
2246         """
2247+        Return the Minkowski sum.
2248+
2249+        INPUT:
2250+
2251+        - ``other`` -- a :class:`Polyhedron_base`.
2252+
2253+        OUTPUT:
2254+       
2255         The Minkowski sum of ``self`` and ``other``.
2256-
2257-        INPUT:
2258-
2259-        - ``other`` -- a :class:`Polyhedron`.
2260-
2261+       
2262         EXAMPLES::
2263 
2264             sage: four_cube = polytopes.n_cube(4)
2265             sage: four_simplex = Polyhedron(vertices = [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
2266-            sage: unholy_union = four_cube + four_simplex
2267-            sage: unholy_union.dim()
2268-            4
2269-            sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]])
2270-            sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]])
2271-            sage: poly_spam_and_eggs = poly_spam + poly_spam + poly_eggs
2272-            sage: poly_spam_and_eggs.n_vertices()
2273-            12
2274+            sage: four_cube + four_simplex
2275+            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 36 vertices
2276+            sage: four_cube.Minkowski_sum(four_simplex) == four_cube + four_simplex
2277+            True
2278+
2279+            sage: poly_spam = Polyhedron([[3,4,5,2],[1,0,0,1],[0,0,0,0],[0,4,3,2],[-3,-3,-3,-3]], base_ring=ZZ)
2280+            sage: poly_eggs = Polyhedron([[5,4,5,4],[-4,5,-4,5],[4,-5,4,-5],[0,0,0,0]], base_ring=QQ)
2281+            sage: poly_spam + poly_spam + poly_eggs
2282+            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 12 vertices
2283         """
2284-        if is_Polyhedron(other):
2285-            new_vertices = []
2286-            for v1 in self.vertex_generator():
2287-                for v2 in other.vertex_generator():
2288-                    new_vertices.append(list(v1() + v2()))
2289+        new_vertices = []
2290+        for v1 in self.vertex_generator():
2291+            for v2 in other.vertex_generator():
2292+                new_vertices.append(list(v1() + v2()))
2293+        if new_vertices != []:
2294             new_rays = self.rays() + other.rays()
2295             new_lines = self.lines() + other.lines()
2296-            other_field = other.field()
2297-
2298-        else:  # assume other is a vector and try to add vertices
2299-            displacement = vector(other)
2300-            new_vertices = [list(x() + displacement) for x in self.vertex_generator()]
2301-            new_rays = self.rays()
2302-            new_lines = self.lines()
2303-            other_field = displacement.base_ring()
2304-
2305+            return self.parent().element_class(self.parent(), [new_vertices, new_rays, new_lines], None)
2306+        else:
2307+            return self.parent().element_class(self.parent(), None, None)
2308+
2309+    _add_ = Minkowski_sum
2310+
2311+    def translation(self, displacement):
2312+        """
2313+        Return the translated polyhedron.
2314+
2315+        INPUT:
2316+
2317+        - ``displacement`` -- a displacement vector or a list/tuple of
2318+          coordinates that determines a displacement vector.
2319+
2320+        OUTPUT:
2321+
2322+        The translated polyhedron.
2323+
2324+        EXAMPLES::
2325+       
2326+            sage: P = Polyhedron([[0,0],[1,0],[0,1]], base_ring=ZZ)
2327+            sage: P.translation([2,1])
2328+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
2329+            sage: P.translation( vector(QQ,[2,1]) )
2330+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
2331+        """
2332+        displacement = vector(displacement)
2333+        new_vertices = [x.vector()+displacement for x in self.vertex_generator()]
2334+        new_rays = self.rays()
2335+        new_lines = self.lines()
2336+        new_ring = self.parent()._coerce_base_ring(displacement.base_ring())
2337+        return Polyhedron(vertices=new_vertices, rays=new_rays, lines=new_lines, base_ring=new_ring)
2338+
2339+    @coerce_binop
2340+    def product(self, other):
2341+        """
2342+        Return the cartesian product.
2343+
2344+        INPUT:
2345+       
2346+        - ``other`` -- a :class:`Polyhedron_base`.
2347+
2348+        OUTPUT:
2349+
2350+        The cartesian product of ``self`` and ``other`` with a
2351+        suitable base ring to encompass the two.
2352+
2353+        EXAMPLES::
2354+
2355+            sage: P1 = Polyhedron([[0],[1]], base_ring=ZZ)
2356+            sage: P2 = Polyhedron([[0],[1]], base_ring=QQ)
2357+            sage: P1.product(P2)
2358+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
2359+
2360+        The cartesian product is the product in the semiring of polyhedra::
2361+
2362+            sage: P1 * P1
2363+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
2364+            sage: P1 * P2
2365+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
2366+            sage: P2 * P2
2367+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
2368+            sage: 2 * P1
2369+            A 1-dimensional polyhedron in ZZ^1 defined as the convex hull of 2 vertices
2370+            sage: P1 * 2.0
2371+            A 1-dimensional polyhedron in RDF^1 defined as the convex hull of 2 vertices
2372+        """
2373+        new_vertices = [ list(x)+list(y)
2374+                         for x in self.vertex_generator() for y in other.vertex_generator()]
2375+        new_rays = []
2376+        new_rays.extend( [ r+[0]*other.ambient_dim()
2377+                           for r in self.ray_generator() ] )
2378+        new_rays.extend( [ [0]*self.ambient_dim()+r
2379+                           for r in other.ray_generator() ] )
2380+        new_lines = []
2381+        new_lines.extend( [ l+[0]*other.ambient_dim()
2382+                            for l in self.line_generator() ] )
2383+        new_lines.extend( [ [0]*self.ambient_dim()+l
2384+                            for l in other.line_generator() ] )
2385         return Polyhedron(vertices=new_vertices,
2386                           rays=new_rays, lines=new_lines,
2387-                          base_ring=self.coerce_field(other_field))
2388-           
2389-
2390-    def __mul__(self, other):
2391+                          base_ring=self.parent()._coerce_base_ring(other))
2392+
2393+    _mul_ = product
2394+   
2395+    def dilation(self, scalar):
2396         """
2397-        Multiplication by ``other``.
2398+        Return the dilated (uniformly stretched) polyhedron.
2399 
2400         INPUT:
2401 
2402-        - ``other`` -- A scalar, not necessarily in :meth:`field`, or
2403-          a :class:`Polyhedron`.
2404+        - ``scalar`` -- A scalar, not necessarily in :meth:`base_ring`,
2405+          or a :class:`Polyhedron`.
2406 
2407         OUTPUT:
2408 
2409@@ -2001,65 +1992,68 @@
2410              sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
2411              sage: p.vertex_generator().next()
2412              A vertex at (2, 4, 8)
2413-             sage: p2 = p*2
2414+             sage: p2 = p.dilation(2)
2415              sage: p2.vertex_generator().next()
2416              A vertex at (4, 8, 16)
2417+             sage: p.dilation(2) == p * 2
2418+             True
2419         """
2420-        if is_Polyhedron(other):
2421-            new_vertices = [ list(x)+list(y)
2422-                             for x in self.vertex_generator() for y in other.vertex_generator()]
2423-            new_rays = []
2424-            new_rays.extend( [ list(r)+[0]*other.ambient_dim()
2425-                               for r in self.ray_generator() ] )
2426-            new_rays.extend( [ [0]*self.ambient_dim()+list(r)
2427-                               for r in other.ray_generator() ] )
2428-            new_lines = []
2429-            new_lines.extend( [ list(l)+[0]*other.ambient_dim()
2430-                                for l in self.line_generator() ] )
2431-            new_lines.extend( [ [0]*self.ambient_dim()+list(l)
2432-                               for l in other.line_generator() ] )
2433-        else:
2434-            new_vertices = [ list(other*v()) for v in self.vertex_generator()]
2435-            new_rays =  self.rays()
2436-            new_lines = self.lines()
2437-
2438+        new_vertices = [ list(scalar*v.vector()) for v in self.vertex_generator()]
2439+        new_rays =  self.rays()
2440+        new_lines = self.lines()
2441         return Polyhedron(vertices=new_vertices,
2442                           rays=new_rays, lines=new_lines,
2443-                          base_ring=self.coerce_field(other))
2444-
2445-
2446-    def __rmul__(self,other):
2447+                          base_ring=self.parent()._coerce_base_ring(scalar.parent()))
2448+
2449+    def _acted_upon_(self, actor, self_on_left):
2450         """
2451-        Right multiplication. 
2452-
2453-        See :meth:`__mul__` for details.
2454+        Implement the multiplicative action by scalars or other polyhedra.
2455+
2456+        INPUT:
2457+
2458+        - ``actor`` -- A scalar, not necessarily in :meth:`base_ring`,
2459+          or a :class:`Polyhedron`.
2460+
2461+        OUTPUT:
2462+
2463+        Multiplication by another polyhedron returns the product
2464+        polytope. Multiplication by a scalar returns the polytope
2465+        dilated by that scalar, possibly coerced to the bigger field.
2466 
2467         EXAMPLES::
2468 
2469+             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,6)])
2470+             sage: p._acted_upon_(2, True) == p.dilation(2)
2471+             True
2472+             sage: p*2 == p.dilation(2)
2473+             True
2474+             sage: p*p == p.product(p)
2475+             True
2476+             sage: p + vector(ZZ,[1,2,3]) == p.translation([1,2,3])
2477+             True
2478+        """
2479+        if is_Polyhedron(actor):
2480+            return self.product(actor)
2481+        if is_Vector(actor):
2482+            return self.translation(actor)
2483+        else:
2484+            return self.dilation(actor)
2485+
2486+    def __div__(self, scalar):
2487+        """
2488+        Divide by a scalar factor.
2489+
2490+        See :meth:`dilation` for details.
2491+
2492+        EXAMPLES::
2493+
2494             sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in srange(2,4)])
2495-            sage: p2 = 3*p + p
2496-            sage: p2.vertex_generator().next()
2497-            A vertex at (8, 16, 32)
2498+            sage: (p/5).Vrepresentation()
2499+            (A vertex at (2/5, 4/5, 8/5), A vertex at (3/5, 9/5, 27/5))
2500         """
2501-        return self.__mul__(other)
2502-
2503-
2504-    def union(self, other):
2505-        """
2506-        Deprecated.  Use ``self.convex_hull(other)`` instead.
2507-       
2508-        EXAMPLES::
2509-       
2510-            sage: Polyhedron(vertices=[[0]]).union( Polyhedron(vertices=[[1]]) )
2511-            doctest:...: DeprecationWarning: (Since Sage Version 4.4.4)
2512-            The function union is replaced by convex_hull.
2513-            A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices
2514-        """
2515-        from sage.misc.misc import deprecation
2516-        deprecation('The function union is replaced by convex_hull.', 'Sage Version 4.4.4')
2517-        return self.convex_hull(other)
2518-
2519-
2520+        return self.dilation(1/scalar)
2521+
2522+    @coerce_binop
2523     def convex_hull(self, other):
2524         """
2525         Return the convex hull of the set-theoretic union of the two
2526@@ -2086,12 +2080,9 @@
2527         hull_vertices = self.vertices() + other.vertices()
2528         hull_rays = self.rays() + other.rays()
2529         hull_lines = self.lines() + other.lines()
2530-        hull_field = self.coerce_field(other)
2531-        return Polyhedron(vertices=hull_vertices, 
2532-                          rays=hull_rays, lines=hull_lines, 
2533-                          base_ring=hull_field)
2534-
2535-
2536+        return self.parent().element_class(self.parent(), [hull_vertices, hull_rays, hull_lines], None)
2537+
2538+    @coerce_binop
2539     def intersection(self, other):
2540         """
2541         Return the intersection of one polyhedron with another.
2542@@ -2102,29 +2093,41 @@
2543 
2544         OUTPUT:
2545 
2546-        The intersection.
2547+        The intersection.
2548+
2549+        Note that the intersection of two `\ZZ`-polyhedra might not be
2550+        a `\ZZ`-polyhedron. In this case, a `\QQ`-polyhedron is
2551+        returned.
2552 
2553         EXAMPLES::
2554 
2555             sage: cube = polytopes.n_cube(3)
2556             sage: oct = polytopes.cross_polytope(3)
2557-            sage: cube_oct = cube.intersection(oct*2)
2558-            sage: len(list( cube_oct.vertex_generator() ))
2559-            12
2560-            sage: cube_oct
2561-            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 12 vertices
2562+            sage: cube.intersection(oct*2)
2563+            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 12 vertices
2564+
2565+       The intersection of two `\ZZ`-polyhedra is not necessarily a `\ZZ`-polyhedron::
2566+
2567+            sage: P = Polyhedron([(0,0),(1,1)], base_ring=ZZ)
2568+            sage: P.intersection(P)
2569+            A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices
2570+            sage: Q = Polyhedron([(0,1),(1,0)], base_ring=ZZ)
2571+            sage: P.intersection(Q)
2572+            A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
2573+            sage: _.Vrepresentation()
2574+            (A vertex at (1/2, 1/2),)
2575         """
2576-        new_ieqs = []
2577-        new_ieqs.extend(self.inequalities())
2578-        new_ieqs.extend(other.inequalities())
2579-
2580-        new_eqns = []
2581-        new_eqns.extend(self.equations())
2582-        new_eqns.extend(other.equations())
2583-
2584-        return Polyhedron(ieqs = new_ieqs, eqns = new_eqns, 
2585-                          base_ring=self.coerce_field(other))
2586-
2587+        new_ieqs = self.inequalities() + other.inequalities()
2588+        new_eqns = self.equations() + other.equations()
2589+        parent = self.parent()
2590+        try:
2591+            return parent.element_class(parent, None, [new_ieqs, new_eqns])
2592+        except TypeError,msg:
2593+            if self.base_ring() is ZZ:
2594+                parent = parent.base_extend(QQ)
2595+                return parent.element_class(parent, None, [new_ieqs, new_eqns])
2596+            else:
2597+                raise TypeError(msg)
2598 
2599     def edge_truncation(self, cut_frac = Integer(1)/3):
2600         r"""
2601@@ -2160,8 +2163,7 @@
2602 
2603         return Polyhedron(vertices=new_vertices, rays=new_rays,
2604                           lines=new_lines,
2605-                          base_ring=self.coerce_field(cut_frac))
2606-
2607+                          base_ring=self.parent()._coerce_base_ring(cut_frac))
2608 
2609     def _make_polyhedron_face(self, Vindices, Hindices):
2610         """
2611@@ -2189,7 +2191,7 @@
2612         """
2613         return PolyhedronFace_base(self, Vindices, Hindices)
2614 
2615-
2616+    @cached_method
2617     def face_lattice(self):
2618         """
2619         Return the face-lattice poset. 
2620@@ -2334,11 +2336,6 @@
2621             http://portal.acm.org/citation.cfm?id=763203 and free of
2622             charge at http://arxiv.org/abs/math/0106043
2623         """
2624-        try:
2625-            return self._face_lattice
2626-        except AttributeError:
2627-            pass
2628-       
2629         coatom_to_Hindex = [ h.index() for h in self.inequality_generator() ]
2630         Hindex_to_coatom = [None] * self.n_Hrepresentation()
2631         for i in range(0,len(coatom_to_Hindex)):
2632@@ -2370,12 +2367,11 @@
2633             return self._make_polyhedron_face(Vindices, Hindices)
2634 
2635         from sage.geometry.hasse_diagram import Hasse_diagram_from_incidences
2636-        self._face_lattice = Hasse_diagram_from_incidences\
2637+        return Hasse_diagram_from_incidences\
2638             (atoms_incidences, coatoms_incidences,
2639              face_constructor=face_constructor, required_atoms=atoms_vertices)
2640-        return self._face_lattice
2641-
2642-
2643+
2644+    @cached_method
2645     def f_vector(self):
2646         r"""
2647         Return the f-vector.
2648@@ -2392,13 +2388,9 @@
2649             sage: p.f_vector()
2650             (1, 7, 12, 7, 1)
2651         """
2652-        try:
2653-            return self._f_vector
2654-        except AttributeError:
2655-            self._f_vector = vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
2656-            return self._f_vector
2657-
2658-
2659+        return vector(ZZ,[len(x) for x in self.face_lattice().level_sets()])
2660+   
2661+    @cached_method
2662     def vertex_graph(self):
2663         """
2664         Return a graph in which the vertices correspond to vertices
2665@@ -2413,25 +2405,21 @@
2666             sage: s4.is_eulerian()
2667             True
2668         """
2669-        try:
2670-            return self._graph
2671-        except AttributeError:
2672-            self._graph = Graph(self.vertex_adjacency_matrix(), loops=True)
2673-            return self._graph
2674-
2675+        return Graph(self.vertex_adjacency_matrix(), loops=True)
2676 
2677     graph = vertex_graph
2678 
2679-
2680     def polar(self):
2681         """
2682-        Return the polar (dual) polytope.  The original vertices are
2683-        translated so that their barycenter is at the origin, and then
2684-        the vertices are used as the coefficients in the polar inequalities.
2685+        Return the polar (dual) polytope. 
2686+
2687+        The original vertices are translated so that their barycenter
2688+        is at the origin, and then the vertices are used as the
2689+        coefficients in the polar inequalities.
2690 
2691         EXAMPLES::
2692 
2693-            sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]])
2694+            sage: p = Polyhedron(vertices = [[0,0,1],[0,1,0],[1,0,0],[0,0,0],[1,1,1]], base_ring=QQ)
2695             sage: p
2696             A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 5 vertices
2697             sage: p.polar()
2698@@ -2439,10 +2427,9 @@
2699         """
2700         assert self.is_compact(), "Not a polytope."
2701 
2702-        verts = [list(v() - self.center()) for v in self.vertex_generator()]
2703-        return Polyhedron(ieqs=[[1] + list(v) for v in verts],
2704-                          base_ring=self.base_ring())
2705-
2706+        verts = [list(v.vector() - self.center()) for v in self.vertex_generator()]
2707+        base_ring = self.parent()._coerce_base_ring(self.center().parent().base_ring())
2708+        return Polyhedron(ieqs=[[1] + list(v) for v in verts], base_ring=base_ring)
2709 
2710     def pyramid(self):
2711         """
2712@@ -2450,8 +2437,10 @@
2713 
2714         EXAMPLES::
2715 
2716-            sage: square = polytopes.n_cube(2)
2717-            sage: egyptian_pyramid = square.pyramid()
2718+            sage: square = polytopes.n_cube(2);  square
2719+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
2720+            sage: egyptian_pyramid = square.pyramid();  egyptian_pyramid
2721+            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices
2722             sage: egyptian_pyramid.n_vertices()
2723             5
2724             sage: for v in egyptian_pyramid.vertex_generator(): print v
2725@@ -2462,11 +2451,9 @@
2726             A vertex at (1, 0, 0)
2727         """
2728         new_verts = \
2729-            [[0] + list(x) for x in self.Vrep_generator()] + \
2730+            [[0] + x for x in self.Vrep_generator()] + \
2731             [[1] + list(self.center())]
2732-
2733-        return Polyhedron(vertices = new_verts, base_ring=self.field())
2734-
2735+        return Polyhedron(vertices=new_verts)
2736 
2737     def bipyramid(self):
2738         """
2739@@ -2501,9 +2488,7 @@
2740             [[-1] + list(self.center())]
2741         new_rays = [[0] + r for r in self.rays()]
2742         new_lines = [[0] + list(l) for l in self.lines()]
2743-        return Polyhedron(vertices=new_verts, 
2744-                          rays=new_rays, lines=new_lines, base_ring=self.field())
2745-
2746+        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines)
2747 
2748     def prism(self):
2749         """
2750@@ -2514,7 +2499,7 @@
2751             sage: square = polytopes.n_cube(2)
2752             sage: cube = square.prism()
2753             sage: cube
2754-            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
2755+            A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
2756             sage: hypercube = cube.prism()
2757             sage: hypercube.n_vertices()
2758             16
2759@@ -2523,10 +2508,9 @@
2760         new_verts.extend( [ [0] + v for v in self.vertices()] )
2761         new_verts.extend( [ [1] + v for v in self.vertices()] )
2762         new_rays =        [ [0] + r for r in self.rays()]
2763-        new_lines =       [ [0] + list(l) for l in self.lines()]
2764-        return Polyhedron(vertices=new_verts,
2765-                          rays=new_rays, lines=new_lines, base_ring=self.field())
2766-
2767+        new_lines =       [ [0] + l for l in self.lines()]
2768+        return Polyhedron(vertices=new_verts, rays=new_rays, lines=new_lines,
2769+                          base_ring=self.base_ring())
2770 
2771     def projection(self):
2772         """
2773@@ -2543,7 +2527,6 @@
2774         self.projection = Projection(self)
2775         return self.projection
2776 
2777-
2778     def render_solid(self, **kwds):
2779         """
2780         Return a solid rendering of a 2- or 3-d polytope.
2781@@ -2562,7 +2545,6 @@
2782             return proj.render_fill_2d(**kwds)
2783         raise ValueError, "render_solid is only defined for 2 and 3 dimensional polyhedra."
2784 
2785-
2786     def render_wireframe(self, **kwds):
2787         """
2788         For polytopes in 2 or 3 dimensions, return the edges
2789@@ -2582,7 +2564,6 @@
2790             return proj.render_outline_2d(**kwds)
2791         raise ValueError, "render_wireframe is only defined for 2 and 3 dimensional polyhedra."
2792 
2793-
2794     def schlegel_projection(self, projection_dir = None, height = 1.1):
2795         """
2796         Returns a projection object whose transformed coordinates are
2797@@ -2599,13 +2580,13 @@
2798         """
2799         proj = self.projection()
2800         if projection_dir == None:
2801-            v = self.vertices()
2802-            f0 = (self.facial_incidences()[0])[1]
2803-            projection_dir = [sum([v[f0[i]][j]/len(f0) for i in range(len(f0))]) 
2804-                              for j in range(len(v[0]))]
2805+            vertices = self.vertices()
2806+            facet = self.Hrepresentation(0)
2807+            f0 = [ v.index() for v in facet.incident() ]
2808+            projection_dir = [sum([vertices[f0[i]][j]/len(f0) for i in range(len(f0))]) 
2809+                              for j in range(self.ambient_dim())]
2810         return proj.schlegel(projection_direction = projection_dir, height = height)
2811         
2812-
2813     def lrs_volume(self, verbose = False):
2814         """
2815         Computes the volume of a polytope.
2816@@ -2656,7 +2637,6 @@
2817 
2818         raise ValueError, "lrs did not return a volume"
2819 
2820-
2821     def contains(self, point):
2822         """
2823         Test whether the polyhedron contains the given ``point``.
2824@@ -2698,13 +2678,13 @@
2825         The empty polyhedron needs extra care, see trac #10238::
2826 
2827             sage: empty = Polyhedron(); empty
2828-            The empty polyhedron in QQ^0
2829+            The empty polyhedron in ZZ^0
2830             sage: empty.contains([])
2831             False
2832             sage: empty.contains([0])               # not a point in QQ^0
2833             False
2834             sage: full = Polyhedron(vertices=[()]); full
2835-            A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex
2836+            A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex
2837             sage: full.contains([])
2838             True
2839             sage: full.contains([0])
2840@@ -2716,7 +2696,7 @@
2841             if len(point)>0:
2842                 return False
2843             else:
2844-                p = vector(self.field(), [])
2845+                p = vector(self.base_ring(), [])
2846 
2847         if len(p)!=self.ambient_dim():
2848             return False
2849@@ -2726,7 +2706,6 @@
2850                 return False
2851         return True
2852 
2853-
2854     def interior_contains(self, point):
2855         """
2856         Test whether the interior of the polyhedron contains the
2857@@ -2763,7 +2742,7 @@
2858         The empty polyhedron needs extra care, see trac #10238::
2859 
2860             sage: empty = Polyhedron(); empty
2861-            The empty polyhedron in QQ^0
2862+            The empty polyhedron in ZZ^0
2863             sage: empty.interior_contains([])
2864             False
2865         """
2866@@ -2773,7 +2752,7 @@
2867             if len(point)>0:
2868                 return False
2869             else:
2870-                p = vector(self.field(), [])
2871+                p = vector(self.base_ring(), [])
2872 
2873         if len(p)!=self.ambient_dim():
2874             return False
2875@@ -2783,7 +2762,6 @@
2876                 return False
2877         return True
2878 
2879-
2880     def relative_interior_contains(self, point):
2881         """
2882         Test whether the relative interior of the polyhedron
2883@@ -2814,7 +2792,7 @@
2884         The empty polyhedron needs extra care, see trac #10238::
2885 
2886             sage: empty = Polyhedron(); empty
2887-            The empty polyhedron in QQ^0
2888+            The empty polyhedron in ZZ^0
2889             sage: empty.relative_interior_contains([])
2890             False
2891         """
2892@@ -2824,7 +2802,7 @@
2893             if len(point)>0:
2894                 return False
2895             else:
2896-                p = vector(self.field(), [])
2897+                p = vector(self.base_ring(), [])
2898 
2899         if len(p)!=self.ambient_dim():
2900             return False
2901@@ -2854,6 +2832,7 @@
2902         """
2903         return self.is_compact() and (self.dim()+1==self.n_vertices())
2904 
2905+    @cached_method
2906     def is_lattice_polytope(self):
2907         r"""
2908         Return whether the polyhedron is a lattice polytope.
2909@@ -2870,14 +2849,13 @@
2910             sage: polytopes.regular_polygon(5).is_lattice_polytope()
2911             False
2912         """
2913-        try:
2914-            return self._is_lattice_polytope
2915-        except AttributeError:
2916-            pass
2917-        self._is_lattice_polytope = self.is_compact() and \
2918-            all(v.is_integral() for v in self.vertex_generator())
2919-        return self._is_lattice_polytope
2920+        if not self.is_compact():
2921+            return False
2922+        if self.base_ring() is ZZ:
2923+            return True
2924+        return all(v.is_integral() for v in self.vertex_generator())
2925         
2926+    @cached_method
2927     def lattice_polytope(self, envelope=False):
2928         r"""
2929         Return an encompassing lattice polytope.
2930@@ -2940,33 +2918,13 @@
2931         if not self.is_compact():
2932             raise NotImplementedError, 'Only compact lattice polytopes are allowed.'
2933 
2934-        def nonintegral_error():
2935-            raise ValueError, 'Some vertices are not integral. '+\
2936-                'You probably want to add the argument '+\
2937-                '"envelope=True" to compute an enveloping lattice polytope.' 
2938-
2939-        # try to make use of cached values, if possible
2940-        if envelope:
2941-            try: 
2942-                return self._lattice_polytope
2943-            except AttributeError:
2944-                pass
2945-        else:
2946-            try: 
2947-                assert self._is_lattice_polytope
2948-                return self._lattice_polytope
2949-            except AttributeError:
2950-                pass
2951-            except AssertionError:
2952-                nonintegral_error()
2953-
2954-        # find the integral vertices
2955         try:
2956-            vertices = matrix(ZZ, self.vertices()).transpose()
2957-            self._is_lattice_polytope = True
2958+            vertices = self.vertices_matrix(ZZ)
2959         except TypeError:
2960-            self._is_lattice_polytope = False
2961-            if envelope==False: nonintegral_error()
2962+            if envelope==False: 
2963+                raise ValueError, 'Some vertices are not integral. '+\
2964+                    'You probably want to add the argument '+\
2965+                    '"envelope=True" to compute an enveloping lattice polytope.' 
2966             vertices = []
2967             for v in self.vertex_generator():
2968                 vbox = [ set([floor(x),ceil(x)]) for x in v ]
2969@@ -2975,8 +2933,7 @@
2970 
2971         # construct the (enveloping) lattice polytope
2972         from sage.geometry.lattice_polytope import LatticePolytope
2973-        self._lattice_polytope = LatticePolytope(vertices)
2974-        return self._lattice_polytope
2975+        return LatticePolytope(vertices)
2976 
2977     def _integral_points_PALP(self):
2978         r"""
2979@@ -3044,8 +3001,10 @@
2980         box_max = []
2981         if self.n_vertices==0:
2982             raise ValueError('Empty polytope is not allowed')
2983+        if not self.is_compact():
2984+            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
2985         for i in range(0,self.ambient_dim()):
2986-            coords = [ v[i] for v in self.Vrep_generator() ]
2987+            coords = [ v[i] for v in self.vertex_generator() ]
2988             max_coord = max(coords)
2989             min_coord = min(coords)
2990             if integral:
2991@@ -3102,7 +3061,7 @@
2992 
2993             sage: v = [(1,0,7,-1), (-2,-2,4,-3), (-1,-1,-1,4), (2,9,0,-5), (-2,-1,5,1)]
2994             sage: simplex = Polyhedron(v); simplex
2995-            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
2996+            A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices
2997             sage: len(simplex.integral_points())
2998             49
2999 
3000@@ -3152,6 +3111,7 @@
3001         # assert all(self.contains(p) for p in points)   # slow
3002         return tuple(points)
3003     
3004+    @cached_method
3005     def combinatorial_automorphism_group(self):
3006         """
3007         Computes the combinatorial automorphism group of the vertex
3008@@ -3186,11 +3146,7 @@
3009             sage: P.combinatorial_automorphism_group()
3010             Permutation Group with generators [(3,4)]
3011         """
3012-        if '_combinatorial_automorphism_group' in self.__dict__:
3013-            return self._combinatorial_automorphism_group
3014-
3015         from sage.groups.perm_gps.permgroup import PermutationGroup
3016-
3017         G = Graph(dense=False)
3018         for edge in self.vertex_graph().edges():
3019             i = edge[0]
3020@@ -3208,7 +3164,6 @@
3021         self._combinatorial_automorphism_group = group
3022         return group
3023 
3024-
3025     def _affine_coordinates(self, Vrep_object):
3026         r"""
3027         Return affine coordinates for a V-representation object.
3028@@ -3247,9 +3202,9 @@
3029         if len(v) != self.ambient_dim():
3030             raise ValueError('Incorrect dimension: '+str(v))
3031 
3032-        return vector(self.field(), [ v[i] for i in self._affine_coordinates_pivots ])
3033+        return vector(self.base_ring(), [ v[i] for i in self._affine_coordinates_pivots ])
3034         
3035-
3036+    @cached_method
3037     def restricted_automorphism_group(self):
3038         r"""
3039         Return the restricted automorphism group.
3040@@ -3397,16 +3352,13 @@
3041             sage: p.restricted_automorphism_group()
3042             Permutation Group with generators [(2,3)]
3043         """
3044-        if '_restricted_automorphism_group' in self.__dict__:
3045-            return self._restricted_automorphism_group
3046-
3047         from sage.groups.perm_gps.permgroup import PermutationGroup
3048 
3049-        if self.field() is QQ:
3050+        if self.base_ring() is ZZ or self.base_ring() is QQ:
3051             def rational_approximation(c):
3052                 return c
3053 
3054-        else:  # self.field() is RDF
3055+        elif self.base_ring() is RDF:
3056             c_list = []
3057             def rational_approximation(c):
3058                 # Implementation detail: Return unique integer if two
3059@@ -3418,7 +3370,7 @@
3060                         return i
3061                 c_list.append(c)
3062                 return len(c_list)-1
3063-       
3064+
3065         # The algorithm identifies the restricted automorphism group
3066         # with the automorphism group of a edge-colored graph. The
3067         # nodes of the graph are the V-representation objects. If all
3068@@ -3475,11 +3427,8 @@
3069 
3070 
3071 
3072-
3073-
3074-
3075 #########################################################################
3076-class PolyhedronFace_base(SageObject):
3077+class PolyhedronFace_base(Polyhedron_base):
3078     r"""
3079     A face of a polyhedron.
3080     
3081@@ -3542,15 +3491,15 @@
3082             sage: PolyhedronFace_base(Polyhedron(), [], [])   # indirect doctest
3083             <>
3084         """
3085+        Element.__init__(self, parent=polyhedron.parent())
3086         self._polyhedron = polyhedron
3087         self._ambient_Vrepresentation_indices = tuple(V_indices)
3088         self._ambient_Hrepresentation_indices = tuple(H_indices)
3089         self._ambient_Vrepresentation = tuple( polyhedron.Vrepresentation(i) for i in V_indices )
3090         self._ambient_Hrepresentation = tuple( polyhedron.Hrepresentation(i) for i in H_indices )
3091-        # self._Vrepresentation =
3092-        # self._Hrepresentation =
3093+        self._Vrepresentation = tuple()
3094+        self._Hrepresentation = tuple()
3095         
3096-
3097     def ambient_Hrepresentation(self, index=None):
3098         r"""
3099         Return the H-representation objects of the ambient polytope
3100@@ -3593,7 +3542,6 @@
3101         else:
3102             return self._ambient_Hrepresentation[index]
3103       
3104-
3105     def ambient_Vrepresentation(self, index=None):
3106         r"""
3107         Return the V-representation objects of the ambient polytope
3108@@ -3636,7 +3584,7 @@
3109         else:
3110             return self._ambient_Vrepresentation[index]
3111 
3112-
3113+    @cached_method
3114     def n_ambient_Hrepresentation(self):
3115         """
3116         Return the number of objects that make up the ambient
3117@@ -3662,9 +3610,9 @@
3118             sage: face.n_ambient_Hrepresentation()
3119             4
3120         """
3121-        return len(self._ambient_Hrepresentation)
3122-
3123-
3124+        return len(self.ambient_Hrepresentation())
3125+
3126+    @cached_method
3127     def n_ambient_Vrepresentation(self):
3128         """
3129         Return the number of objects that make up the ambient
3130@@ -3687,9 +3635,9 @@
3131             sage: face.n_ambient_Vrepresentation()
3132             2
3133         """
3134-        return len(self._ambient_Vrepresentation)
3135-
3136-
3137+        return len(self.ambient_Vrepresentation())
3138+
3139+    @cached_method
3140     def dim(self):
3141         """
3142         Return the dimension of the face.
3143@@ -3706,17 +3654,12 @@
3144               1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3145               1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3]
3146         """
3147-        if '_dim' in self.__dict__:
3148-            return self._dim
3149-
3150         if self.n_ambient_Vrepresentation()==0:
3151-            self._dim = -1
3152+            return -1
3153         else:
3154             origin = vector(self.ambient_Vrepresentation(0))
3155             v_list = [ vector(v)-origin for v in self.ambient_Vrepresentation() ]
3156-            self._dim = matrix(v_list).rank()
3157-        return self._dim
3158-
3159+            return matrix(v_list).rank()
3160 
3161     def _repr_(self):
3162         r"""
3163diff --git a/sage/geometry/polyhedron/base_ZZ.py b/sage/geometry/polyhedron/base_ZZ.py
3164--- a/sage/geometry/polyhedron/base_ZZ.py
3165+++ b/sage/geometry/polyhedron/base_ZZ.py
3166@@ -139,7 +139,7 @@
3167             sage: p.polar()
3168             A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 4 vertices
3169             sage: type(_)
3170-            <class 'sage.geometry.polyhedron.backend_ppl.Polyhedron_ZZ_ppl'>
3171+            <class 'sage.geometry.polyhedron.backend_ppl.Polyhedra_ZZ_ppl_with_category.element_class'>
3172             sage: p.polar().base_ring()
3173             Integer Ring
3174         """
3175@@ -173,7 +173,7 @@
3176         
3177         * ``self`` is compact (a polytope).
3178 
3179-        * ``self`` contains the origin.
3180+        * ``self`` contains the origin as an interior point.
3181 
3182         This implies that
3183         
3184@@ -182,6 +182,15 @@
3185         * The dual polyhedron is again a polytope (that is, a compact
3186           polyhedron), though not necessarily a lattice polytope.
3187 
3188+        EXAMPLES::
3189+
3190+            sage: Polyhedron([(1,1),(1,0),(0,1)], base_ring=ZZ).has_IP_property()
3191+            False
3192+            sage: Polyhedron([(0,0),(1,0),(0,1)], base_ring=ZZ).has_IP_property()
3193+            False
3194+            sage: Polyhedron([(-1,-1),(1,0),(0,1)], base_ring=ZZ).has_IP_property()
3195+            True
3196+
3197         REFERENCES::
3198 
3199         ..  [PALP]
3200@@ -191,43 +200,56 @@
3201             Comput.Phys.Commun. 157 (2004) 87-106
3202             http://arxiv.org/abs/math/0204356
3203         """
3204-        return self.is_compact() and self.contains(self.ambient_space().zero())
3205+        return self.is_compact() and self.interior_contains(self.ambient_space().zero())
3206 
3207-    def fibrations(self):
3208+    def fibration_generator(self, dim):
3209         """
3210+        Generate the lattice polytope fibrations.
3211+       
3212+        For the purposes of this function, a lattice polytope fiber is
3213+        a sub-lattice polytope. Projecting the plane spanned by the
3214+        subpolytope to a point yields another lattice polytope, the
3215+        base of the fibration.
3216+
3217+        INPUT:
3218+       
3219+        - ``dim`` -- integer. The dimension of the lattice polytope
3220+          fiber.
3221+
3222+        OUTPUT:
3223+
3224+        A generator yielding the distinct lattice polytope fibers of
3225+        given dimension.
3226+       
3227         EXAMPLES::
3228 
3229             sage: P = Polyhedron(toric_varieties.P4_11169().fan().rays(), base_ring=ZZ)
3230-            sage: list( P.fibrations() )
3231-            [A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 3 vertices]
3232+            sage: list( P.fibration_generator(2) )
3233+            [A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices]
3234         """
3235-        if not self.has_IP_property():
3236-            raise ValueError('The polytope must have the IP property.')
3237-        # todo: just go through pairs of points on the same facet
3238-        fiber_dimension = 2
3239-        points = self.integral_points()
3240+        from sage.combinat.combinat import combinations_iterator
3241+        if not self.is_compact():
3242+            raise ValueError('Only polytopes (compact polyhedra) are allowed.')
3243+
3244+        nonzero_points = [p for p in self.integral_points() if not p.is_zero()]
3245+        origin = [[0]*self.ambient_dim()]
3246         fibers = set()
3247-        for i1 in range(0,len(points)):
3248-            p1 = points[i1]
3249-            if p1.is_zero():
3250-                continue
3251-            for i2 in range(i1+1,len(points)):
3252-                p2 = points[i2]
3253-                if p2.is_zero():
3254+        parent = self.parent()
3255+
3256+        for points in combinations_iterator(nonzero_points, dim):
3257+                plane = parent.element_class(parent, [origin,[],points], None)
3258+                if plane.dim() != dim:
3259                     continue
3260-                plane_12 = Polyhedron(lines=[p1,p2])
3261-                if plane_12.dim() != 2:
3262+                fiber = self.intersection(plane)
3263+                if fiber.base_ring() is not ZZ:
3264                     continue
3265-                fiber = self.intersection(plane_12)
3266-                if not fiber.is_lattice_polytope():
3267-                    continue
3268-                fiber_matrix = matrix(ZZ,sorted(fiber.integral_points()))
3269-                fiber_matrix.set_immutable()
3270-                if fiber_matrix not in fibers:
3271+                fiber_vertices = tuple(sorted(tuple(v) for v in fiber.vertex_generator()))
3272+                if fiber_vertices not in fibers:
3273                     yield fiber
3274-                    fibers.update([fiber_matrix])
3275+                    fibers.update([fiber_vertices])
3276+                plane.delete()
3277                 
3278-
3279+                   
3280 
3281 
3282         
3283diff --git a/sage/geometry/polyhedron/constructor.py b/sage/geometry/polyhedron/constructor.py
3284--- a/sage/geometry/polyhedron/constructor.py
3285+++ b/sage/geometry/polyhedron/constructor.py
3286@@ -39,7 +39,7 @@
3287 
3288     sage: trunc_quadr = Polyhedron(vertices=[[1,0],[0,1]], rays=[[1,0],[0,1]])
3289     sage: trunc_quadr
3290-    A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays
3291+    A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 2 rays
3292     sage: v = trunc_quadr.vertex_generator().next()  # the first vertex in the internal enumeration
3293     sage: v
3294     A vertex at (0, 1)
3295@@ -56,9 +56,9 @@
3296     sage: type(v)
3297     <class 'sage.geometry.polyhedron.representation.Vertex'>
3298     sage: type( v() )
3299-    <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
3300+    <type 'sage.modules.vector_integer_dense.Vector_integer_dense'>
3301     sage: v.polyhedron()
3302-    A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 2 rays
3303+    A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 2 rays
3304     sage: r = trunc_quadr.ray_generator().next()
3305     sage: r
3306     A ray in the direction (0, 1)
3307@@ -105,9 +105,7 @@
3308 from sage.rings.all import QQ, ZZ, RDF
3309 from sage.misc.decorators import rename_keyword
3310 
3311-from misc import (
3312-    _set_to_None_if_empty, _set_to_empty_if_None,
3313-    _common_length_of )
3314+from misc import _make_listlist, _common_length_of
3315 
3316 
3317 
3318@@ -118,7 +116,7 @@
3319 @rename_keyword(deprecated='Sage version 4.7.2', field='base_ring')
3320 def Polyhedron(vertices=None, rays=None, lines=None,
3321                ieqs=None, eqns=None,
3322-               base_ring=QQ, minimize=True, verbose=False,
3323+               ambient_dim=None, base_ring=None, minimize=True, verbose=False,
3324                backend=None):
3325     """
3326     Construct a polyhedron object.
3327@@ -131,7 +129,9 @@
3328     INPUT:
3329 
3330     - ``vertices`` -- list of point. Each point can be specified as
3331-      any iterable container of ``base_ring`` elements.
3332+      any iterable container of ``base_ring`` elements. If ``rays`` or
3333+      ``lines`` are specified but no ``vertices``, the origin is
3334+      taken to be the single vertex.
3335         
3336     - ``rays`` -- list of rays. Each ray can be specified as any
3337       iterable container of ``base_ring`` elements.
3338@@ -151,16 +151,20 @@
3339       used. Floating point arithmetic is faster but might give the
3340       wrong result for degenerate input.
3341 
3342+    - ``ambient_dim`` -- integer. The ambient space dimension. Usually
3343+      can be figured out automatically from the H/Vrepresentation
3344+      dimensions. 
3345+
3346     - ``backend`` -- string or ``None`` (default). The backend to use. Valid choices are
3347 
3348-      * ``'cddr'``: cdd (:mod:`~sage.geometry.polyhedron.backend_cdd`)
3349-        with rational coefficients
3350+      * ``'cdd'``: use cdd
3351+        (:mod:`~sage.geometry.polyhedron.backend_cdd`) with `\QQ` or
3352+        `\RDF` coefficients depending on ``base_ring``.
3353 
3354-      * ``'cddf'``: cdd with floating-point coefficients
3355 
3356       * ``'ppl'``: use ppl
3357-        (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\QQ` or
3358-        `\ZZ` coefficients depending on ``base_ring``.
3359+        (:mod:`~sage.geometry.polyhedron.backend_ppl`) with `\ZZ` or
3360+        `\QQ` coefficients depending on ``base_ring``.
3361 
3362     Some backends support further optional arguments:
3363 
3364@@ -221,8 +225,8 @@
3365         sage: positive_coords = Polyhedron(ieqs=[
3366         ...       [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], 
3367         ...       [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1]])
3368-        sage: P = Polyhedron(ieqs=positive_coords.inequalities() + [
3369-        ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]], eqns=[[-31,1,1,1,1,1,1]])
3370+        sage: P = Polyhedron(ieqs=positive_coords.inequalities() + (
3371+        ...       [0,0,1,-1,-1,1,0], [0,0,-1,1,-1,1,0]), eqns=[[-31,1,1,1,1,1,1]])
3372         sage: P
3373         A 5-dimensional polyhedron in QQ^6 defined as the convex hull of 7 vertices
3374         sage: P.dim()
3375@@ -242,63 +246,99 @@
3376         setting of cdd.
3377     """
3378     # Clean up the arguments
3379-    vertices = _set_to_None_if_empty(vertices)
3380-    rays     = _set_to_None_if_empty(rays)
3381-    lines    = _set_to_None_if_empty(lines)
3382-    ieqs     = _set_to_None_if_empty(ieqs)
3383-    eqns     = _set_to_None_if_empty(eqns)
3384+    vertices = _make_listlist(vertices)
3385+    rays     = _make_listlist(rays)
3386+    lines    = _make_listlist(lines)
3387+    ieqs     = _make_listlist(ieqs)
3388+    eqns     = _make_listlist(eqns)
3389 
3390-    got_Vrep = (vertices is not None or rays is not None or lines is not None)
3391-    got_Hrep = (ieqs is not None or eqns is not None)
3392+    got_Vrep = (len(vertices+rays+lines) > 0)
3393+    got_Hrep = (len(ieqs+eqns) > 0)
3394     
3395     if got_Vrep and got_Hrep:
3396         raise ValueError('You cannot specify both H- and V-representation.')
3397     elif got_Vrep:
3398-        vertices = _set_to_empty_if_None(vertices)
3399-        rays     = _set_to_empty_if_None(rays)
3400-        lines    = _set_to_empty_if_None(lines)
3401-        Vrep = [vertices, rays, lines]
3402-        Hrep = None
3403-        ambient_dim = _common_length_of(*Vrep)[1]
3404+        deduced_ambient_dim = _common_length_of(vertices, rays, lines)[1]
3405     elif got_Hrep:
3406-        ieqs = _set_to_empty_if_None(ieqs)
3407-        eqns = _set_to_empty_if_None(eqns)
3408-        Vrep = None
3409-        Hrep = [ieqs, eqns]
3410-        ambient_dim = _common_length_of(*Hrep)[1] - 1
3411+        deduced_ambient_dim = _common_length_of(ieqs, eqns)[1] - 1
3412     else:
3413-        Vrep = None
3414-        Hrep = None
3415-        ambient_dim = 0
3416+        if ambient_dim is None:
3417+            deduced_ambient_dim = 0
3418+        else:
3419+            deduced_ambient_dim = ambient_dim
3420+        if base_ring is None:
3421+            base_ring = ZZ
3422+
3423+    # set ambient_dim
3424+    if ambient_dim is not None and deduced_ambient_dim!=ambient_dim:
3425+        raise ValueError('Ambient space dimension mismatch. Try removing the "ambient_dim" parameter.')
3426+    ambient_dim = deduced_ambient_dim
3427 
3428-    if backend is not None:
3429-        if backend=='ppl' and base_ring is QQ:
3430-            from backend_ppl import Polyhedron_QQ_ppl
3431-            return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
3432-        if backend=='ppl' and base_ring is ZZ:
3433-            from backend_ppl import Polyhedron_ZZ_ppl
3434-            return Polyhedron_ZZ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
3435-        if backend=='cddr':
3436-            from backend_cdd import Polyhedron_QQ_cdd
3437-            return Polyhedron_QQ_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
3438-        if backend=='cddf':
3439-            from backend_cdd import Polyhedron_RDF_cdd
3440-            return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
3441-        raise ValueError('No suitable backend implemented.')
3442+    # figure out base_ring
3443+    from sage.misc.flatten import flatten
3444+    values = flatten(vertices+rays+lines+ieqs+eqns)
3445+    if base_ring is not None:
3446+        try:
3447+            convert = not all(x.parent() is base_ring for x in values)
3448+        except AttributeError:   # No x.parent() method?
3449+            convert = True
3450+    else:
3451+        from sage.rings.integer import is_Integer
3452+        from sage.rings.rational import is_Rational
3453+        from sage.rings.real_double import is_RealDoubleElement
3454+        if all(is_Integer(x) for x in values):
3455+            if got_Vrep:
3456+                base_ring = ZZ
3457+            else:   # integral inequalities usually do not determine a latice polytope!
3458+                base_ring = QQ
3459+            convert=False
3460+        elif all(is_Rational(x) for x in values):
3461+            base_ring = QQ
3462+            convert=False
3463+        elif all(is_RealDoubleElement(x) for x in values):
3464+            base_ring = RDF
3465+            convert=False
3466+        else:
3467+            try:
3468+                map(ZZ, values)
3469+                if got_Vrep:
3470+                    base_ring = ZZ
3471+                else:
3472+                    base_ring = QQ
3473+                convert = True
3474+            except TypeError:
3475+                from sage.structure.sequence import Sequence
3476+                values = Sequence(values)
3477+                if QQ.has_coerce_map_from(values.universe()):
3478+                    base_ring = QQ
3479+                    convert = True
3480+                else:
3481+                    base_ring = RDF
3482+                    convert = True
3483 
3484-    if base_ring is QQ:
3485-        from backend_ppl import Polyhedron_QQ_ppl
3486-        return Polyhedron_QQ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
3487-    elif base_ring is RDF:
3488-        from backend_cdd import Polyhedron_RDF_cdd
3489-        return Polyhedron_RDF_cdd(ambient_dim, Vrep, Hrep, verbose=verbose)
3490-    elif base_ring is ZZ:
3491-        from backend_ppl import Polyhedron_ZZ_ppl
3492-        return Polyhedron_ZZ_ppl(ambient_dim, Vrep, Hrep, minimize=minimize)
3493-    else:
3494-        raise ValueError('Polyhedron objects can only be constructed over QQ and RDF')
3495+    # Add the origin if necesarry
3496+    if got_Vrep and len(vertices)==0:
3497+        vertices = [ [0]*ambient_dim ]
3498 
3499+    # Specific backends can override the base_ring
3500+    from sage.geometry.polyhedron.parent import Polyhedra
3501+    parent = Polyhedra(base_ring, ambient_dim, backend=backend)
3502+    base_ring = parent.base_ring()
3503+   
3504+    # Convert into base_ring if necessary
3505+    def convert_base_ring(lstlst):
3506+        return [ [base_ring(x) for x in lst] for lst in lstlst]
3507+    Hrep = Vrep = None
3508+    if got_Hrep:
3509+        if convert:
3510+            Hrep = [convert_base_ring(ieqs), convert_base_ring(eqns)]
3511+        else:
3512+            Hrep = [ieqs, eqns]
3513+    if got_Vrep:
3514+        if convert:
3515+            Vrep = [convert_base_ring(vertices), convert_base_ring(rays), convert_base_ring(lines)]
3516+        else:
3517+            Vrep = [vertices, rays, lines]
3518 
3519-
3520-
3521-
3522+    # finally, construct the Polyhedron
3523+    return parent.element_class(parent, Vrep, Hrep)
3524diff --git a/sage/geometry/polyhedron/misc.py b/sage/geometry/polyhedron/misc.py
3525--- a/sage/geometry/polyhedron/misc.py
3526+++ b/sage/geometry/polyhedron/misc.py
3527@@ -58,29 +58,36 @@
3528         [1]
3529     """
3530     if x is None: return x
3531+    x = list(x)
3532     if len(x)==0: return None
3533     return x
3534 
3535 
3536 #########################################################################
3537-def _set_to_empty_if_None(x):
3538+def _make_listlist(x):
3539     """
3540-    Helper function to clean up arguments: Returns the empty list if
3541-    x==None or x is an empty container.
3542+    Helper function to clean up arguments.
3543+
3544+    INPUT:
3545+   
3546+    - ``x`` -- ``None`` or an iterable of iterables.
3547+
3548+    OUTPUT
3549+
3550+    A list of lists.
3551 
3552     EXAMPLES::
3553 
3554         sage: import sage.geometry.polyhedron.misc as P
3555-        sage: [] == P._set_to_empty_if_None(tuple())
3556+        sage: [] == P._make_listlist(tuple())
3557         True
3558-        sage: [] == P._set_to_empty_if_None(None)
3559+        sage: [] == P._make_listlist(None)
3560         True
3561-        sage: P._set_to_empty_if_None([1])
3562-        [1]
3563+        sage: P._make_listlist([(1,2),[3,4]])
3564+        [[1, 2], [3, 4]]
3565     """
3566     if x is None: return []
3567-    if len(x)==0: return []
3568-    return x
3569+    return [list(y) for y in x]
3570 
3571 
3572 #########################################################################
3573diff --git a/sage/geometry/polyhedron/parent.py b/sage/geometry/polyhedron/parent.py
3574new file mode 100644
3575--- /dev/null
3576+++ b/sage/geometry/polyhedron/parent.py
3577@@ -0,0 +1,728 @@
3578+r"""
3579+Parents for Polyhedra
3580+"""
3581+
3582+#*****************************************************************************
3583+#       Copyright (C) 2011 Volker Braun <vbraun.name@gmail.com>
3584+#
3585+#  Distributed under the terms of the GNU General Public License (GPL)
3586+#                  http://www.gnu.org/licenses/
3587+#******************************************************************************
3588+
3589+from sage.structure.parent import Parent
3590+from sage.structure.element import get_coercion_model
3591+from sage.structure.unique_representation import UniqueRepresentation
3592+from sage.modules.free_module import is_FreeModule
3593+from sage.misc.cachefunc import cached_method
3594+from sage.rings.all import ZZ, QQ, RDF, is_Field, is_CommutativeRing
3595+
3596+from sage.geometry.polyhedron.base import Polyhedron_base, is_Polyhedron
3597+from representation import Inequality, Equation, Vertex, Ray, Line
3598+
3599+
3600+def Polyhedra(base_ring, ambient_dim, backend=None):
3601+    """
3602+    EXAMPLES::
3603+   
3604+        sage: from sage.geometry.polyhedron.parent import Polyhedra
3605+        sage: Polyhedra(ZZ, 3)
3606+        Polyhedra in ZZ^3
3607+        sage: type(_)
3608+        <class 'sage.geometry.polyhedron.parent.Polyhedra_ZZ_ppl_with_category'>
3609+        sage: Polyhedra(QQ, 3, backend='cdd')
3610+        Polyhedra in QQ^3
3611+        sage: type(_)
3612+        <class 'sage.geometry.polyhedron.parent.Polyhedra_QQ_cdd_with_category'>
3613+    """
3614+    if backend is None:
3615+        if base_ring is ZZ:
3616+            return Polyhedra_ZZ_ppl(base_ring, ambient_dim)
3617+        elif base_ring is QQ:
3618+            return Polyhedra_QQ_ppl(base_ring, ambient_dim)
3619+        elif base_ring is RDF:
3620+            return Polyhedra_RDF_cdd(base_ring, ambient_dim)
3621+        else:
3622+            raise ValueError('Polyhedral objects can only be constructed over ZZ, QQ, and RDF')
3623+    elif backend=='ppl' and base_ring is QQ:
3624+        return Polyhedra_QQ_ppl(base_ring, ambient_dim)
3625+    elif backend=='ppl' and base_ring is ZZ:
3626+        return Polyhedra_ZZ_ppl(base_ring, ambient_dim)
3627+    elif backend=='cdd' and base_ring is QQ:
3628+        return Polyhedra_QQ_cdd(QQ, ambient_dim)
3629+    elif backend=='cdd' and base_ring is RDF:
3630+        return Polyhedra_RDF_cdd(RDF, ambient_dim)
3631+    else:
3632+        raise ValueError('No such backend (='+str(backend)+
3633+                         ') implemented for given basering (='+str(base_ring)+').')
3634+
3635+
3636+
3637+class Polyhedra_base(UniqueRepresentation, Parent):
3638+    r"""
3639+    Polyhedra in a fixed ambient space.
3640+
3641+    INPUT:
3642+
3643+    - ``base_ring`` -- either ``ZZ``, ``QQ``, or ``RDF``. The base
3644+      ring of the ambient module/vector space.
3645+
3646+    - ``ambient_dim`` -- integer. The ambient space dimension.
3647+
3648+    EXAMPLES::
3649+   
3650+        sage: from sage.geometry.polyhedron.parent import Polyhedra
3651+        sage: Polyhedra(ZZ, 3)
3652+        Polyhedra in ZZ^3
3653+    """
3654+    def __init__(self, base_ring, ambient_dim):
3655+        """
3656+        The Python constructor.
3657+
3658+        EXAMPLES::
3659+
3660+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3661+            sage: Polyhedra(QQ, 3)
3662+            Polyhedra in QQ^3
3663+
3664+        TESTS::
3665+       
3666+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3667+            sage: P = Polyhedra(QQ, 3)
3668+            sage: TestSuite(P).run(skip='_test_pickling')
3669+        """
3670+        self._ambient_dim = ambient_dim
3671+        from sage.categories.polyhedra import PolyhedralSets
3672+        Parent.__init__(self, base=base_ring, category=PolyhedralSets(base_ring))
3673+        self._Inequality_pool = []
3674+        self._Equation_pool = []
3675+        self._Vertex_pool = []
3676+        self._Ray_pool = []
3677+        self._Line_pool = []
3678+
3679+    def recycle(self, polyhedron):
3680+        """
3681+        Recycle the H/V-representation objects of a polyhedron.
3682+       
3683+        This speeds up creation of new polyhedra by reusing
3684+        objects. After recycling a polyhedron object, it is not in a
3685+        consistent state any more and neither the polyhedron nor its
3686+        H/V-representation objects may be used any more.
3687+
3688+        INPUT:
3689+
3690+        - ``polyhedron`` -- a polyhedron whose parent is ``self``.
3691+
3692+       
3693+        EXAMPLES::
3694+
3695+            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
3696+            sage: p.parent().recycle(p)
3697+
3698+        TESTS::
3699+
3700+            sage: p = Polyhedron([(0,0),(1,0),(0,1)])
3701+            sage: n = len(p.parent()._Vertex_pool)
3702+            sage: p.delete()
3703+            sage: len(p.parent()._Vertex_pool) - n
3704+            3
3705+        """
3706+        if self is not polyhedron.parent():
3707+            raise TypeError('The polyhedron has the wrong parent class.')
3708+        self._Inequality_pool.extend(polyhedron.inequalities())
3709+        self._Equation_pool.extend(polyhedron.equations())
3710+        self._Vertex_pool.extend(polyhedron.vertices())
3711+        self._Ray_pool.extend(polyhedron.rays())
3712+        self._Line_pool.extend(polyhedron.lines())
3713+        for Hrep in polyhedron.Hrep_generator():
3714+            Hrep._polyhedron = None
3715+        for Vrep in polyhedron.Vrep_generator():
3716+            Vrep._polyhedron = None
3717+
3718+    def ambient_dim(self):
3719+        r"""
3720+        Return the dimension of the ambient space.
3721+
3722+        EXAMPLES::
3723+
3724+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3725+            sage: Polyhedra(QQ, 3).ambient_dim()
3726+            3
3727+        """
3728+        return self._ambient_dim
3729+
3730+    @cached_method
3731+    def an_element(self):
3732+        r"""
3733+        Returns a Polyhedron.
3734+
3735+        EXAMPLES::
3736+
3737+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3738+            sage: Polyhedra(QQ, 4).an_element()
3739+            A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 5 vertices
3740+        """
3741+        p = [0] * self.ambient_dim()
3742+        points = [p]
3743+        for i in range(0,self.ambient_dim()):
3744+            p = [0] * self.ambient_dim()
3745+            p[i] = 1
3746+            points.append(p)
3747+        return self.element_class(self, [points,[],[]], None)
3748+
3749+    @cached_method
3750+    def some_elements(self):
3751+        r"""
3752+        Returns a list of some elements of the semigroup.
3753+
3754+        EXAMPLES::
3755+
3756+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3757+            sage: Polyhedra(QQ, 4).some_elements()
3758+            [A 3-dimensional polyhedron in QQ^4 defined as the convex hull of 4 vertices,
3759+             A 4-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex and 4 rays,
3760+             A 2-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices and 1 ray,
3761+             The empty polyhedron in QQ^4]
3762+            sage: Polyhedra(ZZ,0).some_elements()
3763+            [The empty polyhedron in ZZ^0,
3764+             A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex]
3765+        """
3766+        if self.ambient_dim() == 0:
3767+            return [
3768+                self.element_class(self, None, None),
3769+                self.element_class(self, None, [[],[]]) ]
3770+        points = []
3771+        for i in range(0,self.ambient_dim()+5):
3772+            points.append([i*j^2 for j in range(0,self.ambient_dim())])
3773+        return [ 
3774+            self.element_class(self, [points[0:self.ambient_dim()+1], [], []], None),
3775+            self.element_class(self, [points[0:1], points[1:self.ambient_dim()+1], []], None),
3776+            self.element_class(self, [points[0:3], points[4:5], []], None),
3777+            self.element_class(self, None, None) ]
3778+ 
3779+    @cached_method
3780+    def zero_element(self):
3781+        r"""
3782+        Returns the polyhedron consisting of the origin, which is the
3783+        neutral element for Minkowski addition.
3784+
3785+        EXAMPLES::
3786+
3787+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3788+            sage: p = Polyhedra(QQ, 4).zero_element();  p
3789+            A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex
3790+            sage: p+p == p
3791+            True
3792+        """
3793+        Vrep = [[[self.base_ring().zero()]*self.ambient_dim()], [], []]
3794+        return self.element_class(self, Vrep, None)
3795+
3796+    @cached_method
3797+    def Vrepresentation_space(self):
3798+        r"""
3799+        Return the ambient vector space.
3800+
3801+        This is the vector space or module containing the
3802+        Vrepresentation vectors.
3803+       
3804+        OUTPUT:
3805+       
3806+        A free module over the base ring of dimension :meth:`ambient_dim`.
3807+       
3808+        EXAMPLES::
3809+
3810+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3811+            sage: Polyhedra(QQ, 4).Vrepresentation_space()
3812+            Vector space of dimension 4 over Rational Field
3813+            sage: Polyhedra(QQ, 4).ambient_space()
3814+            Vector space of dimension 4 over Rational Field
3815+        """
3816+        if is_Field(self.base_ring()):
3817+            from sage.modules.free_module import VectorSpace
3818+            return VectorSpace(self.base_ring(), self.ambient_dim())
3819+        else:
3820+            from sage.modules.free_module import FreeModule
3821+            return FreeModule(self.base_ring(), self.ambient_dim())
3822+
3823+    ambient_space = Vrepresentation_space
3824+
3825+    @cached_method
3826+    def Hrepresentation_space(self):
3827+        r"""
3828+        Return the linear space containing the H-representation vectors.
3829+
3830+        OUTPUT:
3831+       
3832+        A free module over the base ring of dimension :meth:`ambient_dim` + 1.
3833+       
3834+        EXAMPLES::
3835+       
3836+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3837+            sage: Polyhedra(ZZ, 2).Hrepresentation_space()
3838+            Ambient free module of rank 3 over the principal ideal domain Integer Ring
3839+        """
3840+        if is_Field(self.base_ring()):
3841+            from sage.modules.free_module import VectorSpace
3842+            return VectorSpace(self.base_ring(), self.ambient_dim()+1)
3843+        else:
3844+            from sage.modules.free_module import FreeModule
3845+            return FreeModule(self.base_ring(), self.ambient_dim()+1)
3846+
3847+    def _repr_ambient_module(self):
3848+        """
3849+        Return an abbreviated string representation of the ambient
3850+        space.
3851+
3852+        OUTPUT:
3853+
3854+        String.
3855+
3856+        EXAMPLES::
3857+
3858+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3859+            sage: Polyhedra(QQ, 3)._repr_ambient_module()
3860+            'QQ^3'
3861+        """
3862+        if self.base_ring() is ZZ: 
3863+            s = 'ZZ'
3864+        elif self.base_ring() is QQ: 
3865+            s = 'QQ'
3866+        elif self.base_ring() is RDF: 
3867+            s = 'RDF'
3868+        else:               
3869+            assert False
3870+        s += '^' + repr(self.ambient_dim()) 
3871+        return s
3872+
3873+    def _repr_(self):
3874+        """
3875+        Return a string representation.
3876+
3877+        OUTPUT:
3878+
3879+        String.
3880+       
3881+        EXAMPLES::
3882+
3883+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3884+            sage: Polyhedra(QQ, 3)
3885+            Polyhedra in QQ^3
3886+            sage: Polyhedra(QQ, 3)._repr_()
3887+            'Polyhedra in QQ^3'
3888+        """
3889+        return 'Polyhedra in '+self._repr_ambient_module()
3890+
3891+    def _element_constructor_(self, *args, **kwds):
3892+        """
3893+        The element (polyhedron) constructor.
3894+
3895+        INPUT:
3896+
3897+        - ``Vrep`` -- a list `[vertices, rays, lines]`` or ``None``.
3898+       
3899+        - ``Hrep`` -- a list `[ieqs, eqns]`` or ``None``.
3900+
3901+        - ``**kwds`` -- optional keywords that are passed to the
3902+          polyhedron constructor.
3903+
3904+        EXAMPLES::
3905+
3906+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3907+            sage: P = Polyhedra(QQ, 3)
3908+            sage: P._element_constructor_([[(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [], []], None)
3909+            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
3910+            sage: P([[(0,0,0),(1,0,0),(0,1,0),(0,0,1)], [], []], None)
3911+            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
3912+            sage: P(0)
3913+            A 0-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex
3914+        """
3915+        nargs = len(args)
3916+        if nargs==2:
3917+            Vrep, Hrep = args
3918+            return self.element_class(self, Vrep, Hrep, **kwds)
3919+        if nargs==1 and is_Polyhedron(args[0]):
3920+            polyhedron = args[0]
3921+            Hrep = [ polyhedron.inequality_generator(), polyhedron.equation_generator() ]
3922+            return self.element_class(self, None, Hrep, **kwds)
3923+        if nargs==1 and args[0]==0:
3924+            return self.zero_element()
3925+        raise ValueError('Cannot convert to polyhedron object.')
3926+
3927+    def base_extend(self, base_ring, backend=None):
3928+        """
3929+        Return the base extended parent.
3930+
3931+        INPUT:
3932+       
3933+        - ``base_ring``, ``backend`` -- see
3934+          :func:`~sage.geometry.polyhedron.constructor.Polyhedron`.
3935+       
3936+        EXAMPLES::
3937+           
3938+            sage: from sage.geometry.polyhedron.parent import Polyhedra
3939+            sage: Polyhedra(ZZ,3).base_extend(QQ)
3940+            Polyhedra in QQ^3
3941+            sage: Polyhedra(ZZ,3).an_element().base_extend(QQ)
3942+            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 4 vertices
3943+        """
3944+        if self.base_ring().has_coerce_map_from(base_ring):
3945+            return self
3946+        elif base_ring.has_coerce_map_from(self.base_ring()):
3947+            return Polyhedra(base_ring, self.ambient_dim())
3948+
3949+    def _coerce_base_ring(self, other):
3950+        """
3951+        Return the common base rincg for both ``self`` and ``other``.
3952+
3953+        This method is not part of the coercion framework, but only a
3954+        convenience function for :class:`Polyhedra_base`.
3955+       
3956+        INPUT:
3957+
3958+        - ``other`` -- must be either:
3959+       
3960+            * another ``Polyhedron`` object
3961+       
3962+            * `\ZZ`, `\QQ`, `RDF`, or a ring that can be coerced into them.
3963+       
3964+            * a constant that can be coerced to `\ZZ`, `\QQ`, or `RDF`.
3965+
3966+        OUTPUT:
3967+
3968+        Either `\ZZ`, `\QQ`, or `RDF`. Raises ``TypeError`` if
3969+        ``other`` is not a suitable input.
3970+
3971+        .. NOTE::
3972+       
3973+            "Real" numbers in sage are not necessarily elements of
3974+            `RDF`. For example, the literal `1.0` is not.
3975+
3976+        EXAMPLES::
3977+
3978+            sage: triangle_QQ  = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=QQ).parent()
3979+            sage: triangle_RDF = Polyhedron(vertices = [[1,0],[0,1],[1,1]], base_ring=RDF).parent()
3980+            sage: triangle_QQ._coerce_base_ring(QQ)
3981+            Rational Field
3982+            sage: triangle_QQ._coerce_base_ring(triangle_RDF)
3983+            Real Double Field
3984+            sage: triangle_RDF._coerce_base_ring(triangle_QQ)
3985+            Real Double Field
3986+            sage: triangle_QQ._coerce_base_ring(RDF)
3987+            Real Double Field
3988+            sage: triangle_QQ._coerce_base_ring(ZZ)
3989+            Rational Field
3990+            sage: triangle_QQ._coerce_base_ring(1/2)
3991+            Rational Field
3992+            sage: triangle_QQ._coerce_base_ring(0.5)
3993+            Real Double Field
3994+        """
3995+        try:
3996+            other_ring = other.base_ring()
3997+        except AttributeError:
3998+            try:
3999+                # other is a constant?
4000+                other_ring = other.parent()
4001+            except AttributeError:
4002+                try:
4003+                    ZZ.coerce(other)
4004+                    other_ring = ZZ
4005+                except TypeError:
4006+                    pass
4007+                try:
4008+                    QQ.coerce(other)
4009+                    other_ring = QQ
4010+                except TypeError:
4011+                    pass
4012+                try:
4013+                    RDF.coerce(other)
4014+                    other_ring = RDF
4015+                except TypeError:
4016+                    other_ring = None
4017+               
4018+        if not other_ring.is_exact():
4019+            other_ring = RDF  # the only supported floating-point numbers for now
4020+
4021+        cm_map, cm_ring = get_coercion_model().analyse(self.base_ring(), other_ring)
4022+        if cm_ring is None:
4023+            raise TypeError('Could not coerce '+str(other)+' into ZZ, QQ, or RDF.')
4024+        return cm_ring
4025+
4026+    def _coerce_map_from_(self, X):
4027+        r"""
4028+        Return whether there is a coercion from ``X``
4029+
4030+        INPUT:
4031+
4032+        - ``X`` -- anything.
4033+
4034+        OUTPUT:
4035+
4036+        Boolean.
4037+
4038+        EXAMPLE::
4039+
4040+            sage: from sage.geometry.polyhedron.parent import Polyhedra
4041+            sage: Polyhedra(QQ,3).has_coerce_map_from( Polyhedra(ZZ,3) )   # indirect doctest
4042+            True
4043+            sage: Polyhedra(ZZ,3).has_coerce_map_from( Polyhedra(QQ,3) )
4044+            False
4045+        """
4046+        if not isinstance(X, Polyhedra_base):
4047+            return False
4048+        if self.ambient_dim() != X.ambient_dim():
4049+            return False
4050+        return self.base_ring().has_coerce_map_from(X.base_ring())
4051+
4052+    def _get_action_(self, other, op, self_is_left):
4053+        """
4054+        Register actions with the coercion model.
4055+
4056+        The monoid actions are Minkowski sum and cartesian product. In
4057+        addition, we want multiplication by a scalar to be dilation
4058+        and addition by a vector to be translation. This is
4059+        implemented as an action in the coercion model.
4060+
4061+        INPUT:
4062+
4063+        - ``other`` -- a scalar or a vector.
4064+
4065+        - ``op`` -- the operator.
4066+       
4067+        - ``self_is_left`` -- boolean. Whether ``self`` is on the left
4068+          of the operator.
4069+
4070+        OUTPUT:
4071+
4072+        An action that is used by the coercion model.
4073+
4074+        EXAMPLES::
4075+       
4076+            sage: from sage.geometry.polyhedron.parent import Polyhedra
4077+            sage: Polyhedra(ZZ,2).get_action(ZZ)   # indirect doctest
4078+            Right action by Integer Ring on Polyhedra in ZZ^2
4079+            sage: Polyhedra(ZZ,2).get_action(QQ)
4080+            Right action by Rational Field on Polyhedra in QQ^2
4081+            with precomposition on left by Conversion map:
4082+              From: Polyhedra in ZZ^2
4083+              To:   Polyhedra in QQ^2
4084+            with precomposition on right by Identity endomorphism of Rational Field
4085+            sage: Polyhedra(QQ,2).get_action(ZZ)
4086+            Right action by Integer Ring on Polyhedra in QQ^2
4087+            sage: Polyhedra(QQ,2).get_action(QQ)
4088+            Right action by Rational Field on Polyhedra in QQ^2
4089+           
4090+            sage: Polyhedra(ZZ,2).an_element() * 2
4091+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
4092+            sage: Polyhedra(ZZ,2).an_element() * (2/3)
4093+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
4094+            sage: Polyhedra(QQ,2).an_element() * 2
4095+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
4096+            sage: Polyhedra(QQ,2).an_element() * (2/3)
4097+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
4098+
4099+            sage: 2     * Polyhedra(ZZ,2).an_element()
4100+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
4101+            sage: (2/3) * Polyhedra(ZZ,2).an_element()
4102+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
4103+            sage: 2     * Polyhedra(QQ,2).an_element()
4104+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
4105+            sage: (2/3) * Polyhedra(QQ,2).an_element()
4106+            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
4107+
4108+            sage: from sage.geometry.polyhedron.parent import Polyhedra
4109+            sage: Polyhedra(ZZ,2).get_action( ZZ^2, op=operator.add)
4110+            Right action by Ambient free module of rank 2 over the principal ideal
4111+            domain Integer Ring on Polyhedra in ZZ^2
4112+            with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2
4113+            with precomposition on right by Free module morphism defined by the matrix
4114+            [1 0]
4115+            [0 1]
4116+            Domain: Ambient free module of rank 2 over the principal ideal domain ...
4117+            Codomain: Ambient free module of rank 2 over the principal ideal domain ...
4118+        """
4119+        import operator
4120+        from sage.structure.coerce_actions import ActedUponAction
4121+        from sage.categories.action import PrecomposedAction
4122+
4123+        if op is operator.add and is_FreeModule(other):
4124+            base_ring = self._coerce_base_ring(other)
4125+            extended_self = self.base_extend(base_ring)
4126+            extended_other = other.base_extend(base_ring)
4127+            action = ActedUponAction(extended_other, extended_self, not self_is_left)
4128+            if self_is_left:
4129+                action = PrecomposedAction(action, 
4130+                                           extended_self.coerce_map_from(self), 
4131+                                           extended_other.coerce_map_from(other))
4132+            else:
4133+                action = PrecomposedAction(action, 
4134+                                           extended_other.coerce_map_from(other),
4135+                                           extended_self.coerce_map_from(self))
4136+            return action
4137+       
4138+        if op is operator.mul and is_CommutativeRing(other):
4139+            ring = self._coerce_base_ring(other)
4140+            if ring is self.base_ring():
4141+                return ActedUponAction(other, self, not self_is_left)
4142+            extended = self.base_extend(ring)
4143+            action = ActedUponAction(ring, extended, not self_is_left)
4144+            if self_is_left:
4145+                action = PrecomposedAction(action, 
4146+                                           extended.coerce_map_from(self), 
4147+                                           ring.coerce_map_from(other))
4148+            else:
4149+                action = PrecomposedAction(action, 
4150+                                           ring.coerce_map_from(other), 
4151+                                           extended.coerce_map_from(self))
4152+            return action
4153+               
4154+    def _make_Inequality(self, polyhedron, data):
4155+        """
4156+        Create a new inequality object.
4157+
4158+        INPUT:
4159+
4160+        - ``polyhedron`` -- the new polyhedron.
4161+
4162+        - ``data`` -- the H-representation data.
4163+
4164+        OUTPUT:
4165+
4166+        A new :class:`~sage.geometry.polyhedron.representation.Inequality` object.
4167+
4168+        EXAMPLES::
4169+
4170+            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)])   # indirect doctest
4171+            sage: p.inequality_generator().next()
4172+            An inequality (0, 0, -1) x + 3 >= 0
4173+        """
4174+        try:
4175+            obj = self._Inequality_pool.pop()
4176+        except IndexError:
4177+            obj = Inequality(self)
4178+        obj._set_data(polyhedron, data)
4179+        return obj
4180+   
4181+    def _make_Equation(self, polyhedron, data):
4182+        """
4183+        Create a new equation object.
4184+
4185+        INPUT:
4186+
4187+        - ``polyhedron`` -- the new polyhedron.
4188+
4189+        - ``data`` -- the H-representation data.
4190+
4191+        OUTPUT:
4192+
4193+        A new :class:`~sage.geometry.polyhedron.representation.Equation` object.
4194+
4195+        EXAMPLES::
4196+
4197+            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)])   # indirect doctest
4198+            sage: p.equation_generator().next()                 
4199+            An equation (0, 44, -25) x - 13 == 0
4200+        """
4201+        try:
4202+            obj = self._Equation_pool.pop()
4203+        except IndexError:
4204+            obj = Equation(self)
4205+        obj._set_data(polyhedron, data)
4206+        return obj
4207+
4208+    def _make_Vertex(self, polyhedron, data):
4209+        """
4210+        Create a new vertex object.
4211+
4212+        INPUT:
4213+
4214+        - ``polyhedron`` -- the new polyhedron.
4215+
4216+        - ``data`` -- the V-representation data.
4217+
4218+        OUTPUT:
4219+
4220+        A new :class:`~sage.geometry.polyhedron.representation.Vertex` object.
4221+
4222+        EXAMPLES::
4223+
4224+            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)])   # indirect doctest
4225+            sage: p.vertex_generator().next()
4226+            A vertex at (1, 2, 3)
4227+        """
4228+        try:
4229+            obj = self._Vertex_pool.pop()
4230+        except IndexError:
4231+            obj = Vertex(self)
4232+        obj._set_data(polyhedron, data)
4233+        return obj
4234+
4235+    def _make_Ray(self, polyhedron, data):
4236+        """
4237+        Create a new ray object.
4238+
4239+        INPUT:
4240+
4241+        - ``polyhedron`` -- the new polyhedron.
4242+
4243+        - ``data`` -- the V-representation data.
4244+
4245+        OUTPUT:
4246+
4247+        A new :class:`~sage.geometry.polyhedron.representation.Ray` object.
4248+
4249+        EXAMPLES::
4250+
4251+            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], rays=[(5/6,6/7,7/8)])   # indirect doctest
4252+            sage: p.ray_generator().next()
4253+            A ray in the direction (140, 144, 147)
4254+        """
4255+        try:
4256+            obj = self._Ray_pool.pop()
4257+        except IndexError:
4258+            obj = Ray(self)
4259+        obj._set_data(polyhedron, data)
4260+        return obj
4261+
4262+    def _make_Line(self, polyhedron, data):
4263+        """
4264+        Create a new line object.
4265+
4266+        INPUT:
4267+
4268+        - ``polyhedron`` -- the new polyhedron.
4269+
4270+        - ``data`` -- the V-representation data.
4271+
4272+        OUTPUT:
4273+
4274+        A new :class:`~sage.geometry.polyhedron.representation.Line` object.
4275+
4276+        EXAMPLES::
4277+
4278+            sage: p = Polyhedron([(1,2,3),(2/3,3/4,4/5)], lines=[(5/6,6/7,7/8)])   # indirect doctest
4279+            sage: p.line_generator().next()                                     
4280+            A line in the direction (140, 144, 147)
4281+        """
4282+        try:
4283+            obj = self._Line_pool.pop()
4284+        except IndexError:
4285+            obj = Line(self)
4286+        obj._set_data(polyhedron, data)
4287+        return obj
4288+       
4289+
4290+
4291+from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd, Polyhedron_RDF_cdd
4292+from sage.geometry.polyhedron.backend_ppl import Polyhedron_ZZ_ppl, Polyhedron_QQ_ppl
4293+
4294+class Polyhedra_ZZ_ppl(Polyhedra_base):
4295+    Element = Polyhedron_ZZ_ppl
4296+
4297+class Polyhedra_QQ_ppl(Polyhedra_base):
4298+    Element = Polyhedron_QQ_ppl
4299+
4300+class Polyhedra_QQ_cdd(Polyhedra_base):
4301+    Element = Polyhedron_QQ_cdd
4302+
4303+class Polyhedra_RDF_cdd(Polyhedra_base):
4304+    Element = Polyhedron_RDF_cdd
4305+
4306diff --git a/sage/geometry/polyhedron/representation.py b/sage/geometry/polyhedron/representation.py
4307--- a/sage/geometry/polyhedron/representation.py
4308+++ b/sage/geometry/polyhedron/representation.py
4309@@ -16,7 +16,6 @@
4310 from sage.structure.element import is_Vector
4311 from sage.rings.all import QQ, ZZ, RDF
4312 from sage.modules.free_module_element import vector
4313-from sage.misc.all import cached_method
4314 
4315 
4316 
4317@@ -39,6 +38,11 @@
4318         You should not (and cannot) instantiate it yourself. You can
4319         only obtain them from a Polyhedron() class.
4320 
4321+    TESTS::
4322+   
4323+            sage: import sage.geometry.polyhedron.representation as P
4324+            sage: P.PolyhedronRepresentation()
4325+            <class 'sage.geometry.polyhedron.representation.PolyhedronRepresentation'>
4326     """
4327     
4328     # Numeric values for the output of the type() method
4329@@ -48,34 +52,18 @@
4330     RAY = 3
4331     LINE = 4
4332     
4333-    def __init__(self, polyhedron, data):
4334-        """
4335-        Initializes the PolyhedronRepresentation object.
4336-       
4337-        TESTS::
4338-       
4339-            sage: import sage.geometry.polyhedron.representation as P
4340-            sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
4341-            sage: tuple(pr)
4342-            (1, 2, 3)
4343-            sage: TestSuite(pr).run(skip='_test_pickling')
4344-        """
4345-        R = polyhedron.base_ring()
4346-        self._representation_data = tuple(R(x) for x in data)
4347-        self._polyhedron = polyhedron
4348-
4349     def __len__(self):
4350         """
4351         Returns the length of the representation data.
4352         
4353         TESTS::
4354         
4355-            sage: import sage.geometry.polyhedron.representation as P
4356-            sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
4357-            sage: pr.__len__()
4358+            sage: p = Polyhedron(vertices=[[1,2,3]])
4359+            sage: v = p.Vrepresentation(0)
4360+            sage: v.__len__()
4361             3
4362         """
4363-        return len(self._representation_data)
4364+        return self._vector.degree()
4365 
4366     def __getitem__(self, i):
4367         """
4368@@ -83,12 +71,55 @@
4369         
4370         TESTS::
4371         
4372-            sage: import sage.geometry.polyhedron.representation as P
4373-            sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
4374-            sage: pr.__getitem__(1)
4375+            sage: p = Polyhedron(vertices=[[1,2,3]])
4376+            sage: v = p.Vrepresentation(0)
4377+            sage: v.__getitem__(1)
4378             2
4379         """
4380-        return self._representation_data[i]
4381+        return self._vector[i]
4382+
4383+    def vector(self, base_ring=None):
4384+        """
4385+        Returns the vector representation of the H/V-representation object.
4386+
4387+        INPUT:
4388+
4389+        - ``base_ring`` -- the base ring of the vector. 
4390+
4391+        OUTPUT:
4392+       
4393+        For a V-representation object, a vector of length
4394+        :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`. For
4395+        a H-representation object, a vector of length
4396+        :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`
4397+        + 1.
4398+
4399+        EXAMPLES::
4400+
4401+            sage: s = polytopes.cuboctahedron() 
4402+            sage: v = s.vertex_generator().next()
4403+            sage: v
4404+            A vertex at (-1/2, -1/2, 0)
4405+            sage: v.vector()
4406+            (-1/2, -1/2, 0)
4407+            sage: v()
4408+            (-1/2, -1/2, 0)
4409+            sage: type(v())
4410+            <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
4411+
4412+       Conversion to a different base ring can be forced with the optional argument::
4413+
4414+            sage: v.vector(RDF)
4415+            (-0.5, -0.5, 0.0)
4416+            sage: vector(RDF, v)
4417+            (-0.5, -0.5, 0.0)
4418+        """
4419+        if (base_ring is None) or (base_ring is self._base_ring):
4420+            return self._vector
4421+        else:
4422+            return vector(base_ring, self._vector)
4423+
4424+    _vector_ = vector
4425 
4426     def polyhedron(self):
4427         """
4428@@ -96,10 +127,10 @@
4429         
4430         TESTS::
4431         
4432-            sage: import sage.geometry.polyhedron.representation as P
4433-            sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
4434-            sage: pr.polyhedron()
4435-            A 0-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex
4436+            sage: p = Polyhedron(vertices=[[1,2,3]])
4437+            sage: v = p.Vrepresentation(0)
4438+            sage: v.polyhedron()
4439+            A 0-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex
4440         """
4441         return self._polyhedron
4442 
4443@@ -108,23 +139,14 @@
4444         Returns the vector representation of the representation
4445         object. Shorthand for the vector() method.
4446 
4447-        Note that the vector() method is only implemented in derived
4448-        classes.
4449-
4450         TESTS::
4451         
4452-            sage: import sage.geometry.polyhedron.representation as P
4453-            sage: pr = Polyhedron(vertices = [[1,2,3]]).Vrepresentation(0)
4454-            sage: pr.__call__()
4455+            sage: p = Polyhedron(vertices=[[1,2,3]])
4456+            sage: v = p.Vrepresentation(0)
4457+            sage: v.__call__()
4458             (1, 2, 3)
4459-           
4460-            sage: pr = P.PolyhedronRepresentation(Polyhedron(vertices = [[1,2,3]]), [1,2,3])
4461-            sage: pr.__call__()
4462-            Traceback (most recent call last):
4463-            ...
4464-            AttributeError: 'PolyhedronRepresentation' object has no attribute 'vector'
4465         """
4466-        return self.vector()
4467+        return self._vector
4468 
4469     def index(self):
4470         """
4471@@ -150,6 +172,75 @@
4472         """
4473         return self._index
4474 
4475+    def __add__(self, coordinate_list):
4476+        """
4477+        Return the coordinates concatenated with ``coordinate_list``.
4478+
4479+        INPUT:
4480+
4481+        - ``coordinate_list`` -- a list.
4482+
4483+        OUTPUT:
4484+
4485+        The coordinates of ``self`` concatenated with ``coordinate_list``.
4486+
4487+        EXAMPLES::
4488+
4489+            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
4490+            sage: v = p.Vrepresentation(0); v
4491+            A vertex at (1, 0)
4492+            sage: v + [4,5]
4493+            [1, 0, 4, 5]
4494+        """
4495+        if not isinstance(coordinate_list, list):
4496+            raise TypeError('Can only concatenate with a list of coordinates')
4497+        return list(self) + coordinate_list
4498+
4499+    def __radd__(self, coordinate_list):
4500+        """
4501+        Return ``coordinate_list`` concatenated with the coordinates.
4502+
4503+        INPUT:
4504+
4505+        - ``coordinate_list`` -- a list.
4506+
4507+        OUTPUT:
4508+
4509+        ``coordinate_list`` concatenated with the coordinates of ``self``.
4510+
4511+        EXAMPLES::
4512+
4513+            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
4514+            sage: v = p.Vrepresentation(0); v
4515+            A vertex at (1, 0)
4516+            sage: [4,5] + v
4517+            [4, 5, 1, 0]
4518+        """
4519+        if not isinstance(coordinate_list, list):
4520+            raise TypeError('Can only concatenate with a list of coordinates')
4521+        return coordinate_list + list(self)
4522+   
4523+    def count(self, i):
4524+        """
4525+        Count the number of occurrences of ``i`` in the coordinates.
4526+       
4527+        INPUT:
4528+
4529+        - ``i`` -- Anything.
4530+
4531+        OUTPUT:
4532+
4533+        Integer. The number of occurrences of ``i`` in the coordinates.
4534+
4535+        EXAMPLES::
4536+       
4537+            sage: p = Polyhedron(vertices=[(0,1,1,2,1)])
4538+            sage: v = p.Vrepresentation(0); v
4539+            A vertex at (0, 1, 1, 2, 1)
4540+            sage: v.count(1)
4541+            3
4542+        """
4543+        return sum([1 for j in self if i==j])
4544 
4545 
4546 class Hrepresentation(PolyhedronRepresentation):
4547@@ -157,47 +248,61 @@
4548     The internal base class for H-representation objects of
4549     a polyhedron. Inherits from ``PolyhedronRepresentation``.
4550     """
4551-    def __init__(self, polyhedron, data):
4552+
4553+    def __init__(self, polyhedron_parent):
4554+        """
4555+        Initializes the PolyhedronRepresentation object.
4556+       
4557+        TESTS::
4558+       
4559+            sage: from sage.geometry.polyhedron.representation import Hrepresentation
4560+            sage: pr = Hrepresentation(Polyhedron(vertices = [[1,2,3]]).parent())
4561+            sage: tuple(pr)
4562+            (0, 0, 0, 0)
4563+            sage: TestSuite(pr).run(skip='_test_pickling')
4564+        """
4565+        self._polyhedron_parent = polyhedron_parent
4566+        self._base_ring = polyhedron_parent.base_ring()
4567+        self._vector = polyhedron_parent.Hrepresentation_space()(0)
4568+        self._A = polyhedron_parent.ambient_space()(0)
4569+        self._b = polyhedron_parent.base_ring()(0)
4570+        self._index = 0
4571+
4572+    def _set_data(self, polyhedron, data):
4573         """
4574         Initialization function.
4575 
4576+        The H/V-representation objects are kept in a pool, and this
4577+        function is used to reassign new values to already existing
4578+        (but unused) objects. You must not call this function on
4579+        objects that are in normal use.
4580+
4581+        INPUT:
4582+
4583+        - ``polyhedron`` -- the new polyhedron.
4584+
4585+        - ``data`` -- the H-representation data.
4586+
4587         TESTS::
4588 
4589             sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
4590-            sage: pH = p.Hrepresentation(0)
4591+            sage: pH = p.Hrepresentation(0)   # indirect doctest
4592             sage: TestSuite(pH).run(skip='_test_pickling')
4593         """
4594-        if len(data) != 1+polyhedron.ambient_dim():
4595+        assert polyhedron.parent() is self._polyhedron_parent
4596+        if len(data) != self._vector.degree():
4597             raise ValueError, \
4598                 'H-representation data requires a list of length ambient_dim+1'
4599-        super(Hrepresentation, self).__init__(polyhedron, data)
4600+
4601+        for i in range(0, self._vector.degree()):
4602+            self._vector.set(i, data[i])
4603+        for i in range(0, self._A.degree()):
4604+            self._A.set(i, data[i+1])
4605+        self._b = self._base_ring(data[0])
4606+
4607         self._index = len(polyhedron._Hrepresentation)
4608         polyhedron._Hrepresentation.append(self)
4609-   
4610-    @cached_method
4611-    def vector(self):
4612-        """
4613-        Returns the vector representation of the H-representation object.
4614-
4615-        OUTPUT:
4616-       
4617-        A vector of length
4618-        :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim` + 1.
4619-
4620-        EXAMPLES::
4621-
4622-            sage: s = polytopes.cuboctahedron() 
4623-            sage: v = s.vertex_generator().next()
4624-            sage: v
4625-            A vertex at (-1/2, -1/2, 0)
4626-            sage: v.vector()
4627-            (-1/2, -1/2, 0)
4628-            sage: v()
4629-            (-1/2, -1/2, 0)
4630-            sage: type(v())
4631-            <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
4632-        """
4633-        return self.polyhedron().Hrepresentation_space()(self._representation_data)
4634+        self._polyhedron = polyhedron
4635 
4636     def is_H(self):
4637         """
4638@@ -239,7 +344,6 @@
4639         """       
4640         return False
4641     
4642-    @cached_method
4643     def A(self):
4644         r"""
4645         Returns the coefficient vector `A` in `A\vec{x}+b`.
4646@@ -251,9 +355,8 @@
4647             sage: pH.A()
4648             (1, 0)
4649         """
4650-        return self.polyhedron().ambient_space()(self._representation_data[1:])
4651+        return self._A
4652 
4653-    @cached_method
4654     def b(self):
4655         r"""
4656         Returns the constant `b` in `A\vec{x}+b`.
4657@@ -265,7 +368,7 @@
4658             sage: pH.b()
4659             0
4660         """
4661-        return self._representation_data[0]
4662+        return self._b
4663 
4664     def neighbors(self):
4665         """
4666@@ -365,7 +468,6 @@
4667         if is_Vector(Vobj):
4668             return self.A() * Vobj + self.b()
4669         return Vobj.evaluated_on(self)
4670-        #return self.A() * Vobj.vector() + self.b()
4671 
4672     def incident(self):
4673         """
4674@@ -400,21 +502,6 @@
4675     A linear inequality (supporting hyperplane) of the
4676     polyhedron. Inherits from ``Hrepresentation``.
4677     """
4678-    def __init__(self, polyhedron, data):
4679-        """
4680-        A linear inequality (supporting hyperplane) of the
4681-        polyhedron. Inherits from ``Hrepresentation``.
4682-
4683-        TESTS::
4684-
4685-            sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
4686-            sage: a = p.inequality_generator().next()
4687-            sage: a
4688-            An inequality (-1, 1, 0) x + 0 >= 0
4689-            sage: TestSuite(a).run(skip='_test_pickling')
4690-        """
4691-        super(Inequality, self).__init__(polyhedron, data)
4692-
4693 
4694     def type(self):
4695         r"""
4696@@ -559,20 +646,6 @@
4697     strictly smaller-dimensional than the ambient space, and contained
4698     in this hyperplane. Inherits from ``Hrepresentation``.
4699     """
4700-    def __init__(self, polyhedron, data):
4701-        """
4702-        Initializes an equation object.
4703-
4704-        TESTS::
4705-
4706-            sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
4707-            sage: a = p.equation_generator().next()
4708-            sage: a
4709-            An equation (0, 0, 1) x + 0 == 0
4710-            sage: TestSuite(a).run(skip='_test_pickling')
4711-        """
4712-        super(Equation, self).__init__(polyhedron, data)
4713-
4714 
4715     def type(self):
4716         r"""
4717@@ -693,52 +766,56 @@
4718     The base class for V-representation objects of a
4719     polyhedron. Inherits from ``PolyhedronRepresentation``.
4720     """
4721-    def __init__(self, polyhedron, data):
4722+
4723+    def __init__(self, polyhedron_parent):
4724         """
4725-        Initialization function for the vertex representation.
4726+        Initializes the PolyhedronRepresentation object.
4727+       
4728+        TESTS::
4729+       
4730+            sage: p = Polyhedron(vertices = [[0,0,0],[1,1,0],[1,2,0]])
4731+            sage: a = p.inequality_generator().next()
4732+            sage: a
4733+            An inequality (-1, 1, 0) x + 0 >= 0
4734+            sage: TestSuite(a).run(skip='_test_pickling')
4735+        """
4736+        self._polyhedron_parent = polyhedron_parent
4737+        self._base_ring = polyhedron_parent.base_ring()
4738+        self._vector = polyhedron_parent.Vrepresentation_space()(0)
4739+        self._index = 0
4740+
4741+    def _set_data(self, polyhedron, data):
4742+        """
4743+        Initialization function.
4744+
4745+        The H/V-representation objects are kept in a pool, and this
4746+        function is used to reassign new values to already existing
4747+        (but unused) objects. You must not call this function on
4748+        objects that are in normal use.
4749+
4750+        INPUT:
4751+
4752+        - ``polyhedron`` -- the new polyhedron.
4753+
4754+        - ``data`` -- the V-representation data.
4755 
4756         TESTS::
4757-       
4758-            sage: p = Polyhedron(ieqs = [[1, 0, 0, 0, 1], [1, 1, 0, 0, 0], [1, 0, 1, 0, 0]])
4759-            sage: from sage.geometry.polyhedron.representation import Vrepresentation
4760-            sage: p._Vrepresentation = Sequence([])
4761-            sage: vr = Vrepresentation(p,[1,2,3,4])
4762-            sage: vr.__init__(p,[1,2,3,5])
4763-            sage: vr.vector()
4764-            (1, 2, 3, 5)
4765-            sage: TestSuite(vr).run(skip='_test_pickling')
4766+
4767+            sage: p = Polyhedron(ieqs = [[0,1,0],[0,0,1],[1,-1,0,],[1,0,-1]])
4768+            sage: pV = p.Vrepresentation(0)   # indirect doctest
4769+            sage: TestSuite(pV).run(skip='_test_pickling')
4770         """
4771-        if len(data) != polyhedron.ambient_dim():
4772+        assert polyhedron.parent() is self._polyhedron_parent
4773+        if len(data) != self._vector.degree():
4774             raise ValueError, \
4775                 'V-representation data requires a list of length ambient_dim'
4776-        super(Vrepresentation, self).__init__(polyhedron, data)
4777+       
4778+        for i in range(0, self._vector.degree()):
4779+            self._vector.set(i, data[i])
4780+
4781         self._index = len(polyhedron._Vrepresentation)
4782         polyhedron._Vrepresentation.append(self)
4783-
4784-    @cached_method
4785-    def vector(self):
4786-        """
4787-        Returns the vector representation of the V-representation object.
4788-
4789-        OUTPUT:
4790-       
4791-        A vector of length
4792-        :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.ambient_dim`.
4793-
4794-        EXAMPLES::
4795-
4796-            sage: s = polytopes.cuboctahedron()
4797-            sage: v = s.vertex_generator().next()
4798-            sage: v
4799-            A vertex at (-1/2, -1/2, 0)
4800-            sage: v.vector()
4801-            (-1/2, -1/2, 0)
4802-            sage: v()
4803-            (-1/2, -1/2, 0)
4804-            sage: type(v())
4805-            <type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
4806-        """
4807-        return self.polyhedron().Vrepresentation_space()(self._representation_data)
4808+        self._polyhedron = polyhedron
4809 
4810     def is_V(self): 
4811         """
4812@@ -906,20 +983,6 @@
4813     """
4814     A vertex of the polyhedron. Inherits from ``Vrepresentation``.
4815     """
4816-    def __init__(self, polyhedron, data):
4817-        """
4818-        Initializes the vertex object.
4819-
4820-        TESTS::
4821-
4822-            sage: p = Polyhedron(ieqs = [[0,0,1],[0,1,0],[1,-1,0]])
4823-            sage: v1 = p.vertex_generator().next()
4824-            sage: v1
4825-            A vertex at (1, 0)
4826-            sage: TestSuite(v1).run(skip='_test_pickling')
4827-        """
4828-        super(Vertex, self).__init__(polyhedron, data)
4829-
4830 
4831     def type(self):
4832         r"""
4833@@ -999,7 +1062,6 @@
4834         """
4835         return Hobj.A() * self.vector() + Hobj.b()
4836 
4837-    @cached_method
4838     def is_integral(self):
4839         r"""
4840         Return whether the coordinates of the vertex are all integral.
4841@@ -1014,27 +1076,13 @@
4842             sage: [ v.is_integral() for v in p.vertex_generator() ]
4843             [True, False, True]
4844         """
4845-        return all(x in ZZ for x in self._representation_data)
4846+        return (self._base_ring is ZZ) or all(x in ZZ for x in self)
4847 
4848 
4849 class Ray(Vrepresentation):
4850     """
4851     A ray of the polyhedron. Inherits from ``Vrepresentation``.
4852     """
4853-    def __init__(self, polyhedron, data):
4854-        """
4855-        Initializes a ray object.
4856-
4857-        TESTS::
4858-
4859-            sage: p = Polyhedron(ieqs = [[0,0,1],[0,1,0],[1,-1,0]])
4860-            sage: r1 = p.ray_generator().next()
4861-            sage: r1
4862-            A ray in the direction (0, 1)
4863-            sage: TestSuite(r1).run(skip='_test_pickling')
4864-        """
4865-        super(Ray, self).__init__(polyhedron, data)
4866-
4867 
4868     def type(self):
4869         r"""
4870@@ -1112,22 +1160,6 @@
4871     A line (Minkowski summand `\simeq\RR`) of the
4872     polyhedron. Inherits from ``Vrepresentation``.
4873     """
4874-    def __init__(self, polyhedron, data):
4875-        """
4876-        Initializes the line object.
4877-
4878-        TESTS::
4879-
4880-            sage: p = Polyhedron(ieqs = [[1, 0, 0, 1],[1,1,0,0]])
4881-            sage: a = p.line_generator().next()
4882-            sage: p._Vrepresentation = Sequence([])
4883-            sage: a.__init__(p,[1,2,3])
4884-            sage: a
4885-            A line in the direction (1, 2, 3)
4886-            sage: TestSuite(a).run(skip='_test_pickling')
4887-        """
4888-        super(Line, self).__init__(polyhedron, data)
4889-
4890 
4891     def type(self):
4892         r"""
4893@@ -1158,7 +1190,6 @@
4894         """
4895         return self.LINE
4896 
4897-
4898     def is_line(self):
4899         """
4900         Tests if the object is a line.  By construction it must be.
4901diff --git a/sage/geometry/triangulation/point_configuration.py b/sage/geometry/triangulation/point_configuration.py
4902--- a/sage/geometry/triangulation/point_configuration.py
4903+++ b/sage/geometry/triangulation/point_configuration.py
4904@@ -1575,7 +1575,7 @@
4905 
4906             sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) 
4907             sage: p.convex_hull()
4908-            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
4909+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 4 vertices
4910         """
4911         try:
4912             return self._polyhedron
4913@@ -1833,7 +1833,7 @@
4914 
4915             sage: p = PointConfiguration([[0,0],[1,0],[2,1],[1,2],[0,1]])
4916             sage: poly = p.secondary_polytope()
4917-            sage: matrix(poly.vertices()).transpose()
4918+            sage: poly.vertices_matrix()
4919             [1 1 3 3 5]
4920             [3 5 1 4 1]
4921             [4 2 5 2 4]
4922diff --git a/sage/rings/polynomial/groebner_fan.py b/sage/rings/polynomial/groebner_fan.py
4923--- a/sage/rings/polynomial/groebner_fan.py
4924+++ b/sage/rings/polynomial/groebner_fan.py
4925@@ -1021,18 +1021,15 @@
4926         
4927         INPUT:
4928         
4929-       
4930-        -  ``polyhedral_data`` - an object with 4d vertex and
4931+        -  ``polyhedral_data`` -- an object with 4d vertex and
4932            adjacency information
4933         
4934-       
4935         OUTPUT:
4936         
4937         
4938-        -  ``edges`` - a list of edges in 3d - each list item
4939+        -  ``edges`` -- a list of edges in 3d - each list item
4940            is a pair of points
4941         
4942-       
4943         EXAMPLES::
4944         
4945             sage: R4.<w,x,y,z> = PolynomialRing(QQ,4)
4946@@ -1052,18 +1049,19 @@
4947         """
4948         fpoints = polyhedral_data.vertices()
4949         tpoints = [self._embed_tetra(q) for q in fpoints]
4950-        adj_data = polyhedral_data.vertex_adjacencies()
4951         edges = []
4952-        for adj in adj_data:
4953-            for vert in adj[1]:
4954-                if vert > adj[0]:
4955+        for vertex in polyhedral_data.vertices():
4956+            i = vertex.index()
4957+            for adjacent_vertex in vertex.adjacent():
4958+                j = adjacent_vertex.index()
4959+                if j>i:
4960                     try:
4961-                        edges.append([tpoints[adj[0]],tpoints[vert]])
4962+                        edges.append([tpoints[i],tpoints[j]])
4963                     except:
4964                         print adj
4965                         print 'tpoints: ' + str(tpoints)
4966                         print 'fpoints: ' + str(fpoints)
4967-                        print vert
4968+                        print adjacent_vertex
4969                         print polyhedral_data.ieqs()
4970                         raise RuntimeError, adj
4971         return edges
4972@@ -1107,10 +1105,12 @@
4973         #This is really just for debugging
4974         if verbose:
4975             for x in cone_info:
4976-                print x.ieqs() + [[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]]
4977-                print x.linearities()
4978+                print x.inequalities() + ([1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1])
4979+                print x.equations()
4980                 print ""
4981-        cone_info = [Polyhedron(ieqs = x.ieqs() + [[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]], eqns = x.linearities()) for x in cone_info]
4982+        cone_info = [Polyhedron(ieqs = x.inequalities() + 
4983+                                ([1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,0,0,0,1]), 
4984+                                eqns = x.equations()) for x in cone_info]
4985         all_lines = []
4986         for cone_data in cone_info:
4987             try:
4988diff --git a/sage/rings/polynomial/multi_polynomial.pyx b/sage/rings/polynomial/multi_polynomial.pyx
4989--- a/sage/rings/polynomial/multi_polynomial.pyx
4990+++ b/sage/rings/polynomial/multi_polynomial.pyx
4991@@ -6,6 +6,7 @@
4992 
4993 include "sage/ext/stdsage.pxi"
4994 from sage.rings.integer cimport Integer
4995+from sage.rings.integer_ring import ZZ
4996 
4997 from sage.misc.derivative import multi_derivative
4998 from sage.rings.infinity import infinity
4999@@ -862,7 +863,7 @@
5000             sage: f = 1 + x*y + x^3 + y^3
5001             sage: P = f.newton_polytope()
5002             sage: P
5003-            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices
5004+            A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
5005             sage: P.is_simple()
5006             True
5007 
5008@@ -870,14 +871,15 @@
5009 
5010             sage: R.<x,y> = QQ[]
5011             sage: R(0).newton_polytope()
5012-            The empty polyhedron in QQ^0
5013+            The empty polyhedron in ZZ^0
5014             sage: R(1).newton_polytope()
5015-            A 0-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex
5016-           
5017+            A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex
5018+            sage: R(x^2+y^2).newton_polytope().integral_points()
5019+            ((0, 2), (1, 1), (2, 0))
5020         """
5021         from sage.geometry.polyhedron.constructor import Polyhedron
5022         e = self.exponents()
5023-        P = Polyhedron(vertices = e)
5024+        P = Polyhedron(vertices=e, base_ring=ZZ)
5025         return P
5026 
5027     def __iter__(self):
5028diff --git a/sage/rings/rational.pyx b/sage/rings/rational.pyx
5029--- a/sage/rings/rational.pyx
5030+++ b/sage/rings/rational.pyx
5031@@ -293,6 +293,27 @@
5032     return (c, d) if not b_negative else (c, ~d)
5033 
5034 
5035+def is_Rational(x):
5036+    """
5037+    Return true if x is of the Sage rational number type.
5038+   
5039+    EXAMPLES::
5040+   
5041+        sage: from sage.rings.rational import is_Rational
5042+        sage: is_Rational(2)
5043+        False
5044+        sage: is_Rational(2/1)
5045+        True
5046+        sage: is_Rational(int(2))
5047+        False
5048+        sage: is_Rational(long(2))
5049+        False
5050+        sage: is_Rational('5')
5051+        False
5052+    """
5053+    return isinstance(x, Rational)
5054+
5055+
5056 cdef class Rational(sage.structure.element.FieldElement):
5057     """
5058     A Rational number.