# Copyright 2015 Kevin Ryde
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this file.  See the file COPYING.  If not, see
# <http://www.gnu.org/licenses/>.

package Graph::Maker::Beineke;
use 5.004;
use strict;
use Carp 'croak';
use Graph::Maker;
use Graph::Maker::Star;
use Graph::Maker::Wheel;

use vars '$VERSION','@ISA';
$VERSION = 1;
@ISA = ('Graph::Maker');


# uncomment this to run the ### lines
# use Smart::Comments;

my @G_data
  = (undef, # 0
     undef, # 1
     [
      # G2    1--\
      #      / \  \
      #     2---3  5
      #      \ /  /
      #       4--/
      # https://hog.grinvin.org/ViewGraphInfo.action?id=438
      [1,2],[1,3],[1,5],
      [2,3],[2,4],
      [3,4],
      [5,4],
     ],
     [
      # G3 = K5-e complete 5 less one edge
      #      1
      #     /|\
      #    / 2 \
      #   / /|\ \
      #  / / 3 \ \
      #  |/ / \ \ |
      #  4--------5
      # https://hog.grinvin.org/ViewGraphInfo.action?id=450
      #
      [1,2],[1,4],[1,5],
      [2,3],[2,4],[2,5],
      [3,4],[3,5],
      [4,5],
     ],
     [
      # G4   1----5
      #     / \
      #    2---3
      #     \ /
      #      4----6
      # https://hog.grinvin.org/ViewGraphInfo.action?id=922
      #
      [1,2],[1,3],[1,5],
      [2,3],[2,4],
      [3,4],
      [4,6],
     ],
     [
      # G5    1
      #      /|\
      #     / 3 \
      #    / / \ \
      #    2-----4
      #     \    /
      #      \  /
      #       5----6
      # https://hog.grinvin.org/ViewGraphInfo.action?id=21099
      #
      [1,2],[1,5],[1,3],
      [2,5],[2,3],[2,4],
      [3,4],[3,5],
      [4,6],
     ],
     [
      # G6    1
      #      /|\
      #     / 3 \
      #    / / \ \
      #    2-----4
      #    \ \ / /
      #     \ 5 /
      #      \|/
      #       6
      # https://hog.grinvin.org/ViewGraphInfo.action?id=744
      #
      [1,2],[1,5],[1,3],
      [2,5],
      [2,3],[2,6],[2,4],
      [3,5],[3,6],[3,4],
      [4,6],
     ],
     [
      # G7   1----5
      #     / \   |
      #    2---3  |
      #     \ /   |
      #      4----6
      # https://hog.grinvin.org/ViewGraphInfo.action?id=21093
      #
      [1,2],[1,3],[1,5],
      [2,3],[2,4],
      [3,4],
      [4,6],
      [5,6],
     ],
     [
      # G8 1---2
      #    | / |
      #    3---4
      #    | / |
      #    5---6
      # https://hog.grinvin.org/ViewGraphInfo.action?id=21096
      #
      [1,2],[1,3],
      [2,3],[2,4],
      [3,4],[3,5],
      [4,5],[4,6],
      [5,6],
     ],
    );

sub _default_graph_maker {
  require Graph;
  return Graph->new(@_);
}
sub _make_graph {
  my ($params) = @_;
  my $graph_maker = delete($params->{'graph_maker'}) || \&_default_graph_maker;
  return $graph_maker->(%$params);
}

sub init {
  my ($self, %params) = @_;

  my $G = delete($params{'G'}) || 0;
  ### $G

  my $graph;
  if ($G == 1) {
    # G1 = claw = star 3
    # https://hog.grinvin.org/ViewGraphInfo.action?id=204
    #
    $graph = Graph::Maker->new('star', N=>4, %params);

  } elsif ($G == 9) {
    # G9 = wheel 6
    #        2        6 vertices
    #      / | \     10 edges
    #    4---1---3
    #     \ / \  /
    #      5---6
    # https://hog.grinvin.org/ViewGraphInfo.action?id=204
    #
    $graph = Graph::Maker->new('wheel', N=>6, %params);

  } else {
    my $edge_aref = $G_data[$G]
      || croak "Unrecognised G: ", $G;

    $graph = _make_graph(\%params);
    $graph->add_edges(@$edge_aref);
    if ($graph->is_directed) {
      $graph->add_edges(map {[reverse @$_]} @$edge_aref->edges);
    }
  }

  # override possible name from star or wheel
  $graph->set_graph_attribute (name => "Beineke G$G");

  return $graph;
}

Graph::Maker->add_factory_type('Beineke' => __PACKAGE__);
1;

=for stopwords Ryde

=head1 NAME

Graph::Maker::Beineke - create Beineke non-line graphs

=for test_synopsis my ($graph)

=head1 SYNOPSIS

 use Graph::Maker::Beineke;
 $graph = Graph::Maker->new ('Beineke', G => 9);

=head1 DESCRIPTION

C<Graph::Maker::Beineke> creates C<Graph.pm> graphs of the 9 graphs given by
Beineke

=over

Lowell W. Beineke, "Characterizations of Derived Graphs", Journal of
Combinatorial Theory, volume 9, 1970, pages 129-135.
L<http://www.sciencedirect.com/science/article/pii/S0021980070800199>

=back

Beineke shows that line graphs are characterized as all graphs which do not
contain as induced sub-graphs any of the following graphs

                                    
    G1    2           G2   1--\          G3    1                 
          |               / \  \              /|\                
          1              2---3  5            / 2 \               
         / \              \ /  /            / /|\ \              
        3   4              4--/            / / 3 \ \             
                                           |/ / \ \ |            
    claw = 4-star                          4--------5            
                                                                 
                                  K5-e complete 5 less one edge
                                         

    G4   1----5       G5    1            G6    1
        / \                /|\                /|\
       2---3              / 3 \              / 3 \
        \ /              / / \ \            / / \ \
         4----6          2-----4            2-----4
                          \   /             \ \ / /
                           \ /               \ 5 /
                            5----6            \|/
                                               6

    G7   1----5       G8  1---2          G9    2
        / \   |           | / |              / | \
       2---3  |           3---4            4---1---3
        \ /   |           | / |             \ / \  /
         4----6           5---6              5---6

                                            6-wheel

G1 is the claw (4-star) and is created by C<Graph::Maker::Star>.  G9 is the
6-wheel and is created by C<Graph::Maker::Wheel>.

=head1 FUNCTIONS

=over

=item C<$graph = Graph::Maker-E<gt>new('Beineke', key =E<gt> value, ...)>

The key/value parameters are

    G =>  integer 1 to 9

Other parameters are passed to C<Graph-E<gt>new()>.

=back

=head1 SEE ALSO

L<Graph::Maker>,
L<Graph::Maker::Star>,
L<Graph::Maker::Wheel>

=head1 LICENSE

Copyright 2015 Kevin Ryde

This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any later
version.

This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
This file.  If not, see L<http://www.gnu.org/licenses/>.

=cut
