String representation of trivalent 2-stratifolds with trivial fundamental group
Abstract
We give a Python program that is capable to compute and print all the distinct trivalent 2-stratifold graphs up to white vertices with trivial fundamental group (see [6]). Our algorithm uses the three basic operations described in [7] to construct new graphs from any set of given graphs. We iterate this process to construct all the desired graphs. The algorithm includes an optimization that reduces the repetition of generated graphs, this is done by recognizing equivalent white vertices of a graph under automorphism. We use a variation of the AHU algorithm to identify those vertices and as well to distinguish isomorphic graphs in linear time. The returned string from the AHU algorithm is also used as a hashing function to search for repeated graphs in amortized constant time.
1 Introduction
Since 2016, the authors José Carlos Gómez-Larrañaga, Francisco González-Acuña, and Wolfgang Heil have studied 2-stratifolds [5]. There are multiple motivations to follow their work, but one of the most interesting is the applications of the 2-stratifolds on the field of Topological Data Analysis.
The classification of 2-manifolds has been well studied, but the study of the 2-stratifolds has just started. On [7], Gómez-Larrañaga, González-Acuña, and Wolfgang started to analyze the ones with trivial fundamental group, giving a process to build them. And continuing with that work, it’s easy to ask how many of those exist.
Moreover, using the operations described in their work, we started to wonder if there was possible to use them to get every 2-stratifold. Yair Hernández, wrote a computational algorithm [8] to build some of them, and based on that code, we decided to extend it to get the 2-stratifolds meticulously; in an optimized way.
Since the operations described on [7] are performed on white vertices, it was decided to use the number of white vertices as a parameter for the algorithm, limiting the number of graphs that it was going to build. Therefore our program can calculate and draw the graph representation defined in [7] of every 2-stratifold with trivial fundamental group up to white vertices.
The code was written on Python and can be consulted on [1]. In order to identify different graphs, it used a modified version of the AHU algorithm. And to optimize the algorithm, there is defined an identification among white vertices under automorphisms of the graph (see def. 5.3). The modified version of the AHU algorithm, the algorithm 4, allows us to identify every graph with a unique string, which is the string representation, that is used as a hash to discard the repeated graphs and optimize the building process.
The contents of this paper include a description of the algorithm previously mentioned and the proof that it actually builds all the graphs that it is asked to. In section 2, there are given basic graph theory definitions, that are necessary to understand the proves. In section 3, there are proven some known results of graph isomorphisms but applied to the graph representations of the 2-stratifolds. In the next section,“Characterizing weighted trees with a string”, we describe the modified version of the AHU algorithm and we explain how it is helpful to solve the problem of classifying the trivalent graphs and therefore the 2-stratifolds with trivial fundamental group. In the section “The graph generator algorithm”, we describe the main algorithm that assigns a string representation to every graph, and we give the results of the construction of the graphs up to 11 white vertices, including a comparison between the optimized and non-optimized version. Finally, in “Nomenclature” we explained the tag that is given to every graph at the end of the algorithm because although the string representation is unique, it doesn’t work as a quick resume of the general shape of the graph.
2 Preamble
Definition 2.1.
We will say that a graph generated by a simply-connected trivalent 2-dimensional stratifold is a trivalent graph.
Definition 2.2.
Let be a graph, a set of vertices such that is adjacent to , and for every is called a path from to in .
Definition 2.3.
The degree of a vertex in a graph is the number of vertices in that are adjacent to . The set of all the vertices that are adjacent to are the neighbors of and we denote them by . A vertex of degree 1 is a leaf.
Definition 2.4.
Given a path in the length of the path is the sum of the weights of the edges encountered in . For two vertices and , the shortest path is the path with minimum length, and the largest path is the path with maximum length. The length (without weights) of a path is the length of the path considering that all the weights are 1.
Definition 2.5.
Let be a vertex of a graph , its eccentricity is the length (without weights) of the largest path from to another vertex in . The radius of , , is the smallest eccentricity among the vertices of . For any vertex , such that we say that is a central vertex of , if has only one central vertex , we say that is the center of .
Definition 2.6.
Given a graph , we say that is a tree if and only if for every vertices of , there exists a path from to and there is no path with positive length from to itself. A rooted tree is a tree with a special vertex identified as the root.
Definition 2.7.
On a rooted tree, a vertex is a child of vertex if, in the path from the root to , immediately succeeds . We said that is parent of if and only if is child of .
3 Isomorphic graphs
Definition 3.1.
Two weighted graphs and are isomorphic if there exists a bijective function such that two vertices and are adjacent in if and only if and are adjacent in , and for every edge, in , the edge in has the same weight as . If there is no such function as described above, the and are non-isomorphic graphs. (Definition from [4]) Moreover, for and rooted trees with roots , respectively, we say that and are isomorphic as rooted trees if they are isomorphic and .
Lemma 3.1.
If two graphs and are isomorphic with a function , for vertex of , is a leaf of if and only if is a leaf of .
Proof.
Let a leaf of , then by definition, there exists only one vertex adjacent to in , suppose . As and are adjacent in , and are adjacent in . For any other vertex in , different from or ; is not adjacent to in and therefore is not adjacent to in . Then, is the only vertex adjacent to in , concluding that must be a leaf of . Analogously if is a leaf of we can conclude that must be a leaf of . ∎
Corollary 3.1.1.
If two graphs and are isomorphic, then they have the same number of leaves.
Definition 3.2.
Two trivalent graphs and are isomorphic as trivalent graphs if there is an isomorphism as weighted graphs such that, if are the sets of black vertices of , and are the sets of white vertices of , the functions and are bijective.
Lemma 3.2.
If two trivalent graphs and are isomorphic, then they have the same number of white and black vertices and the same number of leaves.
Proof.
If and are two trivalent graphs that are isomorphic, there exists such that and are bijective, therefore and . And by corollary 3.1.1, and have the same number of leaves. ∎
Theorem 3.3 (Theorem 2.7 in [4]).
There exists a unique path between any two vertices of a tree.
Lemma 3.4.
For and two isomorphic trees with isomorphism function , for every two vertices , in , the length of the path in is the same as the length of the path in .
Proof.
Given that and are trees, by theorem 3.3 there exists a unique path between any two vertices in them. Let , be vertices in , there exists a unique path between them, such that is a sequence of adjacent vertices without repetition in . For two adjacent vertices let’s denote as the length of the edge between them, then the length of is
First, notice that by the definition of path and are adjacent in , then are adjacent in , for every , . Also by definition of , for , and by definition of this implies that for .
Then is a sequence of adjacent vertices without repetition in , which implies that is a path, and since is a tree, is the unique path in .
Finally, by definition of for every edge, in , the edge in has the same weight, therefore:
∎
Corollary 3.4.1.
For and two isomorphic trees, their radius will have the same length.
Lemma 3.5.
Let and be two isomorphic trees with isomorphism function , for any vertex of , the function , where is the set of the neighbors of , is a bijective function with codomain in .
Proof.
Given a vertex of , let . That happens if and only if . In the other hand, is neighbor of if and only if . By using a particular case of the previous lemma we have that , therefore if and only if . Since is a bijection then is a bijection too. This means that the images of the neighbors of are the neighbors of the image of . ∎
Let’s denote as the path from to in the graph and as its length (without weights), since all the graphs generated by the simply-connected trivalent 2-dimensional stratifolds are trees, by Theorem 3.3 this is well defined.
Lemma 3.6.
For any vertex in a tree , if is a vertex such that then is a leaf.
Proof.
Suppose that is not a leaf, then the degree of is at least , then there exists neighbor of such that . By theorem 3.3 we know that such exists, because there is a unique path from to which means that there is only one neighbor of connected to . If there where neighbors of connected to , there would be two paths from to and that is a contradiction.
Let’s notice that the
but that’s a contradiction to the definition of eccentricity. Therefore the degree of must be at most 1, and is a leaf of . ∎
Theorem 3.7 (Uniqueness of the center).
Let be a trivalent graph, then there exists center of and it is unique.
Proof.
By definition, there exists at least one vertex such that .
First, let’s notice that two vertices of different colors in a trivalent graph can’t be both central vertices. Every trivalent graph has the property that all the neighbors of a white vertex are black vertices and vice versa, also all the leaves are white. Then by parity, the from any white vertex to a leaf would be even and the from any black vertex to a leaf would be odd, using the lemma 3.6 we can conclude that the eccentricity of a white vertex would be always different from the eccentricity of a black vertex, which means that they can’t be both central vertices.
Now suppose that there exists such that is a central vertex of . Without loss of generality we can assume that are both white. Then there exists a black vertex such that . We would prove that .
Let be the leaves of , by definition, for any leaf , we will have and .
Notice that for any we have two options, or . We will analyze both cases.
Case 1, :
If , in particular because and the last one is unique, by lemma 3.3. Notice that there exists a unique vertex (it could happen that ) such that and , therefore we have that
Then .
Case 2, :
Since then therefore
which implies .
From both cases, we can conclude that for any leaf , then
contradicting the fact that and were both central vertices because there is another vertex with lower eccentricity than the radius.
This proves that for any trivalent graph, the center exists and it is unique.
∎
Lemma 3.8.
Any two trivalent graphs are isomorphic as trivalent graphs if and only if they are isomorphic as graphs.
Proof.
By definition, it is clear that isomorphism as trivalent graphs implies isomorphism. We only need to prove that isomorphism implies isomorphism as trivalent graphs, which is the isomorphism function determines a bijection between the set of black vertices of both graphs, analogously with the white vertices.
Let and be two trivalent graphs. If instead of the length in lemma 3.4 we consider the length (without weights) we can conclude that for any vertex , if then .
Using the same parity argument as in the previous proof, notice that if only if are both white or both black. Moreover, would be odd if and only if and are black, and would be even if and only if and are white.
This gives us a partition of the graph that assures us that the image of any white vertex is going to be a white vertex, and the image of any black vertex is going to be a black vertex. Therefore the restriction of to the set of black vertices in is a bijection with codomain the set of black vertices in , analogously with the white vertices. Then we can conclude that isomorphism implies isomorphism as trivalent graphs.
∎
Lemma 3.9.
For and two isomorphic trivalent graphs with isomorphism function , then the center of is the image of the center of under .
Proof.
As a result of the lemma 3.4, if we consider the length (without weights) instead of the length, for any , the eccentricity of in will be the same as the eccentricity of in . Let be the center of , which is unique, using corollary 3.4.1 we have that
By definition, since we can conclude that is the center of . ∎
Lemma 3.10.
Given and trivalent graphs, if we select the center of each graph as its root, and are isomorphic as trivalent graphs if and only if and are isomorphic as rooted trees.
Proof.
If and are isomorphic as trivalent graphs, by lemma 3.9, since the center of is the image of under the isomorphism function, it is immediate that and are isomorphic as rooted trees. Now let’s suppose that and are isomorphic as rooted trees. By definition, the isomorphism as rooted trees implies that and are isomorphic, therefore by lemma 3.10, since and are two trivalent graphs that are isomorphic, then they are isomorphic as trivalent graphs. ∎
4 Characterizing weighted trees with a string
So far, we have described how two isomorphic trivalent graphs behave, but we need tools to identify if two trivalent graphs are isomorphic. This is important because the main goal is to know how many and which are all the trivalent stratifolds for a given number of white vertices. Since the trivalent stratifolds are associated with a unique trivalent graph, having a classification for the trivalent graphs gives us a classification for the trivalent stratifolds.
The generation of all the trivalent graphs is an iterative process that creates a lot of isomorphic graphs, we will discuss this process further in Section 6. But it is because of this excess of repetitions, that we need an optimal algorithm that can recognize isomorphic graphs with as few operations as possible.
In the book The Design and Analysis of Computer Algorithms [2] the authors propose an algorithm that allows us to identify if two non-weighted rooted trees are isomorphic in time. This algorithm is known as the AHU algorithm, the acronyms AHU comes from the initials of the authors Aho, Hopcroft, and Ullman. To use this algorithm is necessary to remark that two isomorphic trees could be non-isomorphic as rooted trees (see Fig. 1 for an example).

In the article Tree isomorphism Algorithms: Speed vs. Clarity [3], there is an algorithm that improves the idea of Aho, Hopcroft, and Ullman, by implementing the use of parenthetical tuples. And then substituting the use of ‘(’, ‘)’ for ‘1’ and ‘0’ respectively, the latest have a natural order.
Given a rooted tree , the main idea of the algorithm is to assign a unique string to each vertex of recursively. The string assigned to a vertex is created recursively from the string associated with its children. And finally, assign to the string associated with its root. Then we can conclude that two rooted trees are isomorphic if and only if they have the same associated string.
We now present the pseudo-code of the AHU Algorithm. An example of this process can be seen in Fig. 2.

Although this algorithm allows us to recognize if two rooted trees are isomorphic, it doesn’t allow us to distinguish if two rooted trees with weights are isomorphic, because it doesn’t take into account the weights. Since trivalent graphs are weighted trees, this algorithm doesn’t work for our problem in the first instance.
By theorem 3.7, given a trivalent graph , there is a unique vertex such that is the central vertex of , we call the center of . The uniqueness of the center for every trivalent graph allows us to mark this vertex as the root of the trivalent graph, without ambiguity.
We have proven that the center exists, but so far we only have given an exhaustive algorithm to find it. In [2] on pages 176 to 179, Aho, Hopcroft, and Ullman describe the algorithm Depth-first search whose purpose is to find the largest path in a tree. It is proven that this algorithm only needs steps on a graph with vertices and edges. The idea of this algorithm is to visit every vertex of the tree in an ordered way, going deeper before continuing to another branch of the tree, this way we can assure that we visit every vertex exactly once.
To find the center of the trivalent graph it is only necessary to find the longest path in the tree and then find the middle vertex of it. This will always be the center of the tree. The pseudo-code is the algorithm 3.
The Algorithm 3 successfully finds the center of any trivalent graph because it first finds a path of maximal length (a diameter) of the tree. Any diameter of a trivalent has an even length (see Theorem 3.7 ). By the definition of the center, all vertices must be at a distance at most half of the diameter. That is why the center must be in the middle of any diameter.
To prove that we can find a diameter with two runs of DFS we do as follows. What we have to show is that at the first run of the DFS we end up at the end of a diameter of . So, at the next run, we will end up at the other end of the diameter. Then, what we have to show is that that farthest vertex from a given vertex in belongs to a diameter of .
Let be one of the farthest vertices from . Observe first that has to be a leaf, otherwise, we can find a farther vertex from . Now, let a diametrical path of . As is a leaf, if belongs to then the proof would be over. Lets call and the ends of . By the definition of , the vertices and need to be no further from than . If one of them were closer to , we can prove that one of the paths from to or is longer than (an analysis by cases is needed it here). This contradicts the fact that is a diameter. Similarly, if both and are as far from than , it implies that one of the paths from to or is as long as , making the end of a diameter. Which completes the proof. So, the second time that the DFS runs, it will find the other end of the diameter.
This algorithm needs twice the number of steps that Deep-first_search plus a constant, which means that this algorithm is still linear and only depends on the number of vertices and edges of the graph.
Now, every trivalent graph can be seen as a rooted tree and therefore we can apply the AHU algorithm to it. The problem is that the AHU algorithm doesn’t take into account the weights of the edges, but we have solved this problem by instead of assigning only numbers ‘1’ and ‘0’ we include the numbers ‘2’ and ‘3’ depending on the weight in the edge that connects the vertex with its father. This algorithm still runs on linear time.
The recursive part of the algorithm is given by the following pseudo-code:
Now, given any trivalent graph, to get its string it is necessary to get its center first and then get the string associated with that vertex. For the complete implementation, see Algorithm 5.
Definition 4.1.
Given a trivalent graph we call the output of TG_to_string () [5] as the string representation of .
Theorem 4.1.
Given two trivalent graphs, they are isomorphic if and only if they have the same string representation.
To prove this theorem, we are going to give an algorithm that recovers the original graph given a string, and this will prove that there is a unique graph associated with any string.
This algorithm draws a unique trivalent graph given a string representation, therefore we are giving a bijection between the trivalent graphs and the string representations, proving the theorem 4.1.
This algorithm can be extended for n-colored trees in general, also it can be extended for trees with a greater amount of weights, it only needed to add more start-close indicator numbers to identify the different weights.
5 The graph generator algorithm
Given a tivalent graph, one can generate more by applying the operations O1 or O2 to any white vertex of it. Or given two trivalent graphs, we can generate a new one by applying the operation O1* in one white vertex of each graph. It is proven in [7] that all the trivalent graphs can be obtained by recursively using these operations in all the previous trivalent graphs, starting with the B111 and B12 trees.
The B111 and B12 trees are defined in [7] in Definition 1.
Definition 5.1.
-
1.
The B111-tree is the bi-colored tree consisting of one black vertex incident to three edges each of label 1 and three terminal white vertices each of genus 0.
-
2.
The B12-tree is the bi-colored tree consisting of one black vertex incident to two edges one of label 1, the other of label 2, and two terminal white vertices each of genus 0.
Also the operations O1, O2 and O1* are defined in [7].
Definition 5.2.
In a trivalent graph let be a white vertex and let be the edges incident to () and let be the black vertex incident to (). We define the operations and on that changes to a new trivalent graph as follows:
-
1.
O1. Let . Attach one white vertex of a B111-tree to , cut off from and attach to another white vertex of the B111-tree.
-
2.
O2. Attach a B12-tree to so that the terminal edge has label 1.
-
3.
O1*. On the other hand, let and be two disjoint trivalent graphs and let be a white vertex of (). Attach a B111-tree to so that and are identified with two distinct white vertices of the B111-tree.
To get all the trivalent graphs with white vertices, we have implemented a program that has two fundamental parts. The first part constructs all the trivalent graphs with white vertices () and the second part reduces the list by eliminating the repetitions.
We should mention that whenever we add a graph to we have to check if the graph is already there. Here is when we have to use the string representation of its elements (see Def. 4.1) to compare them. Even more, we can set the string representation as a hashing function, so we don’t have to iterate over all the elements of to decide if it already there or not, and decide it in amortized constant time. The complete implementation can be found in the repository https://github.com/MyHerket/TrivalentStratifold in GitHub.
As explained before, the creation of a new trivalent graph is an iterative process. And we are going to prove that the previous algorithm creates all the trivalent graphs with white vertices.
Lemma 5.1.
Let be a trivalent graph, there exists at least one leaf of such that the weight of the adjacent edge to is 1.
Proof.
We are going to proceed by induction. First, notice that for and there exists a leaf such that the weight of the adjacent edge to is 1.
Let be a trivalent graph, if we perform in one of its vertices, we are attaching a by one of its white vertices, letting 2 white vertices free that are going to be leaves of with such that the weight of the adjacent edges to them is 1.
On the other hand, if we perform in one of ’s vertices, we are attaching a to it by the only white vertex whose adjacent edge weight is 2, therefore the white vertex whose adjacent edge weight is 1, is now a leaf of the new graph
Finally, if we perform to and other graph, by definition we take a and attach one white vertex to , one to the other graph and the last one is free, which is the leaf whose adjacent edge weight is 1.
Since the process to get any trivalent graph is taking or and performing or , as many times as we want in each step we have a leaf whose adjacent edge weight is 1, therefore the resulting trivalent graph has it.
∎
Remark.
Let be a trivalent graph with white vertices, the resulting trivalent graph after performing in any white vertex of has white vertices.
Remark.
Let be a trivalent graph with white vertices, the resulting trivalent graph after performing in any white vertex of has white vertices.
Remark.
Let and be trivalent graphs with and white vertices, respectively. The resulting graph after performing in any pair of white vertices of and has white nodes.
Using the previous remarks we have the following theorem:
Theorem 5.2.
For any an integer greater than 3. The list of all the trivalent graphs with white vertices, (including isomorphisms) will be obtained by performing the operation to all the trivalent graphs with white vertices in each of their white vertices, performing the operation to all the trivalent graphs with white nodes in each of their vertices and finally for every , such that perform the operation in all the pairs of white vertices of every pair of trivalent graphs where the first one is an element of the list of trivalent graphs with white vertices and the second one is an element of the list of trivalent graphs with white vertices.
Proof.
Let be an integer greater than 3. By the remarks, it is clear that performing the algorithm described will give us a subset of the list of all the trivalent graphs with white vertices. Let’s see that this subset is the total set.
Let be a trivalent graph with white vertices and a leaf of such that the edge adjacent to has weight 1, it exists by lemma 5.1. We know that is a white vertex, by theorem 1 in [7].
Let be the black node adjacent to . If has degree 2, let be the other vertex adjacent to , when we erase the vertices we get a new graph with white vertices such that after performing in in the vertex we get .
If has degree 3, then is part of a , and let and the vertices adjacent to different to . If there is () such that its degree is one, suppose , when we erase the vertices , we get a new trivalent graph with white vertices such that after performing in we get the original trivalent graph . On the other hand when neither nor has degree 1, when we erase the vertices we get two trivalent graphs and such that the sum of their white vertices is and after performing in we get the original graph .
Therefore every trivalent graph of the list was a result of a step in the algorithm described in the theorem and the algorithm gives us all the graphs, including isomorphisms.
∎
Total | Created | |
---|---|---|
2 | 1 | 1 |
3 | 3 | 3 |
4 | 6 | 11 |
5 | 18 | 37 |
6 | 51 | 150 |
7 | 167 | 573 |
8 | 551 | 2267 |
9 | 1954 | 8997 |
10 | 7066 | 36498 |
11 | 26486 | 149708 |
This process is exhaustive, we can assure that it creates all the trivalent graphs with white vertices, but it creates too many repetitions. This is because there are symmetries in the rooted trivalent graphs, and when applying any operation in two symmetric vertices the resulting trivalent graph is the same.
Definition 5.3.
Given a rooted trivalent graph, we say that two vertices are symmetric if there exists an automorphism (as rooted weighted graphs) such that .
It is clear that if two vertices are symmetric, they must have the same string representation because the string representation of a vertex depends solely on the isomorphisms class of the subtree defined by the descendants of . Unfortunately, having the same string representation is not enough to recognize symmetric vertices. The fathers of two symmetrical vertices and must be symmetrical as well ( an automorphism must send the father of to the father of ). This implies, that the process of detecting symmetrical vertices can be iterated recursively, and it will end when the fathers of two vertices coincide (when they are siblings).
We use the above idea for detecting symmetric white vertices of a graph . And we modified algorithm 7 to work only with symmetrically distinct white vertices. These changes reduced the number of generated graphs by around as shown in Table 2.
Created | Reduction | |
---|---|---|
4 | 11 | 0,00% |
5 | 32 | 13,51% |
6 | 122 | 18,67% |
7 | 467 | 18,50% |
8 | 1781 | 21,44% |
9 | 7099 | 21,10% |
10 | 28852 | 20,95% |
11 | 119168 | 20,40% |
More optimization could’ve been done to avoid so many repetitions, but the program would’ve run in exponential time anyway. Because the number of graphs we want to construct has exponential growth.
6 Nomenclature
We need a nomenclature to differentiate the trivalent graphs. For a trivalent graph, the tag is going to be the identifier of . To have a general idea of the shape of the graph it is necessary to include the number of leaves, black and white nodes. Also, we will include the length of the largest and shortest leaf paths of . And an ID number that identifies as a unique graph.
Denote the sets of white vertices, black vertices and leaves of , respectively.
The tag will have the following structure:
= [ , , , length(shortest leaf path), length(largest leaf path), ID number]
The number is automatically generated by the program when using the Hash table that uses the unique string representation of to order it in the list of trivalent graphs.
References
- [1] Trivalent stratifold repository.
- [2] Alfred V. Aho, John E. Hopcroft, and Jeffrey D. Ullman. The design and analysis of computer algorithms. Addison-Wesley Publishing Co., Reading, Mass.-London-Amsterdam, 1975. Second printing, Addison-Wesley Series in Computer Science and Information Processing.
- [3] Douglas M. Campbell and David Radford. Tree isomorphism algorithms: speed vs. clarity. Math. Mag., 64(4):252–261, 1991.
- [4] Gary Chartrand and Ping Zhang. Chromatic graph theory. Discrete Mathematics and its Applications (Boca Raton). CRC Press, Boca Raton, FL, 2009.
- [5] J. C. Gómez-Larrañaga, F. González-Acuña, and Wolfgang Heil. 2-dimensional stratifolds. In A mathematical tribute to Professor José María Montesinos Amilibia, pages 395–405. Dep. Geom. Topol. Fac. Cien. Mat. UCM, Madrid, 2016.
- [6] J. C. Gomez-Larrañaga, F. González-Acuña, and Wolfgang Heil. Classification of simply-connected trivalent 2-dimensional stratifolds. Topology Proc., 52:329–340, 2018.
- [7] J. C. Gomez-Larrañaga, F. González-Acuña, and Wolfgang Heil. Models of simply-connected trivalent 2-dimensional stratifolds. Bol. Soc. Mat. Mex., 26:1301––1312, 2020.
- [8] Hernández Yair. Stratifolds. https://github.com/yair-hdz/stratifolds, 2018.