1 /* Copyright (c) 1997-2021
2    Ewgenij Gawrilow, Michael Joswig, and the polymake team
3    Technische Universität Berlin, Germany
4    https://polymake.org
5 
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version: http://www.gnu.org/licenses/gpl.txt.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 --------------------------------------------------------------------------------
16 */
17 
18 #include "polymake/graph/connected.h"
19 #include "polymake/Graph.h"
20 
21 namespace polymake { namespace topaz {
22 namespace {
23 
24 // return values: 1=true, 0=false, -1=undef (does not occur here)
25 template <typename Complex>
fill_graph(Graph<> & G,const Complex & C,Int * bad_link_p)26 Int fill_graph(Graph<>& G, const Complex& C, Int* bad_link_p)
27 {
28    // check whether each vertex is contained in 1 or 2 edges
29    for (auto c_it = entire(C); !c_it.at_end(); ++c_it) {
30       auto f_it = c_it->begin();
31       const Int n1 = *f_it;
32       const Int n2 = *++f_it;
33       G.edge(n1, n2);
34       if (G.degree(n1) > 2) {
35          if (bad_link_p) *bad_link_p = n1;
36          return 0;
37       }
38       if (G.degree(n2) > 2) {
39          if (bad_link_p) *bad_link_p = n2;
40          return 0;
41       }
42    }
43 
44    return 1;
45 }
46 
47 }
48 
49 // return values: 1=true, 0=false, -1=undef (does not occur here)
50 template <typename Complex, typename VertexSet>
is_ball_or_sphere(const Complex & C,const GenericSet<VertexSet> & V,int_constant<1>)51 Int is_ball_or_sphere(const Complex& C, const GenericSet<VertexSet>& V, int_constant<1>)
52 {
53    Graph<> G(V);
54    // check graph for three properties
55    // (1) connected
56    // (2) degree(v)<3 all v in V
57    // (3) #{v|degree(v)=1} =: n_leafs equals 0 or 2
58    if (fill_graph(G, C, nullptr) == 0 || !graph::is_connected(G)) return 0;
59 
60    Int n_leaves = 0;
61    for (auto v = entire(V.top()); !v.at_end(); ++v)
62       if (G.degree(*v) == 1) {
63          if (++n_leaves > 2) return 0;
64       }
65 
66    return n_leaves != 1 ? 1 : 0;
67 }
68 
69 // return values: 1=true, 0=false, -1=undef (does not occur here)
70 template <typename Complex, typename VertexSet>
is_manifold(const Complex & C,const GenericSet<VertexSet> & V,int_constant<1>,Int * bad_link_p)71 Int is_manifold(const Complex& C, const GenericSet<VertexSet>& V, int_constant<1>, Int* bad_link_p)
72 {
73    Graph<> G(V);
74    return fill_graph(G, C, bad_link_p);
75 }
76 
77 } }
78 
79 // Local Variables:
80 // mode:C++
81 // c-basic-offset:3
82 // indent-tabs-mode:nil
83 // End:
84