// File: 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
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq (%rax), %rcx
addq $0x18, %rcx
movq %rcx, -0x30(%rbp)
movq -0x10(%rbp), %rcx
movl 0xc(%rcx), %ecx
movl %ecx, 0x20(%rax)
movslq 0x20(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x3040
movq %rax, %rcx
movq -0x90(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x30(%rbp), %rdi
movl 0x20(%rax), %esi
callq 0x77d0
movq %rax, %rcx
movq -0x90(%rbp), %rax
movq %rcx, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movq -0x30(%rbp), %rdi
movl 0x20(%rax), %esi
callq 0x77d0
movq %rax, %rcx
movq -0x90(%rbp), %rax
movq %rcx, -0x48(%rbp)
movq -0x30(%rbp), %rdi
movl 0x20(%rax), %esi
callq 0x77d0
movq %rax, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movl $0x0, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movq -0x90(%rbp), %rcx
movl -0x5c(%rbp), %eax
cmpl 0x20(%rcx), %eax
jge 0x9f3d
movq -0x90(%rbp), %rax
movq -0x20(%rbp), %rcx
movslq -0x5c(%rbp), %rdx
movl (%rcx,%rdx,4), %edx
subl 0x20(%rax), %edx
movq 0x18(%rax), %rax
movslq -0x5c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x5c(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x9f2d
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0x5c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq 0x20(%rcx), %rcx
movslq -0x5c(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
je 0x9f2d
movl -0x5c(%rbp), %edx
movq -0x38(%rbp), %rax
movslq -0x3c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x9f2f
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x9eb2
jmp 0x9f3f
cmpl $0x0, -0x3c(%rbp)
jle 0xa1a0
movq -0x38(%rbp), %rax
movl -0x3c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x60(%rbp)
movl -0x3c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x3c(%rbp)
movl $0x0, -0x54(%rbp)
movl $0x0, -0x58(%rbp)
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
movq -0x10(%rbp), %rcx
movq 0x18(%rcx), %rcx
movslq -0x60(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
jge 0x9fe8
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x38(%rcx), %rcx
movslq -0x60(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x64(%rbp), %rdx
movslq (%rcx,%rdx,4), %rcx
cmpl $-0x1, (%rax,%rcx,4)
jne 0x9fdb
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movslq -0x60(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x64(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movq -0x48(%rbp), %rax
movslq -0x54(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x9fdd
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x9f7a
movq -0x90(%rbp), %rcx
movq -0x20(%rbp), %rax
movslq -0x60(%rbp), %rdx
movl (%rax,%rdx,4), %eax
subl 0x20(%rcx), %eax
movl %eax, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movq -0x18(%rbp), %rcx
movq 0x18(%rcx), %rcx
movslq -0x68(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
jge 0xa08e
movq -0x90(%rbp), %rdx
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x38(%rcx), %rcx
movslq -0x68(%rbp), %rsi
movq (%rcx,%rsi,8), %rcx
movslq -0x6c(%rbp), %rsi
movl (%rcx,%rsi,4), %ecx
addl 0x20(%rdx), %ecx
movslq %ecx, %rcx
cmpl $-0x1, (%rax,%rcx,4)
jne 0xa07e
movq -0x90(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x38(%rcx), %rcx
movslq -0x68(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x6c(%rbp), %rdx
movl (%rcx,%rdx,4), %edx
addl 0x20(%rax), %edx
movq -0x50(%rbp), %rax
movslq -0x58(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0xa080
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0xa007
movq -0x48(%rbp), %rdi
movq -0x48(%rbp), %rsi
movslq -0x54(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
movq -0x28(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdx
callq 0xa1f0
movq -0x50(%rbp), %rdi
movq -0x50(%rbp), %rsi
movslq -0x58(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
movq -0x28(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdx
callq 0xa240
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
cmpl -0x54(%rbp), %eax
jge 0xa19b
movq -0x90(%rbp), %rax
movq -0x50(%rbp), %rcx
movslq -0x84(%rbp), %rdx
movl (%rcx,%rdx,4), %esi
movq -0x20(%rbp), %rcx
movq -0x48(%rbp), %rdx
movslq -0x84(%rbp), %rdi
movslq (%rdx,%rdi,4), %rdx
movl %esi, (%rcx,%rdx,4)
movq -0x48(%rbp), %rcx
movslq -0x84(%rbp), %rdx
movl (%rcx,%rdx,4), %esi
movq -0x20(%rbp), %rcx
movq -0x50(%rbp), %rdx
movslq -0x84(%rbp), %rdi
movslq (%rdx,%rdi,4), %rdx
movl %esi, (%rcx,%rdx,4)
movq -0x50(%rbp), %rcx
movslq -0x84(%rbp), %rdx
movl (%rcx,%rdx,4), %edx
subl 0x20(%rax), %edx
movq 0x18(%rax), %rax
movq -0x48(%rbp), %rcx
movslq -0x84(%rbp), %rsi
movslq (%rcx,%rsi,4), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x48(%rbp), %rax
movslq -0x84(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movq -0x38(%rbp), %rax
movslq -0x3c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0xa0e0
jmp 0x9f3f
movq -0x90(%rbp), %rax
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl 0x20(%rax), %edx
callq 0x7a30
movq -0x90(%rbp), %rax
movq -0x30(%rbp), %rdi
movq -0x48(%rbp), %rsi
movl 0x20(%rax), %edx
callq 0x7a30
movq -0x90(%rbp), %rax
movq -0x30(%rbp), %rdi
movq -0x50(%rbp), %rsi
movl 0x20(%rax), %edx
callq 0x7a30
addq $0x90, %rsp
popq %rbp
retq
nop