Ticket #11880: trac_11880-isgci-more-review-nt.patch

File trac_11880-isgci-more-review-nt.patch, 17.5 KB (added by nthiery, 8 years ago)
  • sage/graphs/isgci.py

    # HG changeset patch
    # User Nicolas M. Thiery <nthiery@users.sf.net>
    # Date 1331035007 -3600
    # Node ID 3b2ec16872f736785e2e3a3748f5841f2aa62ebe
    # Parent  8ecaf1bedc84712727f5c47863fabf88ac99e11d
    [mq]: trac_11880-isgci-review-nt.patch
    
    diff --git a/sage/graphs/isgci.py b/sage/graphs/isgci.py
    a b interface which is easier to deal with t 
    1818rewritten many times until it stabilizes :-)
    1919
    2020Presently, it is possible to use this database through the variables and methods
    21 present in the :obj:`graph_classes <sage.graphs.isgci.GraphClasses>` object.
     21present in the :obj:`graph_classes <GraphClasses>` object.
    2222For instance::
    2323
    2424    sage: Trees = graph_classes.Tree
    And indeed, trees are chordal graphs. 
    4747        Unknown
    4848
    4949Given a graph class, one can obtain its associated information in the
    50 ISGCI database with the :meth:`show
    51 <sage.graphs.isgci.GraphClass.show>` method::
     50ISGCI database with the :meth:`~GraphClass.show` method::
    5251
    5352    sage: Chordal.show()
    5453    Class of graphs : Chordal
    ISGCI database with the :meth:`show 
    7372    Recognition                    :  Linear
    7473
    7574It is possible to obtain the complete list of the classes stored in ISGCI by
    76 calling the :meth:`show_all <sage.graphs.isgci.GraphClasses.show_all>` function
    77 (beware -- long output)::
     75calling the :meth:`~GraphClasses.show_all` method (beware -- long output)::
    7876
    7977    sage: graph_classes.show_all()
    8078    ID        | name                                     | type                 | smallgraph
    calling the :meth:`show_all <sage.graphs 
    8987    ...
    9088
    9189Until a proper search method is implemented, this lets one find
    92 classes which do not appear in:obj:`graph_classes.* <sage.graphs.isgci.GraphClasses>`.
     90classes which do not appear in :obj:`graph_classes.* <GraphClasses>`.
    9391
    9492To retrieve a class of graph from its ISGCI ID one may use
    95 :meth:`graph_classes.get_class <GraphClasses.get_class>`::
     93the :meth:`~GraphClasses.get_class` method::
    9694
    9795    sage: GC = graph_classes.get_class("gc_5")
    9896    sage: GC
    To retrieve a class of graph from its IS 
    10199Predefined classes
    102100------------------
    103101
    104 :obj:`graph_classes <sage.graphs.isgci.GraphClasses>` currently lists the following graph classes
     102:obj:`graph_classes <GraphClasses>` currently predefines the following graph classes
    105103
    106104.. list-table::
    107105   :widths: 20 30
    Predefined classes 
    112110
    113111   * - BinaryTrees
    114112
    115      - :meth:`BalancedTree <sage.graphs.graph_generators.GraphGenerators.BalancedTree>`,
    116        :meth:`is_tree <sage.graphs.generic_graph.GenericGraph.is_tree>`
     113     - :meth:`~sage.graphs.graph_generators.GraphGenerators.BalancedTree`,
     114       :meth:`~sage.graphs.generic_graph.GenericGraph.is_tree`
    117115
    118116   * - Bipartite
    119117
    120      - :meth:`BalancedTree <sage.graphs.graph_generators.GraphGenerators.BalancedTree>`,
    121        :meth:`is_bipartite <sage.graphs.graph.Graph.is_bipartite>`
     118     - :meth:`~sage.graphs.graph_generators.GraphGenerators.BalancedTree`,
     119       :meth:`~sage.graphs.graph.Graph.is_bipartite`
    122120
    123121   * - Block
    124122
    125      - :meth:`blocks_and_cut_vertices <sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices>`,
     123     - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`,
    126124
    127125   * - Chordal
    128126
    129      - :meth:`is_chordal <sage.graphs.generic_graph.GenericGraph.is_chordal>`
     127     - :meth:`~sage.graphs.generic_graph.GenericGraph.is_chordal`
    130128
    131129   * - Comparability
    132130     -
    133131
    134132   * - Gallai
    135133
    136      - :meth:`is_gallai_tree <sage.graphs.generic_graph.GenericGraph.is_gallai_tree>`
     134     - :meth:`~sage.graphs.generic_graph.GenericGraph.is_gallai_tree`
    137135
    138136   * - Grid
    139137
    140      - :meth:`Grid2dGraph <sage.graphs.graph_generators.GraphGenerators.Grid2dGraph>`,
    141        :meth:`GridGraph <sage.graphs.graph_generators.GraphGenerators.GridGraph>`
     138     - :meth:`~sage.graphs.graph_generators.GraphGenerators.Grid2dGraph`,
     139       :meth:`~sage.graphs.graph_generators.GraphGenerators.GridGraph`
    142140
    143141   * - Interval
    144142
    145      - :meth:`RandomInterval <sage.graphs.graph_generators.GraphGenerators.RandomInterval>`,
    146        :meth:`IntervalGraph <sage.graphs.graph_generators.GraphGenerators.IntervalGraph>`,
    147        :meth:`is_interval <sage.graphs.generic_graph.GenericGraph.is_interval>`
     143     - :meth:`~sage.graphs.graph_generators.GraphGenerators.RandomInterval`,
     144       :meth:`~sage.graphs.graph_generators.GraphGenerators.IntervalGraph`,
     145       :meth:`~sage.graphs.generic_graph.GenericGraph.is_interval`
    148146
    149147   * - Line
    150148
    151      - :meth:`line_graph_forbidden_subgraphs <sage.graphs.graph_generators.GraphGenerators.line_graph_forbidden_subgraphs>`,
    152        :meth:`is_line_graph <sage.graphs.graph.Graph.is_line_graph>`
     149     - :meth:`~sage.graphs.graph_generators.GraphGenerators.line_graph_forbidden_subgraphs`,
     150       :meth:`~sage.graphs.graph.Graph.is_line_graph`
    153151
    154152   * - Modular
    155153
    156      - :meth:`modular_decomposition <sage.graphs.graph.Graph.modular_decomposition>`
     154     - :meth:`~sage.graphs.graph.Graph.modular_decomposition`
    157155
    158156   * - Outerplanar
    159157
    160      - :meth:`is_circular_planar <sage.graphs.generic_graph.GenericGraph.is_circular_planar>`
     158     - :meth:`~sage.graphs.generic_graph.GenericGraph.is_circular_planar`
    161159
    162160   * - Perfect
    163161
    164      - :meth:`is_perfect <sage.graphs.graph.Graph.is_perfect>`
     162     - :meth:`~sage.graphs.graph.Graph.is_perfect`
    165163
    166164   * - Planar
    167165
    168      - :meth:`is_planar <sage.graphs.generic_graph.GenericGraph.is_planar>`
     166     - :meth:`~sage.graphs.generic_graph.GenericGraph.is_planar`
    169167
    170168   * - Split
    171169
    172      - :meth:`is_split <sage.graphs.graph.Graph.is_split>`
     170     - :meth:`~sage.graphs.graph.Graph.is_split`
    173171
    174172   * - Tree
    175173
    176      - :meth:`trees <sage.graphs.graph_generators.GraphGenerators.trees>`,
    177        :meth:`is_tree <sage.graphs.generic_graph.GenericGraph.is_tree>`
     174     - :meth:`~sage.graphs.graph_generators.GraphGenerators.trees`,
     175       :meth:`~sage.graphs.generic_graph.GenericGraph.is_tree`
    178176
    179177   * - UnitDisk
    180      - :meth:`IntervalGraph <sage.graphs.graph_generators.GraphGenerators.IntervalGraph>`,
     178     - :meth:`~sage.graphs.graph_generators.GraphGenerators.IntervalGraph`,
    181179
    182180   * - UnitInterval
    183181
    184      - :meth:`is_interval <sage.graphs.generic_graph.GenericGraph.is_interval>`
     182     - :meth:`~sage.graphs.generic_graph.GenericGraph.is_interval`
    185183
    186184Sage's view of ISGCI
    187185--------------------
    188186
    189187The database is stored by Sage in two ways.
    190188
    191 **The classes :** the list of all graph classes and their properties is stored
    192 in a huge dictionary (see :meth:`classes()
    193 <sage.graphs.isgci.GraphClasses.classes>`). Below is what Sage knows of
    194 ``gc_249``::
     189**The classes**: the list of all graph classes and their properties is stored
     190in a huge dictionary (see :meth:`~sage.graphs.isgci.GraphClasses.classes`).
     191Below is what Sage knows of ``gc_249``::
    195192
    196193    sage: graph_classes.classes()['gc_249']
    197     {'problems': 
    198         {'Independent set': 'Polynomial', 
    199          'Treewidth': 'Unknown', 
    200          'Weighted independent set': 'Polynomial', 
    201          'Cliquewidth expression': 'NP-complete', 
    202          'Weighted clique': 'Polynomial', 
    203          'Clique cover': 'Unknown', 
    204          'Domination': 'NP-complete', 
    205          'Clique': 'Polynomial', 
    206          'Colourability': 'NP-complete', 
    207          'Cliquewidth': 'Unbounded', 
    208          '3-Colourability': 'NP-complete', 
    209          'Recognition': 'Linear'}, 
    210      'type': 'base', 
    211      'ID': 'gc_249', 
     194    {'problems':
     195        {'Independent set': 'Polynomial',
     196         'Treewidth': 'Unknown',
     197         'Weighted independent set': 'Polynomial',
     198         'Cliquewidth expression': 'NP-complete',
     199         'Weighted clique': 'Polynomial',
     200         'Clique cover': 'Unknown',
     201         'Domination': 'NP-complete',
     202         'Clique': 'Polynomial',
     203         'Colourability': 'NP-complete',
     204         'Cliquewidth': 'Unbounded',
     205         '3-Colourability': 'NP-complete',
     206         'Recognition': 'Linear'},
     207     'type': 'base',
     208     'ID': 'gc_249',
    212209     'name': 'line'}
    213210
    214 **The class inclusion digraph :** Sage remembers the class inclusions through
    215 the inclusion digraph (see :meth:`inclusion_digraph()
    216 <sage.graphs.isgci.GraphClasses.inclusion_digraph>`). Its nodes are ID of ISGCI
    217 classes::
     211**The class inclusion digraph**: Sage remembers the class inclusions through
     212the inclusion digraph (see :meth:`~sage.graphs.isgci.GraphClasses.inclusion_digraph`).
     213Its nodes are ID of ISGCI classes::
    218214
    219     sage: d = graph_classes.inclusion_digraph() 
    220     sage: d.vertices()[-10:]                   
     215    sage: d = graph_classes.inclusion_digraph()
     216    sage: d.vertices()[-10:]
    221217    ['gc_990', 'gc_991', 'gc_992', 'gc_993', 'gc_994', 'gc_995', 'gc_996', 'gc_997', 'gc_998', 'gc_999']
    222218
    223219An arc from ``gc1`` to ``gc2`` means that ``gc1`` is a superclass of
    result :: 
    241237    [perfect graphs, unimodular graphs, bipartite graphs]
    242238
    243239What ISGCI knows is that perfect graphs contain unimodular graph which contain
    244 bipartite graphs. And so bipartite graphs are perfect !
     240bipartite graphs. Therefore bipartite graphs are perfect !
    245241
    246242.. note::
    247243
    248244    The inclusion digraph is **NOT ACYCLIC**. Indeed, several entries
    249245    exist in the ISGCI database which represent the same graph class,
    250     for instance Perfect graphs and Berge graphs ::
     246    for instance Perfect graphs and Berge graphs::
    251247
    252248        sage: graph_classes.inclusion_digraph().is_directed_acyclic()
    253249        False
    bipartite graphs. And so bipartite graph 
    265261Information for developpers
    266262----------------------------
    267263
    268 * The database is not *so* large, but enough to avoid loading it at Sage's
    269   startup. This is the reason why the methods :meth:`classes()
    270   <sage.graphs.isgci.GraphClasses.classes>` and :meth:`inclusion_digraph()
    271   <sage.graphs.isgci.GraphClasses.inclusion_digraph>` are cached.
     264* The database is loaded not *so* large, but it is still preferable to
     265  only load it on demand. This is achieved through the cached methods
     266  :meth:`~sage.graphs.isgci.GraphClasses.classes` and
     267  :meth:`~sage.graphs.isgci.GraphClasses.inclusion_digraph`.
    272268
    273 * Once the database has been accessed once, the information is extracted from
    274   the ``.sobj`` files in which it is stored and their information is stored in
    275   the following variables :
     269* Upon the first access to the database, the information is extracted
     270  from the ``.sobj`` files and stored in the following variables :
    276271
    277272  * ``sage.graphs.isgci._classes`` (dictionary)
    278273  * ``sage.graphs.isgci._inclusions`` (list of dictionaries)
    279274  * ``sage.graphs.isgci._inclusion_digraph`` (DiGraph)
    280275
    281   Note that the digraph is only built if necessary (for instance if the user
    282   tried to compare two classes).
     276  Note that the digraph is only built if necessary (for instance if
     277  the user tries to compare two classes).
    283278
    284279.. todo::
    285280
    Information for developpers 
    289284      return ``False``, and implement strict inclusions.
    290285
    291286    * Implement a proper search method for the classes not listed in
    292       :obj:`graph_classes <sage.graphs.isgci.GraphClasses>`
     287      :obj:`graph_classes <GraphClasses>`
    293288
    294289      .. seealso: :func:`sage.graphs.isgci.show_all`.
    295290
    296291    * Some of the graph classes appearing in :obj:`graph_classes
    297       <sage.graphs.isgci.GraphClasses>` already have a recognition
     292      <GraphClasses>` already have a recognition
    298293      algorithm implemented in Sage. It would be so nice to be able to
    299294      write ``g in Trees``, ``g in Perfect``, ``g in Chordal``, ... :-)
    300295
    class GraphClass(SageObject, UniqueRepre 
    366361        self._name = name
    367362        self._gc_id = gc_id
    368363
    369     def __repr__(self):
     364    def _repr_(self):
    370365        r"""
    371366        Returns a short description of the class
    372367
    373368        EXAMPLE::
    374369
    375             sage: graph_classes.Chordal
     370            sage: graph_classes.Chordal  # indirect doctest
    376371            Chordal graphs
    377372        """
    378373        return self._name+" graphs"
    class GraphClass(SageObject, UniqueRepre 
    451446from sage.misc.cachefunc import cached_method
    452447
    453448class GraphClasses(UniqueRepresentation):
    454     def __init__(self):
    455         self._classes = {}
    456         self._inclusions = []
    457         self._inclusion_digraph = None
    458 
    459449    def get_class(self, id):
    460450        r"""
    461451        Returns the class corresponding to the given id in the ISGCI database.
    class GraphClasses(UniqueRepresentation) 
    466456
    467457        .. seealso:
    468458
    469             :meth:`show_all <sage.graphs.isgci.GraphClasses.show_all>`
     459            :meth:`~sage.graphs.isgci.GraphClasses.show_all`
    470460
    471461        EXAMPLE:
    472462
    class GraphClasses(UniqueRepresentation) 
    499489    @cached_method
    500490    def classes(self):
    501491        r"""
    502         Returns the graph classes as a dictionary.
     492        Returns the graph classes, as a dictionary.
    503493
    504         If the database it has not been built from the local sobj files, this
    505         methods load it.
     494        Upon the first call, this loads the database from the local
     495        sobj files. Subsequent calls are cached.
     496
     497        EXAMPLES::
     498
     499            sage: t = graph_classes.classes()
     500            sage: type(t)
     501            <type 'dict'>
     502            sage: sorted(t["gc_151"].keys())
     503            ['ID', 'name', 'problems', 'type']
     504            sage: t["gc_151"]['name']
     505            'cograph'
     506            sage: t["gc_151"]['problems']['Clique']
     507            'Linear'
    506508        """
    507         if self._classes == {}:
    508             self._classes, self._inclusions = self._get_ISGCI()
     509        classes, inclusions = self._get_ISGCI()
     510        self.inclusions.set_cache(inclusions)
     511        return classes
    509512
    510         return self._classes
     513    @cached_method
     514    def inclusions(self):
     515        r"""
     516        Returns the graph class inclusions
     517
     518        OUTPUT:
     519
     520        a list of dictionaries
     521
     522        Upon the first call, this loads the database from the local
     523        sobj files. Subsequent calls are cached.
     524
     525        EXAMPLES::
     526
     527            sage: t = graph_classes.inclusions()
     528            sage: type(t)
     529            <type 'list'>
     530            sage: t[0]
     531            {'super': 'gc_2', 'sub': 'gc_1'}
     532        """
     533        self.classes()
     534        return self.inclusions()
    511535
    512536    @cached_method
    513537    def inclusion_digraph(self):
    514538        r"""
    515539        Returns the class inclusion digraph
    516540
    517         If the database it has not been built from the local sobj files, this
    518         methods load it.
     541        Upon the first call, this loads the database from the local
     542        sobj files. Subsequent calls are cached.
     543
     544        EXAMPLES::
     545
     546            sage: g = graph_classes.inclusion_digraph(); g
     547            Digraph on ... vertices
    519548        """
    520         if not (self._inclusion_digraph is None):
    521             return
    522 
    523         classes = self.classes()
     549        classes    = self.classes()
     550        inclusions = self.inclusions()
    524551
    525552        from sage.graphs.digraph import DiGraph
    526         self._inclusion_digraph = DiGraph()
    527         self._inclusion_digraph.add_vertices(classes.keys())
     553        inclusion_digraph = DiGraph()
     554        inclusion_digraph.add_vertices(classes.keys())
    528555
    529         for edge in self._inclusions:
     556        for edge in inclusions:
    530557            if edge.get("confidence","") == "unpublished":
    531558                continue
     559            inclusion_digraph.add_edge(edge['super'], edge['sub'])
    532560
    533             self._inclusion_digraph.add_edge(edge['super'], edge['sub'])
    534 
    535         self._inclusions = []
    536 
    537         return self._inclusion_digraph
     561        return inclusion_digraph
    538562
    539563    def _download_db(self):
    540564        r"""
    class GraphClasses(UniqueRepresentation) 
    648672
    649673        print "Database downloaded"
    650674
    651         self._classes, self._inclusions = self._create_db()
     675        classes, inclusions = self._create_db()
    652676
    653677        print "XML file converted into Python dictionaries"
    654678
    655679        from sage.all import save
    656680
    657681        # Trying to save to Sage's directory
     682        # TODO: get rid of duplication
    658683        try:
    659             save(self._classes, SAGE_ROOT+'/data/graphs/isgci_classes.sobj')
    660             save(self._inclusions, SAGE_ROOT+'/data/graphs/isgci_inclusions.sobj')
    661             self._inclusions = self._inclusion_digraph = None
    662             self._classes = {}
     684            save(classes, SAGE_ROOT+'/data/graphs/isgci_classes.sobj')
     685            save(inclusions, SAGE_ROOT+'/data/graphs/isgci_inclusions.sobj')
     686            self.classes.clear_cache()
     687            self.inclusions.clear_cache()
     688            self.inclusion_digraph.clear_cache()
    663689            print "Database saved to .sobj files in "+SAGE_ROOT+'/data/graphs/'
    664690            return
    665691
    class GraphClasses(UniqueRepresentation) 
    667693            # TODO: improve!
    668694            print "Could not save save database in "+SAGE_ROOT+'/data/graphs/'
    669695            print "Now attempting to save the files to "+str(SAGE_DB)
    670             pass
    671696
    672697        # Trying to save to the user's home directory
    673         save(self._classes, SAGE_DB+"/isgci_classes.sobj")
    674         save(self._inclusions, SAGE_DB+"/isgci_inclusions.sobj")
    675         self._inclusions = self._inclusion_digraph = None
    676         self._classes = {}
     698        save(classes, SAGE_DB+"/isgci_classes.sobj")
     699        save(inclusions, SAGE_DB+"/isgci_inclusions.sobj")
     700        self.classes.clear_cache()
     701        self.inclusions.clear_cache()
     702        self.inclusion_digraph.clear_cache()
    677703        print "Database saved to .sobj files in "+SAGE_DB
    678704
    679705    def _get_ISGCI(self):
    class GraphClasses(UniqueRepresentation) 
    691717        .. NOTE::
    692718
    693719            This method returns the data contained in the most recent ISGCI database
    694             present on the computer. See :func:`update_db` to update the latter.
     720            present on the computer. See :meth:`update_db` to update the latter.
    695721
    696722        EXAMPLE::
    697723