Ticket #14535: trac14535-immutable_graphs_vb.patch

File trac14535-immutable_graphs_vb.patch, 8.9 KB (added by vbraun, 8 years ago)

Updated patch

  • sage/combinat/posets/hasse_diagram.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1367834112 -7200
    # Node ID 4efe495aa3ef4fd0d1c2d30675846f3973d54ff3
    # Parent  aa7aca259cdd74c051c7e0ce0414f753fce2b6cd
    Mutability for graphs
    
    diff --git a/sage/combinat/posets/hasse_diagram.py b/sage/combinat/posets/hasse_diagram.py
    a b  
    4646        Hasse diagram of a poset containing 4 elements
    4747        sage: TestSuite(H).run()
    4848    """
     49    def __init__(self, *args, **kwds):
     50        """
     51        Hasse diagrams are immutable digraphs, which is made sure here.
    4952
    50     # Hasse diagrams are immutable. This temporary hack enables the
    51     # __hash__ method of DiGraph
    52     _immutable = True
     53        EXAMPLES::
     54
     55            sage: from sage.combinat.posets.hasse_diagram import HasseDiagram
     56            sage: H = HasseDiagram({0:[1,2],1:[3],2:[3],3:[]})
     57            sage: D = {H:1}  # indirect doctest
     58            sage: D
     59            {Hasse diagram of a poset containing 4 elements: 1}
     60
     61        """
     62        DiGraph.__init__(self, *args, **kwds)
     63        # Hasse diagrams are immutable.
     64        self.set_immutable()
    5365
    5466    def _repr_(self):
    5567        r"""
    5668        TESTS::
     69
    5770            sage: from sage.combinat.posets.hasse_diagram import HasseDiagram
    5871            sage: H = HasseDiagram({0:[1,2],1:[3],2:[3],3:[]})
    5972            sage: H._repr_()
  • sage/geometry/polyhedron/base.py

    diff --git a/sage/geometry/polyhedron/base.py b/sage/geometry/polyhedron/base.py
    a b  
    30773077            sage: s4.is_eulerian()
    30783078            True
    30793079        """
    3080         return Graph(self.vertex_adjacency_matrix(), loops=True)
     3080        G = Graph(self.vertex_adjacency_matrix(), loops=True)
     3081        G.set_immutable()
     3082        return G
    30813083
    30823084    graph = vertex_graph
    30833085
  • sage/graphs/bipartite_graph.py

    diff --git a/sage/graphs/bipartite_graph.py b/sage/graphs/bipartite_graph.py
    a b  
    3333#*****************************************************************************
    3434
    3535from graph import Graph
     36from sage.structure.mutability import require_mutable
    3637
    3738class BipartiteGraph(Graph):
    3839    r"""
     
    420421        else:
    421422            return "".join(["Bipartite ", s])
    422423
     424    @require_mutable
    423425    def add_vertex(self, name=None, left=False, right=False):
    424426        """
    425427        Creates an isolated vertex. If the vertex already exists, then
     
    515517
    516518        return retval
    517519
     520    @require_mutable
    518521    def add_vertices(self, vertices, left=False, right=False):
    519522        """
    520523        Add vertices to the bipartite graph from an iterable container of
     
    608611
    609612        return
    610613
     614    @require_mutable
    611615    def delete_vertex(self, vertex, in_order=False):
    612616        """
    613617        Deletes vertex, removing all incident edges. Deleting a non-existent
     
    677681                raise RuntimeError(
    678682                    "Vertex (%s) not found in partitions" % vertex)
    679683
     684    @require_mutable
    680685    def delete_vertices(self, vertices):
    681686        """
    682687        Remove vertices from the bipartite graph taken from an iterable
     
    721726                    raise RuntimeError(
    722727                        "Vertex (%s) not found in partitions" % vertex)
    723728
     729    @require_mutable
    724730    def add_edge(self, u, v=None, label=None):
    725731        """
    726732        Adds an edge from ``u`` and ``v``.
  • sage/graphs/generic_graph.py

    diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
    a b  
    308308from sage.rings.rational import Rational
    309309from generic_graph_pyx import GenericGraph_pyx, spring_layout_fast
    310310from sage.graphs.dot2tex_utils import assert_have_dot2tex
     311from sage.structure.mutability import require_mutable
    311312
    312313class GenericGraph(GenericGraph_pyx):
    313314    """
     
    460461                        return False
    461462            return True
    462463
    463     def __hash__(self):
    464         """
    465         Since graphs are mutable, they should not be hashable, so we return
    466         a type error.
    467        
    468         EXAMPLES::
    469        
    470             sage: hash(Graph())
    471             Traceback (most recent call last):
    472             ...
    473             TypeError: graphs are mutable, and thus not hashable
    474         """
    475         if getattr(self, "_immutable", False):
    476             return hash((tuple(self.vertices()), tuple(self.edges())))
    477         raise TypeError("graphs are mutable, and thus not hashable")
    478        
    479464    def __mul__(self, n):
    480465        """
    481466        Returns the sum of a graph with itself n times.
     
    784769                    setattr(G, attr, copy(old_attr))
    785770
    786771        G._weighted = self._weighted
     772        G._is_immutable = False
    787773        return G
    788774
    789775    copy = __copy__
     
    74497435   
    74507436
    74517437    ### Vertex handlers
    7452 
     7438    @require_mutable
    74537439    def add_vertex(self, name=None):
    74547440        """
    74557441        Creates an isolated vertex. If the vertex already exists, then
     
    74857471        """
    74867472        return self._backend.add_vertex(name)
    74877473
     7474    @require_mutable
    74887475    def add_vertices(self, vertices):
    74897476        """
    74907477        Add vertices to the (di)graph from an iterable container of
     
    75227509        """
    75237510        return self._backend.add_vertices(vertices)
    75247511
     7512    @require_mutable
    75257513    def delete_vertex(self, vertex, in_order=False):
    75267514        """
    75277515        Deletes vertex, removing all incident edges. Deleting a
     
    75847572       
    75857573        self._backend.del_vertex(vertex)
    75867574
     7575    @require_mutable
    75877576    def delete_vertices(self, vertices):
    75887577        """
    75897578        Remove vertices from the (di)graph taken from an iterable container
     
    81498138
    81508139
    81518140    ### Edge handlers
    8152    
     8141    @require_mutable
    81538142    def add_edge(self, u, v=None, label=None):
    81548143        """
    81558144        Adds an edge from u and v.
     
    84038392        for e in edges:
    84048393            self.subdivide_edge(e, k)
    84058394
     8395    @require_mutable
    84068396    def delete_edge(self, u, v=None, label=None):
    84078397        r"""
    84088398        Delete the edge from u to v, returning silently if vertices or edge
     
    85558545        else:
    85568546            self.delete_edge(u, v)
    85578547
     8548    @require_mutable
    85588549    def set_edge_label(self, u, v, l):
    85598550        """
    85608551        Set the edge label of a given edge.
  • sage/graphs/generic_graph_pyx.pxd

    diff --git a/sage/graphs/generic_graph_pyx.pxd b/sage/graphs/generic_graph_pyx.pxd
    a b  
    55cdef run_spring(int, int, double*, int*, int, bint)
    66
    77cdef class GenericGraph_pyx(SageObject):
    8     pass
    9 
    10 
     8    cdef public bint _is_immutable
    119
    1210cdef class SubgraphSearch:
    1311    cdef int ng
  • sage/graphs/generic_graph_pyx.pyx

    diff --git a/sage/graphs/generic_graph_pyx.pyx b/sage/graphs/generic_graph_pyx.pyx
    a b  
    2929    double sqrt(double)
    3030
    3131cdef class GenericGraph_pyx(SageObject):
    32     pass
     32
     33    def set_immutable(self):
     34        """
     35        Make sure that this graph can't be changed.
     36
     37        EXAMPLES::
     38
     39            sage: G = Graph()
     40            sage: G.is_mutable()
     41            True
     42            sage: G.add_edge((1,2), label='alpha')
     43            sage: G.set_immutable()
     44            sage: G.add_edge((3,1), label='beta')
     45            Traceback (most recent call last):
     46            ...
     47            ValueError: <class 'sage.graphs.graph.Graph'> instance is
     48            immutable, <function add_edge at ...> must not be called
     49        """
     50        self._is_immutable = True
     51
     52    def is_immutable(self):
     53        """
     54        Test whether this graph is immutable.
     55
     56        EXAMPLES::
     57
     58            sage: G = Graph()
     59            sage: G.is_immutable()
     60            False
     61            sage: G.add_edge((1,2), label='alpha')
     62            sage: G.set_immutable()
     63            sage: G.is_immutable()
     64            True
     65        """
     66        return self._is_immutable
     67
     68    def is_mutable(self):
     69        """
     70        Test whether this graph can be changed.
     71
     72        EXAMPLES::
     73
     74            sage: G = Graph()
     75            sage: G.is_mutable()
     76            True
     77            sage: G.add_edge((1,2), label='alpha')
     78            sage: G.set_immutable()
     79            sage: G.is_mutable()
     80            False
     81        """
     82        return not self._is_immutable
     83
     84    def __hash__(self):
     85        """
     86        Since graphs are mutable, they should not be hashable, so we return
     87        a type error.
     88       
     89        EXAMPLES::
     90       
     91            sage: G = Graph()
     92            sage: hash(G)
     93            Traceback (most recent call last):
     94            ...
     95            TypeError: This graph is mutable, and thus not hashable
     96            sage: G.set_immutable()
     97            sage: hash(G)
     98            107815166986306181
     99
     100        """
     101        if self._is_immutable:
     102            return hash((tuple(self.vertices()), tuple(self.edges())))
     103        raise TypeError, "This graph is mutable, and thus not hashable"
    33104
    34105def spring_layout_fast_split(G, **options):
    35106    """