// File: /workspace/github_c_makefile_star2_O3/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 0x17eea
movq %rdi, %r14
movl %edx, 0x8(%rsp)
movq %r8, 0x20(%rsp)
movq %r9, 0x28(%rsp)
movl %ecx, 0xc(%rsp)
cmpl $0x4, %ecx
movl %esi, 0x18(%rsp)
jne 0x17a58
leaq 0x153b9(%rip), %rbx     # 0x2cdcb
leaq 0x11c4d(%rip), %r15     # 0x29666
leaq 0x7(%rsp), %r12
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2110
movq %r15, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x2230
callq 0x2180
movb 0x7(%rsp), %cl
leal -0x70(%rcx), %eax
cmpb $-0x2, %al
jb 0x17a1e
movl 0x8(%r14), %eax
cltd
idivl 0x10(%r14)
cmpb $0x6e, %cl
je 0x17a62
jmp 0x17b3e
movb $0x6e, 0x7(%rsp)
cltd
idivl 0x10(%r14)
movl %eax, %ebp
movslq %eax, %r12
leaq (,%r12,4), %rbx
movq %rbx, %rdi
callq 0x21d0
movq %rax, %r15
movq %rbx, %rdi
callq 0x21d0
testl %r12d, %r12d
jle 0x17b3e
movq %rax, 0x10(%rsp)
movl %ebp, %r12d
movq 0x20(%r14), %rax
xorl %ebx, %ebx
xorl %r13d, %r13d
xorl %ebp, %ebp
movl (%rax,%rbx,4), %edi
movq %r14, %rsi
callq 0xc7ef
testl %eax, %eax
je 0x17abc
movl %r13d, %ecx
leal 0x1(%r13), %eax
movq %r15, %rdx
movl %eax, %r13d
jmp 0x17ac8
movl %ebp, %ecx
leal 0x1(%rbp), %eax
movq 0x10(%rsp), %rdx
movl %eax, %ebp
movq 0x20(%r14), %rax
movl (%rax,%rbx,4), %esi
movslq %ecx, %rcx
movl %esi, (%rdx,%rcx,4)
incq %rbx
cmpq %rbx, %r12
jne 0x17a9e
testl %r13d, %r13d
movq 0x10(%rsp), %rdi
jle 0x17b3e
movl %ebp, %esi
movq %r14, %rdx
callq 0xbf32
movq %rax, %rbx
movq %rax, %rdi
movl 0x18(%rsp), %esi
movl 0x8(%rsp), %edx
movl 0xc(%rsp), %ecx
movq 0x20(%rsp), %r8
movq 0x28(%rsp), %r9
callq 0x179d4
movq %rax, %r12
movq %rbx, %rdi
callq 0xc82d
testq %r12, %r12
sete %al
testl %ebp, %ebp
setg %cl
testb %cl, %al
je 0x17ba4
movq %r15, %rdi
callq 0x2030
movq 0x10(%rsp), %rdi
jmp 0x17ee5
movq %rsp, %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x834c
movq %rax, %rbx
movl (%r15), %eax
movq (%rbx), %r12
cmpl $0x1, %eax
jne 0x17b67
movq %rbx, %rdi
callq 0x2030
jmp 0x17eed
cmpl $0x0, 0x14(%r12)
jle 0x17c09
movl 0x8(%r14), %eax
cltd
idivl 0x10(%r14)
subl 0xc(%r14), %eax
movl 0x18(%rsp), %ebp
cmpl %ebp, %eax
jle 0x17ce4
leaq 0x1528d(%rip), %rdi     # 0x2ce20
xorl %r12d, %r12d
movl %eax, %esi
xorl %eax, %eax
callq 0x2110
jmp 0x17eed
movl %r13d, %eax
movq %rax, 0x18(%rsp)
movq %r12, %r13
xorl %r12d, %r12d
movq %r13, %rbx
movl (%r15,%r12,4), %edi
movq %r14, %rsi
callq 0x790b
movq %rax, %rbp
movq %r13, %rdi
movq %rax, %rsi
movq %r14, %rdx
callq 0x7f14
movq %rax, %r13
movq %rbp, %rdi
callq 0x7447
movq %rbx, %rdi
callq 0x7447
incq %r12
cmpq %r12, 0x18(%rsp)
jne 0x17bb2
movq %r15, %rdi
callq 0x2030
movq 0x10(%rsp), %rdi
callq 0x2030
movq %r13, %r12
jmp 0x17eed
cmpl $0x2, %eax
movl 0x18(%rsp), %ebp
jl 0x17c30
movl $0x1, %r15d
movq (%rbx,%r15,8), %rdi
callq 0x7447
incq %r15
movslq (%rsp), %rax
cmpq %rax, %r15
jl 0x17c18
movq (%rbx), %r12
movq (%r12), %rdi
movl 0x8(%r12), %esi
movq %r14, %rdx
callq 0xc29a
movq %rax, %r15
movq %rax, %rdi
movl %ebp, %esi
movl 0x8(%rsp), %edx
movl 0xc(%rsp), %ecx
movq 0x20(%rsp), %r8
movq 0x28(%rsp), %r9
callq 0x179d4
movq %rax, %r14
movq %r15, %rdi
callq 0xc82d
testq %r14, %r14
je 0x17d36
callq 0x7394
movq %rax, %r12
movl 0x14(%r14), %eax
movl %eax, 0x14(%r12)
movq (%rbx), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movq (%r14), %rdx
movl 0x8(%r14), %ecx
leaq 0x8(%r12), %r8
callq 0x2544
movq %rax, (%r12)
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(%r12)
movq %r14, 0x20(%r12)
movq (%rbx), %rax
movq %rax, 0x28(%r12)
movb $0x2, 0x18(%r12)
jmp 0x17b5a
movq 0x28(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x1822a
movl (%rsp), %esi
leaq 0x1517b(%rip), %rdi     # 0x2ce79
xorl %eax, %eax
callq 0x2110
movl 0xc(%rsp), %eax
cmpl $0x4, %eax
ja 0x17ec4
movl %eax, %eax
leaq 0x14e61(%rip), %rcx     # 0x2cb7c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl (%rsp), %edx
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rcx
callq 0x1702a
jmp 0x17d8d
movq (%rbx), %rdi
callq 0x7447
jmp 0x17ee2
movl (%rsp), %edx
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rcx
movq 0x20(%rsp), %r8
callq 0x17608
jmp 0x17d8d
movq %r14, %rdi
movl %ebp, %esi
callq 0x13f10
jmp 0x17d8d
testq %r15, %r15
je 0x17e93
cmpl $0x2, 0xc(%r15)
jl 0x17e93
movl (%rsp), %edx
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rcx
movq %r15, %r8
callq 0x186cf
testq %rax, %rax
je 0x17e05
movq %rax, %r12
cmpl $0x0, 0x14(%r12)
jg 0x17dde
movl 0x8(%r12), %esi
movl 0x8(%r14), %eax
cltd
idivl 0x10(%r14)
cmpl %eax, %esi
jge 0x17dde
cmpl $0x0, (%rsp)
jle 0x17dd2
xorl %r15d, %r15d
movq (%rbx,%r15,8), %rdi
callq 0x7447
incq %r15
movslq (%rsp), %rax
cmpq %rax, %r15
jl 0x17db8
movl 0x8(%r12), %esi
movq %r12, (%rbx)
movq (%r12), %rdi
jmp 0x17c39
cmpl $0x0, (%rsp)
jle 0x17b5a
xorl %r14d, %r14d
movq (%rbx,%r14,8), %rdi
callq 0x7447
incq %r14
movslq (%rsp), %rax
cmpq %rax, %r14
jl 0x17deb
jmp 0x17b5a
leaq 0x15084(%rip), %rdi     # 0x2ce90
movl %ebp, %esi
movl %ebp, %edx
xorl %eax, %eax
callq 0x2110
callq 0x2180
jmp 0x17ec4
leaq 0x34(%rsp), %r12
movq %r14, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq 0x165e8
movq %rax, 0x10(%rsp)
movslq (%r12), %r13
testq %r13, %r13
jle 0x17ea1
xorl %r15d, %r15d
xorl %r12d, %r12d
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 0x17e6b
movq %rbp, %rdi
callq 0x743b
movq %rax, %r12
movq %rbp, %rdi
callq 0x7447
incq %r15
cmpq %r15, %r13
jne 0x17e47
testq %r12, %r12
movl 0x18(%rsp), %ebp
je 0x17ea1
movq 0x10(%rsp), %rdi
callq 0x2030
jmp 0x17d95
leaq 0x15072(%rip), %rdi     # 0x2cf0c
callq 0x2090
jmp 0x17ec4
leaq 0x15007(%rip), %rdi     # 0x2ceaf
movl %ebp, %esi
movl 0x8(%rsp), %edx
xorl %eax, %eax
callq 0x2110
callq 0x2180
movq 0x10(%rsp), %rdi
callq 0x2030
cmpl $0x0, (%rsp)
jle 0x17ee2
xorl %r14d, %r14d
movq (%rbx,%r14,8), %rdi
callq 0x7447
incq %r14
movslq (%rsp), %rax
cmpq %rax, %r14
jl 0x17ecd
movq %rbx, %rdi
callq 0x2030
xorl %r12d, %r12d
movq %r12, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq