// File: /workspace/github_cpp_makefile_star2_O2/conp-solutions[P]cnfmiter/AtLeastTwoSolutions.cc
// Function: main
int main(int argc, char **argv)
{
    int opt;
    int tseitin = 0;
    int maxsat = 0;
    std::cerr << "c AtLeastTwoSolutions generates a CNF formula " << std::endl
              << "c which is satisfiable if the given input formula has at least 2 models" << std::endl
              << "c" << std::endl
              << "c OPTIONS" << std::endl
              << "c -t x ... only force differences among the variables 1 to x" << std::endl
              << "c -W   ... encode a MaxSat formula that tries to get two solutions with largest hamming distance" << std::endl
              << "c -w   ... same as -w, but use the pre 2020 MaxSat format" << std::endl
              << std::endl;

    // Retrieve the options:
    while ((opt = getopt(argc, argv, "t:wW")) != -1) { // for each option...
        switch (opt) {
        case 't':
            tseitin = atoi(optarg);
            std::cerr << "c set tseitin variable to " << tseitin << std::endl;
            break;
        case 'w':
            maxsat = 1;
            std::cerr << "c enable maxsat pre-2021 mode" << std::endl;
            break;
        case 'W':
            maxsat = 2;
            std::cerr << "c enable maxsat post-2020 mode" << std::endl;
            break;
        case '?': // unknown option...
            std::cerr << "c unknown option: '" << char(optopt) << "'!" << std::endl;
            exit(1);
            break;
        }
    }

    if (optind + 1 != argc) {
        std::cerr << "not enough parameters, abort!" << std::endl;
        return 1;
    }

    std::string fn1 = (argv[optind + 0]);
    gzFile in1 = gzopen(fn1.c_str(), "rb");

    if (!in1) {
        std::cerr << "failed to open first file, abort!" << std::endl;
        return 1;
    }
    if (tseitin < 0) {
        std::cerr << "tseitin variable negative, abort" << std::endl;
        return 1;
    }

    Formula f1;

    parse_DIMACS(in1, f1);
    gzclose(in1);

    std::cerr << "c Parsed formula with " << f1.nVars() << " vars and " << f1.clauses.size() << std::endl;

    Formula result;
    int input_vars = f1.nVars();
    int var_offset = input_vars;
    int output_vars = 2 * input_vars;
    while (output_vars > result.nVars()) result.newVar();
    std::vector<Lit> rewritten_clause;

    /* add formula 2 times, once with a full variable offset */
    /* duplicate this, to check whether a formuala has more models */
    for (const auto &clause : f1.clauses) {
        result.addClause_(clause);
        rewritten_clause.clear();
        for (int i = 0; i < clause.size(); ++i) {
            Lit l = clause[i];
            Var v = var(l);
            rewritten_clause.push_back(mkLit(v + var_offset, sign(l)));
        }
        result.addClause_(rewritten_clause);
    }

    /* encode variable differences for given number of variables */
    /* this grows quadratic in the number of models that should be checked for */
    Var max_v = tseitin == 0 ? input_vars : tseitin;
    int next_var = output_vars;
    std::vector<Lit> one_unequal_clause;
    std::cerr << "c encode variable equivalences for first " << max_v << " variables" << std::endl;
    for (Var v = 0; v < max_v; ++v) {
        Lit a = mkLit(v);
        Lit A = mkLit(v + var_offset);
        Lit next_lit = mkLit(next_var++);
        while (var(next_lit) >= result.nVars()) result.newVar();
        /* a <-> (a+offset) <-> next_lit */
        generate_equivalence(result, a, A, next_lit);
        one_unequal_clause.push_back(~next_lit);
    }

    /* enforce that at least one assignment has to be different */
    result.addClause_(one_unequal_clause);

    std::stringstream s;
    if (maxsat == 0) {
        s << "encode formula to check whether there are more than 1 solution for " << fn1;
        if (tseitin != 0) s << " with tseitin base variable " << tseitin;
        /* one of the common literal pair should have unequal truth values has to be */
        print_formula(result, s.str());
    } else {
        s << "encode formula to find two solutions with the highest hamming distance for a given formula, at least 1, for " << fn1;
        if (tseitin != 0) s << " with tseitin base variable " << tseitin;
        /* there is a cost setting variables to equal truth values, hence, pay cost for each unit */
        print_maxsat_formula(result, one_unequal_clause, s.str(), maxsat == 1);
    }


    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x100138, %rsp         # imm = 0x100138
movq %rsi, %rbx
movl %edi, %r15d
movq 0x45e2(%rip), %r12      # 0x6ff0
leaq 0x1673(%rip), %rsi      # 0x4088
movq %r12, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
leaq 0x168b(%rip), %rsi      # 0x40b7
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
leaq 0x16bc(%rip), %rsi      # 0x40ff
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
leaq 0x16a7(%rip), %rsi      # 0x4101
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
leaq 0x169a(%rip), %rsi      # 0x410b
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
leaq 0x16c0(%rip), %rsi      # 0x4148
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
leaq 0x170a(%rip), %rsi      # 0x41a9
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
movl $0x0, -0x30(%rbp)
leaq 0x1726(%rip), %r14      # 0x41e3
leaq 0x175d(%rip), %r13      # 0x4221
movl $0x0, -0x2c(%rbp)
movq %rax, %rdi
callq 0x20a0
movl %r15d, %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x2040
cmpl $-0x1, %eax
je 0x2b65
cmpl $0x57, %eax
je 0x2b38
cmpl $0x74, %eax
je 0x2aff
cmpl $0x77, %eax
je 0x2b4b
cmpl $0x3f, %eax
jne 0x2ad3
jmp 0x317f
movq 0x44a2(%rip), %rax      # 0x6fa8
movq (%rax), %rdi
callq 0x21e0
movl %eax, %r13d
movq %r12, %rdi
leaq 0x16cd(%rip), %rsi      # 0x41e8
callq 0x2160
movq %rax, %rdi
movl %r13d, -0x2c(%rbp)
movl %r13d, %esi
leaq 0x16f0(%rip), %r13      # 0x4221
callq 0x2240
jmp 0x2acb
movq %r12, %rdi
movq %r13, %rsi
callq 0x2160
pushq $0x2
popq %rcx
movl %ecx, -0x30(%rbp)
jmp 0x2acb
movq %r12, %rdi
leaq 0x16ae(%rip), %rsi      # 0x4203
callq 0x2160
pushq $0x1
popq %rcx
movl %ecx, -0x30(%rbp)
jmp 0x2acb
movq 0x4464(%rip), %rax      # 0x6fd0
movslq (%rax), %rax
leal 0x1(%rax), %ecx
cmpl %r15d, %ecx
jne 0x2d41
movq (%rbx,%rax,8), %rsi
leaq -0x110(%rbp), %rbx
leaq -0x100160(%rbp), %rdx
movq %rbx, %rdi
callq 0x2070
movq (%rbx), %rdi
leaq 0x16d6(%rip), %rsi      # 0x4275
callq 0x21c0
testq %rax, %rax
je 0x304a
cmpl $0x0, -0x2c(%rbp)
js 0x3053
leaq -0x88(%rbp), %rcx
andl $0x0, -0x8(%rcx)
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
andq $0x0, 0x10(%rcx)
leaq -0x100160(%rbp), %rdi
movq %rax, -0xd8(%rbp)
movq %rax, %rsi
callq 0x38be
leaq -0x70(%rbp), %r12
andq $0x0, 0x10(%r12)
xorps %xmm0, %xmm0
movaps %xmm0, (%r12)
movq $0x0, -0x40(%rbp)
leaq -0x100160(%rbp), %r13
leaq 0x1820(%rip), %r14      # 0x442b
leaq -0xb0(%rbp), %rbx
movl $0x0, -0x44(%rbp)
movl $0x0, -0x38(%rbp)
movq %r13, %rdi
callq 0x32a4
movslq -0x158(%rbp), %rax
cmpl -0x154(%rbp), %eax
jge 0x2d64
movzbl -0x100158(%rbp,%rax), %eax
cmpl $0x70, %eax
je 0x2c74
cmpl $0x63, %eax
jne 0x2cad
movslq -0x158(%rbp), %rax
cmpl -0x154(%rbp), %eax
jge 0x2c20
movb -0x100158(%rbp,%rax), %r15b
movq %r13, %rdi
callq 0x3910
cmpb $0xa, %r15b
jne 0x2c4d
jmp 0x2c20
xorl %r15d, %r15d
movsbl (%r15,%r14), %eax
cmpq $0x5, %r15
je 0x2d00
movslq -0x158(%rbp), %rcx
pushq $-0x1
popq %rdx
cmpl -0x154(%rbp), %ecx
jge 0x2c9c
movzbl -0x100158(%rbp,%rcx), %edx
cmpl %eax, %edx
jne 0x2d00
incq %r15
movq %r13, %rdi
callq 0x3910
jmp 0x2c77
movq -0x70(%rbp), %rax
cmpq %rax, -0x68(%rbp)
je 0x2cbb
movq %rax, -0x68(%rbp)
movq %r13, %rdi
callq 0x32e3
testl %eax, %eax
je 0x2d23
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
movl -0x90(%rbp), %edx
cmpl %edx, %ecx
jle 0x2ce2
incl %edx
movl %edx, -0x90(%rbp)
jmp 0x2cd4
xorl %edx, %edx
testl %eax, %eax
setle %dl
leal -0x2(%rdx,%rcx,2), %eax
movl %eax, -0xb0(%rbp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3920
jmp 0x2cbb
testb %al, %al
jne 0x31c3
movq %r13, %rdi
callq 0x32e3
movl %eax, -0x38(%rbp)
movq %r13, %rdi
callq 0x32e3
movl %eax, -0x44(%rbp)
jmp 0x2c20
movq -0x40(%rbp), %rax
incl %eax
movq %rax, -0x40(%rbp)
leaq -0x88(%rbp), %rdi
movq %r12, %rsi
callq 0x3514
jmp 0x2c20
movq 0x42a8(%rip), %rdi      # 0x6ff0
leaq 0x1508(%rip), %rsi      # 0x4257
callq 0x2160
movq %rax, %rdi
callq 0x20a0
pushq $0x1
popq %rbx
jmp 0x3129
movl -0x38(%rbp), %eax
cmpl -0x90(%rbp), %eax
jne 0x313d
movl -0x44(%rbp), %eax
cmpl %eax, -0x40(%rbp)
jne 0x315e
leaq -0x70(%rbp), %rdi
callq 0x380c
movq -0xd8(%rbp), %rdi
callq 0x2230
movq 0x4255(%rip), %rdi      # 0x6ff0
leaq 0x1519(%rip), %rsi      # 0x42bb
callq 0x2160
movl -0x90(%rbp), %esi
movq %rax, %rdi
callq 0x2240
leaq 0x1516(%rip), %rsi      # 0x42d2
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
movq -0x80(%rbp), %rax
subq -0x88(%rbp), %rax
pushq $0x18
popq %rcx
cqto
idivq %rcx
movq %rax, %rsi
callq 0x20e0
movq %rax, %rdi
callq 0x20a0
leaq -0x68(%rbp), %r15
andl $0x0, -0x8(%r15)
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
andq $0x0, 0x10(%r15)
movl -0x90(%rbp), %eax
movq %rax, -0x38(%rbp)
leal (%rax,%rax), %r12d
xorl %eax, %eax
testl %r12d, %r12d
cmovgl %r12d, %eax
negl %eax
pushq $0x1
popq %rcx
leal (%rax,%rcx), %edx
cmpl $0x1, %edx
je 0x2e2a
movl %ecx, -0x70(%rbp)
incl %ecx
jmp 0x2e1b
xorps %xmm0, %xmm0
leaq -0xb0(%rbp), %rbx
andq $0x0, 0x10(%rbx)
movaps %xmm0, (%rbx)
movq -0x88(%rbp), %r14
movq -0x80(%rbp), %rax
movq %rax, -0x40(%rbp)
leaq -0x100160(%rbp), %r13
cmpq -0x40(%rbp), %r14
je 0x2ec2
movq %r15, %rdi
movq %r14, %rsi
callq 0x3514
movq -0xb0(%rbp), %rax
cmpq %rax, -0xa8(%rbp)
je 0x2e7a
movq %rax, -0xa8(%rbp)
xorl %r15d, %r15d
movq (%r14), %rax
movq 0x8(%r14), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %r15, %rcx
jbe 0x2ead
movl (%rax,%r15,4), %eax
addl %r12d, %eax
movl %eax, -0x100160(%rbp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x3920
incq %r15
jmp 0x2e7d
leaq -0x68(%rbp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3514
addq $0x18, %r14
jmp 0x2e52
movl -0x2c(%rbp), %ebx
testl %ebx, %ebx
cmovel -0x38(%rbp), %ebx
xorps %xmm0, %xmm0
movaps %xmm0, -0xd0(%rbp)
andq $0x0, -0xc0(%rbp)
movq 0x410c(%rip), %rdi      # 0x6ff0
leaq 0x13f2(%rip), %rsi      # 0x42dd
callq 0x2160
movq %rax, %rdi
movl %ebx, %esi
callq 0x2240
leaq 0x1406(%rip), %rsi      # 0x4307
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
xorl %r14d, %r14d
testl %ebx, %ebx
cmovlel %r14d, %ebx
leaq -0x100160(%rbp), %r15
cmpl %ebx, %r14d
je 0x2f79
movq -0x38(%rbp), %rax
leal (%r14,%rax), %edx
leal 0x1(%r12), %r13d
movl -0x70(%rbp), %eax
cmpl %eax, %r12d
jl 0x2f42
incl %eax
movl %eax, -0x70(%rbp)
jmp 0x2f36
leal (%r14,%r14), %esi
addl %edx, %edx
addl %r12d, %r12d
leaq -0x70(%rbp), %rdi
movl %r12d, %ecx
callq 0x23cc
orl $0x1, %r12d
movl %r12d, -0x100160(%rbp)
leaq -0xd0(%rbp), %rdi
movq %r15, %rsi
callq 0x3920
incl %r14d
movl %r13d, %r12d
jmp 0x2f21
leaq -0xd0(%rbp), %rsi
leaq -0x68(%rbp), %r14
movq %r14, %rdi
callq 0x3514
leaq -0x100160(%rbp), %rdi
callq 0x2100
leaq -0x100150(%rbp), %rbx
cmpl $0x0, -0x30(%rbp)
je 0x3076
leaq 0x13c3(%rip), %rsi      # 0x4373
movq %rbx, %rdi
callq 0x2160
leaq -0x110(%rbp), %rsi
movq %rax, %rdi
callq 0x2140
cmpl $0x0, -0x2c(%rbp)
je 0x2fe7
leaq 0x1382(%rip), %rsi      # 0x4356
movq %rbx, %rdi
callq 0x2160
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x2240
leaq -0xf0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x34bc
leaq -0x100148(%rbp), %rsi
leaq -0x130(%rbp), %rdi
callq 0x21f0
xorl %ecx, %ecx
cmpl $0x1, -0x30(%rbp)
sete %cl
leaq -0x70(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
leaq -0x130(%rbp), %rdx
callq 0x2661
leaq -0x130(%rbp), %rdi
callq 0x2090
leaq -0xf0(%rbp), %rdi
callq 0x380c
jmp 0x30e3
leaq 0x1227(%rip), %rsi      # 0x4278
jmp 0x305a
leaq 0x1240(%rip), %rsi      # 0x429a
movq 0x3f8f(%rip), %rdi      # 0x6ff0
callq 0x2160
movq %rax, %rdi
callq 0x20a0
pushq $0x1
popq %rbx
jmp 0x311d
leaq 0x1295(%rip), %rsi      # 0x4312
movq %rbx, %rdi
callq 0x2160
leaq -0x110(%rbp), %rsi
movq %rax, %rdi
callq 0x2140
cmpl $0x0, -0x2c(%rbp)
je 0x30b4
leaq 0x12b5(%rip), %rsi      # 0x4356
movq %rbx, %rdi
callq 0x2160
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x2240
leaq -0x100148(%rbp), %rsi
leaq -0x150(%rbp), %rdi
callq 0x21f0
leaq -0x70(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x2502
leaq -0x150(%rbp), %rdi
callq 0x2090
leaq -0x100160(%rbp), %rdi
callq 0x2110
leaq -0xd0(%rbp), %rdi
callq 0x380c
leaq -0xb0(%rbp), %rdi
callq 0x380c
movq %r14, %rdi
callq 0x3792
leaq -0x88(%rbp), %rdi
callq 0x3792
xorl %ebx, %ebx
leaq -0x110(%rbp), %rdi
callq 0x2090
movl %ebx, %eax
addq $0x100138, %rsp         # imm = 0x100138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x3e84(%rip), %rax      # 0x6fc8
movq (%rax), %rcx
leaq 0x1305(%rip), %rdi      # 0x4453
pushq $0x3e
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x2d73
movq 0x3e63(%rip), %rax      # 0x6fc8
movq (%rax), %rcx
leaq 0x1323(%rip), %rdi      # 0x4492
pushq $0x3c
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x2d7f
movq 0x3e6a(%rip), %rdi      # 0x6ff0
leaq 0x10b3(%rip), %rsi      # 0x4240
callq 0x2160
movq 0x3e1f(%rip), %rcx      # 0x6fb8
movsbl (%rcx), %esi
movq %rax, %rdi
callq 0x2180
leaq 0x10a9(%rip), %rsi      # 0x4254
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20a0
pushq $0x1
popq %rdi
callq 0x2190
movslq -0x158(%rbp), %rax
cmpl -0x154(%rbp), %eax
jge 0x31dc
movzbl -0x100158(%rbp,%rax), %esi
jmp 0x31df
pushq $-0x1
popq %rsi
leaq 0x124b(%rip), %rdi      # 0x4431
xorl %eax, %eax
callq 0x2030
pushq $0x3
jmp 0x31bd
movq %rax, %rbx
leaq -0x150(%rbp), %rdi
callq 0x2090
jmp 0x3229
movq %rax, %rbx
leaq -0x130(%rbp), %rdi
callq 0x2090
jmp 0x3216
movq %rax, %rbx
leaq -0xf0(%rbp), %rdi
callq 0x380c
jmp 0x3229
jmp 0x3245
movq %rax, %rbx
leaq -0x100160(%rbp), %rdi
callq 0x2110
jmp 0x3248
jmp 0x3245
movq %rax, %rbx
jmp 0x3290
movq %rax, %rbx
jmp 0x3284
jmp 0x3245
movq %rax, %rbx
leaq -0xd0(%rbp), %rdi
callq 0x380c
jmp 0x326f
jmp 0x326c
jmp 0x325e
jmp 0x325e
jmp 0x325e
movq %rax, %rbx
leaq -0x70(%rbp), %rdi
callq 0x380c
jmp 0x3284
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x380c
leaq -0x68(%rbp), %rdi
callq 0x3792
leaq -0x88(%rbp), %rdi
callq 0x3792
leaq -0x110(%rbp), %rdi
callq 0x2090
movq %rbx, %rdi
callq 0x2250