// File: /workspace/github_c_makefile_star2_O1/pwelke[P]GraphMiningTools/outerplanar.c
// Function: isOuterplanarBlock
char isOuterplanarBlock(struct Graph* g, struct ShallowGraphPool* sgp) {
	struct ShallowGraph* list = getShallowGraph(sgp);
	struct ShallowGraph* pairs = getShallowGraph(sgp);
	struct ShallowGraph* edges = getGraphEdges(g, sgp);
	struct VertexList* node = NULL;
	struct VertexList* pair = NULL;
	struct VertexList** edgeArray;
	struct VertexList** pairArray;
	struct VertexList* idx;
	int i, j, k;
	int n = 0;
	char found;


	/*
	 * Get a list "list" of vertices of degree 2 and mark them as such in the graph
	 * by setting ->d = 1. Also, count the number of not-NULL vertices.
	 * This is useful if the algorithm gets some "induced subgraph" where some
	 * vertices are not used.
	 */
	for (i=0; i<g->n; ++i) {
		if (g->vertices[i]) {

			++n;

			/* if vertex has degree 2, add it to list and mark it as such */
			if (isDegreeTwoVertex(g->vertices[i])) {
				struct VertexList* e = getVertexList(sgp->listPool);
				e->endPoint = g->vertices[i];
				pushEdge(list, e);

				g->vertices[i]->d = 1;
			}
		}
	}

	/* first check. number of edges ok ? */
	if (g->m > 2 * n - 3) {
		/* printf("incorrect edge count\n"); */
		dumpShallowGraph(sgp, list);
		dumpShallowGraph(sgp, pairs);
		dumpShallowGraph(sgp, edges);
		return 0;
	}

	/* second check: enough vertices of degree 2? */
	if (list->m < 2) {
		/* printf("not enough vertices of degree 2\n"); */
		dumpShallowGraph(sgp, list);
		dumpShallowGraph(sgp, pairs);
		dumpShallowGraph(sgp, edges);
		return 0;
	}

	/*
	 * Successively remove vertices of degree 2
	 */
	for (i=1, node=list->edges; /*node && */  (i<=n-2);  ++i, node=node->next) {

		struct Vertex* v = node->endPoint;

		/* near and next are the two vertices adjacent to node */
		struct Vertex* near = v->neighborhood->endPoint;
		struct Vertex* next = v->neighborhood->next->endPoint;

		/* if the edges leading to near and next are artificial triangulation
		 * edges that were added below in a previous step, add them to the
		 * edges list. Do it s.t. startPoint->number <= endPoint->number, as
		 * there will be lexicographic sorting */
		if (v->neighborhood->flag) {
			if (v->number < near->number) {
				appendEdge(edges, shallowCopyEdge(v->neighborhood, sgp->listPool));
			} else {
				appendEdge(edges, inverseEdge(v->neighborhood, sgp->listPool));
			}
		}
		if (v->neighborhood->next->flag) {
			if (v->number < next->number) {
				appendEdge(edges, shallowCopyEdge(v->neighborhood->next, sgp->listPool));
			} else {
				appendEdge(edges, inverseEdge(v->neighborhood->next, sgp->listPool));
			}
		}


		/* add the pair (near, next) to pairs list, sort lexicographically
		 we have to add pair to the adjacency list of the graph, if this edge
		 does not already exist. Mark newly added edges in the flag tag. */
		pair = getVertexList(sgp->listPool);

		if (near->number < next->number) {

			pair->startPoint = near;
			pair->endPoint = next;

			/* this is for the case where g is not maximal outerplanar and
			 * a "triangulation edge" is added */
			if (!isIncident(near, next)) {
				struct VertexList* tmp = shallowCopyEdge(pair, sgp->listPool);
				tmp->flag = 1;
				addEdge(near, tmp);

				tmp = inverseEdge(pair, sgp->listPool);
				tmp->flag = 1;
				addEdge(next, tmp);
			}
		} else {

			pair->startPoint = next;
			pair->endPoint = near;

			/* this is for the case where g is not maximal outerplanar and
			 * a "triangulation edge" is added */
			if (!isIncident(near, next)) {
				struct VertexList* tmp = shallowCopyEdge(pair, sgp->listPool);
				tmp->flag = 1;
				addEdge(next, tmp);

				tmp =  inverseEdge(pair, sgp->listPool);
				tmp->flag = 1;
				addEdge(near, tmp);
			}
		}

		pushEdge(pairs, pair);

		/* remove node from Graph, check if one of the neighbors
		 * becomes degree two vertex. If it is not already in list
		 * (which is encoded in ->d), add it to list.
		 *
		 * TODO ?
		 * BUG: not degree two vertex, but 2-vertex. this is a difference
		 * But 2-vertices make no sense in the context of ops */
		removeEdge(near, v, sgp->listPool);
		if (isDegreeTwoVertex(near)) {
			if (!near->d) {
				struct VertexList* e = getVertexList(sgp->listPool);
				e->endPoint = near;
				/* printf("add %i to list of deg 2 vertices\n", near->number); */
				appendEdge(list, e);
				near->d = 1;
			}
		}

		removeEdge(next, v, sgp->listPool);
		if (isDegreeTwoVertex(next)) {
			if (!next->d) {
				struct VertexList* e = getVertexList(sgp->listPool);
				/* printf("add %i to list of deg 2 vertices\n", next->number); */
				e->endPoint = next;
				appendEdge(list, e);
				next->d = 1;
			}
		}


		/* Here, the vertex should be removed from the graph,
		 * but isMaximalOuterplanar has no pointer to a VertexPool. Thus we
		 * only dump the neighborhood of v. */
		dumpVertexListRecursively(sgp->listPool, v->neighborhood);
		v->neighborhood = NULL;


		/* this part may be omitted as it seems to be the case that
		 * "searching the list of pairs for an occurrence of something that
		 * is not in the list of edges includes an abort if there are e.g.
		 * two copies of an edge in pairs, but only one copy f that edge in
		 * edges.
		 *
		 * mistake in the paper. one has to check, if the new edge
		 * is not contained in more than two triangles. As one triangle
		 * is already deleted by removing v there can be only one other
		 * triangle left without violation of this condition in the former
		 * graph */
		if (commonNeighborCount(near, next) > 1) {
			/* printf("removing node %i creates an edge that lies on more than two triangles\n", node->endPoint->number); */
			dumpShallowGraph(sgp, list);
			dumpShallowGraph(sgp, pairs);
			dumpShallowGraph(sgp, edges);
			return 0;
		}



		/* at this point, node->endPoint should be dumped, but this is not necessary
		 * as it is not considered any more and can be handled when dumping the whole
		 * graph
		dumpVertexList(sgp->listPool, popEdge(list)); */

		if (list->m - i < 2) {
			/* printf("removing node %i leaves not enough degree 2 vertices\n", node->endPoint->number); */
			dumpShallowGraph(sgp, list);
			dumpShallowGraph(sgp, pairs);
			dumpShallowGraph(sgp, edges);
			return 0;
		}
	}

	/* add the last edge (near, next) to edges */
	appendEdge(edges, shallowCopyEdge(pair, sgp->listPool));

	/* check for occurrence of something in pairs, that is not in edges
	 * for this, sort the two lists in lexicographic order and sweep through
	 * the two arrays afterwards */
	edgeArray = malloc(edges->m * sizeof(struct VertexList*));
	for (i=0, idx=edges->edges; i<edges->m; ++i, idx=idx->next) {
		edgeArray[i] = idx;
	}

	pairArray = malloc(pairs->m * sizeof(struct VertexList*));
	for (i=0, idx=pairs->edges; i<pairs->m; ++i, idx=idx->next) {
		pairArray[i] = idx;
	}

	qsort(pairArray, pairs->m, sizeof(struct VertexList*), &compareDirectedEdges);
	qsort(edgeArray, edges->m, sizeof(struct VertexList*), &compareDirectedEdges);


	/* sweep */
	for (j=0, k=0, found=1; j<pairs->m; ++j) {

		/* increment currentEdge as long as it is lex. smaller than sweeper. */
		for (; compareDirectedEdges(&(pairArray[j]), &(edgeArray[k])) > 0; ++k);

		/* check if the two are equal */
		if (compareDirectedEdges(&(pairArray[j]), &(edgeArray[k])) == 0) {
			++k;
			continue;

		} else {
			/* this is bad, g is no mop */
			found = 0;
			break;
		}
	}

	/* garbage collection */
	dumpShallowGraph(sgp, list);
	dumpShallowGraph(sgp, pairs);
	dumpShallowGraph(sgp, edges);
	free(edgeArray);
	free(pairArray);

	return found;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r15
movq %rdi, %r14
movq %rsi, %rdi
callq 0x14aae
movq %rax, %rbp
movq %r15, %rdi
callq 0x14aae
movq %rax, 0x8(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x8376
movq %rax, (%rsp)
cmpl $0x0, (%r14)
jle 0x16f73
xorl %ebx, %ebx
xorl %r12d, %r12d
movq 0x10(%r14), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x16f66
incl %r12d
callq 0x7cb4
testb %al, %al
je 0x16f66
movq 0x10(%r15), %rdi
callq 0x1432b
movq 0x10(%r14), %rcx
movq (%rcx,%rbx,8), %rcx
movq %rcx, 0x18(%rax)
movq %rbp, %rdi
movq %rax, %rsi
callq 0x840c
movq 0x10(%r14), %rax
movq (%rax,%rbx,8), %rax
movl $0x1, 0x28(%rax)
incq %rbx
movslq (%r14), %rax
cmpq %rax, %rbx
jl 0x16f1e
jmp 0x16f76
xorl %r12d, %r12d
leal -0x3(,%r12,2), %eax
cmpl %eax, 0x4(%r14)
jg 0x16f8a
cmpl $0x2, 0x10(%rbp)
jge 0x16fc3
movq %r15, %rdi
movq %rbp, %rsi
callq 0x14b19
movq %r15, %rdi
movq 0x8(%rsp), %rsi
callq 0x14b19
movq %r15, %rdi
movq (%rsp), %rsi
callq 0x14b19
xorl %r12d, %r12d
movl %r12d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x3, %r12d
movq %r15, 0x20(%rsp)
movq %rbp, 0x10(%rsp)
jge 0x16fe1
movq $0x0, 0x18(%rsp)
jmp 0x17202
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movq %rbp, %rbx
movq %rcx, 0x30(%rsp)
movq (%rbx), %rbx
movq 0x18(%rbx), %r13
movq 0x8(%r13), %rdi
movq 0x8(%rdi), %rax
movq 0x18(%rdi), %rbp
movq 0x18(%rax), %r14
cmpl $0x0, 0x24(%rdi)
je 0x17034
movl 0x18(%r13), %eax
cmpl 0x18(%rbp), %eax
jge 0x1701f
movq 0x10(%r15), %rsi
callq 0x7bc0
jmp 0x17028
movq 0x10(%r15), %rsi
callq 0x7bdc
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x88b9
movq 0x8(%r13), %rax
movq 0x8(%rax), %rdi
cmpl $0x0, 0x24(%rdi)
je 0x1706c
movl 0x18(%r13), %eax
cmpl 0x18(%r14), %eax
jge 0x17057
movq 0x10(%r15), %rsi
callq 0x7bc0
jmp 0x17060
movq 0x10(%r15), %rsi
callq 0x7bdc
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x88b9
movq 0x10(%r15), %rdi
callq 0x1432b
movq %rax, %r15
movl 0x18(%rbp), %eax
cmpl 0x18(%r14), %eax
jge 0x1709c
movq %rbp, 0x10(%r15)
movq %r14, 0x18(%r15)
movq %rbp, %rdi
movq %r14, %rsi
callq 0x7c9f
movq %rbp, %rdx
movq %r14, %rcx
jmp 0x170b5
movq %r14, 0x10(%r15)
movq %rbp, 0x18(%r15)
movq %rbp, %rdi
movq %r14, %rsi
callq 0x7c9f
movq %r14, %rdx
movq %rbp, %rcx
testb %al, %al
jne 0x1710f
movq %rdx, 0x28(%rsp)
movq %rcx, 0x18(%rsp)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rsi
movq %r15, %rdi
callq 0x7bc0
movl $0x1, %ecx
movl %ecx, 0x24(%rax)
movq 0x28(%rsp), %rdi
movq %rax, %rsi
callq 0x7cd0
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rsi
movq %r15, %rdi
callq 0x7bdc
movl $0x1, %ecx
movl %ecx, 0x24(%rax)
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x7cd0
movq 0x8(%rsp), %rdi
movq %r15, 0x18(%rsp)
movq %r15, %rsi
callq 0x840c
movq 0x20(%rsp), %r15
movq 0x10(%r15), %rdx
movq %rbp, %rdi
movq %r13, %rsi
callq 0x7cdd
movq %rbp, %rdi
callq 0x7cb4
testb %al, %al
je 0x17168
cmpl $0x0, 0x28(%rbp)
jne 0x17168
movq 0x10(%r15), %rdi
callq 0x1432b
movq %rbp, 0x18(%rax)
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x88b9
movl $0x1, 0x28(%rbp)
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %r13, %rsi
callq 0x7cdd
movq %r14, %rdi
callq 0x7cb4
testb %al, %al
je 0x171ac
cmpl $0x0, 0x28(%r14)
jne 0x171ac
movq 0x10(%r15), %rdi
callq 0x1432b
movq %r14, 0x18(%rax)
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x88b9
movl $0x1, 0x28(%r14)
movq 0x10(%r15), %rdi
movq 0x8(%r13), %rsi
callq 0x143b8
movq $0x0, 0x8(%r13)
movq %rbp, %rdi
movq %r14, %rsi
callq 0x7c48
cmpl $0x2, %eax
jge 0x17362
movq 0x10(%rsp), %rbp
movl 0x10(%rbp), %eax
movq 0x30(%rsp), %rcx
addl %ecx, %eax
cmpl $0x1, %eax
jle 0x16f8a
addq $0x8, %rbx
leal (%r12,%rcx), %eax
decl %eax
decl %ecx
cmpl $0x1, %eax
jne 0x16fe9
movq 0x10(%r15), %rsi
movq 0x18(%rsp), %rdi
callq 0x7bc0
movq (%rsp), %rbx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x88b9
movslq 0x10(%rbx), %rbx
leaq (,%rbx,8), %rdi
callq 0x1190
movq %rax, %r14
testq %rbx, %rbx
jle 0x17251
xorl %eax, %eax
movq (%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, (%r14,%rax,8)
incq %rax
addq $0x8, %rcx
cmpq %rax, %rbx
jne 0x1723e
movq 0x8(%rsp), %rax
movslq 0x10(%rax), %r13
leaq (,%r13,8), %rdi
callq 0x1190
movq %rax, %r15
testq %r13, %r13
jle 0x17289
xorl %eax, %eax
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, (%r15,%rax,8)
incq %rax
addq $0x8, %rcx
cmpq %rax, %r13
jne 0x17276
leaq -0x11860(%rip), %r12    # 0x5a30
movl $0x8, %edx
movq %r15, %rdi
movq %r13, %rsi
movq %r12, %rcx
callq 0x1080
movq (%rsp), %rax
movslq 0x10(%rax), %rsi
movl $0x8, %edx
movq %r14, %rdi
movq %r12, %rcx
callq 0x1080
movb $0x1, %r12b
movq 0x8(%rsp), %rax
cmpl $0x0, 0x10(%rax)
jle 0x17324
xorl %ebx, %ebx
xorl %ebp, %ebp
leaq (%r15,%rbx,8), %r12
movslq %ebp, %rbp
leaq (%r14,%rbp,8), %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0x5a30
incq %rbp
addq $0x8, %r13
testl %eax, %eax
jg 0x172d8
addq $-0x8, %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0x5a30
testl %eax, %eax
jne 0x1731c
incq %rbx
movq 0x8(%rsp), %rax
movslq 0x10(%rax), %rax
cmpq %rax, %rbx
jl 0x172cd
movq 0x10(%rsp), %rbp
movb $0x1, %r12b
jmp 0x17324
xorl %r12d, %r12d
movq 0x10(%rsp), %rbp
movq 0x20(%rsp), %rbx
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x14b19
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x14b19
movq %rbx, %rdi
movq (%rsp), %rsi
callq 0x14b19
movq %r14, %rdi
callq 0x1030
movq %r15, %rdi
callq 0x1030
jmp 0x16fb1
movq %r15, %rdi
movq 0x10(%rsp), %rsi
jmp 0x16f90