/*This is a hacked together program to do some basic consistency checkingon a Triangulation.  It is intended for development use only, so I cantest some functions as I write them, rather than waiting till I haveenough done to compute meaningful results.*/#include <stdio.h>#include <stdlib.h>#include "kernel.h"void consistency_check(Triangulation *manifold);static void		count_tetrahedra(Triangulation *manifold);static void		check_neighbors_and_gluings(Triangulation *manifold);static void		check_peripheral_curves(Triangulation *manifold);static void		check_edge_classes(Triangulation *manifold);static void		check_orientation(Triangulation *manifold);static void		check_edge_orientation(Triangulation *manifold);static void		check_cusps(Triangulation *manifold);static Boolean	cusp_on_list(Cusp *cusp0, Triangulation *manifold);void consistency_check(	Triangulation *manifold){	count_tetrahedra(manifold);	check_neighbors_and_gluings(manifold);	check_peripheral_curves(manifold);	check_edge_classes(manifold);	check_orientation(manifold);	check_edge_orientation(manifold);	check_cusps(manifold);	printf("%s is OK\n", manifold->name);	return;}static void count_tetrahedra(	Triangulation *manifold){	Tetrahedron	*tet;	int			count;	count = 0;	for (tet = manifold->tet_list_begin.next;		 tet != &manifold->tet_list_end;		 tet = tet->next)		count++;	if (count != manifold->num_tetrahedra) {		printf("Wrong number of tetrahedra in consistency_check().\n");		exit(0);	}	return;}static void check_neighbors_and_gluings(	Triangulation *manifold){	Tetrahedron	*tet,				*nbr;	int			i,				op_i;	Permutation	this_gluing;	for (tet = manifold->tet_list_begin.next;		 tet != &manifold->tet_list_end;		 tet = tet->next)		for (i = 0; i < 4; i++) {			this_gluing	= tet->gluing[i];			nbr			= tet->neighbor[i];			op_i		= EVALUATE(this_gluing, i);			if (nbr->neighbor[op_i] != tet) {				printf("Inconsistent neighbor data in consistency_check().\n");				exit(0);			}			if (nbr->gluing[op_i] != inverse_permutation[this_gluing]) {				printf("Inconsistent gluing data in consistency_check().\n");				exit(0);			}		}	return;}static void check_peripheral_curves(	Triangulation *manifold){	Tetrahedron	*tet,				*nbr;	int			i,				j,				k,				l,				op_i,				op_j,				op_k,				sum;	Permutation	this_gluing;	for (tet = manifold->tet_list_begin.next;		 tet != &manifold->tet_list_end;		 tet = tet->next)	{		for (i = 0; i < 4; i++) {			this_gluing	= tet->gluing[i];			nbr			= tet->neighbor[i];			op_i		= EVALUATE(this_gluing, i);			for (j = 0; j < 4; j++) {				if (i == j)					continue;				op_j = EVALUATE(this_gluing, j);				for (k = 0; k < 2; k++) {					op_k = (parity[this_gluing] == orientation_preserving) ? k : !k;					for (l = 0; l < 1; l++)						if (tet->curve[l][k][j][i] != - nbr->curve[l][op_k][op_j][op_i]) {							printf("bad peripheral curve in consistency_check()\n");							exit(0);						}				}			}		}		for (i = 0; i < 4; i++)				/* which vertex	*/			for (j = 0; j < 2; j++)			/* which sheet	*/				for (l = 0; l < 2; l++) {	/* which curve	*/					sum = 0;					for (k = 0; k < 4; k++)	/* which side	*/						if (k != i)							sum += tet->curve[l][j][i][k];					if (sum != 0) {						printf("bad peripheral curve sum in consistency_check()\n");						exit(0);					}				}	}	/*	 *	Let's also check that the meridian and longitude are nonzero.	 *	This was a problem once.	 */	for (i = 0; i < 2; i++) {	/* which curve */		Boolean all_zeros;		all_zeros = TRUE;		for (tet = manifold->tet_list_begin.next;			 tet != &manifold->tet_list_end;			 tet = tet->next)			for (j = 0; j < 2; j++)				for (k = 0; k < 4; k++)					for (l = 0; l < 4; l++)						if (k != l && tet->curve[i][j][k][l] != 0)							all_zeros = FALSE;		if (all_zeros == TRUE) {			printf("missing peripheral curve in consistency_check()\n");			exit(0);		}	}	return;}static void check_edge_classes(	Triangulation *manifold){	int				edge_class_count,					edge_order,					sum;	EdgeClass		*edge;	PositionedTet	ptet0,					ptet;	edge_class_count = 0;	sum = 0;	for (edge = manifold->edge_list_begin.next;		 edge != &manifold->edge_list_end;		 edge = edge->next)	{		set_left_edge(edge, &ptet0);		ptet = ptet0;		edge_order = 0;		do {			if (ptet.tet->edge_class[edge_between_faces[ptet.near_face][ptet.left_face]] != edge) {				printf("incorrectly labelled edge class in consistency_check()\n");				exit(0);			}			/*	While we're here, let's check the local orientability of the EdgeClass. */			if (ptet.tet == ptet0.tet			 && ptet.near_face == ptet0.near_face			 && ptet.left_face == ptet0.left_face			 && ! same_positioned_tet(&ptet, &ptet0)			) {				printf("nonorientable EdgeClass in consistency_check()\n");				exit(0);			}			edge_order++;			veer_left(&ptet);		} while ( ! same_positioned_tet(&ptet, &ptet0));		if (edge_order != edge->order) {			printf("wrong edge class order in consistency_check()\n");			exit(0);		}		edge_class_count++;		sum += edge->order;	}	if (edge_class_count != manifold->num_tetrahedra) {		printf("wrong number of EdgeClasses in consistency_check()\n");		exit(0);	}	if (sum != 6 * manifold->num_tetrahedra) {		printf("wrong sum of orders of EdgeClasses in consistency_check()\n");		exit(0);	}	return;}static void check_orientation(	Triangulation	*manifold){	Tetrahedron	*tet;	int			i;	if (manifold->orientability == oriented_manifold)		for (tet = manifold->tet_list_begin.next;			 tet != &manifold->tet_list_end;			 tet = tet->next)			for (i = 0; i < 4; i++)				if (parity[tet->gluing[i]] != orientation_preserving) {					printf("orientation error in consistency_check()\n");					exit(0);				}	return;}static void check_edge_orientation(	Triangulation	*manifold){	Tetrahedron	*tet,				*nbr;	int			i,				j,				nbr_i,				nbr_j;	EdgeIndex	e,				nbr_e;	for (tet = manifold->tet_list_begin.next;		 tet != &manifold->tet_list_end;		 tet = tet->next)		for (i = 0; i < 4; i++) {			nbr = tet->neighbor[i];			nbr_i = EVALUATE(tet->gluing[i], i);			for (j = 0; j < 4; j++) {				if (i == j)					continue;				nbr_j = EVALUATE(tet->gluing[i], j);				e     = edge_between_faces[  i  ][  j  ];				nbr_e = edge_between_faces[nbr_i][nbr_j];				if (					(tet->edge_orientation[e] == nbr->edge_orientation[nbr_e])				 != (parity[tet->gluing[i]] == orientation_preserving)				)				{					printf("edge_orientation error in consistency_check()\n");					exit(0);				}			}		}	return;}static void check_cusps(	Triangulation	*manifold){	Tetrahedron	*tet,				*nbr;	int			i,				j,				nbr_j;	int			count,				torus_count,				Klein_count;	Cusp		*cusp;	/*	 *	Check consistency across gluings.	 */	for (tet = manifold->tet_list_begin.next;		 tet != &manifold->tet_list_end;		 tet = tet->next)		for (i = 0; i < 4; i++) {			nbr = tet->neighbor[i];			for (j = 0; j < 4; j++) {				if (i == j)					continue;				nbr_j = EVALUATE(tet->gluing[i], j);				if (tet->cusp[j] != nbr->cusp[nbr_j]) {					printf("cusp error in consistency_check()\n");					exit(0);				}			}		}	/*	 *	Count the cusps.	 */	count		= 0;	torus_count	= 0;	Klein_count	= 0;	for (cusp = manifold->cusp_list_begin.next;		 cusp != &manifold->cusp_list_end;		 cusp = cusp->next)	{		count++;		if (cusp->topology == torus_cusp)			torus_count++;		else			Klein_count++;	}	if (count != manifold->num_cusps	 || torus_count != manifold->num_or_cusps	 || Klein_count != manifold->num_nonor_cusps	)	{		printf("wrong number of cusps in consistency_check()\n");		exit(0);	}	/*	 *	Are all cusp pointers valid?	 */	for (tet = manifold->tet_list_begin.next;		 tet != &manifold->tet_list_end;		 tet = tet->next)		for (i = 0; i < 4; i++)			if (cusp_on_list(tet->cusp[i], manifold) == FALSE) {				printf("bad tet->cusp in consistency_check()\n");				exit(0);			}	return;}static Boolean cusp_on_list(	Cusp			*cusp0,	Triangulation	*manifold){	Cusp	*cusp;	for (cusp = manifold->cusp_list_begin.next;		 cusp != &manifold->cusp_list_end;		 cusp = cusp->next)		if (cusp0 == cusp)			return(TRUE);	return(FALSE);}