<commit_before>#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <getopt.h>

#include "cactus.h"
#include "commonC.h"

/*
 * The script checks the nets are structured as we expect, essentially by
 * calling net_check for each net in the tree. We do a couple of other tests also..
 */

Cap *A(Cap *cap) {
	Cap *cap2 = cap_getParent(cap);
	while(1) {
		if(cap_getAdjacency(cap2) != NULL) {
			return cap2;
		}
		if(cap_getParent(cap2) == NULL) {
			assert(end_getRootInstance(cap_getEnd(cap2)) == cap2);
			return cap2;
		}
		cap2 = cap_getParent(cap2);
	}
}

Hash *computeHashA(Net *net) {
	/*
	 * For each attached, non-root cap c finds A(c) and puts it in a hash "hashA",
	 * such that hashA[c] = A(c).
	 * Where A(c) is the lowest common ancestor of c which is attached, else
	 * A(c) is the root ancestor of A(c).
	 */
	Hash *hashA = hash_construct();
	Event *rootEvent = eventTree_getRootEvent(net_getEventTree(net));
	Cap *cap;
	Net_CapIterator *capIterator = net_getCapIterator(net);

	while((cap = net_getNextCap(capIterator)) != NULL) {
		if(cap_getEvent(cap) != rootEvent && cap_getAdjacency(cap) != NULL) {
			Cap *cap2 = A(cap);
			assert(hash_search(hashA, cap) == NULL);
			hash_insert(hashA, cap, cap2);
		}
	}
	net_destructCapIterator(capIterator);

	return hashA;
}

Hash *computeHashInvA(Net *net) {
	/*
	 * For each attached or root cap c finds A'(c) and puts it in a hash "hashInvA",
	 *  such that hashInvA[c] = A'(c).
	 * Where A'(c) is the inverse of A(c) such that A'(c) = { d \in C | A(d) = c },
	 * and C is the set of all caps. The members of A'(c) are called bottom nodes.
	 *
	 */
	Hash *hashInvA = hash_construct();
	Event *rootEvent = eventTree_getRootEvent(net_getEventTree(net));
	Cap *cap;
	Net_CapIterator *capIterator = net_getCapIterator(net);

	while((cap = net_getNextCap(capIterator)) != NULL) {
		if(cap_getEvent(cap) != rootEvent && cap_getAdjacency(cap) != NULL) {
			Cap *cap2 = A(cap);
			struct List *list;
			if((list = hash_search(hashInvA, cap2)) == NULL) {
				list = constructEmptyList(0, NULL);
				hash_insert(hashInvA, cap2, list);
			}
			listAppend(list, cap);
		}
	}
	net_destructCapIterator(capIterator);

	return hashInvA;
}

static void checkFaces(Net *net) {
	/*
	 *
	 */
	//Compute hashes for A(c) and A'(c) (see legends for def).
	Hash *hashA = computeHashA(net);
	Hash *hashInvA = computeHashInvA(net);

	//Construct lifted edges using A(c) function hash.
	//Hash *liftedEdgesHash = computeLiftedEdges(net, hashA);

	//Constructs lifted edge/adjacency edge connected components, called modules.
	//Faces are simply the nodes in the modules (the top nodes) and the set of
	//bottom nodes.
	//struct List *modules = computeModules(net, liftedEdgesHash);

	//Check all trivial faces are not represented in the set of Faces stored in the net.


	//Check all non-trival faces are represented in the set of Faces stored in the net.
}

static void checkTreeIsTerminalNormalised(Net *net) {
	/*
	 * A cactus tree is terminally normalised if all leaf nets are terminal.
	 * We haven't made this part of the api checks yet, as I don't know if we'll keep it
	 * forever.
	 */
	if(net_isLeaf(net)) {
		assert(net_isTerminal(net));
		assert(net_getBlockNumber(net) == 0);
		//The following are defensive checks.
		Group *group;
		Net_GroupIterator *iterator = net_getGroupIterator(net);
		while((group = net_getNextGroup(iterator)) != NULL) {
			assert(group_isLeaf(group));
		}
		net_destructGroupIterator(iterator);
	}<commit_msg>Incomplete - taskmake terminal faces building work <commit_after>#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <getopt.h>

#include "cactus.h"
#include "commonC.h"

/*
 * The script checks the nets are structured as we expect, essentially by
 * calling net_check for each net in the tree. We do a couple of other tests also..
 */

Cap *A(Cap *cap) {
	Cap *cap2 = cap_getParent(cap);
	while(1) {
		if(cap_getAdjacency(cap2) != NULL) {
			return cap2;
		}
		if(cap_getParent(cap2) == NULL) {
			assert(end_getRootInstance(cap_getEnd(cap2)) == cap2);
			return cap2;
		}
		cap2 = cap_getParent(cap2);
	}
}

Hash *computeHashA(Net *net) {
	/*
	 * For each attached, non-root cap c finds A(c) and puts it in a hash "hashA",
	 * such that hashA[c] = A(c).
	 * Where A(c) is the lowest common ancestor of c which is attached, else
	 * A(c) is the root ancestor of A(c).
	 */
	Hash *hashA = hash_construct();
	Event *rootEvent = eventTree_getRootEvent(net_getEventTree(net));
	Cap *cap;
	Net_CapIterator *capIterator = net_getCapIterator(net);

	while((cap = net_getNextCap(capIterator)) != NULL) {
		if(cap_getEvent(cap) != rootEvent && cap_getAdjacency(cap) != NULL) {
			Cap *cap2 = A(cap);
			assert(hash_search(hashA, cap) == NULL);
			hash_insert(hashA, cap, cap2);
		}
	}
	net_destructCapIterator(capIterator);

	return hashA;
}

Hash *computeHashInvA(Net *net) {
	/*
	 * For each attached or root cap c finds A'(c) and puts it in a hash "hashInvA",
	 *  such that hashInvA[c] = A'(c).
	 * Where A'(c) is the inverse of A(c) such that A'(c) = { d \in C | A(d) = c },
	 * and C is the set of all caps. The members of A'(c) are called bottom nodes.
	 *
	 */
	Hash *hashInvA = hash_construct();
	Event *rootEvent = eventTree_getRootEvent(net_getEventTree(net));
	Cap *cap;
	Net_CapIterator *capIterator = net_getCapIterator(net);

	while((cap = net_getNextCap(capIterator)) != NULL) {
		if(cap_getEvent(cap) != rootEvent && cap_getAdjacency(cap) != NULL) {
			Cap *cap2 = A(cap);
			struct List *list;
			if((list = hash_search(hashInvA, cap2)) == NULL) {
				list = constructEmptyList(0, NULL);
				hash_insert(hashInvA, cap2, list);
			}
			listAppend(list, cap);
		}
	}
	net_destructCapIterator(capIterator);

	return hashInvA;
}
/*
Hash *computeLiftedEdges(Net *net, Hash *hashA, Hash *hashInvA) {
	Hash *liftedEdgesHash = hash_construct();
	Hash_Iterator *iterator = hash_getIterator(hashInvA);
	Cap *topCap;
	while((topCap = hash_getNext(iterator)) != NULL) {
		struct List *bottomCaps = hashInvA(topCap);
		struct List *liftedEdges = constructEmptyList(0);
		hash_insert(liftedEdgesHash, topCap, liftedEdges);
		int32_t i;
		for(i=0; i<bottomNodes->length; i++) {
			Cap *bottomCap = bottomCaps->list[i];
			Cap *adjacentBottomCap = cap_getAdjacency(bottomCap);
			assert(adjacentBottomCap != NULL);
			Cap *adjacentTopCap = hash_search(adjacentBottomCap, hashA);
			assert(adjacentTopCap != NULL);
			assert(hash_search(hashInvA, adjacentTopCap) != NULL);
			listAppend(liftedEdgesHash, adjacentTopCap);
		}
	}
	hash_destructIterator(iterator);
}

void computeModulesP(Cap *topCap, Hash *liftedEdges, struct List *module,
		Hash *modulesHash) {
	int32_t i;
	Cap *adjacentTopCap;
	if(hash_search(modulesHash, topCap) == NULL) {
		//Add to module
		hash_insert(modulesHash, topCap, module);
		listAppend(module, topCap);

		//Traverse the lifted edges
		struct List *liftedEdges = hash_search(liftedEdges, topCap);
		for(i=0; i<liftedEdges->length; i++) {
			adjacentTopCap = liftedEdges->list[i];
			computeModulesP(adjacentTopCap, liftedEdges, module, modulesHash);
		}

		//Traverse the direct adjaceny
		adjacentTopCap = cap_getAdjacency(topCap);
		if(adjacentTopCap != NULL) {
			computeModulesP(adjacentTopCap, liftedEdges, module, modulesHash);
		}
	}
}

struct List *computeModules(Net *net, Hash *liftedEdges) {
	struct List *modules = constructEmptyList(0, destructList);
	Hash *modulesHash = hash_construct();

	Hash_Iterator *iterator = hash_getIterator(hashInvA);
	Cap *topCap;
	while((topCap = hash_getNext(iterator)) != NULL) {
		if(hash_search(modulesHash, topCap) == NULL) {
			struct List *module = constructEmptyList();
			computeModulesP(topCap, liftedEdges, module, modulesHash);
			listAppend(modules, module);
			assert(module->length >= 2);
		}
	}
	hash_destructIterator(iterator);
	hash_destruct(modulesHash);
	return modules;
}

int32_t isDisjoint

int32_t isTrivialFace(Net *net, struct List *module, Hash *hashInvA) {
	if(module->length > 2) {
		return 0;
	}
	assert(module->length == 2);
	return isSimpleFace(net, module, hashInvA);
}

void checkTrivialFaceP(Net *net, Cap *topCap, Hash *hashInvA) {
	assert(cap_getFace(topCap) == NULL); //top node of trivial face can not be in a cap.
	assert(cap_getFace(cap_getReverse(topCap)) == NULL); //defensive, again top node of trivial face can not be in a cap.
	//Currently we don't look at the bottom nodes
	struct List *bottomNodes = hash_search(hashInvA, topCap);
	assert(bottomNodes != NULL);
	assert(net != NULL);
}

void checkTrivialFace(Net *net, struct List *module, Hash *hashInvA) {
	//Checks the top nodes do not have an associated fae.
	assert(module->length == 2);
	checkTrivialFaceP(net, module->list[0], hashInvA);
	checkTrivialFaceP(net, module->list[1], hashInvA);
}

void checkNonTrivialFace(Net *net, struct List *module, Hash *hashInvA) {
	//Checks the top nodes are all in one associated face.
	//Checks the set of bottom nodes for each face are in agreement.
	int32_t i, j, k, l;
	assert(module->length > 0);
	Cap *topCap = module->list[0];
	Face *face = cap_getFace(topCap);
	assert(face != NULL);
	for(i=1; i<module->length; i++) {
		topCap = module->list[i];
		assert(face == cap_getFace(topCap));
		j = face_getTopNodeIndex(face, topCap);
		assert(face_getTopNode(face, j) == topCap);
		struct List *bottomCaps = hash_search(hashInvA, topCap);
		assert(bottomCaps != NULL);
		for(k=0; k<bottomCaps->length; k++) {
			Cap *bottomCap = bottomCaps->list[k];
		    l = face_getBottomNodeIndex(face, j, bottomCap);
		    assert(face_getBottomNode(j, l) == bottomCap);
		}
	}
}

void diffFaces(Net *net, struct List *modules, Hash *hashInvA) {
	int32_t i;
	for(i=0; i<modules; i++) {
		struct List *module = modules->list[i];
		if(isTrivialFace(module, hashInvA)) {
			checkTrivialFace(net, module, hashInvA);
		}
		else {
			checkNonTrivialFace(net, module, hashInvA);
		}
	}
}

static void checkFaces(Net *net) {
	//Compute hashes for A(c) and A'(c) (see legends for def).
	Hash *hashA = computeHashA(net);
	Hash *hashInvA = computeHashInvA(net);

	//Construct lifted edges using A(c) function hash.
	Hash *liftedEdgesHash = computeLiftedEdges(net, hashA);

	//Constructs lifted edge/adjacency edge connected components, called modules.
	//Faces are simply the nodes in the modules (the top nodes) and the set of
	//bottom nodes.
	struct List *modules = computeModules(net, liftedEdgesHash);

	//Check all faces we have computed are the same as those computed by Daniel.
	diffFaces(net, modules);
}*/

static void checkTreeIsTerminalNormalised(Net *net) {
	/*
	 * A cactus tree is terminally normalised if all leaf nets are terminal.
	 * We haven't made this part of the api checks yet, as I don't know if we'll keep it
	 * forever.
	 */
	if(net_isLeaf(net)) {
		assert(net_isTerminal(net));
		assert(net_getBlockNumber(net) == 0);
		//The following are defensive checks.
		Group *group;
		Net_GroupIterator *iterator = net_getGroupIterator(net);
		while((group = net_getNextGroup(iterator)) != NULL) {
			assert(group_isLeaf(group));
		}
		net_destructGroupIterator(iterator);
	}
{'fraction_non_alphanumeric': 0.1308961212661614, 'fraction_numerical': 0.005528310298707088, 'mean_word_length': 4.489965736661772, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2807140', 'n_tokens_mistral': 4219, 'n_tokens_neox': 3942, 'n_words': 1095}