// File: kc885[P]SAT-Solver-with-CDCL/cdcl.cpp
// Function: ck_cdcl_solver::Solver::unitPropagate(std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int>>&, int)
bool unitPropagate(std::unordered_set<int> &implied, int level){
            //visited array
            std::vector<int> visited(clauses.size(),0);
            
            std::unordered_set<int> intermediate;
            

            //unit propagation
            
            int new_imply_flag;
            do{
                new_imply_flag = 0;
                for (int i =0; i < (int)clauses.size(); i++){
                    if(visited[i] == 0){
                        
                        visited[i] = 1;
                        
                        //analyze this clause
                        int val = 0;
                        int undef_num = 0;
                        int target_var;
                        
                        for(auto iter = clauses[i].begin(); iter != clauses[i].end(); iter++){
                            if(val_decisionLevel[std::abs(*iter)] == 0){
                                undef_num++;
                                target_var = *iter;
                                if(undef_num > 1)
                                    break;
                            }
                            else if(val_decisionLevel[std::abs(*iter)] * (*iter) > 0){
                                val = 1;
                                break;
                            }
                        }
                        
                        if(val == 0 ){
                            //conflict
                            if(undef_num == 0){
                               
                                //learn a new clause
                                std::unordered_set<int> learnt_level;
                                std::unordered_set<int> learnt;
                                
                                for(auto iter = intermediate.begin(); iter!= intermediate.end();iter++){
                                    if(intermediate.count(-(*iter)) == 0){
                                        varToClause[*iter].push_back(clauses.size());
                                        learnt.insert(*iter);
                                    }
                                }

 
                                clauses.push_back(learnt);
                                
                                for(auto iter = implied.begin(); iter != implied.end(); iter++)
                                    val_decisionLevel[*iter] = 0;
                                return false;
                            }
                            //imply a new variable
                            else if(undef_num == 1){
                                new_imply_flag = 1;
                                implied.insert(std::abs(target_var));
                                
                                
                                val_decisionLevel[std::abs(target_var)] = (((target_var) > 0) - ((target_var) < 0))*level;
                                
                                //get variables which help to imply this variable(inclusing itself)
                                for(auto iter = clauses[i].begin(); iter != clauses[i].end(); iter++){
                                    intermediate.insert(*iter);
                                }
                                
                                for(auto iter = varToClause[target_var].begin();iter != varToClause[target_var].end(); iter++)
                                    visited[*iter] = 0;
                                for(auto iter = varToClause[-target_var].begin();iter != varToClause[-target_var].end(); iter++)
                                    visited[*iter] = 0;
                                break;        
                            }
                        }
                          
                    }  
                }

            }while(new_imply_flag == 1);
            return true;
        }

