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