// File: aaronshim[P]SATurday/./solver.cpp
// Function: Solver::solveR(Formula*, Model*, int)
Model *Solver::solveR(Formula *formula, Model *model, int backtrackDepth) {
  invariant(formula != NULL, 2331);

  // Restart solver if nodes failed is above cutoff.
  if (nodesFailed >= CUTOFF) {
    return NULL;
  }

  int state = formula->simplify(model);
  switch (state) {
    case -1: // If unsat, return null.
      if (DEBUG >= 5)
        cout << "Unsatisfied model: " << model->toString() << endl;
      return NULL;
    case 1: // If sat, return the model.
      model->complete();
      return model->clone();
  }

  int nextIndex = formula->nextVar();
  invariant(!model->isAssigned(nextIndex), 1940);

  // Should we try setting the literal or clearing the literal first?
  int firstSet = rand() % 2;
  //int firstSet = 0;

  if (DEBUG >= 5)
    cout << "firstSet = " << firstSet << endl;

  Model *retModel;

  if (DEBUG >= 5) {
    cout << "Trying a value for " << nextIndex + 1 << " at depth " <<
      backtrackDepth << "..." << endl;
  }
  if (DEBUG >= 2) {
    if (backtrackDepth > maxDepth) {
      maxDepth = backtrackDepth;
    }
    cout << "progress: " << backtrackDepth << "/" << formula->getNVars() <<
            "\tnodes failed: " << nodesFailed << endl;
  }

  if ((retModel = solveRClone(formula, model, nextIndex, firstSet, backtrackDepth))) {
    nodesFailed = 0;
    return retModel;
  }

  if (DEBUG >= 5) {
    cout << "Backtracking... depth=" << backtrackDepth << endl;
  }

  if ((retModel = solveRClone(formula, model, nextIndex, !firstSet, backtrackDepth))) {
    nodesFailed = 0;
    return retModel;
  }

  nodesFailed ++;

  return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
cmpq $0x0, -0x10(%rbp)
setne %al
movzbl %al, %edi
andl $0x1, %edi
movl $0x91b, %esi            # imm = 0x91B
callq 0x2360
movl 0x77eb(%rip), %eax      # 0xb12c
cmpl 0x77c9(%rip), %eax      # 0xb110
jl 0x3956
movq $0x0, -0x8(%rbp)
jmp 0x3a6b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x3240
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x34(%rbp)
subl $-0x1, %eax
je 0x397d
jmp 0x3973
movl -0x34(%rbp), %eax
subl $0x1, %eax
je 0x398a
jmp 0x39a5
movq $0x0, -0x8(%rbp)
jmp 0x3a6b
movq -0x18(%rbp), %rdi
callq 0x25c0
movq -0x18(%rbp), %rdi
callq 0x2740
movq %rax, -0x8(%rbp)
jmp 0x3a6b
movq -0x10(%rbp), %rdi
callq 0x3340
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x2590
xorb $-0x1, %al
movzbl %al, %edi
andl $0x1, %edi
movl $0x794, %esi            # imm = 0x794
callq 0x2360
callq 0x2050
movl $0x2, %ecx
cltd
idivl %ecx
movl %edx, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x24(%rbp), %edx
movl -0x28(%rbp), %ecx
movl -0x1c(%rbp), %r8d
callq 0x3a80
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
je 0x3a14
movl $0x0, 0x7722(%rip)      # 0xb12c
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3a6b
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x24(%rbp), %edx
cmpl $0x0, -0x28(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %ecx
movl -0x1c(%rbp), %r8d
callq 0x3a80
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
je 0x3a54
movl $0x0, 0x76e2(%rip)      # 0xb12c
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3a6b
movl 0x76d2(%rip), %eax      # 0xb12c
addl $0x1, %eax
movl %eax, 0x76c9(%rip)      # 0xb12c
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)