// File: /workspace/github_c_makefile_star2_O2/cbouilla[P]AES-attacks-finder/Search.c
// Function: SearchAlgo_tmp
Solver SearchAlgo_tmp(SysEqLin E, int temps, int memoire, int r, string_list_t *variable_names, Symetric_structure S) // 2° partie de la recherche
{
	if (E->a==0) return NULL;
	
	char c;
	
	if (r==4)
	{
		do
		{
			printf("You will perform a manual search. Would you like to keep all the variables? (o/n) : ");
			scanf(" %c",&c);
			getchar();
		} while (c!='o' && c!='n');
	}
	else c='n';
	int N=E->a/E->gen;
	if (c=='n')
	{
		/* On enlève les variables apparaissant linéairement */
		int * __restrict X1=malloc(N*sizeof(int));
		int * __restrict X2=malloc(N*sizeof(int));
		int pos1=0;
		int pos2=0;
		int i;
		for (i = 0; i < N; i++)
		{
			if (ApparaitLineairement(E->varligne[i],E)) X1[pos1++]=E->varligne[i];
			else X2[pos2++]=E->varligne[i];
		}
		if (pos1>0)
		{
			SysEqLin F=ExtraireEX2(X2,pos2,E);
			Solver B=SearchAlgo_tmp(F,temps,memoire,r,variable_names,S);
			freeSysEq(F);
			if (B==NULL && pos2>0)
			{
				free(X1);
				free(X2);
				return NULL;
			}
			for (i = 0; i < pos1; i++)
			{
				Solver tmp=BaseSolver(X1[i],E);
				Solver tmp2=UnionSolver(B,tmp,E);
				freeSolver(tmp);
				freeSolver(B);
				B=tmp2;
			}
			free(X1);
			free(X2);
			return B;
		}
	}	
	
	int N1;
	Solver * __restrict B1=MakeSolver1(E,&N1);
	Solver B;


	if (N1==1)
	{
		B=B1[0];
		free(B1);
		return B;
	}
	
	if (B1[0]->sortie<=0) // Si l'une des solvers 1 a moins d'une solution autant la trouver et faire une recherche en la connaissant.
	{
		int i;
		for (i = 1; i < N1; i++) freeSolver(B1[i]);
		SysEqLin F=EsachantX(B1[0]->var,B1[0]->Nvar,E);
		B=SearchAlgo_tmp(F,temps,memoire,r,variable_names,S);
		freeSysEq(F);
		if (B==NULL)
		{
			freeSolver(B1[0]);
			free(B1);
			return NULL;
		}
		Solver tmp=NewSolver();
		tmp->sortie=B->sortie;
		tmp->var=UnionListesTriees(B1[0]->var,B1[0]->Nvar,B->var,B->Nvar,&tmp->Nvar);
		tmp->temps=max(B->temps,B1[0]->temps);
		tmp->memoire=max(B->memoire,B1[0]->memoire);
		tmp->fils1=B;
		tmp->fils2=B1[0];
		tmp->type=2;
		//tmp->parents=1;
		free(B1);
		return tmp;
	}
	
	if (temps<E->a/E->gen-E->b)
	{
		printf("We expect 2^(8 x %d) solutions for the non-linear part of the system ---> increase time\n",E->a/E->gen-E->b);
		return NULL;
	}
	
	UpdateSymetricStructure(S,E);
	
	Solver * __restrict B2;
	int N2,i;
	printf(" %d low time solvers \n",N1);
	switch (r)
	{
		case 0:
			B=RandomizedSearch(temps,B1,N1,E);
			if (B==NULL)
			{
				printf("No solution found in %d || %d\n",temps,temps);
				getchar();
			}
			break;
		case 1:
			B2 = ExhaustiveSearchBalancedSolver(E,temps,&N2);
			B=NULL;
			for (i = 0; i < N2; i++)
			{
				//printf("Solver %d :",i);
				//PrintVarSolver(B2[i]);
				if (B2[i]->Nvar==E->a/E->gen) B=copySolver(B2[i]);
				freeSolver(B2[i]);
			}
			if (B==NULL)
			{
				printf("There is no solution in %d || %d\n",temps,memoire);
				getchar();
			}
			free(B2);
			break;
		case 2:
			B = SearchAlgoLowMem(E,temps);
			if (B==NULL)
			{
				printf("No solution found in %d || %d\n",temps,temps);
				getchar();
			}
			break;
		case 3:
			if (S!=NULL && S->n_message>1)
			{
				B =SearchUneSolverN3_SymetricVersion(temps,B1,N1,E,S);
				if (B==NULL)
				{
					printf("No solution found in %d || %d\n",temps,temps);
					getchar();
				}
			}
			else
			{
				printf("search not available for this system\n");
				B=NULL;
			}
			break;
		case 4:
			B=ManualSearch(temps,B1,N1,E,variable_names);
			if (B==NULL)
			{
				printf("No solution found in %d || %d\n",temps,temps);
				getchar();
			}
			break;
		default:
			break;
	}
	if (B==NULL)
	{
		for (i = 0; i < N1; i++) freeSolver(B1[i]);
		free(B1);
		return NULL;
	}
	
	if (B->sortie<=0 && B->Nvar<E->a/E->gen) // On a trouvé une solver avec moins d'une solution -> on relance en supposant qu'on la connait
	{
		for (i = 0; i < N1; i++) freeSolver(B1[i]);
 		B1[0]=B;
		SysEqLin F=EsachantX(B1[0]->var,B1[0]->Nvar,E);
		B=SearchAlgo_tmp(F,temps,memoire,r,variable_names,S);
		freeSysEq(F);
		if (B==NULL)
		{
			freeSolver(B1[0]);
			free(B1);
			return NULL;
		}
		Solver tmp=NewSolver();
		tmp->sortie=B->sortie;
		tmp->var=UnionListesTriees(B1[0]->var,B1[0]->Nvar,B->var,B->Nvar,&tmp->Nvar);
		tmp->temps=max(B->temps,B1[0]->temps);
		tmp->memoire=max(B->memoire,B1[0]->memoire);
		tmp->fils1=B;
		tmp->fils2=B1[0];
		tmp->type=2;
		//tmp->parents=1;
		free(B1);
		return tmp;
	}
	for (i = 0; i < N1; i++) freeSolver(B1[i]);
	free(B1);
	return B;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl 0x8(%rdi), %eax
testl %eax, %eax
je 0x15e6e
movq %rdi, %r14
movl %edx, 0x8(%rsp)
movq %r8, 0x20(%rsp)
movq %r9, 0x28(%rsp)
cmpl $0x4, %ecx
movl %esi, 0x18(%rsp)
movl %ecx, 0xc(%rsp)
jne 0x15b97
leaq 0x15216(%rip), %rbx     # 0x2ad6b
leaq 0x11aaa(%rip), %r15     # 0x27606
leaq 0x3(%rsp), %r12
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2110
movq %r15, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x2220
callq 0x2170
movb 0x3(%rsp), %al
leal -0x70(%rax), %ecx
cmpb $-0x2, %cl
jb 0x15b61
cmpb $0x6e, %al
jne 0x15c77
movl 0x8(%r14), %eax
jmp 0x15b9c
movb $0x6e, 0x3(%rsp)
cltd
idivl 0x10(%r14)
movslq %eax, %r12
leaq (,%r12,4), %rbx
movq %rbx, %rdi
callq 0x21c0
movq %rax, %r15
movq %rbx, %rdi
callq 0x21c0
movq %rax, 0x10(%rsp)
xorl %ebx, %ebx
testl %r12d, %r12d
cmovlel %ebx, %r12d
xorl %ebp, %ebp
xorl %r13d, %r13d
cmpq %rbx, %r12
je 0x15c16
movq 0x20(%r14), %rax
movl (%rax,%rbx,4), %edi
movq %r14, %rsi
callq 0xb528
testl %eax, %eax
je 0x15bf9
movl %r13d, %eax
leal 0x1(%r13), %edx
movq %r15, %rcx
movl %edx, %r13d
jmp 0x15c05
movl %ebp, %eax
leal 0x1(%rbp), %edx
movq 0x10(%rsp), %rcx
movl %edx, %ebp
movq 0x20(%r14), %rdx
movl (%rdx,%rbx,4), %edx
cltq
movl %edx, (%rcx,%rax,4)
incq %rbx
jmp 0x15bd2
testl %r13d, %r13d
jle 0x15c77
movq 0x10(%rsp), %rdi
movl %ebp, %esi
movq %r14, %rdx
callq 0xace0
movq %rax, %r12
movq %rax, %rdi
movl 0x18(%rsp), %esi
movl 0x8(%rsp), %edx
movl 0xc(%rsp), %ecx
movq 0x20(%rsp), %r8
movq 0x28(%rsp), %r9
callq 0x15b17
movq %rax, %rbx
movq %r12, %rdi
callq 0xb562
testq %rbx, %rbx
sete %al
testl %ebp, %ebp
setg %cl
testb %cl, %al
je 0x15cd8
movq %r15, %rdi
callq 0x2030
movq 0x10(%rsp), %rdi
jmp 0x15e69
leaq 0x4(%rsp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x771f
movq %rax, %rbx
movl (%r15), %eax
movq (%rbx), %rbp
cmpl $0x1, %eax
je 0x15e02
cmpl $0x0, 0x14(%rbp)
jle 0x15d37
movl 0x8(%r14), %eax
cltd
idivl 0x10(%r14)
subl 0xc(%r14), %eax
movl 0x18(%rsp), %ebp
cmpl %ebp, %eax
movl 0xc(%rsp), %r12d
jle 0x15e0c
leaq 0x150f8(%rip), %rdi     # 0x2adc0
xorl %ebp, %ebp
movl %eax, %esi
xorl %eax, %eax
callq 0x2110
jmp 0x15e70
movl %r13d, %eax
movq %rax, 0x18(%rsp)
xorl %r12d, %r12d
movq %rbx, %rbp
cmpq %r12, 0x18(%rsp)
je 0x15d25
movl (%r15,%r12,4), %edi
movq %r14, %rsi
callq 0x6d1e
movq %rax, %r13
movq %rbp, %rdi
movq %rax, %rsi
movq %r14, %rdx
callq 0x72e2
movq %rax, %rbx
movq %r13, %rdi
callq 0x6852
movq %rbp, %rdi
callq 0x6852
incq %r12
movq %rbx, %rbp
jmp 0x15ce6
movq %r15, %rdi
callq 0x2030
movq 0x10(%rsp), %rdi
jmp 0x15e05
pushq $0x1
popq %r15
movl 0x18(%rsp), %ebp
movl 0xc(%rsp), %r12d
cltq
cmpq %rax, %r15
jge 0x15d5d
movq (%rbx,%r15,8), %rdi
callq 0x6852
incq %r15
movl 0x4(%rsp), %eax
jmp 0x15d44
movq (%rbx), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movq %r14, %rdx
callq 0xb021
movq %rax, %r15
movq %rax, %rdi
movl %ebp, %esi
movl 0x8(%rsp), %edx
movl %r12d, %ecx
movq 0x20(%rsp), %r8
movq 0x28(%rsp), %r9
callq 0x15b17
movq %rax, %r14
movq %r15, %rdi
callq 0xb562
testq %r14, %r14
je 0x15e5e
callq 0x67a4
movq %rax, %rbp
movl 0x14(%r14), %eax
movl %eax, 0x14(%rbp)
movq (%rbx), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movq (%r14), %rdx
movl 0x8(%r14), %ecx
leaq 0x8(%rbp), %r8
callq 0x2440
movq %rax, (%rbp)
movq (%rbx), %rax
movq 0xc(%r14), %xmm0
movq 0xc(%rax), %xmm1
movdqa %xmm0, %xmm2
pcmpgtd %xmm1, %xmm2
pand %xmm2, %xmm0
pandn %xmm1, %xmm2
por %xmm0, %xmm2
movq %xmm2, 0xc(%rbp)
movq %r14, 0x20(%rbp)
movq (%rbx), %rax
movq %rax, 0x28(%rbp)
movb $0x2, 0x18(%rbp)
movq %rbx, %rdi
callq 0x2030
jmp 0x15e70
movq 0x28(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x1632e
movl 0x4(%rsp), %esi
leaq 0x14ff2(%rip), %rdi     # 0x2ae19
xorl %eax, %eax
callq 0x2110
cmpl $0x4, %r12d
ja 0x15ff2
movl %r12d, %eax
leaq 0x14cda(%rip), %rcx     # 0x2ab1c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x4(%rsp), %edx
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rcx
callq 0x1529c
jmp 0x15ece
movq (%rbx), %rdi
callq 0x6852
movq %rbx, %rdi
callq 0x2030
xorl %ebp, %ebp
movq %rbp, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x4(%rsp), %edx
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rcx
movq 0x20(%rsp), %r8
callq 0x157a3
jmp 0x15ece
movq %r14, %rdi
movl %ebp, %esi
callq 0x122f8
jmp 0x15ece
testq %r15, %r15
je 0x15fe6
cmpl $0x2, 0xc(%r15)
jl 0x15fe6
movl 0x4(%rsp), %edx
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rcx
movq %r15, %r8
callq 0x16767
testq %rax, %rax
je 0x15edb
movq %rax, %r13
jmp 0x15f91
leaq 0x14f4e(%rip), %rdi     # 0x2ae30
movl %ebp, %esi
movl %ebp, %edx
xorl %eax, %eax
callq 0x2110
callq 0x2170
jmp 0x15ff2
leaq 0x34(%rsp), %r12
movq %r14, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq 0x14980
movq %rax, 0x10(%rsp)
movl (%r12), %r13d
xorl %r15d, %r15d
testl %r13d, %r13d
cmovlel %r15d, %r13d
xorl %r12d, %r12d
cmpq %r15, %r13
je 0x15f55
movq 0x10(%rsp), %rax
movq (%rax,%r15,8), %rbp
movl 0x8(%rbp), %ecx
movl 0x8(%r14), %eax
cltd
idivl 0x10(%r14)
cmpl %eax, %ecx
jne 0x15f48
movq %rbp, %rdi
callq 0x6846
movq %rax, %r12
movq %rbp, %rdi
callq 0x6852
incq %r15
jmp 0x15f1f
testq %r12, %r12
movq %r12, %r15
movl 0x18(%rsp), %ebp
movl 0xc(%rsp), %r12d
jne 0x15f7f
leaq 0x14ee2(%rip), %rdi     # 0x2ae4f
movl %ebp, %esi
movl 0x8(%rsp), %edx
xorl %eax, %eax
callq 0x2110
callq 0x2170
movq 0x10(%rsp), %rdi
callq 0x2030
movq %r15, %r13
testq %r15, %r15
je 0x15ff2
cmpl $0x0, 0x14(%r13)
jg 0x15fc4
movl 0x8(%r13), %ecx
movl 0x8(%r14), %eax
cltd
idivl 0x10(%r14)
cmpl %eax, %ecx
jge 0x15fc4
xorl %r15d, %r15d
movslq 0x4(%rsp), %rax
cmpq %rax, %r15
jge 0x16011
movq (%rbx,%r15,8), %rdi
callq 0x6852
incq %r15
jmp 0x15fac
xorl %r14d, %r14d
movq %r13, %rbp
movslq 0x4(%rsp), %rax
cmpq %rax, %r14
jge 0x15e02
movq (%rbx,%r14,8), %rdi
callq 0x6852
incq %r14
jmp 0x15fca
leaq 0x14ebf(%rip), %rdi     # 0x2aeac
callq 0x2090
xorl %r14d, %r14d
movslq 0x4(%rsp), %rax
cmpq %rax, %r14
jge 0x15e66
movq (%rbx,%r14,8), %rdi
callq 0x6852
incq %r14
jmp 0x15ff5
movq %r13, (%rbx)
movq (%r13), %rdi
movl 0x8(%r13), %esi
jmp 0x15d66