// File: /workspace/github_c_makefile_star2_O1/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 $0x58, %rsp
cmpl $0x0, 0x8(%rdi)
je 0x17a58
movq %r9, %r12
movq %r8, %rbp
movq %rdi, %r13
movl %esi, 0x14(%rsp)
movl %edx, 0x18(%rsp)
movl %ecx, 0x1c(%rsp)
cmpl $0x4, %ecx
jne 0x17757
leaq 0x15648(%rip), %rbx     # 0x2cd6b
leaq 0x11edc(%rip), %r14     # 0x29606
leaq 0xf(%rsp), %r15
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2110
movq %r14, %rdi
movq %r15, %rsi
xorl %eax, %eax
callq 0x2230
callq 0x2180
movb 0xf(%rsp), %al
addb $-0x70, %al
cmpb $-0x2, %al
jb 0x1772f
jmp 0x1775c
movb $0x6e, 0xf(%rsp)
movl 0x8(%r13), %eax
cltd
idivl 0x10(%r13)
cmpb $0x6e, 0xf(%rsp)
jne 0x178de
movl %eax, %r15d
movq %rbp, 0x30(%rsp)
movq %r12, 0x48(%rsp)
movslq %eax, %r14
leaq (,%r14,4), %rbx
movq %rbx, %rdi
callq 0x21d0
movq %rax, 0x20(%rsp)
movq %rbx, %rdi
callq 0x21d0
movq %rax, 0x38(%rsp)
testl %r14d, %r14d
jle 0x177fb
movl %r15d, %r15d
xorl %ebp, %ebp
xorl %ebx, %ebx
xorl %r12d, %r12d
movq 0x20(%rsp), %r14
movq 0x20(%r13), %rax
movl (%rax,%rbp,4), %edi
movq %r13, %rsi
callq 0xc415
testl %eax, %eax
je 0x177d5
movl %ebx, %eax
leal 0x1(%rbx), %edx
movq %r14, %rcx
movl %edx, %ebx
jmp 0x177e5
movl %r12d, %eax
leal 0x1(%r12), %edx
movq 0x38(%rsp), %rcx
movl %edx, %r12d
movq 0x20(%r13), %rdx
movl (%rdx,%rbp,4), %edx
cltq
movl %edx, (%rcx,%rax,4)
incq %rbp
cmpq %rbp, %r15
jne 0x177b6
jmp 0x17800
xorl %r12d, %r12d
xorl %ebx, %ebx
testl %ebx, %ebx
jle 0x1785f
movq 0x38(%rsp), %rdi
movl %r12d, %esi
movq %r13, 0x40(%rsp)
movq %r13, %rdx
callq 0xbb8a
movq %rax, %rbp
movq %rax, %rdi
movl 0x14(%rsp), %esi
movl 0x18(%rsp), %edx
movl 0x1c(%rsp), %ecx
movq 0x30(%rsp), %r8
movq 0x48(%rsp), %r9
callq 0x176ea
movq %rax, %r15
movq %rbp, %rdi
callq 0xc453
testq %r15, %r15
sete %al
testl %r12d, %r12d
setg %cl
testb %cl, %al
je 0x17861
xorl %r13d, %r13d
movq 0x40(%rsp), %r12
jmp 0x178b2
jmp 0x178cc
movl %ebx, %eax
movq %rax, 0x28(%rsp)
xorl %r14d, %r14d
movq 0x40(%rsp), %r12
movq 0x20(%rsp), %rax
movl (%rax,%r14,4), %edi
movq %r12, %rsi
callq 0x754c
movq %rax, %rbp
movq %r15, %rdi
movq %rax, %rsi
movq %r12, %rdx
callq 0x7be3
movq %rax, %r13
movq %rbp, %rdi
callq 0x7060
movq %r15, %rdi
callq 0x7060
incq %r14
movq %r13, %r15
cmpq %r14, 0x28(%rsp)
jne 0x17870
movq 0x20(%rsp), %rdi
callq 0x2030
movq 0x38(%rsp), %rdi
callq 0x2030
movq %r13, %r15
movq %r12, %r13
testl %ebx, %ebx
movq 0x48(%rsp), %r12
movq 0x30(%rsp), %rbp
jg 0x17c6c
leaq 0x10(%rsp), %rbx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x8010
movq %rax, %r14
cmpl $0x1, (%rbx)
movq (%rax), %r15
je 0x17c64
cmpl $0x0, 0x14(%r15)
jle 0x17935
movl 0x8(%r13), %eax
cltd
idivl 0x10(%r13)
subl 0xc(%r13), %eax
movl 0x14(%rsp), %ebx
cmpl %ebx, %eax
jle 0x179f9
leaq 0x1549c(%rip), %rdi     # 0x2cdc0
xorl %r15d, %r15d
movl %eax, %esi
xorl %eax, %eax
callq 0x2110
jmp 0x17c6c
cmpl $0x2, 0x10(%rsp)
jl 0x17957
movl $0x1, %ebx
movq (%r14,%rbx,8), %rdi
callq 0x7060
incq %rbx
movslq 0x10(%rsp), %rax
cmpq %rax, %rbx
jl 0x17941
movq (%r14), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movq %r13, %rdx
callq 0xbed5
movq %rax, %r15
movq %rax, %rdi
movl 0x14(%rsp), %esi
movl 0x18(%rsp), %edx
movl 0x1c(%rsp), %ecx
movq %rbp, %r8
movq %r12, %r9
callq 0x176ea
movq %rax, %rbx
movq %r15, %rdi
callq 0xc453
testq %rbx, %rbx
je 0x17a48
callq 0x6fb4
movq %rax, %r15
movl 0x14(%rbx), %eax
movl %eax, 0x14(%r15)
movq (%r14), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movq (%rbx), %rdx
movl 0x8(%rbx), %ecx
leaq 0x8(%r15), %r8
callq 0x2544
movq %rax, (%r15)
movl 0xc(%rbx), %eax
movq (%r14), %rcx
movl 0xc(%rcx), %edx
cmpl %edx, %eax
cmovgl %eax, %edx
movl %edx, 0xc(%r15)
movl 0x10(%rbx), %eax
movl 0x10(%rcx), %ecx
cmpl %ecx, %eax
cmovgl %eax, %ecx
movl %ecx, 0x10(%r15)
movq %rbx, 0x20(%r15)
movq (%r14), %rax
movq %rax, 0x28(%r15)
movb $0x2, 0x18(%r15)
jmp 0x17c64
movq %r12, %rdi
movq %r13, %rsi
callq 0x17ff2
movl 0x10(%rsp), %esi
leaq 0x1540a(%rip), %rdi     # 0x2ce19
xorl %eax, %eax
callq 0x2110
movl 0x1c(%rsp), %eax
cmpl $0x4, %eax
ja 0x17b3f
movl %eax, %eax
leaq 0x150f0(%rip), %rcx     # 0x2cb1c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x10(%rsp), %edx
movl %ebx, %edi
movq %r14, %rsi
movq %r13, %rcx
callq 0x16d57
jmp 0x17aab
movq (%r14), %rdi
callq 0x7060
movq %r14, %rdi
callq 0x2030
xorl %r15d, %r15d
jmp 0x17c6c
movl 0x10(%rsp), %edx
movl %ebx, %edi
movq %r14, %rsi
movq %r13, %rcx
movq %rbp, %r8
callq 0x17365
jmp 0x17aab
movq %r13, %rdi
movl %ebx, %esi
callq 0x13ba8
jmp 0x17aab
testq %r12, %r12
je 0x17b41
cmpl $0x2, 0xc(%r12)
jl 0x17b41
movl 0x10(%rsp), %edx
movl %ebx, %edi
movq %r14, %rsi
movq %r13, %rcx
movq %r12, %r8
callq 0x18470
testq %rax, %rax
je 0x17ab8
movq %rax, %r15
jmp 0x17b8f
leaq 0x15371(%rip), %rdi     # 0x2ce30
xorl %r15d, %r15d
movl %ebx, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x2110
callq 0x2180
jmp 0x17b8f
movq %rbp, 0x30(%rsp)
leaq 0x54(%rsp), %r15
movq %r13, %rdi
movl %ebx, %esi
movq %r15, %rdx
callq 0x162dc
movq %rax, 0x20(%rsp)
movslq (%r15), %rbp
testq %rbp, %rbp
jle 0x17b52
xorl %ebx, %ebx
movq $0x0, 0x28(%rsp)
movq 0x20(%rsp), %rax
movq (%rax,%rbx,8), %r15
movl 0x8(%r15), %ecx
movl 0x8(%r13), %eax
cltd
idivl 0x10(%r13)
cmpl %eax, %ecx
jne 0x17b2d
movq %r15, %rdi
callq 0x7054
movq %rax, 0x28(%rsp)
movq %r15, %rdi
callq 0x7060
incq %rbx
cmpq %rbx, %rbp
jne 0x17b06
jmp 0x17b5b
jmp 0x17b8f
leaq 0x15364(%rip), %rdi     # 0x2ceac
callq 0x2090
xorl %r15d, %r15d
jmp 0x17b8f
movq $0x0, 0x28(%rsp)
movq 0x28(%rsp), %r15
testq %r15, %r15
movl 0x14(%rsp), %esi
jne 0x17b80
leaq 0x152df(%rip), %rdi     # 0x2ce4f
movl 0x18(%rsp), %edx
xorl %eax, %eax
callq 0x2110
callq 0x2180
movq 0x20(%rsp), %rdi
callq 0x2030
movq 0x30(%rsp), %rbp
testq %r15, %r15
je 0x17c3d
cmpl $0x0, 0x14(%r15)
jg 0x17c1c
movl 0x8(%r15), %ecx
movl 0x8(%r13), %eax
cltd
idivl 0x10(%r13)
cmpl %eax, %ecx
jge 0x17c1c
cmpl $0x0, 0x10(%rsp)
jle 0x17bcf
xorl %ebx, %ebx
movq (%r14,%rbx,8), %rdi
callq 0x7060
incq %rbx
movslq 0x10(%rsp), %rax
cmpq %rax, %rbx
jl 0x17bb9
movq %r15, (%r14)
movq (%r15), %rdi
movl 0x8(%r15), %esi
movq %r13, %rdx
callq 0xbed5
movq %rax, %r15
movq %rax, %rdi
movl 0x14(%rsp), %esi
movl 0x18(%rsp), %edx
movl 0x1c(%rsp), %ecx
movq %rbp, %r8
movq %r12, %r9
callq 0x176ea
movq %rax, %rbx
movq %r15, %rdi
callq 0xc453
testq %rbx, %rbx
jne 0x17999
movq (%r14), %rdi
callq 0x7060
jmp 0x17c61
cmpl $0x0, 0x10(%rsp)
jle 0x17c64
xorl %ebx, %ebx
movq (%r14,%rbx,8), %rdi
callq 0x7060
incq %rbx
movslq 0x10(%rsp), %rax
cmpq %rax, %rbx
jl 0x17c25
jmp 0x17c64
cmpl $0x0, 0x10(%rsp)
jle 0x17c61
xorl %r15d, %r15d
xorl %ebx, %ebx
movq (%r14,%rbx,8), %rdi
callq 0x7060
incq %rbx
movslq 0x10(%rsp), %rax
cmpq %rax, %rbx
jl 0x17c49
jmp 0x17c64
xorl %r15d, %r15d
movq %r14, %rdi
callq 0x2030
movq %r15, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq