U
    b6h                     @   s   d dl mZmZmZmZ d dlmZ d dlmZ d dlm	Z	m
Z
 d dlZe
eZejZe ZG dd deZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZeeedZdd e D ZG dd deZdS )    )absolute_importdivisionprint_functionunicode_literals)array)combinations)DEBUG	getLoggerNc                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_ClauseListzEStorage for the CNF clauses, represented as a list of tuples of ints.c                 C   s   g | _ | j j| _| j j| _d S N)_clause_listappendextendself r   2lib/python3.8/site-packages/conda/common/_logic.py__init__   s    
z_ClauseList.__init__c                 C   s
   t | jS )z2
        Return number of stored clauses.
        lenr   r   r   r   r   get_clause_count   s    z_ClauseList.get_clause_countc                 C   s
   t | jS )z
        Get state information to be able to revert temporary additions of
        supplementary clauses.  _ClauseList: state is simply the number of clauses.
        r   r   r   r   r   
save_state#   s    z_ClauseList.save_statec                 C   s   |}g | j |d< dS )
        Restore state saved via `save_state`.
        Removes clauses that were added after the state has been saved.
        Nr   )r   saved_stateZlen_clausesr   r   r   restore_state*   s    z_ClauseList.restore_statec                 C   s   | j S )+Return clauses as a list of tuples of ints.r   r   r   r   r   as_list2   s    z_ClauseList.as_listc                 C   s,   t d}| jD ]}|| |d q|S )X
        Return clauses as a flat int array, each clause being terminated by 0.
        ir   )r   r   r   r   )r   Zclause_arraycr   r   r   as_array6   s
    

z_ClauseList.as_arrayN)
__name__
__module____qualname____doc__r   r   r   r   r   r!   r   r   r   r   r
      s   r
   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )_ClauseArrayzp
    Storage for the CNF clauses, represented as a flat int array.
    Each clause is terminated by int(0).
    c                 C   s"   t d| _| jj| _| jj| _d S )Nr   )r   _clause_arrayr   _array_appendr   _array_extendr   r   r   r   r   F   s    

z_ClauseArray.__init__c                 C   s   |D ]}|  | qd S r   )r   )r   Zclausesclauser   r   r   r   M   s    z_ClauseArray.extendc                 C   s   |  | | d d S )Nr   )r)   r(   )r   r*   r   r   r   r   Q   s    
z_ClauseArray.appendc                 C   s   | j dS )z
        Return number of stored clauses.
        This is an O(n) operation since we don't store the number of clauses
        explicitly due to performance reasons (Python interpreter overhead in
        self.append).
        r   )r'   countr   r   r   r   r   U   s    z_ClauseArray.get_clause_countc                 C   s
   t | jS )z
        Get state information to be able to revert temporary additions of
        supplementary clauses. _ClauseArray: state is the length of the int
        array, NOT number of clauses.
        )r   r'   r   r   r   r   r   ^   s    z_ClauseArray.save_statec                 C   s   |}t d| j|d< dS )r   r   N)r   r'   )r   r   Zlen_clause_arrayr   r   r   r   f   s    z_ClauseArray.restore_statec                 c   s:   g }| j D ]*}|dkr*t|V  |  q
|| q
dS )r   r   N)r'   tupleclearr   )r   r*   vr   r   r   r   n   s    


z_ClauseArray.as_listc                 C   s   | j S )r   )r'   r   r   r   r   r!   x   s    z_ClauseArray.as_arrayN)r"   r#   r$   r%   r   r   r   r   r   r   r   r!   r   r   r   r   r&   A   s   	
r&   c                   @   sX   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdS )
_SatSolverzX
    Simple wrapper to call a SAT solver given a _ClauseList/_ClauseArray instance.
    c                 K   s*   |pi | _ t | _| jj| _| jj| _d S r   )_run_kwargsr
   _clausesr   
add_clauser   add_clauses)r   
run_kwargsr   r   r   r      s    

z_SatSolver.__init__c                 C   s
   | j  S r   )r1   r   r   r   r   r   r      s    z_SatSolver.get_clause_countc                 C   s
   | j  S r   )r1   r   r   r   r   r   r      s    z_SatSolver.as_listc                 C   s
   | j  S r   )r1   r   r   r   r   r   r      s    z_SatSolver.save_statec                 C   s   | j |S r   )r1   r   )r   r   r   r   r   r      s    z_SatSolver.restore_statec                 K   s:   | j  }|| | j|f|}| |}| |}|S r   )r0   copyupdatesetupinvokeprocess_solution)r   mkwargsr4   solversat_solutionsolutionr   r   r   run   s    



z_SatSolver.runc                 K   s
   t  dS )z?Create a solver instance, add the clauses to it, and return it.NNotImplementedError)r   r:   r;   r   r   r   r7      s    z_SatSolver.setupc                 C   s
   t  dS )z@Start the actual SAT solving and return the calculated solution.Nr@   )r   r<   r   r   r   r8      s    z_SatSolver.invokec                 C   s
   t  dS )z
        Process the solution returned by self.invoke.
        Returns a list of satisfied variables or None if no solution is found.
        Nr@   r   r=   r   r   r   r9      s    z_SatSolver.process_solutionN)r"   r#   r$   r%   r   r   r   r   r   r?   r7   r8   r9   r   r   r   r   r/      s   r/   c                   @   s&   e Zd Zd	ddZdd Zdd ZdS )
_PycoSatSolverr   c                 K   s    ddl m} || j ||dS )Nr   )	itersolve)varsZ
prop_limit)pycosatrD   r1   r   )r   r:   limitr;   rD   r   r   r   r7      s    z_PycoSatSolver.setupc                 C   s,   zt |}W n tk
r$   d}Y nX ~|S )NUNSAT)nextStopIteration)r   Ziter_solr=   r   r   r   r8      s    
z_PycoSatSolver.invokec                 C   s   |dkrd S |S )N)rH   ZUNKNOWNr   rB   r   r   r   r9      s    z_PycoSatSolver.process_solutionN)r   r"   r#   r$   r7   r8   r9   r   r   r   r   rC      s   

rC   c                   @   s&   e Zd Zd	ddZdd Zdd ZdS )
_PyCryptoSatSolver   c                 K   s*   ddl m} ||d}|| j  |S )Nr   )Solver)threads)pycryptosatrN   r3   r1   r   )r   r:   rO   r;   rN   r<   r   r   r   r7      s    
z_PyCryptoSatSolver.setupc                 C   s   |  \}}|sd }|S r   )solve)r   r<   satr=   r   r   r   r8      s    z_PyCryptoSatSolver.invokec                 C   s   |sd S dd t |D }|S )Nc                 S   s   g | ]\}}|r|qS r   r   ).0r   br   r   r   
<listcomp>   s      z7_PyCryptoSatSolver.process_solution.<locals>.<listcomp>)	enumerate)r   r>   r   r   r   r9      s    z#_PyCryptoSatSolver.process_solutionN)rM   rK   r   r   r   r   rL      s   
rL   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )_PySatSolverc                 K   s&   ddl m} | }|| j  |S )Nr   )Glucose4)Zpysat.solversrX   Zappend_formular1   r   )r   r:   r;   rX   r<   r   r   r   r7      s    z_PySatSolver.setupc                 C   s"   |  sd }n| }|  |S r   )rQ   Z	get_modeldelete)r   r<   r=   r   r   r   r8      s
    z_PySatSolver.invokec                 C   s   |d krd }n|}|S r   r   )r   r=   r>   r   r   r   r9      s    z_PySatSolver.process_solutionNrK   r   r   r   r   rW      s   rW   )rF   rP   Zpysatc                 C   s   i | ]\}}||qS r   r   )rS   stringclsr   r   r   
<dictcomp>   s      r\   c                   @   s   e Zd Zdee fddZdd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zd8ddZd9ddZd:ddZd;ddZd<ddZd=d d!Zd"d# Zd$d% Zd>d&d'Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd?d2d3Zd@d4d5ZdAd6d7ZdS )BClausesr   c                 C   s\   d| _ || _zt| }W n" tk
r:   td|Y nX | | _| jj| _| jj| _d S )NFzUnknown SAT solver: {})	unsatr:   _sat_solver_str_to_clsKeyErrorrA   format_sat_solverr2   r3   )r   r:   Zsat_solver_strZsat_solver_clsr   r   r   r     s    
zClauses.__init__c                 C   s
   | j  S r   )rb   r   r   r   r   r   r     s    zClauses.get_clause_countc                 C   s
   | j  S r   )rb   r   r   r   r   r   r     s    zClauses.as_listc                 C   s   | j d }|| _ |S )NrM   )r:   )r   r:   r   r   r   new_var  s    
zClauses.new_varc                    sR   t |trN|   |  fdd|d D  |  fdd|d D   S |S )Nc                 3   s   | ]}  f| V  qd S r   r   rS   yxr   r   	<genexpr>   s     z!Clauses.assign.<locals>.<genexpr>r   c                 3   s   | ]} f| V  qd S r   r   rd   rf   r   r   rh   !  s     rM   )
isinstancer,   rc   r3   )r   valsr   rf   r   assign  s    
zClauses.assignc                 C   s   t dd |D rtS dd |D }t|}|dkr8tS |dkrH|d S tdd |D rtdd |D g td	d |D g fS | t| j||S d S )
Nc                 s   s   | ]}|t kV  qd S r   )FALSErS   r.   r   r   r   rh   &  s     z"Clauses.Combine.<locals>.<genexpr>c                 S   s   g | ]}|t kr|qS r   )TRUErm   r   r   r   rU   (  s      z#Clauses.Combine.<locals>.<listcomp>r   rM   c                 s   s   | ]}t |tV  qd S r   )ri   r,   rm   r   r   r   rh   .  s     c                 s   s   | ]}|d  V  qdS r   Nr   rm   r   r   r   rh   /  s     c                 s   s   | ]}|d  V  qdS )rM   Nr   rm   r   r   r   rh   /  s     )	anyrl   r   rn   allsumAllmaprk   )r   argspolaritynvr   r   r   Combine%  s    (zClauses.Combinec                 C   s   | j  }||d|i}t|tr@| |d  | |d  nD|tthkrd| |rX|n| f n | j | | j	p|tk|k| _	d S )Nrv   r   rM   )
rb   r   ri   r,   r3   rn   rl   r2   r   r^   )r   funcru   rv   r   rj   r   r   r   Eval3  s    

zClauses.Evalc                 G   s   | j ||dd d S )NFrv   rz   r   ry   ru   r   r   r   Prevent@  s    zClauses.Preventc                 G   s   | j ||dd d S )NTr{   r|   r}   r   r   r   RequireC  s    zClauses.RequireNFc                 C   s   | S r   r   )r   rg   rv   add_new_clausesr   r   r   NotF  s    zClauses.Notc                 C   s   |t ks|t krt S |tkr |S |tkr,|S ||kr8|S || krFt S ||k rX|| }}|r|  }|dkr| | |f| |fg |dkr| || | fg |S |dkr|f|fgng }|dkr| | fgng }||fS NTNFN)rl   rn   rc   r3   r   fgrv   r   rg   pvalnvalr   r   r   AndI  s,    

zClauses.Andc                 C   s   |t ks|t krt S |tkr |S |tkr,|S ||kr8|S || krFt S ||k rX|| }}|r|  }|dkr| | ||fg |dkr| || f|| fg |S |dkr||fgng }|dkr| f| fgng }||fS r   )rn   rl   rc   r3   r   r   r   r   Ore  s,    

z
Clauses.Orc                 C   s  |t kr|S |tkr$| j|||dS |t kr0|S |tkr>| S ||krJt S || krXtS ||k rj|| }}|r|  }|dkr| | ||f| | | fg |dkr| || |f||| fg |S |dkr||f| | fgng }|dkr| |f|| fgng }||fS Nr   r   r   )rl   rn   r   rc   r3   r   r   r   r   Xor}  s0    

" "zClauses.Xorc           	      C   s  |t kr|S |tkr|S |t kr2| j||||dS |tkrN| j| |||dS |tkrh| j||||dS |t kr| j|| ||dS ||kr| j||||dS || kr| j| |||dS ||kr| j||||dS || kr| j|| ||dS ||kr|S || kr | j||||dS ||k r<|||   }}}|r|  }|dkr~| | | |f| ||f| ||fg |dkr| || | f||| f|| | fg |S |dkr| |f||f||fgng }|dkr| | f|| f| | fgng }||fS r   )rn   rl   r   r   r   rc   r3   )	r   r    tr   rv   r   rg   r   r   r   r   r   ITE  sH    




*
,&.zClauses.ITEc                 C   s   t  }|D ]2}|tkrq
|tks*| |kr2t  S || q
t|}|dkrRtS |dkrltdd |D S |dkrdd |D ng }|dkrtd	d |D gng }||fS )
Nr   rM   c                 s   s   | ]
}|V  qd S r   r   rm   r   r   r   rh     s     zClauses.All.<locals>.<genexpr>r   c                 S   s   g | ]
}|fqS r   r   rm   r   r   r   rU     s     zClauses.All.<locals>.<listcomp>r   c                 s   s   | ]}| V  qd S r   r   rm   r   r   r   rh     s     )setrn   rl   addr   rI   r,   r   iterrv   rj   r.   rw   r   r   r   r   r   rs     s     zClauses.Allc                 C   s   t  }|D ]4}|tkrq
n|tks,| |kr4t  S || q
t|}|dkrTtS |dkrntdd |D S |dkrt|gng }|dkrdd |D ng }||fS )	Nr   rM   c                 s   s   | ]
}|V  qd S r   r   rm   r   r   r   rh     s     zClauses.Any.<locals>.<genexpr>r   r   c                 S   s   g | ]}| fqS r   r   rm   r   r   r   rU     s     zClauses.Any.<locals>.<listcomp>)r   rl   rn   r   r   rI   r,   r   r   r   r   Any  s    zClauses.Anyc                 C   s@   g }t t| j|dD ]\}}|| ||| q| ||S )N   )r   rt   r   r   r   rx   )r   rj   rv   Zcombosv1v2r   r   r   AtMostOne_NSQ  s    zClauses.AtMostOne_NSQc                 C   s*   t |}dgt| }| ||ddd|S )NrM   r   Tlistr   LinearBoundr   rj   rv   litscoeffsr   r   r   AtMostOne_BDD  s    zClauses.AtMostOne_BDDc                 C   s0   t |}| ||}| ||}| ||f|S r   )r   r   r   rx   )r   rj   rv   r   r   r   r   r   ExactlyOne_NSQ  s    zClauses.ExactlyOne_NSQc                 C   s*   t |}dgt| }| ||ddd|S )NrM   Tr   r   r   r   r   ExactlyOne_BDD  s    zClauses.ExactlyOne_BDDc                 C   s   g }d}t ||D ]X\}}|tkr,||7 }q|tks|dkr>q|dk r\||7 }| |  }}|||f qtt t| p~d\}}|||fS )Nr   )r   r   )ziprn   rl   r   r,   sorted)r   r   r   ZequationoffsetZcoeffZlitr   r   r   LB_Preprocess  s    zClauses.LB_Preprocessc                 C   s\  t dd |d | D }|d d|f}|g}	i }
|	j}|	j}|
j}| j}d}|	rT|	d \}}}|| }|| }|dkr||krt|
| < qN||ks|dk rt|
| < qN|| }|| }|d8 }||8 }||dk r|n|| |f}||}|d kr|| qN||dk r|| n||f}||}|d kr6|| qN|t||||dd|
| < qN|
| S )Nc                 s   s   | ]
}|V  qd S r   r   rS   r    r   r   r   rh     s     zClauses.BDD.<locals>.<genexpr>rM   r   Tr   )rr   r   popgetr   rn   rl   abs)r   r   r   ntermslohirv   totaltargetZ
call_stackZretZcall_stack_appendZcall_stack_popZret_getr   ZcsumZndxZlower_limitZupper_limitZLAZLCZhi_keyZthiZlo_keyZtlor   r   r   BDD  sF    


zClauses.BDDc                    s  |r&|  ||\}}}||8 } |8  t|}|rp|d  krpt fdd|D }	td|	|f  ||	8 }nd}	tdd |d | D }
|rt|dg}t |
g | krtS |dkr|dkrtnt}n| 	|||| |}|	r| 
dd ||d  D |}| ||f|}|S )	Nr   c                 3   s   | ]}| kV  qd S r   r   r   r   r   r   rh   A  s     z&Clauses.LinearBound.<locals>.<genexpr>z+Eliminating %d/%d terms for bound violationr   c                 s   s   | ]
}|V  qd S r   r   r   r   r   r   rh   G  s     c                 S   s   g | ]
}| qS r   r   )rS   ar   r   r   rU   R  s     z'Clauses.LinearBound.<locals>.<listcomp>)r   r   rr   logtracemaxminrl   rn   r   rs   rx   )r   r   r   r   r   Z
preprocessrv   r   r   Znpruner   resZpruner   r   r   r   :  s.    
zClauses.LinearBoundc                 C   s.   t trt d|   | jj||d}|S )Nz"Invoking SAT with clause count: %srG   )r   isEnabledForr   debugr   rb   r?   )r   r:   rG   r>   r   r   r   _run_satV  s    
zClauses._run_satc                 C   s   | j r
dS | jsg S | j }|rPdd }t||}|rP|d sFdS | | | j| j|d}|r||dksp|s|| j| |S )z
        Calculate a SAT solution for the current clause set.

        Returned is the list of those solutions.  When the clauses are
        unsatisfiable, an empty list is returned.

        Nc                 s   sB   dd }| D ]0}t ||}|s*|V   q>|d tkr|V  qd S )Nc                 s   s*   | D ] }|t krq|V  |tkr q&qd S r   )rl   rn   )ccr    r   r   r   preproc_k  s    z.Clauses.sat.<locals>.preproc.<locals>.preproc_r   )r,   rn   )Zeqsr   r   r   r   r   preprocj  s    zClauses.sat.<locals>.preprocr   r   )r^   r:   rb   r   r   r3   r   r   )r   Z
additionalZ	includeIfrG   r   r   r>   r   r   r   rR   \  s     

zClauses.satc              	      s<  |dkst || jk r(td |  }|dks6| jrbtd ||r\tdd |D d ndfS |sxtd |dfS | ||\}}}t|}d	d
 }dd }dd}	|dkrdndD ]v}
|
rt	d |}nt	d |}dd t
||D }|||  }| j}ttr|  }| j }|r<|
s<|d }	t	d|f  |	dkrf| d n|	|
rtfddt
||D }tfddt
||D }| | j| |r| | j| n| | j||d ttrt	d||  | f  |  }|dkrJd t	d|f  |krqn6k}|}|||  }t	d|f  |rq|| _| j |kr| j| d| _d}	qNtd|
rdnd f   dkr q4q|
r fddt
||D } fd d|D }|||}	 qtd!|||  q| fS )"z
        Minimize the objective function given by (coeff, integer) pairs in
        zip(coeffs, lits).
        The actual minimization is multiobjective: first, we minimize the
        largest active coefficient value, then we minimize the sum.
        Nz#Clauses added, recomputing solutionzConstraints are unsatisfiablec                 s   s   | ]}t |V  qd S r   )r   r   r   r   r   rh     s     z#Clauses.minimize.<locals>.<genexpr>rM   z!Empty objective, trivial solutionr   c                    s   t  fdd| D S )Nc                 3   s   | ]}  |d V  qdS ro   r   rS   sobjective_dictr   r   rh     s     z5Clauses.minimize.<locals>.peak_val.<locals>.<genexpr>)r   Zsolr   r   r   r   peak_val  s    z"Clauses.minimize.<locals>.peak_valc                    s   t  fdd| D S )Nc                 3   s   | ]}  |d V  qdS ro   r   r   r   r   r   rh     s     z4Clauses.minimize.<locals>.sum_val.<locals>.<genexpr>)rr   r   r   r   r   sum_val  s    z!Clauses.minimize.<locals>.sum_val)TF)FzBeginning peak minimizationzBeginning sum minimizationc                 S   s   i | ]\}}||qS r   r   rS   r    r   r   r   r   r\     s      z$Clauses.minimize.<locals>.<dictcomp>zInitial range (%d,%d)r   c                 3   s   | ]\}}| kr|V  qd S r   r   r   )midr   r   rh     s      c                 3   s.   | ]&\}} |  krkrn q|V  qd S r   r   r   )r   r   r   r   rh     s
      
  Fz+Bisection attempt: (%d,%d), (%d+%d) clausesz$Bisection failure, new range=(%d,%d)z$Bisection success, new range=(%d,%d)zFinal %s objective: %dpeakrr   c                    s   g | ]\}}| kr|qS r   r   r   bestvalr   r   rU     s      z$Clauses.minimize.<locals>.<listcomp>c                    s   g | ]}| kr|qS r   r   r   r   r   r   rU     s      zNew peak objective: %d)r   r:   r   r   rR   r^   rr   r   r   r   r   r   r   r   rb   r   r,   r~   r   r   r   r   )r   r   r   ZbestsolZtrymaxr   Zmaxvalr   r   Ztry0r   Zobjvalr   r   Zm_origZnzr   ZpreventZrequireZnewsolZdoner   )r   r   r   r   minimize  s    

"










zClauses.minimize)NF)F)F)F)F)N)N)r   )NFr   )NF)r"   r#   r$   _sat_solver_cls_to_strrC   r   r   r   rc   rk   rx   rz   r~   r   r   r   r   r   r   rs   r   r   r   r   r   r   r   r   r   rR   r   r   r   r   r   r]     s4   




)

2

'r]   )Z
__future__r   r   r   r   r   	itertoolsr   Zloggingr   r	   sysr"   r   maxsizern   rl   objectr
   r&   r/   rC   rL   rW   r_   itemsr   r]   r   r   r   r   <module>   s&   ->0