// File: biotomas[P]ipasir/app/icnf/icnf.c
// Function: main
int main (int argc, char ** argv) {
  int res = 0, i, ch, lit, max_var = 0, assumption;
  char *line = NULL, *line_content;
  size_t len = 0, parsed, solves = 0, parsed_assumptions = 0, core_size = 0;
  ssize_t read;
  char * sig;
  double pre_time, post_time;
  int * current_assumptions = NULL;

  for (i = 1; i < argc; i++) {
    if (!strcmp (argv[i], "-h")) usage ();
    else if (argv[i][0] == '-') die ("invalid '%s' (try '-h')", argv[i]);
    else if (name) die ("multiple files '%s' and '%s'", name, argv[i]);
    else name = argv[i];
  }

  solver = ipasir_init ();

  sig = strdup (ipasir_signature (solver));
  msg ("icnf generic IPASIR Solver");
  msg ("initialized '%s'", sig);

  if (name) {
    closefile = 2;
    if (hasuffix (name, ".bz2")) file = pipeit (name, "bzcat %s");
    else if (hasuffix (name, ".gz")) file = pipeit (name, "gunzip -c %s");
    else file = fopen (name, "r"), closefile = 1;
    if (!file) die ("can not read '%s'", name);
  } else name = "<stdin>", file = stdin;

  msg ("reading '%s'", name);

  while (NEXT () == 'c') {
    while (NEXT () != '\n')
      if (ch == EOF)
    perr ("unexpected end-of-file in comment");
  }
  if (ch != 'p') perr ("expected 'p' or 'c'");
  if (fscanf (file, " inccnf") != 0)
    perr ("invalid header");

  msg ("found 'p inccnf' header at line %d", lineno);
  lit = 0;

  while ((read = getline(&line, &len, file)) != -1) {
    lineno ++;
    /* skip line breaks */
    if( line[0] == '\n') continue;

    /* skip short lines */
    if( read < 1 ) die ("found an empty line in the file");

    /* skip comments */
    if( line[0] == 'c' ) continue;

    line_content = line;
    parsed = 0;
    assumption = 0;

    if( line[0] == 'a' ) {
      if(read < 2) die("expected assumption vector to solve in '%s' (line %d)", line, lineno);
      parsed = 2;
      line_content = &(line[parsed]);
      assumption = 1;
      parsed_assumptions = 0;
    }

    while ( (i = sscanf (line_content, "%d", &lit)) == 1) {

      /* track highest variable */
      if (lit < 0) max_var = max_var > -lit ? max_var : -lit;
      else max_var = max_var > lit ? max_var : lit;

      /* in case we're on the assumption line, assume the literals and solver */
      if (!assumption) {
        ipasir_add (solver, lit);
      }
      else if (lit)
      {
        ipasir_assume(solver, lit);
        /* track variables to be assumed */
        if (current_assumptions == NULL || parsed_assumptions >= max_var)
          current_assumptions = realloc(current_assumptions, sizeof(int) * (max_var > parsed_assumptions ? max_var : parsed_assumptions));
        current_assumptions[parsed_assumptions] = lit;
        parsed_assumptions ++;
      }

      /* stop at the end of the clause, do not read the rest of the line */
      if (!lit) break;
      while (parsed < read && line[parsed] != ' ') ++parsed;
      /* actually skip space */
       ++parsed;
      if (parsed >= read) break;
      line_content = &(line[parsed]);
    }

    if (i != 1) die ("expected literals or a clause delimiter on line %s (line %d), but did not find any\n", lineno);

    if(assumption) {
      core_size = 0;
      solves ++;
      msg ("solved assumptions %lu (%d assumptions) on line %d ...", solves, parsed_assumptions, lineno);
      pre_time = getime ();
      res = ipasir_solve(solver);
      post_time = getime ();

      /* print model, or unsat core */
      if (res == 10)
      {
        if (max_var) {
          fflush (stdout);
          printf ("s SATISFIABLE\n");
          fputc ('v', stdout);
          for (i = 1; i <= max_var; i++) {
          if (!(i % 8)) fputs ("\nv", stdout);
            printf (" %d", ipasir_val (solver, i));
          }
          fputc ('\n', stdout);
        }
        printf ("v 0\n");
      } else if (res == 20) {
        core_size = 0;
        fflush (stdout);
        printf ("s UNSATISFIABLE\n");
        fputc ('v', stdout);
        for( i=0; i < parsed_assumptions; ++i )
        {
          if (ipasir_failed(solver, current_assumptions[i] < 0 ? -current_assumptions[i] : current_assumptions[i]))
          {
            core_size ++;
            printf (" %d", current_assumptions[i]);
          }
        }
        fputc ('\n', stdout);
        printf ("v 0\n");
      }

      msg ("solved assumptions %lu with results %d and unsat core of %u in %.2f seconds", solves, res, core_size, post_time - pre_time);
    }
  }

  if (!feof (file)) perr ("end of file is not reached yet");
  if (current_assumptions) free(current_assumptions);
  if (closefile == 2) pclose (file);
  if (closefile == 1) fclose (file);

  /* cleanup */
  fflush (stdout);
  ipasir_release (solver);
  msg ("released '%s' after %.2f seconds", sig, getime ());
  msg ("exit %d", res);
  free (sig);
  return res;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movl $0x0, -0x24(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x88(%rbp)
movl $0x1, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x1435
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x18c70(%rip), %rsi     # 0x1a010
callq 0x1100
cmpl $0x0, %eax
jne 0x13b1
callq 0x2090
jmp 0x1425
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x13e1
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x18c3b(%rip), %rdi     # 0x1a013
movb $0x0, %al
callq 0x1be0
jmp 0x1423
cmpq $0x0, 0x1fd4f(%rip)     # 0x21138
je 0x140e
movq 0x1fd46(%rip), %rsi     # 0x21138
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
leaq 0x18c26(%rip), %rdi     # 0x1a02b
movb $0x0, %al
callq 0x1be0
jmp 0x1421
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x1fd17(%rip)     # 0x21138
jmp 0x1423
jmp 0x1425
jmp 0x1427
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1381
movb $0x0, %al
callq 0x20c0
movq %rax, 0x1fcfd(%rip)     # 0x21140
movq 0x1fcf6(%rip), %rdi     # 0x21140
movb $0x0, %al
callq 0x20b0
movq %rax, %rdi
callq 0x11f0
movq %rax, -0x70(%rbp)
leaq 0x18be4(%rip), %rdi     # 0x1a048
movb $0x0, %al
callq 0x1cc0
movq -0x70(%rbp), %rsi
leaq 0x18bed(%rip), %rdi     # 0x1a063
movb $0x0, %al
callq 0x1cc0
cmpq $0x0, 0x1fcb3(%rip)     # 0x21138
je 0x1544
movl $0x2, 0x1fcb3(%rip)     # 0x21148
movq 0x1fc9c(%rip), %rdi     # 0x21138
leaq 0x18bd1(%rip), %rsi     # 0x1a074
callq 0x1da0
cmpl $0x0, %eax
je 0x14c9
movq 0x1fc84(%rip), %rdi     # 0x21138
leaq 0x18bbe(%rip), %rsi     # 0x1a079
callq 0x1e40
movq %rax, 0x1fc89(%rip)     # 0x21150
jmp 0x1523
movq 0x1fc68(%rip), %rdi     # 0x21138
leaq 0x18bab(%rip), %rsi     # 0x1a082
callq 0x1da0
cmpl $0x0, %eax
je 0x14fd
movq 0x1fc50(%rip), %rdi     # 0x21138
leaq 0x18b97(%rip), %rsi     # 0x1a086
callq 0x1e40
movq %rax, 0x1fc55(%rip)     # 0x21150
jmp 0x1521
movq 0x1fc34(%rip), %rdi     # 0x21138
leaq 0x1b901(%rip), %rsi     # 0x1ce0c
callq 0x1190
movq %rax, 0x1fc39(%rip)     # 0x21150
movl $0x1, 0x1fc27(%rip)     # 0x21148
jmp 0x1523
cmpq $0x0, 0x1fc25(%rip)     # 0x21150
jne 0x1542
movq 0x1fc04(%rip), %rsi     # 0x21138
leaq 0x18b58(%rip), %rdi     # 0x1a093
movb $0x0, %al
callq 0x1be0
jmp 0x1563
leaq 0x18b5a(%rip), %rax     # 0x1a0a5
movq %rax, 0x1fbe6(%rip)     # 0x21138
movq 0x1fa7f(%rip), %rax     # 0x20fd8
movq (%rax), %rax
movq %rax, 0x1fbed(%rip)     # 0x21150
movq 0x1fbce(%rip), %rsi     # 0x21138
leaq 0x18b3c(%rip), %rdi     # 0x1a0ad
movb $0x0, %al
callq 0x1cc0
movq 0x1fbd1(%rip), %rdi     # 0x21150
leaq 0x1fb9a(%rip), %rsi     # 0x21120
callq 0x1ec0
movl %eax, -0x1c(%rbp)
cmpl $0x63, %eax
jne 0x15c8
jmp 0x1595
movq 0x1fbb4(%rip), %rdi     # 0x21150
leaq 0x1fb7d(%rip), %rsi     # 0x21120
callq 0x1ec0
movl %eax, -0x1c(%rbp)
cmpl $0xa, %eax
je 0x15c6
cmpl $-0x1, -0x1c(%rbp)
jne 0x15c4
leaq 0x18afd(%rip), %rdi     # 0x1a0ba
movb $0x0, %al
callq 0x1f00
jmp 0x1595
jmp 0x1578
cmpl $0x70, -0x1c(%rbp)
je 0x15dc
leaq 0x18b07(%rip), %rdi     # 0x1a0dc
movb $0x0, %al
callq 0x1f00
movq 0x1fb6d(%rip), %rdi     # 0x21150
leaq 0x18b06(%rip), %rsi     # 0x1a0f0
movb $0x0, %al
callq 0x1070
cmpl $0x0, %eax
je 0x1604
leaq 0x18afb(%rip), %rdi     # 0x1a0f8
movb $0x0, %al
callq 0x1f00
movl 0x1fb16(%rip), %esi     # 0x21120
leaq 0x18af6(%rip), %rdi     # 0x1a107
movb $0x0, %al
callq 0x1cc0
movl $0x0, -0x20(%rbp)
movq 0x1fb2a(%rip), %rdx     # 0x21150
leaq -0x30(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x11c0
movq %rax, -0x68(%rbp)
cmpq $-0x1, %rax
je 0x1b10
movl 0x1fad9(%rip), %eax     # 0x21120
addl $0x1, %eax
movl %eax, 0x1fad0(%rip)     # 0x21120
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
jne 0x165e
jmp 0x161f
cmpq $0x1, -0x68(%rbp)
jge 0x1673
leaq 0x18abe(%rip), %rdi     # 0x1a12a
movb $0x0, %al
callq 0x1be0
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x63, %eax
jne 0x1681
jmp 0x161f
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x48(%rbp)
movl $0x0, -0x28(%rbp)
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x61, %eax
jne 0x16e6
cmpq $0x2, -0x68(%rbp)
jge 0x16c3
movq -0x30(%rbp), %rsi
movl 0x1fa6b(%rip), %edx     # 0x21120
leaq 0x18a8e(%rip), %rdi     # 0x1a14a
movb $0x0, %al
callq 0x1be0
movq $0x2, -0x48(%rbp)
movq -0x30(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x1, -0x28(%rbp)
movq $0x0, -0x58(%rbp)
jmp 0x16e8
movq -0x38(%rbp), %rdi
leaq 0x18a34(%rip), %rsi     # 0x1a127
leaq -0x20(%rbp), %rdx
movb $0x0, %al
callq 0x1150
movl %eax, -0x18(%rbp)
cmpl $0x1, %eax
jne 0x1890
cmpl $0x0, -0x20(%rbp)
jge 0x173d
movl -0x24(%rbp), %eax
xorl %ecx, %ecx
subl -0x20(%rbp), %ecx
cmpl %ecx, %eax
jle 0x1727
movl -0x24(%rbp), %eax
movl %eax, -0x8c(%rbp)
jmp 0x1732
xorl %eax, %eax
subl -0x20(%rbp), %eax
movl %eax, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x1762
movl -0x24(%rbp), %eax
cmpl -0x20(%rbp), %eax
jle 0x1750
movl -0x24(%rbp), %eax
movl %eax, -0x90(%rbp)
jmp 0x1759
movl -0x20(%rbp), %eax
movl %eax, -0x90(%rbp)
movl -0x90(%rbp), %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x28(%rbp)
jne 0x177c
movq 0x1f9d1(%rip), %rdi     # 0x21140
movl -0x20(%rbp), %esi
callq 0x2160
jmp 0x1819
cmpl $0x0, -0x20(%rbp)
je 0x1817
movq 0x1f9b3(%rip), %rdi     # 0x21140
movl -0x20(%rbp), %esi
callq 0x2190
cmpq $0x0, -0x88(%rbp)
je 0x17ac
movq -0x58(%rbp), %rax
movslq -0x24(%rbp), %rcx
cmpq %rcx, %rax
jb 0x17fa
movq -0x88(%rbp), %rax
movq %rax, -0x98(%rbp)
movslq -0x24(%rbp), %rax
cmpq -0x58(%rbp), %rax
jbe 0x17d1
movslq -0x24(%rbp), %rax
movq %rax, -0xa0(%rbp)
jmp 0x17dc
movq -0x58(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rdi
movq -0xa0(%rbp), %rsi
shlq $0x2, %rsi
callq 0x1170
movq %rax, -0x88(%rbp)
movl -0x20(%rbp), %edx
movq -0x88(%rbp), %rax
movq -0x58(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x1819
cmpl $0x0, -0x20(%rbp)
jne 0x1821
jmp 0x1890
jmp 0x1823
movq -0x48(%rbp), %rcx
xorl %eax, %eax
cmpq -0x68(%rbp), %rcx
movb %al, -0xa1(%rbp)
jae 0x184d
movq -0x30(%rbp), %rax
movq -0x48(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
setne %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0x1859
jmp 0x1867
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x1823
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x68(%rbp), %rax
jb 0x187f
jmp 0x1890
movq -0x30(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x16e8
cmpl $0x1, -0x18(%rbp)
je 0x18aa
movl 0x1f884(%rip), %esi     # 0x21120
leaq 0x188dd(%rip), %rdi     # 0x1a180
movb $0x0, %al
callq 0x1be0
cmpl $0x0, -0x28(%rbp)
je 0x1b0b
movq $0x0, -0x60(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rsi
movq -0x58(%rbp), %rdx
movl 0x1f84a(%rip), %ecx     # 0x21120
leaq 0x188f7(%rip), %rdi     # 0x1a1d4
movb $0x0, %al
callq 0x1cc0
callq 0x1ff0
movsd %xmm0, -0x78(%rbp)
movq 0x1f84b(%rip), %rdi     # 0x21140
callq 0x21c0
movl %eax, -0x14(%rbp)
callq 0x1ff0
movsd %xmm0, -0x80(%rbp)
cmpl $0xa, -0x14(%rbp)
jne 0x19d2
cmpl $0x0, -0x24(%rbp)
je 0x19bf
movq 0x1f6ae(%rip), %rax     # 0x20fd0
movq (%rax), %rdi
callq 0x1140
leaq 0x188da(%rip), %rdi     # 0x1a20b
movb $0x0, %al
callq 0x10a0
movq 0x1f691(%rip), %rax     # 0x20fd0
movq (%rax), %rsi
movl $0x76, %edi
callq 0x10f0
movl $0x1, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x24(%rbp), %eax
jg 0x19ab
movl -0x18(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x1981
movq 0x1f65e(%rip), %rax     # 0x20fd0
movq (%rax), %rsi
leaq 0x1889e(%rip), %rdi     # 0x1a21a
callq 0x10d0
movq 0x1f7b8(%rip), %rdi     # 0x21140
movl -0x18(%rbp), %esi
callq 0x2210
movl %eax, %esi
leaq 0x1878d(%rip), %rdi     # 0x1a126
movb $0x0, %al
callq 0x10a0
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1953
movq 0x1f61e(%rip), %rax     # 0x20fd0
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10f0
leaq 0x18857(%rip), %rdi     # 0x1a21d
movb $0x0, %al
callq 0x10a0
jmp 0x1ae8
cmpl $0x14, -0x14(%rbp)
jne 0x1ae6
movq $0x0, -0x60(%rbp)
movq 0x1f5e5(%rip), %rax     # 0x20fd0
movq (%rax), %rdi
callq 0x1140
leaq 0x18828(%rip), %rdi     # 0x1a222
movb $0x0, %al
callq 0x10a0
movq 0x1f5c8(%rip), %rax     # 0x20fd0
movq (%rax), %rsi
movl $0x76, %edi
callq 0x10f0
movl $0x0, -0x18(%rbp)
movslq -0x18(%rbp), %rax
cmpq -0x58(%rbp), %rax
jae 0x1ac4
movq 0x1f70f(%rip), %rax     # 0x21140
movq %rax, -0xb0(%rbp)
movq -0x88(%rbp), %rax
movslq -0x18(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jge 0x1a61
movq -0x88(%rbp), %rcx
movslq -0x18(%rbp), %rdx
xorl %eax, %eax
subl (%rcx,%rdx,4), %eax
movl %eax, -0xb4(%rbp)
jmp 0x1a75
movq -0x88(%rbp), %rax
movslq -0x18(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0xb4(%rbp)
movq -0xb0(%rbp), %rdi
movl -0xb4(%rbp), %esi
callq 0x21e0
cmpl $0x0, %eax
je 0x1ab4
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x88(%rbp), %rax
movslq -0x18(%rbp), %rcx
movl (%rax,%rcx,4), %esi
leaq 0x18679(%rip), %rdi     # 0x1a126
movb $0x0, %al
callq 0x10a0
jmp 0x1ab6
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x1a1c
movq 0x1f505(%rip), %rax     # 0x20fd0
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10f0
leaq 0x1873e(%rip), %rdi     # 0x1a21d
movb $0x0, %al
callq 0x10a0
jmp 0x1ae8
movq -0x50(%rbp), %rsi
movl -0x14(%rbp), %edx
movq -0x60(%rbp), %rcx
movsd -0x80(%rbp), %xmm0
subsd -0x78(%rbp), %xmm0
leaq 0x1872f(%rip), %rdi     # 0x1a233
movb $0x1, %al
callq 0x1cc0
jmp 0x161f
movq 0x1f639(%rip), %rdi     # 0x21150
callq 0x1120
cmpl $0x0, %eax
jne 0x1b2f
leaq 0x18757(%rip), %rdi     # 0x1a27f
movb $0x0, %al
callq 0x1f00
cmpq $0x0, -0x88(%rbp)
je 0x1b45
movq -0x88(%rbp), %rdi
callq 0x1040
cmpl $0x2, 0x1f5fc(%rip)     # 0x21148
jne 0x1b5a
movq 0x1f5fb(%rip), %rdi     # 0x21150
callq 0x10b0
cmpl $0x1, 0x1f5e7(%rip)     # 0x21148
jne 0x1b6f
movq 0x1f5e6(%rip), %rdi     # 0x21150
callq 0x1080
movq 0x1f45a(%rip), %rax     # 0x20fd0
movq (%rax), %rdi
callq 0x1140
movq 0x1f5bb(%rip), %rdi     # 0x21140
callq 0x2130
movq -0x70(%rbp), %rax
movq %rax, -0xc0(%rbp)
callq 0x1ff0
movq -0xc0(%rbp), %rsi
leaq 0x186f6(%rip), %rdi     # 0x1a29e
movb $0x1, %al
callq 0x1cc0
movl -0x14(%rbp), %esi
leaq 0x18706(%rip), %rdi     # 0x1a2bf
movb $0x0, %al
callq 0x1cc0
movq -0x70(%rbp), %rdi
callq 0x1040
movl -0x14(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)