#  Copyright (c) 1997-2010
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
#  http://www.polymake.de
#
#  This program 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 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program 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.
#-------------------------------------------------------------------------------
#  $Project: polymake $$Id: complex_properties.rules 9581 2010-03-16 19:33:46Z herr $

object SimplicialComplex {

declare permutation VertexPerm {

   # Transforming vertices from this into basic object.
   property PERMUTATION : Array<Int>;
}

# @category Basic properties
# Any description of the faces of a simplicial complex.  Redundancy allowed.

property INPUT_FACES : Array<Set>;


# @category Basic properties
# Labels of the vertices.

property VERTEX_LABELS : Array<String>;

rule VERTEX_LABELS : VertexPerm.VERTEX_LABELS, VertexPerm.PERMUTATION {
   $this->VERTEX_LABELS=permuted($this->VertexPerm->VERTEX_LABELS, $this->VertexPerm->PERMUTATION);
}
weight 1.10;

# Find the vertices by given labels.
# @return Set<Int> vertex indices

user_method labeled_vertices {
   my $this=shift;
   if (defined (my $labels=$this->lookup("VERTEX_LABELS"))) {
      new Set([ find_labels($labels, @_) ]);
   } else {
      die "No VERTEX_LABELS stored in this complex";
   }
}

# @category Basic properties
# Number of vertices.

property N_VERTICES : Int;


# @category Basic properties
# Faces which are maximal with respect to inclusion, encoded as their ordered set of vertices.
# The vertices must be numbered 0, ..., n-1.

property FACETS : Array<Set>;

rule FACETS : VertexPerm.FACETS, VertexPerm.PERMUTATION {
   $this->FACETS=permuted_elements($this->VertexPerm->FACETS, $this->VertexPerm->PERMUTATION);
}
weight 1.20;

declare permutation FacetPerm {

   # Transforming [[FACETS]] from this into basic object
   property PERMUTATION : Array<Int>;
}

# @category Basic properties
# Number of [[FACETS]].

property N_FACETS : Int;


# @category Combinatorics
# Inclusion minimal non-faces (vertex subsets which are not faces of the simplicial complex).

property MINIMAL_NON_FACES : Array<Set>;

rule MINIMAL_NON_FACES : VertexPerm.MINIMAL_NON_FACES, VertexPerm.PERMUTATION {
   $this->MINIMAL_NON_FACES=permuted_elements($this->VertexPerm->MINIMAL_NON_FACES, $this->VertexPerm->PERMUTATION);
}
weight 1.20;


# @category Combinatorics
# Number of [[MINIMAL_NON_FACES]].

property N_MINIMAL_NON_FACES : Int;


# @category Basic properties
# Maximal dimension of the [[FACETS]], where the dimension of a facet is defined as
# the number of its vertices minus one.

property DIM : Int;


# @category Basic properties
# A simplicial complex is __pure__ if all its facets have the same dimension.

property PURE : Bool;


# @category Combinatorics
# f<sub>k</sub> is the number of k-faces, for k = 0,... , d, where d is the dimension.

property F_VECTOR : Array<Int>;


# @category Combinatorics
# f<sub>ik</sub> is the number of incident pairs of i-faces and k-faces; the main
# diagonal contains the [[F_VECTOR]].

property F2_VECTOR : Matrix<Int>;


# @category Combinatorics
# Subcomplex generated by faces of codimension 2 that are contained in an odd
# number of faces of codimension 1.

property ODD_SUBCOMPLEX : SimplicialComplex;

rule ODD_SUBCOMPLEX.VertexPerm.PERMUTATION = VertexPerm.PERMUTATION;


# @category Combinatorics
# True if [[GRAPH]] is ([[DIM]] + 1)-colorable.

property BALANCED : Bool;

property FOLDABLE = BALANCED;


# @topic properties/Topology
# The following properties are topological invariants.


# @category Topology
# Reduced Euler characteristic.  Alternating sum of the [[F_VECTOR]] minus 1.

property EULER_CHARACTERISTIC : Int;


# @category Visualization
# Coordinates for the vertices of the simplicial complex, such that the complex is
# embedded without crossings in some R<sup>e</sup>.  Vector (x<sub>1</sub>, .... x<sub>e</sub>) represents a point
# in Euclidean e-space.

property GEOMETRIC_REALIZATION : Matrix<Rational>;


# @category Visualization
# Dimension e of the space in which the [[GEOMETRIC_REALIZATION]] of the complex is embedded.

property G_DIM : Int;

# @category Topology
# fields: torsion, betti (defined in homology.cc)
declare property_type HomologyGroup : c++ (embedded);

# @category Topology
# fields: coeff, faces (defined in homology.cc)
declare property_type CycleGroup : c++ (embedded);

# @category Topology
# Reduced simplicial homology groups H<sub>0</sub>, ..., H<sub>d</sub> (integer coefficients), listed in increasing dimension order.
#
# Each group G is encoded as a sequence ( { (t<sub>1</sub> m<sub>1</sub>) ...  (t<sub>n</sub>  m<sub>n</sub>) } f) of non-negative integers,
# with t<sub>1</sub> > t<sub>2</sub> > ... > <sub>n</sub> > 1, plus an extra non-negative integer f.
# The group G is isomorphic to (Z/t<sub>1</sub>)<sup>m<sub>1</sub></sup> &times; ... &times; (Z/t<sub>n</sub>)<sup>m<sub>n</sub></sup> &times; Z<sup>f</sup>, 
# where Z<sup>0</sup> is the trivial group.

property HOMOLOGY : Array<HomologyGroup>;


# @category Topology
# Reduced cohomology groups, listed in increasing codimension order.
# Encoding similar to [[HOMOLOGY]].

property COHOMOLOGY : Array<HomologyGroup>;


# @category Topology
# Representatives of cycle groups, listed in increasing dimension order.
#
# The first component in each dimension is a matrix of integer coefficients,
# the second component is a vector of faces.  To obtain the chains, one must
# (symbolically) multiply both components.

property CYCLES : Array<CycleGroup>;

### FIXME: needs a client to permute since CycleGroup embedded c++ type
rule nonexistent : CYCLES : VertexPerm.CYCLES, VertexPerm.PERMUTATION;


# @category Topology
# Representatives of cocycle groups, listed in increasing codimension order.
# Encoding similar to [[CYCLES]].

property COCYCLES : Array<CycleGroup>;

### FIXME: needs a client to permute since CycleGroup embedded c++ type
rule nonexistent : COCYCLES : VertexPerm.COCYCLES, VertexPerm.PERMUTATION;


# @category Topology
# fields: parity, positive, negative (defined in intersection_form.cc)
declare property_type IntersectionForm : c++ (embedded);

# @category Topology
# Parity and signature of the intersection form of a closed oriented 4-manifold.
property INTERSECTION_FORM : IntersectionForm;


# @category Topology
# Mod 2 cycle representation of Stiefel-Whitney classes.  Each cycle is represented as a set of simplices.
property STIEFEL_WHITNEY : Array<PowerSet>;

### FIXME: could be done
rule nonexistent : STIEFEL_WHITNEY : VertexPerm.STIEFEL_WHITNEY, VertexPerm.PERMUTATION;


# @category Topology
# True if this is a compact simplicial manifold with boundary.
#
# Depends on heuristic [[SPHERE]] recognition.

property MANIFOLD : Bool;


# @category Topology
# True if this is a [[PURE]] simplicial complex with the property that each ridge is
# contained in either one or two facets.

property PSEUDO_MANIFOLD: Bool;


# @category Topology
# True if this is a [[PURE]] simplicial complex with the property that each ridge is
# contained in exactly two facets.

property CLOSED_PSEUDO_MANIFOLD : Bool;


# @category Topology
# True if this is a [[PSEUDO_MANIFOLD]] with top level homology isomorphic to Z.

property ORIENTED_PSEUDO_MANIFOLD : Bool;


# @category Topology
# An orientation of the facets of an [[ORIENTED_PSEUDO_MANIFOLD]], such that the induced orientations
# of a common ridge of two neighboring facets cancel each other out. Each facet is marked with //true//
# if the orientation is given by the increasing vertex ordering and is marked with //false// if the
# orientation is obtained from the increasing vertex ordering by a transposition.

property ORIENTATION : Array<Bool>;

rule nonexistent : ORIENTATION : VertexPerm.ORIENTATION, VertexPerm.PERMUTATION;

rule ORIENTATION : FacetPerm.ORIENTATION, FacetPerm.PERMUTATION {
   $this->ORIENTATION=permuted($this->FacetPerm->ORIENTATION, $this->VertexPerm->PERMUTATION);
}
weight 1.10;


# @category Topology
# If true then the space is homeomorphic to a sphere.
# However, recognizing spheres is undecidable in dimensions >= 5, and all known algorithms in
# dimension 3 are of outrageous complexity.  We therefore use the flip-heuristics by Bjoerner
# and Lutz.  This means that if this property is false then the space still might be a sphere.

property SPHERE : Bool;


# @category Topology
# Heuristically true if the topological space homeomorphic to a ball.
# Similar remarks hold as for [[SPHERE]].

property BALL : Bool;


# @category Geometric Complexes
# Signature of a geometric simplicial complex embedded in the integer lattice.
# Like [[DUAL_GRAPH_SIGNATURE]], but only simplices with odd normalized volume are counted.

property SIGNATURE : Int;


# @category Basic properties
# The subcomplex consisting of all 1-faces.

property GRAPH : Graph;

rule GRAPH.NodePerm.PERMUTATION = VertexPerm.PERMUTATION;

# @category Combinatorics
# A coloring of the vertices.

property COLORING : Array<Int>;

rule COLORING : VertexPerm.COLORING, VertexPerm.PERMUTATION {
   $this->COLORING=permuted($this->VertexPerm->COLORING, $this->VertexPerm->PERMUTATION);
}
weight 1.10;


# @category Basic properties
# The graph of facet neighborhood.
# Two [[FACETS]] are neighbors if they share a (d-1)-dimensional face.

property DUAL_GRAPH : Graph {

   property COLORING : NodeMap<Undirected,Int>;

}

rule DUAL_GRAPH.NodePerm.PERMUTATION = FacetPerm.PERMUTATION;

# @category Basic properties
# The face lattice of the simplical complex
# organized as a directed graph.  Each node corresponds to some face
# of the simplical complex. It is represented as the list of vertices
# comprising the face. The outgoing arcs point to the containing faces
# of the next dimension. An artificial top node is added to represent
# the entire complex.

property HASSE_DIAGRAM : FaceLattice;

rule HASSE_DIAGRAM : VertexPerm.HASSE_DIAGRAM, VertexPerm.PERMUTATION {
   $this->HASSE_DIAGRAM=permuted_atoms($this->VertexPerm->HASSE_DIAGRAM, $this->VertexPerm->PERMUTATION);
}

rule HASSE_DIAGRAM : FacetPerm.HASSE_DIAGRAM, FacetPerm.PERMUTATION {
   $this->HASSE_DIAGRAM=permuted_coatoms($this->FacetPerm->HASSE_DIAGRAM, $this->FacetPerm->PERMUTATION);
}

# @category Topology
# True if this is a [[CONNECTED]] [[MANIFOLD]] of dimension 2.

property SURFACE : Bool;


# @category Topology
# The __genus__ of a surface.

property GENUS : Int;


# @category Topology
# True if the vertex star of each vertex is [[DUAL_CONNECTED]].

property LOCALLY_STRONGLY_CONNECTED : Bool;


# @category Basic properties
# Codimension-1-faces of a [[PSEUDO_MANIFOLD]] which are contained in one facet only.

property BOUNDARY : SimplicialComplex;

rule BOUNDARY.VertexPerm.PERMUTATION = VertexPerm.PERMUTATION;


# @category Topology
# Edge-subset of a 3-sphere which is a knot or link, that is, a collection of pairwise disjoint cycles.

property KNOT : Array<Set>;

rule KNOT : VertexPerm.KNOT, VertexPerm.PERMUTATION {
   $this->KNOT=permuted_elements($this->VertexPerm->KNOT, $this->VertexPerm->PERMUTATION);
}
weight 1.20;


# @category Combinatorics
# Orbit decomposition of the group of projectivities acting on the set of vertices of facet 0.

property PROJ_ORBITS : PowerSet;

rule PROJ_ORBITS : VertexPerm.PROJ_ORBITS, VertexPerm.PERMUTATION {
   $this->PROJ_ORBITS=permuted($this->VertexPerm->PROJ_ORBITS, $this->VertexPerm->PERMUTATION);
}
weight 1.20;


# @category Combinatorics
# For each vertex the corresponding vertex of facet 0 with respect to the action of the group of projectivities.

property PROJ_DICTIONARY : Array<Int>;

rule nonexistent : PROJ_DICTIONARY : VertexPerm.PROJ_DICTIONARY, VertexPerm.PERMUTATION;


# @category Geometric Complexes
# Volume of a geometric simplicial complex.
# **FIXME:** introduce type RealizedSimplicialComplex<Scalar=Rational> : SimplicialComplex
property VOLUME : Rational;

}


# Local Variables:
# mode: perl
# c-basic-offset:3
# End:
