// File: /workspace/github_cpp_makefile_star2_O1/SNUCSE-CTA[P]GI/src/algorithm.cpp
// Function: Algorithm::computeIso(Graph*, Graph*, int*, Coloring*)
void Algorithm::computeIso(Graph* aG1, Graph* aG2, int32_t* aMapping, Coloring* aColoring)
{
	Memory* global_memory = &(cont.global_memory);
	numNode = aG1->numNode;
	mapping = new int32_t[numNode];
	int32_t* stack = global_memory->getLLArray(numNode);
	int32_t stackSize = 0;
	int32_t* array1 = global_memory->getLLArray(numNode);
	int32_t* array2 = global_memory->getLLArray(numNode);
	int32_t ind1 = 0;
	int32_t ind2 = 0;
	for(int32_t vid = 0; vid < numNode; ++vid) {
		mapping[vid] = aMapping[vid] - numNode;

		if(aG1->one[vid] == 0 && aG1->od[vid] != aG1->d[vid]) { //root
			stack[stackSize] = vid;
			++stackSize;
		}
	}

	//process coreness-1 nodes
	while(stackSize > 0) {
		int32_t r = stack[stackSize - 1];
		--stackSize;
		
		ind1 = 0;
		ind2 = 0;
		for(int32_t i = 0; i < aG1->od[r]; ++i) {
			if(aMapping[ aG1->e[r][i] ] == -1 ) { //unmapped neighbors of r
				array1[ind1] = aG1->e[r][i];
				++ind1;
			}
		}
	
		int32_t mr = aMapping[r] - numNode;
		for(int32_t i = 0; i < aG2->od[mr]; ++i) { //unmapped neighbors of mr
			if(aMapping[ aG2->e[mr][i] + numNode ] == -1) {
				array2[ind2] = aG2->e[mr][i] + numNode;
				++ind2;
			}
		}
			
		//sort array1 and array2 by color
		sort(array1, array1 + ind1,
			[aColoring](const int32_t& a, const int32_t& b) -> bool {
				int32_t ca = aColoring->color[ aColoring->inv[a] ];
				int32_t cb = aColoring->color[ aColoring->inv[b] ];
				return ca < cb;
			}
		);
		sort(array2, array2 + ind2,
			[aColoring](const int32_t& a, const int32_t& b) -> bool {
				int32_t ca = aColoring->color[ aColoring->inv[a] ];
				int32_t cb = aColoring->color[ aColoring->inv[b] ];
				return ca < cb;
			}
		);

		for(int32_t i = 0; i < ind1; ++i) {
			aMapping[array1[i]] = array2[i]; //to check isMapped
			aMapping[array2[i]] = array1[i];
			mapping[array1[i]] = array2[i] - numNode; //output

			stack[stackSize] = array1[i];
			++stackSize;
		}
	}

	global_memory->returnLLArray(stack, numNode);
	global_memory->returnLLArray(array1, numNode);
	global_memory->returnLLArray(array2, numNode);

	//ASSERT
//	int32_t* check = global_memory->getLLArray(numNode);
//	memset(check, 0, sizeof(int32_t) * numNode);
//	for(int32_t vid = 0; vid < aG1->numNode; ++vid) {
//		if( aG1->l[vid] != aG2->l[mapping[vid]] )
//			cout << "ISOMORPHISM ERROR: label not same" << endl;
//		if( aG1->od[vid] != aG2->od[mapping[vid]] )
//			cout << "ISOMORPHISM ERROR: degree not same" << endl;
//		for(int32_t i = 0; i < aG1->od[vid]; ++i) {
//			int32_t adj = aG1->e[vid][i];
//			check[mapping[adj]] = 1;
//		}
//		for(int32_t i = 0; i < aG2->od[mapping[vid]]; ++i) {
//			int32_t adj = aG2->e[mapping[vid]][i];
//			if( check[adj] == 0 )
//				cout << "ISOMORPHISM ERROR: not isomorphic" << endl;
//		}
//	}
//	global_memory->returnLLArray(check, numNode);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r8, %rbp
movq %rcx, %r12
movq %rdx, 0x48(%rsp)
movq %rdi, %r15
movq (%rdi), %r14
addq $0x18, %r14
movq %rsi, 0x10(%rsp)
movslq 0xc(%rsi), %rbx
leaq (,%rbx,4), %rax
testq %rbx, %rbx
movl %ebx, 0x20(%rdi)
movq $-0x1, %rdi
cmovnsq %rax, %rdi
callq 0x2030
movq %rax, 0x18(%r15)
movq %r14, %rdi
movl %ebx, %esi
callq 0x4b34
movq %rax, 0x8(%rsp)
movl 0x20(%r15), %esi
movq %r14, %rdi
callq 0x4b34
movq %rax, %r13
movl 0x20(%r15), %esi
movq %r14, 0x28(%rsp)
movq %r14, %rdi
callq 0x4b34
movq %rax, %rbx
movl 0x20(%r15), %esi
testl %esi, %esi
jle 0x5218
movq 0x18(%r15), %rax
movq 0x10(%rsp), %r8
movq 0x30(%r8), %rcx
xorl %edx, %edx
xorl %r9d, %r9d
movl (%r12,%rdx,4), %edi
subl %esi, %edi
movl %edi, (%rax,%rdx,4)
cmpb $0x0, (%rcx,%rdx)
jne 0x520a
movq 0x18(%r8), %rsi
movq 0x20(%r8), %rdi
movl (%rsi,%rdx,4), %esi
cmpl (%rdi,%rdx,4), %esi
je 0x520a
movslq %r9d, %r9
movq 0x8(%rsp), %rsi
movl %edx, (%rsi,%r9,4)
incl %r9d
incq %rdx
movslq 0x20(%r15), %rsi
cmpq %rsi, %rdx
jl 0x51dc
jmp 0x5220
xorl %r9d, %r9d
movq 0x10(%rsp), %r8
testl %r9d, %r9d
jle 0x547e
leaq 0x40(%r13), %rax
movq %rax, 0x38(%rsp)
leaq 0x40(%rbx), %rax
movq %rax, 0x30(%rsp)
movq %r15, 0x18(%rsp)
movq %rbp, (%rsp)
movl %r9d, %eax
movq 0x8(%rsp), %rcx
movslq -0x4(%rcx,%rax,4), %rax
movq 0x18(%r8), %rcx
cmpl $0x0, (%rcx,%rax,4)
movl $0x0, %r10d
jle 0x5290
movq 0x38(%r8), %rdx
movq (%rdx,%rax,8), %rdx
xorl %esi, %esi
xorl %r10d, %r10d
movslq (%rdx,%rsi,4), %rdi
cmpl $-0x1, (%r12,%rdi,4)
jne 0x5284
movslq %r10d, %r10
movl %edi, (%r13,%r10,4)
incl %r10d
incq %rsi
movslq (%rcx,%rax,4), %rdi
cmpq %rdi, %rsi
jl 0x526e
movslq (%r12,%rax,4), %rax
movslq 0x20(%r15), %rcx
subq %rcx, %rax
movq 0x48(%rsp), %rdx
movq 0x18(%rdx), %rcx
cmpl $0x0, (%rcx,%rax,4)
movq %r9, 0x50(%rsp)
jle 0x52e6
movq 0x38(%rdx), %rdx
movq (%rdx,%rax,8), %rdx
xorl %esi, %esi
xorl %r14d, %r14d
movslq (%rdx,%rsi,4), %r8
movslq 0x20(%r15), %rdi
addq %r8, %rdi
cmpl $-0x1, (%r12,%rdi,4)
jne 0x52d8
movslq %r14d, %r14
movl %edi, (%rbx,%r14,4)
incl %r14d
incq %rsi
movslq (%rcx,%rax,4), %rdi
cmpq %rdi, %rsi
jl 0x52bc
jmp 0x52e9
xorl %r14d, %r14d
movq %r10, 0x20(%rsp)
testl %r10d, %r10d
movq %rbp, %rax
je 0x5381
movq 0x20(%rsp), %rbp
movslq %ebp, %r15
leaq (,%r15,4), %rsi
addq %r13, %rsi
bsrq %r15, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r13, %rdi
movq %rsi, 0x40(%rsp)
movq %rax, %rcx
callq 0x5691
cmpl $0x11, %ebp
jl 0x536a
shlq $0x2, %r15
movq %r13, %rdi
movq 0x38(%rsp), %rbp
movq %rbp, %rsi
movq (%rsp), %rdx
callq 0x5931
addq $-0x40, %r15
movq (%rsp), %rax
movq %rbp, %rdi
movq %rax, %rsi
callq 0x59bd
movq (%rsp), %rax
addq $0x4, %rbp
addq $-0x4, %r15
jne 0x534f
jmp 0x5381
movq %r13, %rdi
movq 0x40(%rsp), %rsi
movq (%rsp), %r15
movq %r15, %rdx
callq 0x5931
movq %r15, %rax
testl %r14d, %r14d
je 0x5400
movslq %r14d, %r15
leaq (%rbx,%r15,4), %rbp
bsrq %r15, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %rbx, %rdi
movq %rbp, %rsi
movq %rax, %rcx
callq 0x59fc
cmpl $0x11, %r14d
jl 0x53eb
shlq $0x2, %r15
movq %rbx, %rdi
movq 0x30(%rsp), %rbp
movq %rbp, %rsi
movq (%rsp), %r14
movq %r14, %rdx
callq 0x5c9c
addq $-0x40, %r15
movq %r14, %rax
movq %rbp, %rdi
movq %rax, %rsi
callq 0x5d28
movq (%rsp), %rax
addq $0x4, %rbp
addq $-0x4, %r15
jne 0x53d0
jmp 0x5400
movq %rbx, %rdi
movq %rbp, %rsi
movq (%rsp), %r14
movq %r14, %rdx
callq 0x5c9c
movq %r14, %rax
movq %rax, %rbp
movq 0x50(%rsp), %r9
decl %r9d
movq 0x20(%rsp), %rcx
testl %ecx, %ecx
jle 0x546b
movq 0x18(%rsp), %r15
movq 0x18(%r15), %rax
movl %r9d, %r9d
movl %ecx, %edx
movq 0x8(%rsp), %rcx
leaq (%rcx,%r9,4), %rsi
xorl %ecx, %ecx
movl (%rbx,%rcx,4), %edi
movslq (%r13,%rcx,4), %r8
movl %edi, (%r12,%r8,4)
movl (%r13,%rcx,4), %edi
movslq (%rbx,%rcx,4), %r8
movl %edi, (%r12,%r8,4)
movl (%rbx,%rcx,4), %edi
subl 0x20(%r15), %edi
movslq (%r13,%rcx,4), %r8
movl %edi, (%rax,%r8,4)
movl (%r13,%rcx,4), %edi
movl %edi, (%rsi,%rcx,4)
incq %rcx
cmpq %rcx, %rdx
jne 0x542d
addl %ecx, %r9d
jmp 0x5470
movq 0x18(%rsp), %r15
testl %r9d, %r9d
movq 0x10(%rsp), %r8
jg 0x5244
movl 0x20(%r15), %edx
movq 0x28(%rsp), %r14
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x4cf0
movl 0x20(%r15), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x4cf0
movl 0x20(%r15), %edx
movq %r14, %rdi
movq %rbx, %rsi
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4cf0