
    *-h>                     j    S SK 7  S SK7  S SK7  SSKJr  S SK Jr  SS jr " S S5      rS	 r/ 4S
 jr	g)   )*    )Fraction)_get_ctxNc                 F    [        U [        5      (       a  U $ [        X5      $ N)
isinstanceNumeral)numctxs     B/home/james-whalen/.local/lib/python3.13/site-packages/z3/z3num.py_to_numeralr      s    #w
s      c                   0   \ rS rSrSrS1S jrS rS rS rS r	S	 r
S
 rS rS rS2S jrS2S jrS2S jrS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r S  r!S! r"S" r#S# r$S$ r%S% r&S& r'S' r(S( r)S) r*S* r+S+ r,S, r-S- r.S. r/S/ r0S0r1g)3r
      aP  
A Z3 numeral can be used to perform computations over arbitrary
precision integers, rationals and real algebraic numbers.
It also automatically converts python numeric values.

>>> Numeral(2)
2
>>> Numeral("3/2") + 1
5/2
>>> Numeral(Sqrt(2))
1.4142135623?
>>> Numeral(Sqrt(2)) + 2
3.4142135623?
>>> Numeral(Sqrt(2)) + Numeral(Sqrt(3))
3.1462643699?

Z3 numerals can be used to perform computations with
values in a Z3 model.

>>> s = Solver()
>>> x = Real('x')
>>> s.add(x*x == 2)
>>> s.add(x > 0)
>>> s.check()
sat
>>> m = s.model()
>>> m[x]
1.4142135623?
>>> m[x] + 1
1.4142135623? + 1

The previous result is a Z3 expression.

>>> (m[x] + 1).sexpr()
'(+ (root-obj (+ (^ x 2) (- 2)) 2) 1.0)'

>>> Numeral(m[x]) + 1
2.4142135623?
>>> Numeral(m[x]).is_pos()
True
>>> Numeral(m[x])**2
2

We can also isolate the roots of polynomials.

>>> x0, x1, x2 = RealVarVector(3)
>>> r0 = isolate_roots(x0**5 - x0 - 1)
>>> r0
[1.1673039782?]

In the following example, we are isolating the roots
of a univariate polynomial (on x1) obtained after substituting
x0 -> r0[0]

>>> r1 = isolate_roots(x1**2 - x0 + 1, [ r0[0] ])
>>> r1
[-0.4090280898?, 0.4090280898?]

Similarly, in the next example we isolate the roots of
a univariate polynomial (on x2) obtained after substituting
x0 -> r0[0] and x1 -> r1[0]

>>> isolate_roots(x1*x2 + x0, [ r0[0], r1[0] ])
[2.8538479564?]

Nc                 |   [        U[        5      (       a  Xl        [        U5      U l        O[        U[
        5      (       d  [        U[        5      (       a#  UR                  U l        UR                  U l        Op[        U[        5      (       a.  [        U5      nUR                  U l        UR                  U l        O-[        X5      nUR                  U l        UR                  U l        [        U R                  5       U R                  5       5        [        U R                  5       U R                  5      (       d   eg r   )r	   Astastr   r   	RatNumRefAlgebraicNumRefArithRefsimplifyRealVal
Z3_inc_refctx_refas_astZ3_algebraic_is_value)selfr   r   rvs        r   __init__Numeral.__init__[   s    c3H}DHY'':c?+K+KwwDHwwDHX&&AuuDHuuDH!AuuDHuuDH4<<>4;;=1$T\\^TXX>>>>r   c                 T    [        U R                  5       U R                  5       5        g r   )
Z3_dec_refr   r   r   s    r   __del__Numeral.__del__m   s    4<<>4;;=1r   c                 V    U R                  5       =(       a    U R                  5       S:H  $ )zReturn True if the numeral is integer.

>>> Numeral(2).is_integer()
True
>>> (Numeral(Sqrt(2)) * Numeral(Sqrt(2))).is_integer()
True
>>> Numeral(Sqrt(2)).is_integer()
False
>>> Numeral("2/3").is_integer()
False
r   )is_rationaldenominatorr%   s    r   
is_integerNumeral.is_integerp   s&     !=d&6&6&8A&==r   c                 `    [        U R                  5       U R                  5       5      [        :H  $ )zReturn True if the numeral is rational.

>>> Numeral(2).is_rational()
True
>>> Numeral("2/3").is_rational()
True
>>> Numeral(Sqrt(2)).is_rational()
False

)Z3_get_ast_kindr   r   Z3_NUMERAL_ASTr%   s    r   r)   Numeral.is_rational~   s"     t||~t{{}=OOr   c                     U R                  5       (       d   e[        [        U R                  5       U R	                  5       5      U R
                  5      $ )zRReturn the denominator if `self` is rational.

>>> Numeral("2/3").denominator()
3
)r)   r
   Z3_get_denominatorr   r   r   r%   s    r   r*   Numeral.denominator   s>     !!"!)$,,.$++-H$((SSr   c                     U R                  5       (       d   e[        [        U R                  5       U R	                  5       5      U R
                  5      $ )zNReturn the numerator if `self` is rational.

>>> Numeral("2/3").numerator()
2
)r)   r
   Z3_get_numeratorr   r   r   r%   s    r   	numeratorNumeral.numerator   s>     !!"!'FQQr   c                 ,    U R                  5       (       + $ )zReturn True if the numeral is irrational.

>>> Numeral(2).is_irrational()
False
>>> Numeral("2/3").is_irrational()
False
>>> Numeral(Sqrt(2)).is_irrational()
True
)r)   r%   s    r   is_irrationalNumeral.is_irrational   s     ##%%%r   c                 0   U R                  5       (       d   e[        R                  R                  S:  a1  [	        [        U R                  5       U R                  5       5      5      $ [        [        U R                  5       U R                  5       5      5      $ )zAReturn a numeral (that is an integer) as a Python long.

           )	r+   sysversion_infomajorintZ3_get_numeral_stringr   r   longr%   s    r   as_longNumeral.as_long   si       ! !!Q&,T\\^T[[]KLL-dllndkkmLMMr   c                     U R                  5       (       d   e[        U R                  5       R                  5       U R	                  5       R                  5       5      $ )zlReturn a numeral (that is a rational) as a Python Fraction.
>>> Numeral("1/5").as_fraction()
Fraction(1, 5)
)r)   r   r6   rC   r*   r%   s    r   as_fractionNumeral.as_fraction   sH    
 !!"!(002D4D4D4F4N4N4PQQr   c                 $    U R                  U5      $ )a@  Return a numeral that approximates the numeral `self`.
The result `r` is such that |r - self| <= 1/10^precision

If `self` is rational, then the result is `self`.

>>> x = Numeral(2).root(2)
>>> x.approx(20)
6838717160008073720548335/4835703278458516698824704
>>> x.approx(5)
2965821/2097152
>>> Numeral(2).approx(10)
2
)upperr   	precisions     r   approxNumeral.approx   s     zz)$$r   c                     U R                  5       (       a  U $ [        [        U R                  5       U R	                  5       U5      U R
                  5      $ )a?  Return a upper bound that approximates the numeral `self`.
The result `r` is such that r - self <= 1/10^precision

If `self` is rational, then the result is `self`.

>>> x = Numeral(2).root(2)
>>> x.upper(20)
6838717160008073720548335/4835703278458516698824704
>>> x.upper(5)
2965821/2097152
>>> Numeral(2).upper(10)
2
)r)   r
   Z3_get_algebraic_number_upperr   r   r   rJ   s     r   rI   Numeral.upper   sC     K8Xabdhdldlmmr   c                     U R                  5       (       a  U $ [        [        U R                  5       U R	                  5       U5      U R
                  5      $ )a&  Return a lower bound that approximates the numeral `self`.
The result `r` is such that self - r <= 1/10^precision

If `self` is rational, then the result is `self`.

>>> x = Numeral(2).root(2)
>>> x.lower(20)
1709679290002018430137083/1208925819614629174706176
>>> Numeral("2/3").lower(10)
2/3
)r)   r
   Z3_get_algebraic_number_lowerr   r   r   rJ   s     r   lowerNumeral.lower   sC     K8Xabdhdldlmmr   c                 J    [        U R                  5       U R                  5      $ )zkReturn the sign of the numeral.

>>> Numeral(2).sign()
1
>>> Numeral(-3).sign()
-1
>>> Numeral(0).sign()
0
)Z3_algebraic_signr   r   r%   s    r   signNumeral.sign   s     !::r   c                 J    [        U R                  5       U R                  5      $ )zReturn True if the numeral is positive.

>>> Numeral(2).is_pos()
True
>>> Numeral(-3).is_pos()
False
>>> Numeral(0).is_pos()
False
)Z3_algebraic_is_posr   r   r%   s    r   is_posNumeral.is_pos        #4<<>488<<r   c                 J    [        U R                  5       U R                  5      $ )zReturn True if the numeral is negative.

>>> Numeral(2).is_neg()
False
>>> Numeral(-3).is_neg()
True
>>> Numeral(0).is_neg()
False
)Z3_algebraic_is_negr   r   r%   s    r   is_negNumeral.is_neg  r]   r   c                 J    [        U R                  5       U R                  5      $ )zReturn True if the numeral is zero.

>>> Numeral(2).is_zero()
False
>>> Numeral(-3).is_zero()
False
>>> Numeral(0).is_zero()
True
>>> sqrt2 = Numeral(2).root(2)
>>> sqrt2.is_zero()
False
>>> (sqrt2 - sqrt2).is_zero()
True
)Z3_algebraic_is_zeror   r   r%   s    r   is_zeroNumeral.is_zero  s     $DLLNDHH==r   c           
          [        [        U R                  5       U R                  [	        XR
                  5      R                  5      U R
                  5      $ )zrReturn the numeral `self + other`.

>>> Numeral(2) + 3
5
>>> Numeral(2) + Numeral(4)
6
>>> Numeral("2/3") + 1
5/3
r
   Z3_algebraic_addr   r   r   r   r   others     r   __add__Numeral.__add__$  s=     '+eU]U]B^BbBbceiememnnr   c           
          [        [        U R                  5       U R                  [	        XR
                  5      R                  5      U R
                  5      $ )z9Return the numeral `other + self`.

>>> 3 + Numeral(2)
5
rg   ri   s     r   __radd__Numeral.__radd__0  =     '+eU]U]B^BbBbceiememnnr   c           
          [        [        U R                  5       U R                  [	        XR
                  5      R                  5      U R
                  5      $ )z:Return the numeral `self - other`.

>>> Numeral(2) - 3
-1
)r
   Z3_algebraic_subr   r   r   r   ri   s     r   __sub__Numeral.__sub__8  rp   r   c           	          [        [        U R                  5       [        XR                  5      R
                  U R
                  5      U R                  5      $ )z9Return the numeral `other - self`.

>>> 3 - Numeral(2)
1
)r
   rr   r   r   r   r   ri   s     r   __rsub__Numeral.__rsub__@  s>     'E888T8X8XZ^ZbZbceiememnnr   c           
          [        [        U R                  5       U R                  [	        XR
                  5      R                  5      U R
                  5      $ )z8Return the numeral `self * other`.
>>> Numeral(2) * 3
6
r
   Z3_algebraic_mulr   r   r   r   ri   s     r   __mul__Numeral.__mul__H  =    
 '+eU]U]B^BbBbceiememnnr   c           
          [        [        U R                  5       U R                  [	        XR
                  5      R                  5      U R
                  5      $ )z7Return the numeral `other * mul`.
>>> 3 * Numeral(2)
6
ry   ri   s     r   __rmul__Numeral.__rmul__O  r}   r   c           
          [        [        U R                  5       U R                  [	        XR
                  5      R                  5      U R
                  5      $ )zReturn the numeral `self / other`.
>>> Numeral(2) / 3
2/3
>>> Numeral(2).root(2) / 3
0.4714045207?
>>> Numeral(Sqrt(2)) / Numeral(Sqrt(3))
0.8164965809?
)r
   Z3_algebraic_divr   r   r   r   ri   s     r   __div__Numeral.__div__V  s=     '+eU]U]B^BbBbceiememnnr   c                 $    U R                  U5      $ r   )r   ri   s     r   __truediv__Numeral.__truediv__a  s    ||E""r   c           	          [        [        U R                  5       [        XR                  5      R
                  U R
                  5      U R                  5      $ )zcReturn the numeral `other / self`.
>>> 3 / Numeral(2)
3/2
>>> 3 / Numeral(2).root(2)
2.1213203435?
)r
   r   r   r   r   r   ri   s     r   __rdiv__Numeral.__rdiv__d  s>     'E888T8X8XZ^ZbZbceiememnnr   c                 $    U R                  U5      $ r   )r   ri   s     r   __rtruediv__Numeral.__rtruediv__m  s    }}U##r   c                 t    [        [        U R                  5       U R                  U5      U R                  5      $ )zReturn the numeral `self^(1/k)`.

>>> sqrt2 = Numeral(2).root(2)
>>> sqrt2
1.4142135623?
>>> sqrt2 * sqrt2
2
>>> sqrt2 * 2 + 1
3.8284271247?
>>> (sqrt2 * 2 + 1).sexpr()
'(root-obj (+ (^ x 2) (* (- 2) x) (- 7)) 2)'
)r
   Z3_algebraic_rootr   r   r   r   ks     r   rootNumeral.rootp  s)     (1EtxxPPr   c                 t    [        [        U R                  5       U R                  U5      U R                  5      $ )zjReturn the numeral `self^k`.

>>> sqrt3 = Numeral(3).root(2)
>>> sqrt3
1.7320508075?
>>> sqrt3.power(2)
3
)r
   Z3_algebraic_powerr   r   r   r   s     r   powerNumeral.power  s)     )$,,.$((AFQQr   c                 $    U R                  U5      $ )zdReturn the numeral `self^k`.

>>> sqrt3 = Numeral(3).root(2)
>>> sqrt3
1.7320508075?
>>> sqrt3**2
3
)r   r   s     r   __pow__Numeral.__pow__  s     zz!}r   c                     [        U R                  5       U R                  [        XR                  5      R                  5      $ )zReturn True if `self < other`.

>>> Numeral(Sqrt(2)) < 2
True
>>> Numeral(Sqrt(3)) < Numeral(Sqrt(2))
False
>>> Numeral(Sqrt(2)) < Numeral(Sqrt(2))
False
)Z3_algebraic_ltr   r   r   r   ri   s     r   __lt__Numeral.__lt__  ,     t||~txxUHH9U9Y9YZZr   c                 
    X:  $ )z?Return True if `other < self`.

>>> 2 < Numeral(Sqrt(2))
False
 ri   s     r   __rlt__Numeral.__rlt__       |r   c                     [        U R                  5       U R                  [        XR                  5      R                  5      $ )zReturn True if `self > other`.

>>> Numeral(Sqrt(2)) > 2
False
>>> Numeral(Sqrt(3)) > Numeral(Sqrt(2))
True
>>> Numeral(Sqrt(2)) > Numeral(Sqrt(2))
False
)Z3_algebraic_gtr   r   r   r   ri   s     r   __gt__Numeral.__gt__  r   r   c                 
    X:  $ )z>Return True if `other > self`.

>>> 2 > Numeral(Sqrt(2))
True
r   ri   s     r   __rgt__Numeral.__rgt__  r   r   c                     [        U R                  5       U R                  [        XR                  5      R                  5      $ )zReturn True if `self <= other`.

>>> Numeral(Sqrt(2)) <= 2
True
>>> Numeral(Sqrt(3)) <= Numeral(Sqrt(2))
False
>>> Numeral(Sqrt(2)) <= Numeral(Sqrt(2))
True
)Z3_algebraic_ler   r   r   r   ri   s     r   __le__Numeral.__le__  r   r   c                 
    X:  $ )zAReturn True if `other <= self`.

>>> 2 <= Numeral(Sqrt(2))
False
r   ri   s     r   __rle__Numeral.__rle__       }r   c                     [        U R                  5       U R                  [        XR                  5      R                  5      $ )zReturn True if `self >= other`.

>>> Numeral(Sqrt(2)) >= 2
False
>>> Numeral(Sqrt(3)) >= Numeral(Sqrt(2))
True
>>> Numeral(Sqrt(2)) >= Numeral(Sqrt(2))
True
)Z3_algebraic_ger   r   r   r   ri   s     r   __ge__Numeral.__ge__  r   r   c                 
    X:*  $ )z@Return True if `other >= self`.

>>> 2 >= Numeral(Sqrt(2))
True
r   ri   s     r   __rge__Numeral.__rge__  r   r   c                     [        U R                  5       U R                  [        XR                  5      R                  5      $ )zReturn True if `self == other`.

>>> Numeral(Sqrt(2)) == 2
False
>>> Numeral(Sqrt(3)) == Numeral(Sqrt(2))
False
>>> Numeral(Sqrt(2)) == Numeral(Sqrt(2))
True
)Z3_algebraic_eqr   r   r   r   ri   s     r   __eq__Numeral.__eq__  r   r   c                     [        U R                  5       U R                  [        XR                  5      R                  5      $ )zReturn True if `self != other`.

>>> Numeral(Sqrt(2)) != 2
True
>>> Numeral(Sqrt(3)) != Numeral(Sqrt(2))
True
>>> Numeral(Sqrt(2)) != Numeral(Sqrt(2))
False
)Z3_algebraic_neqr   r   r   r   ri   s     r   __ne__Numeral.__ne__  s,      +eXX:V:Z:Z[[r   c                     [        U R                  5       U R                  5      (       a)  [        [	        U R                  U R
                  5      5      $ [        [        U R                  U R
                  5      5      $ r   )Z3_is_numeral_astr   r   strr   r   r   r%   s    r   __str__Numeral.__str__  sM    T\\^TXX66y488455txx:;;r   c                 "    U R                  5       $ r   )r   r%   s    r   __repr__Numeral.__repr__  s    ||~r   c                 R    [        U R                  5       U R                  5       5      $ r   )Z3_ast_to_stringr   r   r%   s    r   sexprNumeral.sexpr  s    >>r   c                     U R                   $ r   )r   r%   s    r   r   Numeral.as_ast	  s    xxr   c                 6    U R                   R                  5       $ r   )r   refr%   s    r   r   Numeral.ctx_ref  s    xx||~r   )r   r   r   )
   )2__name__
__module____qualname____firstlineno____doc__r!   r&   r+   r)   r*   r6   r9   rC   rF   rL   rI   rS   rW   r[   r`   rd   rk   rn   rs   rv   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __static_attributes__r   r   r   r
   r
      s    AF?$2>PTR
&NR% n&n"
;
=
=>"
oooooo	o#o$Q	R	
[
[
[
[
[
\<?r   r
   c                     [        U5      n[        U-  " 5       n[        U5       H  nX   R                  X4'   M     [	        U R                  5       U R                  5       X#5      $ )a@  
Evaluate the sign of the polynomial `p` at `vs`.  `p` is a Z3
Expression containing arithmetic operators: +, -, *, ^k where k is
an integer; and free variables x that is_var(x) is True. Moreover,
all variables must be real.

The result is 1 if the polynomial is positive at the given point,
-1 if negative, and 0 if zero.

>>> x0, x1, x2 = RealVarVector(3)
>>> eval_sign_at(x0**2 + x1*x2 + 1, (Numeral(0), Numeral(1), Numeral(2)))
1
>>> eval_sign_at(x0**2 - 2, [ Numeral(Sqrt(2)) ])
0
>>> eval_sign_at((x0 + x1)*(x0 + x2), (Numeral(0), Numeral(Sqrt(2)), Numeral(Sqrt(3))))
1
)lenr   ranger   Z3_algebraic_evalr   r   )pvsr   _vsis        r   eval_sign_atr     sN    $ b'C9-C3Z QYY[!((*c??r   c                 4   [        U5      n[        U-  " 5       n[        U5       H  nX   R                  X4'   M     [	        [        U R                  5       U R                  5       X#5      U R                  5      nU Vs/ s H  n[        U5      PM     sn$ s  snf )aG  
Given a multivariate polynomial p(x_0, ..., x_{n-1}, x_n), returns the
roots of the univariate polynomial p(vs[0], ..., vs[len(vs)-1], x_n).

Remarks:
* p is a Z3 expression that contains only arithmetic terms and free variables.
* forall i in [0, n) vs is a numeral.

The result is a list of numerals

>>> x0 = RealVar(0)
>>> isolate_roots(x0**5 - x0 - 1)
[1.1673039782?]
>>> x1 = RealVar(1)
>>> isolate_roots(x0**2 - x1**4 - 1, [ Numeral(Sqrt(3)) ])
[-1.1892071150?, 1.1892071150?]
>>> x2 = RealVar(2)
>>> isolate_roots(x2**2 + x0 - x1, [ Numeral(Sqrt(3)), Numeral(Sqrt(2)) ])
[]
)
r   r   r   r   	AstVectorZ3_algebraic_rootsr   r   r   r
   )r   r   r   r   r   _rootsr   s          r   isolate_rootsr   )  su    * b'C9-C3Z )!))+qxxz3LaeeTF &'1GAJ'''s   =Br   )
z3z3core	z3printer	fractionsr   r   r   r
   r   r   r   r   r   <module>r      s8        !v vr@2  (r   