// Assembly:
subq $0x298, %rsp            # imm = 0x298
movq %rdi, 0x288(%rsp)
movq %rsi, 0x280(%rsp)
movl %edx, 0x27c(%rsp)
movq 0x288(%rsp), %rdi
movq %rdi, 0x90(%rsp)
addq $0x38, %rdi
callq 0x8b00
movq %rax, 0x98(%rsp)
movl $0x0, 0x25c(%rsp)
leaq 0x25b(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0xbe00
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rcx
leaq 0x260(%rsp), %rdi
leaq 0x25c(%rsp), %rdx
callq 0xbe10
jmp 0xb0e6
leaq 0x25b(%rsp), %rdi
callq 0xbe90
leaq 0x210(%rsp), %rdi
callq 0x38f0
movl $0x0, 0x20c(%rsp)
movl $0x0, 0x208(%rsp)
movq 0x90(%rsp), %rdi
movl 0x208(%rsp), %eax
movl %eax, 0x8c(%rsp)
addq $0x38, %rdi
callq 0x8b00
movq %rax, %rcx
movl 0x8c(%rsp), %eax
cmpl %ecx, %eax
jge 0xb8f1
movslq 0x208(%rsp), %rsi
leaq 0x260(%rsp), %rdi
callq 0xb970
cmpl $0x0, (%rax)
jne 0xb8d9
movslq 0x208(%rsp), %rsi
leaq 0x260(%rsp), %rdi
callq 0xb970
movq 0x90(%rsp), %rdi
movl $0x1, (%rax)
movl $0x0, 0x204(%rsp)
movl $0x0, 0x200(%rsp)
addq $0x38, %rdi
movslq 0x208(%rsp), %rsi
callq 0xbea0
movq %rax, %rdi
callq 0x3980
movq %rax, 0x1f0(%rsp)
movq 0x90(%rsp), %rdi
addq $0x38, %rdi
movslq 0x208(%rsp), %rsi
callq 0xbea0
movq %rax, %rdi
callq 0x39d0
movq %rax, 0x1e8(%rsp)
leaq 0x1f0(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
callq 0x39b0
testb $0x1, %al
jne 0xb206
jmp 0xb326
movq 0x90(%rsp), %rax
addq $0x50, %rax
movq %rax, 0x80(%rsp)
leaq 0x1f0(%rsp), %rdi
callq 0x3a30
movq 0x80(%rsp), %rdi
movl (%rax), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rsi
callq 0xb970
cmpl $0x0, (%rax)
jne 0xb2a3
movl 0x200(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x200(%rsp)
leaq 0x1f0(%rsp), %rdi
callq 0x3a30
movl (%rax), %eax
movl %eax, 0x1fc(%rsp)
cmpl $0x1, 0x200(%rsp)
jle 0xb2a1
jmp 0xb326
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x250(%rsp)
movl %eax, 0x24c(%rsp)
leaq 0x25b(%rsp), %rdi
callq 0xbe90
jmp 0xb959
jmp 0xb308
movq 0x90(%rsp), %rax
addq $0x50, %rax
movq %rax, 0x70(%rsp)
leaq 0x1f0(%rsp), %rdi
callq 0x3a30
movq 0x70(%rsp), %rdi
movl (%rax), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rsi
callq 0xb970
movl (%rax), %eax
movl %eax, 0x7c(%rsp)
leaq 0x1f0(%rsp), %rdi
callq 0x3a30
movq %rax, %rcx
movl 0x7c(%rsp), %eax
imull (%rcx), %eax
cmpl $0x0, %eax
jle 0xb306
movl $0x1, 0x204(%rsp)
jmp 0xb326
jmp 0xb308
jmp 0xb30a
leaq 0x1f0(%rsp), %rdi
xorl %esi, %esi
callq 0x3ac0
movq %rax, 0x1e0(%rsp)
jmp 0xb1bf
cmpl $0x0, 0x204(%rsp)
jne 0xb8d7
cmpl $0x0, 0x200(%rsp)
jne 0xb5a6
leaq 0x1a8(%rsp), %rdi
callq 0x38f0
leaq 0x170(%rsp), %rdi
callq 0x38f0
leaq 0x210(%rsp), %rdi
callq 0x3980
movq %rax, 0x168(%rsp)
leaq 0x210(%rsp), %rdi
callq 0x39d0
movq %rax, 0x160(%rsp)
leaq 0x168(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x39b0
testb $0x1, %al
jne 0xb3a4
jmp 0xb4ca
leaq 0x168(%rsp), %rdi
callq 0x3a30
movl (%rax), %eax
negl %eax
movl %eax, 0x15c(%rsp)
leaq 0x210(%rsp), %rdi
leaq 0x15c(%rsp), %rsi
callq 0x3900
movq %rax, 0x68(%rsp)
jmp 0xb3d8
movq 0x68(%rsp), %rax
cmpq $0x0, %rax
jne 0xb4ac
leaq 0x168(%rsp), %rdi
callq 0x3a30
movq 0x90(%rsp), %rdi
movq %rax, %rsi
callq 0x3a00
movq %rax, 0x60(%rsp)
jmp 0xb40b
movq 0x90(%rsp), %rdi
addq $0x38, %rdi
callq 0x8b00
movq 0x60(%rsp), %rdi
movl %eax, 0x158(%rsp)
leaq 0x158(%rsp), %rsi
callq 0x3550
jmp 0xb437
leaq 0x168(%rsp), %rdi
callq 0x3a30
movq %rax, %rsi
leaq 0x170(%rsp), %rdi
callq 0x3930
movb %dl, 0x57(%rsp)
movq %rax, 0x58(%rsp)
jmp 0xb45f
movb 0x57(%rsp), %al
movq 0x58(%rsp), %rcx
movq %rcx, 0x148(%rsp)
movb %al, 0x150(%rsp)
jmp 0xb4ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x250(%rsp)
movl %eax, 0x24c(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x3b60
leaq 0x1a8(%rsp), %rdi
callq 0x3b60
jmp 0xb93f
jmp 0xb4ae
leaq 0x168(%rsp), %rdi
xorl %esi, %esi
callq 0x3ac0
movq %rax, 0x140(%rsp)
jmp 0xb371
movq 0x90(%rsp), %rdi
addq $0x38, %rdi
leaq 0x170(%rsp), %rsi
callq 0x3af0
jmp 0xb4e5
movq 0x280(%rsp), %rdi
callq 0x3980
movq %rax, 0x138(%rsp)
movq 0x280(%rsp), %rdi
callq 0x39d0
movq %rax, 0x130(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x39b0
testb $0x1, %al
jne 0xb52a
jmp 0xb574
movq 0x90(%rsp), %rax
addq $0x50, %rax
movq %rax, 0x48(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x3a30
movq 0x48(%rsp), %rdi
movslq (%rax), %rsi
callq 0xb970
movl $0x0, (%rax)
leaq 0x138(%rsp), %rdi
xorl %esi, %esi
callq 0x3ac0
movq %rax, 0x128(%rsp)
jmp 0xb4fa
movb $0x0, 0x297(%rsp)
movl $0x1, 0x124(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x3b60
leaq 0x1a8(%rsp), %rdi
callq 0x3b60
jmp 0xb914
cmpl $0x1, 0x200(%rsp)
jne 0xb8d3
movl $0x1, 0x20c(%rsp)
movq 0x280(%rsp), %rdi
movl 0x1fc(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, 0x120(%rsp)
leaq 0x120(%rsp), %rsi
callq 0xbec0
movb %dl, 0x3f(%rsp)
movq %rax, 0x40(%rsp)
jmp 0xb5f4
movq 0x90(%rsp), %rdi
movb 0x3f(%rsp), %al
movq 0x40(%rsp), %rcx
movq %rcx, 0x110(%rsp)
movb %al, 0x118(%rsp)
cmpl $0x0, 0x1fc(%rsp)
setg %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, 0x1fc(%rsp)
setl %cl
andb $0x1, %cl
movzbl %cl, %ecx
subl %ecx, %eax
imull 0x27c(%rsp), %eax
movl %eax, 0x38(%rsp)
addq $0x50, %rdi
movl 0x1fc(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rsi
callq 0xb970
movl 0x38(%rsp), %ecx
movq 0x90(%rsp), %rdi
movl %ecx, (%rax)
addq $0x38, %rdi
movslq 0x208(%rsp), %rsi
callq 0xbea0
movq %rax, %rdi
callq 0x3980
movq %rax, 0x108(%rsp)
movq 0x90(%rsp), %rdi
addq $0x38, %rdi
movslq 0x208(%rsp), %rsi
callq 0xbea0
movq %rax, %rdi
callq 0x39d0
movq %rax, 0x100(%rsp)
leaq 0x108(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x39b0
testb $0x1, %al
jne 0xb6d0
jmp 0xb745
leaq 0x108(%rsp), %rdi
callq 0x3a30
movq %rax, %rsi
leaq 0x210(%rsp), %rdi
callq 0x3930
movb %dl, 0x2f(%rsp)
movq %rax, 0x30(%rsp)
jmp 0xb6f8
movb 0x2f(%rsp), %al
movq 0x30(%rsp), %rcx
movq %rcx, 0xf0(%rsp)
movb %al, 0xf8(%rsp)
leaq 0x108(%rsp), %rdi
xorl %esi, %esi
callq 0x3ac0
movq %rax, 0xe8(%rsp)
jmp 0xb68c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x250(%rsp)
movl %eax, 0x24c(%rsp)
jmp 0xb93f
movq 0x90(%rsp), %rdi
leaq 0x1fc(%rsp), %rsi
callq 0x3a00
movq %rax, 0x20(%rsp)
jmp 0xb761
movq 0x20(%rsp), %rdi
callq 0x40b0
movq %rax, 0xe0(%rsp)
movq 0x90(%rsp), %rdi
leaq 0x1fc(%rsp), %rsi
callq 0x3a00
movq %rax, 0x18(%rsp)
jmp 0xb78f
movq 0x18(%rsp), %rdi
callq 0x3ef0
movq %rax, 0xd8(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0xbf10
testb $0x1, %al
jne 0xb7bc
jmp 0xb7fb
leaq 0xe0(%rsp), %rdi
callq 0x45c0
movslq (%rax), %rsi
leaq 0x260(%rsp), %rdi
callq 0xb970
movl $0x0, (%rax)
leaq 0xe0(%rsp), %rdi
xorl %esi, %esi
callq 0xbf50
movq %rax, 0xd0(%rsp)
jmp 0xb773
movq 0x90(%rsp), %rdi
movl 0x1fc(%rsp), %eax
negl %eax
movl %eax, 0xc4(%rsp)
leaq 0xc4(%rsp), %rsi
callq 0x3580
movq %rax, 0x10(%rsp)
jmp 0xb827
movq 0x10(%rsp), %rdi
callq 0x40b0
movq %rax, 0xc8(%rsp)
movq 0x90(%rsp), %rdi
movl 0x1fc(%rsp), %eax
negl %eax
movl %eax, 0xb4(%rsp)
leaq 0xb4(%rsp), %rsi
callq 0x3580
movq %rax, 0x8(%rsp)
jmp 0xb865
movq 0x8(%rsp), %rdi
callq 0x3ef0
movq %rax, 0xb8(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0xbf10
testb $0x1, %al
jne 0xb892
jmp 0xb8d1
leaq 0xc8(%rsp), %rdi
callq 0x45c0
movslq (%rax), %rsi
leaq 0x260(%rsp), %rdi
callq 0xb970
movl $0x0, (%rax)
leaq 0xc8(%rsp), %rdi
xorl %esi, %esi
callq 0xbf50
movq %rax, 0xa8(%rsp)
jmp 0xb839
jmp 0xb8f1
jmp 0xb8d5
jmp 0xb8d7
jmp 0xb8d9
jmp 0xb8db
movl 0x208(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x208(%rsp)
jmp 0xb116
jmp 0xb8f3
cmpl $0x1, 0x20c(%rsp)
je 0xb100
movb $0x1, 0x297(%rsp)
movl $0x1, 0x124(%rsp)
leaq 0x210(%rsp), %rdi
callq 0x3b60
leaq 0x260(%rsp), %rdi
callq 0x3870
movb 0x297(%rsp), %al
andb $0x1, %al
addq $0x298, %rsp            # imm = 0x298
retq
leaq 0x210(%rsp), %rdi
callq 0x3b60
leaq 0x260(%rsp), %rdi
callq 0x3870
movq 0x250(%rsp), %rdi
callq 0x22d0
nopw %cs:(%rax,%rax)