mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	Fix some PEP-8 violations in Python code (#5295)
* reformat python code using autopep8 * manually wrap some too long lines and adjust some checks * run autopep8 in aggressive mode * run autopep8 in very aggressive mode * manually reformat z3types.py * unify: use double quotes * use sys.version_info instead of sys.version * drop accidentally commited src/util/z3_version.h
This commit is contained in:
		
							parent
							
								
									f1545b04d2
								
							
						
					
					
						commit
						3d8865d925
					
				
					 7 changed files with 1669 additions and 910 deletions
				
			
		
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
############################################
 | 
					############################################
 | 
				
			||||||
# Copyright (c) 2012 Microsoft Corporation
 | 
					# Copyright (c) 2012 Microsoft Corporation
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# Z3 Python interface for Z3 numerals
 | 
					# Z3 Python interface for Z3 numerals
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Author: Leonardo de Moura (leonardo)
 | 
					# Author: Leonardo de Moura (leonardo)
 | 
				
			||||||
| 
						 | 
					@ -12,18 +12,20 @@ from fractions import Fraction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .z3 import _get_ctx
 | 
					from .z3 import _get_ctx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _to_numeral(num, ctx=None):
 | 
					def _to_numeral(num, ctx=None):
 | 
				
			||||||
    if isinstance(num, Numeral):
 | 
					    if isinstance(num, Numeral):
 | 
				
			||||||
        return num
 | 
					        return num
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return Numeral(num, ctx)
 | 
					        return Numeral(num, ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Numeral:
 | 
					class Numeral:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    A Z3 numeral can be used to perform computations over arbitrary
 | 
					    A Z3 numeral can be used to perform computations over arbitrary
 | 
				
			||||||
    precision integers, rationals and real algebraic numbers.
 | 
					    precision integers, rationals and real algebraic numbers.
 | 
				
			||||||
    It also automatically converts python numeric values.
 | 
					    It also automatically converts python numeric values.
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> Numeral(2)
 | 
					    >>> Numeral(2)
 | 
				
			||||||
    2
 | 
					    2
 | 
				
			||||||
    >>> Numeral("3/2") + 1
 | 
					    >>> Numeral("3/2") + 1
 | 
				
			||||||
| 
						 | 
					@ -35,9 +37,9 @@ class Numeral:
 | 
				
			||||||
    >>> Numeral(Sqrt(2)) + Numeral(Sqrt(3))
 | 
					    >>> Numeral(Sqrt(2)) + Numeral(Sqrt(3))
 | 
				
			||||||
    3.1462643699?
 | 
					    3.1462643699?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Z3 numerals can be used to perform computations with 
 | 
					    Z3 numerals can be used to perform computations with
 | 
				
			||||||
    values in a Z3 model.
 | 
					    values in a Z3 model.
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> s = Solver()
 | 
					    >>> s = Solver()
 | 
				
			||||||
    >>> x = Real('x')
 | 
					    >>> x = Real('x')
 | 
				
			||||||
    >>> s.add(x*x == 2)
 | 
					    >>> s.add(x*x == 2)
 | 
				
			||||||
| 
						 | 
					@ -49,34 +51,34 @@ class Numeral:
 | 
				
			||||||
    1.4142135623?
 | 
					    1.4142135623?
 | 
				
			||||||
    >>> m[x] + 1
 | 
					    >>> m[x] + 1
 | 
				
			||||||
    1.4142135623? + 1
 | 
					    1.4142135623? + 1
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    The previous result is a Z3 expression.
 | 
					    The previous result is a Z3 expression.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> (m[x] + 1).sexpr()
 | 
					    >>> (m[x] + 1).sexpr()
 | 
				
			||||||
    '(+ (root-obj (+ (^ x 2) (- 2)) 2) 1.0)'
 | 
					    '(+ (root-obj (+ (^ x 2) (- 2)) 2) 1.0)'
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> Numeral(m[x]) + 1
 | 
					    >>> Numeral(m[x]) + 1
 | 
				
			||||||
    2.4142135623?
 | 
					    2.4142135623?
 | 
				
			||||||
    >>> Numeral(m[x]).is_pos()
 | 
					    >>> Numeral(m[x]).is_pos()
 | 
				
			||||||
    True
 | 
					    True
 | 
				
			||||||
    >>> Numeral(m[x])**2
 | 
					    >>> Numeral(m[x])**2
 | 
				
			||||||
    2
 | 
					    2
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    We can also isolate the roots of polynomials.
 | 
					    We can also isolate the roots of polynomials.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> x0, x1, x2 = RealVarVector(3)
 | 
					    >>> x0, x1, x2 = RealVarVector(3)
 | 
				
			||||||
    >>> r0 = isolate_roots(x0**5 - x0 - 1)
 | 
					    >>> r0 = isolate_roots(x0**5 - x0 - 1)
 | 
				
			||||||
    >>> r0
 | 
					    >>> r0
 | 
				
			||||||
    [1.1673039782?]
 | 
					    [1.1673039782?]
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    In the following example, we are isolating the roots
 | 
					    In the following example, we are isolating the roots
 | 
				
			||||||
    of a univariate polynomial (on x1) obtained after substituting
 | 
					    of a univariate polynomial (on x1) obtained after substituting
 | 
				
			||||||
    x0 -> r0[0]
 | 
					    x0 -> r0[0]
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> r1 = isolate_roots(x1**2 - x0 + 1, [ r0[0] ])
 | 
					    >>> r1 = isolate_roots(x1**2 - x0 + 1, [ r0[0] ])
 | 
				
			||||||
    >>> r1
 | 
					    >>> r1
 | 
				
			||||||
    [-0.4090280898?, 0.4090280898?]
 | 
					    [-0.4090280898?, 0.4090280898?]
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    Similarly, in the next example we isolate the roots of
 | 
					    Similarly, in the next example we isolate the roots of
 | 
				
			||||||
    a univariate polynomial (on x2) obtained after substituting
 | 
					    a univariate polynomial (on x2) obtained after substituting
 | 
				
			||||||
    x0 -> r0[0] and x1 -> r1[0]
 | 
					    x0 -> r0[0] and x1 -> r1[0]
 | 
				
			||||||
| 
						 | 
					@ -85,10 +87,11 @@ class Numeral:
 | 
				
			||||||
    [2.8538479564?]
 | 
					    [2.8538479564?]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, num, ctx=None):
 | 
					    def __init__(self, num, ctx=None):
 | 
				
			||||||
        if isinstance(num, Ast):
 | 
					        if isinstance(num, Ast):
 | 
				
			||||||
            self.ast  = num
 | 
					            self.ast = num
 | 
				
			||||||
            self.ctx  = _get_ctx(ctx)
 | 
					            self.ctx = _get_ctx(ctx)
 | 
				
			||||||
        elif isinstance(num, RatNumRef) or isinstance(num, AlgebraicNumRef):
 | 
					        elif isinstance(num, RatNumRef) or isinstance(num, AlgebraicNumRef):
 | 
				
			||||||
            self.ast = num.ast
 | 
					            self.ast = num.ast
 | 
				
			||||||
            self.ctx = num.ctx
 | 
					            self.ctx = num.ctx
 | 
				
			||||||
| 
						 | 
					@ -102,13 +105,13 @@ class Numeral:
 | 
				
			||||||
            self.ctx = v.ctx
 | 
					            self.ctx = v.ctx
 | 
				
			||||||
        Z3_inc_ref(self.ctx_ref(), self.as_ast())
 | 
					        Z3_inc_ref(self.ctx_ref(), self.as_ast())
 | 
				
			||||||
        assert Z3_algebraic_is_value(self.ctx_ref(), self.ast)
 | 
					        assert Z3_algebraic_is_value(self.ctx_ref(), self.ast)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    def __del__(self):
 | 
					    def __del__(self):
 | 
				
			||||||
        Z3_dec_ref(self.ctx_ref(), self.as_ast())
 | 
					        Z3_dec_ref(self.ctx_ref(), self.as_ast())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_integer(self):
 | 
					    def is_integer(self):
 | 
				
			||||||
        """ Return True if the numeral is integer.
 | 
					        """ Return True if the numeral is integer.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral(2).is_integer()
 | 
					        >>> Numeral(2).is_integer()
 | 
				
			||||||
        True
 | 
					        True
 | 
				
			||||||
        >>> (Numeral(Sqrt(2)) * Numeral(Sqrt(2))).is_integer()
 | 
					        >>> (Numeral(Sqrt(2)) * Numeral(Sqrt(2))).is_integer()
 | 
				
			||||||
| 
						 | 
					@ -129,13 +132,13 @@ class Numeral:
 | 
				
			||||||
        True
 | 
					        True
 | 
				
			||||||
        >>> Numeral(Sqrt(2)).is_rational()
 | 
					        >>> Numeral(Sqrt(2)).is_rational()
 | 
				
			||||||
        False
 | 
					        False
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return Z3_get_ast_kind(self.ctx_ref(), self.as_ast()) == Z3_NUMERAL_AST
 | 
					        return Z3_get_ast_kind(self.ctx_ref(), self.as_ast()) == Z3_NUMERAL_AST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def denominator(self):
 | 
					    def denominator(self):
 | 
				
			||||||
        """ Return the denominator if `self` is rational.
 | 
					        """ Return the denominator if `self` is rational.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral("2/3").denominator()
 | 
					        >>> Numeral("2/3").denominator()
 | 
				
			||||||
        3
 | 
					        3
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					@ -144,14 +147,13 @@ class Numeral:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def numerator(self):
 | 
					    def numerator(self):
 | 
				
			||||||
        """ Return the numerator if `self` is rational.
 | 
					        """ Return the numerator if `self` is rational.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral("2/3").numerator()
 | 
					        >>> Numeral("2/3").numerator()
 | 
				
			||||||
        2
 | 
					        2
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        assert(self.is_rational())
 | 
					        assert(self.is_rational())
 | 
				
			||||||
        return Numeral(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
 | 
					        return Numeral(Z3_get_numerator(self.ctx_ref(), self.as_ast()), self.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def is_irrational(self):
 | 
					    def is_irrational(self):
 | 
				
			||||||
        """ Return True if the numeral is irrational.
 | 
					        """ Return True if the numeral is irrational.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,7 +171,7 @@ class Numeral:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        assert(self.is_integer())
 | 
					        assert(self.is_integer())
 | 
				
			||||||
        if sys.version_info[0] >= 3:
 | 
					        if sys.version_info.major >= 3:
 | 
				
			||||||
            return int(Z3_get_numeral_string(self.ctx_ref(), self.as_ast()))
 | 
					            return int(Z3_get_numeral_string(self.ctx_ref(), self.as_ast()))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return long(Z3_get_numeral_string(self.ctx_ref(), self.as_ast()))
 | 
					            return long(Z3_get_numeral_string(self.ctx_ref(), self.as_ast()))
 | 
				
			||||||
| 
						 | 
					@ -183,9 +185,9 @@ class Numeral:
 | 
				
			||||||
        return Fraction(self.numerator().as_long(), self.denominator().as_long())
 | 
					        return Fraction(self.numerator().as_long(), self.denominator().as_long())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def approx(self, precision=10):
 | 
					    def approx(self, precision=10):
 | 
				
			||||||
        """Return a numeral that approximates the numeral `self`. 
 | 
					        """Return a numeral that approximates the numeral `self`.
 | 
				
			||||||
        The result `r` is such that |r - self| <= 1/10^precision 
 | 
					        The result `r` is such that |r - self| <= 1/10^precision
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        If `self` is rational, then the result is `self`.
 | 
					        If `self` is rational, then the result is `self`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        >>> x = Numeral(2).root(2)
 | 
					        >>> x = Numeral(2).root(2)
 | 
				
			||||||
| 
						 | 
					@ -199,9 +201,9 @@ class Numeral:
 | 
				
			||||||
        return self.upper(precision)
 | 
					        return self.upper(precision)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def upper(self, precision=10):
 | 
					    def upper(self, precision=10):
 | 
				
			||||||
        """Return a upper bound that approximates the numeral `self`. 
 | 
					        """Return a upper bound that approximates the numeral `self`.
 | 
				
			||||||
        The result `r` is such that r - self <= 1/10^precision 
 | 
					        The result `r` is such that r - self <= 1/10^precision
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        If `self` is rational, then the result is `self`.
 | 
					        If `self` is rational, then the result is `self`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        >>> x = Numeral(2).root(2)
 | 
					        >>> x = Numeral(2).root(2)
 | 
				
			||||||
| 
						 | 
					@ -218,9 +220,9 @@ class Numeral:
 | 
				
			||||||
            return Numeral(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
 | 
					            return Numeral(Z3_get_algebraic_number_upper(self.ctx_ref(), self.as_ast(), precision), self.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lower(self, precision=10):
 | 
					    def lower(self, precision=10):
 | 
				
			||||||
        """Return a lower bound that approximates the numeral `self`. 
 | 
					        """Return a lower bound that approximates the numeral `self`.
 | 
				
			||||||
        The result `r` is such that self - r <= 1/10^precision 
 | 
					        The result `r` is such that self - r <= 1/10^precision
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        If `self` is rational, then the result is `self`.
 | 
					        If `self` is rational, then the result is `self`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        >>> x = Numeral(2).root(2)
 | 
					        >>> x = Numeral(2).root(2)
 | 
				
			||||||
| 
						 | 
					@ -236,7 +238,7 @@ class Numeral:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sign(self):
 | 
					    def sign(self):
 | 
				
			||||||
        """ Return the sign of the numeral.
 | 
					        """ Return the sign of the numeral.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral(2).sign()
 | 
					        >>> Numeral(2).sign()
 | 
				
			||||||
        1
 | 
					        1
 | 
				
			||||||
        >>> Numeral(-3).sign()
 | 
					        >>> Numeral(-3).sign()
 | 
				
			||||||
| 
						 | 
					@ -245,10 +247,10 @@ class Numeral:
 | 
				
			||||||
        0
 | 
					        0
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return Z3_algebraic_sign(self.ctx_ref(), self.ast)
 | 
					        return Z3_algebraic_sign(self.ctx_ref(), self.ast)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    def is_pos(self):
 | 
					    def is_pos(self):
 | 
				
			||||||
        """ Return True if the numeral is positive.
 | 
					        """ Return True if the numeral is positive.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral(2).is_pos()
 | 
					        >>> Numeral(2).is_pos()
 | 
				
			||||||
        True
 | 
					        True
 | 
				
			||||||
        >>> Numeral(-3).is_pos()
 | 
					        >>> Numeral(-3).is_pos()
 | 
				
			||||||
| 
						 | 
					@ -260,7 +262,7 @@ class Numeral:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_neg(self):
 | 
					    def is_neg(self):
 | 
				
			||||||
        """ Return True if the numeral is negative.
 | 
					        """ Return True if the numeral is negative.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral(2).is_neg()
 | 
					        >>> Numeral(2).is_neg()
 | 
				
			||||||
        False
 | 
					        False
 | 
				
			||||||
        >>> Numeral(-3).is_neg()
 | 
					        >>> Numeral(-3).is_neg()
 | 
				
			||||||
| 
						 | 
					@ -272,7 +274,7 @@ class Numeral:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_zero(self):
 | 
					    def is_zero(self):
 | 
				
			||||||
        """ Return True if the numeral is zero.
 | 
					        """ Return True if the numeral is zero.
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        >>> Numeral(2).is_zero()
 | 
					        >>> Numeral(2).is_zero()
 | 
				
			||||||
        False
 | 
					        False
 | 
				
			||||||
        >>> Numeral(-3).is_zero()
 | 
					        >>> Numeral(-3).is_zero()
 | 
				
			||||||
| 
						 | 
					@ -353,7 +355,7 @@ class Numeral:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __rdiv__(self, other):
 | 
					    def __rdiv__(self, other):
 | 
				
			||||||
        """ Return the numeral `other / self`.
 | 
					        """ Return the numeral `other / self`.
 | 
				
			||||||
        >>> 3 / Numeral(2) 
 | 
					        >>> 3 / Numeral(2)
 | 
				
			||||||
        3/2
 | 
					        3/2
 | 
				
			||||||
        >>> 3 / Numeral(2).root(2)
 | 
					        >>> 3 / Numeral(2).root(2)
 | 
				
			||||||
        2.1213203435?
 | 
					        2.1213203435?
 | 
				
			||||||
| 
						 | 
					@ -388,7 +390,7 @@ class Numeral:
 | 
				
			||||||
        3
 | 
					        3
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return Numeral(Z3_algebraic_power(self.ctx_ref(), self.ast, k), self.ctx)
 | 
					        return Numeral(Z3_algebraic_power(self.ctx_ref(), self.ast, k), self.ctx)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    def __pow__(self, k):
 | 
					    def __pow__(self, k):
 | 
				
			||||||
        """ Return the numeral `self^k`.
 | 
					        """ Return the numeral `self^k`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -415,7 +417,7 @@ class Numeral:
 | 
				
			||||||
    def __rlt__(self, other):
 | 
					    def __rlt__(self, other):
 | 
				
			||||||
        """ Return True if `other < self`.
 | 
					        """ Return True if `other < self`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        >>> 2 < Numeral(Sqrt(2)) 
 | 
					        >>> 2 < Numeral(Sqrt(2))
 | 
				
			||||||
        False
 | 
					        False
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self > other
 | 
					        return self > other
 | 
				
			||||||
| 
						 | 
					@ -440,7 +442,6 @@ class Numeral:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self < other
 | 
					        return self < other
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __le__(self, other):
 | 
					    def __le__(self, other):
 | 
				
			||||||
        """ Return True if `self <= other`.
 | 
					        """ Return True if `self <= other`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -456,7 +457,7 @@ class Numeral:
 | 
				
			||||||
    def __rle__(self, other):
 | 
					    def __rle__(self, other):
 | 
				
			||||||
        """ Return True if `other <= self`.
 | 
					        """ Return True if `other <= self`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        >>> 2 <= Numeral(Sqrt(2)) 
 | 
					        >>> 2 <= Numeral(Sqrt(2))
 | 
				
			||||||
        False
 | 
					        False
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return self >= other
 | 
					        return self >= other
 | 
				
			||||||
| 
						 | 
					@ -523,13 +524,14 @@ class Numeral:
 | 
				
			||||||
    def ctx_ref(self):
 | 
					    def ctx_ref(self):
 | 
				
			||||||
        return self.ctx.ref()
 | 
					        return self.ctx.ref()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def eval_sign_at(p, vs):
 | 
					def eval_sign_at(p, vs):
 | 
				
			||||||
    """ 
 | 
					    """
 | 
				
			||||||
    Evaluate the sign of the polynomial `p` at `vs`.  `p` is a Z3
 | 
					    Evaluate the sign of the polynomial `p` at `vs`.  `p` is a Z3
 | 
				
			||||||
    Expression containing arithmetic operators: +, -, *, ^k where k is
 | 
					    Expression containing arithmetic operators: +, -, *, ^k where k is
 | 
				
			||||||
    an integer; and free variables x that is_var(x) is True. Moreover,
 | 
					    an integer; and free variables x that is_var(x) is True. Moreover,
 | 
				
			||||||
    all variables must be real.
 | 
					    all variables must be real.
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    The result is 1 if the polynomial is positive at the given point,
 | 
					    The result is 1 if the polynomial is positive at the given point,
 | 
				
			||||||
    -1 if negative, and 0 if zero.
 | 
					    -1 if negative, and 0 if zero.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,15 +549,16 @@ def eval_sign_at(p, vs):
 | 
				
			||||||
        _vs[i] = vs[i].ast
 | 
					        _vs[i] = vs[i].ast
 | 
				
			||||||
    return Z3_algebraic_eval(p.ctx_ref(), p.as_ast(), num, _vs)
 | 
					    return Z3_algebraic_eval(p.ctx_ref(), p.as_ast(), num, _vs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def isolate_roots(p, vs=[]):
 | 
					def isolate_roots(p, vs=[]):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Given a multivariate polynomial p(x_0, ..., x_{n-1}, x_n), returns the 
 | 
					    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).
 | 
					    roots of the univariate polynomial p(vs[0], ..., vs[len(vs)-1], x_n).
 | 
				
			||||||
       
 | 
					
 | 
				
			||||||
    Remarks:
 | 
					    Remarks:
 | 
				
			||||||
    * p is a Z3 expression that contains only arithmetic terms and free variables.
 | 
					    * p is a Z3 expression that contains only arithmetic terms and free variables.
 | 
				
			||||||
    * forall i in [0, n) vs is a numeral.
 | 
					    * forall i in [0, n) vs is a numeral.
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    The result is a list of numerals
 | 
					    The result is a list of numerals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> x0 = RealVar(0)
 | 
					    >>> x0 = RealVar(0)
 | 
				
			||||||
| 
						 | 
					@ -573,5 +576,4 @@ def isolate_roots(p, vs=[]):
 | 
				
			||||||
    for i in range(num):
 | 
					    for i in range(num):
 | 
				
			||||||
        _vs[i] = vs[i].ast
 | 
					        _vs[i] = vs[i].ast
 | 
				
			||||||
    _roots = AstVector(Z3_algebraic_roots(p.ctx_ref(), p.as_ast(), num, _vs), p.ctx)
 | 
					    _roots = AstVector(Z3_algebraic_roots(p.ctx_ref(), p.as_ast(), num, _vs), p.ctx)
 | 
				
			||||||
    return [ Numeral(r) for r in _roots ]
 | 
					    return [Numeral(r) for r in _roots]
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
############################################
 | 
					############################################
 | 
				
			||||||
# Copyright (c) 2012 Microsoft Corporation
 | 
					# Copyright (c) 2012 Microsoft Corporation
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# Z3 Python interface for Z3 polynomials
 | 
					# Z3 Python interface for Z3 polynomials
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Author: Leonardo de Moura (leonardo)
 | 
					# Author: Leonardo de Moura (leonardo)
 | 
				
			||||||
| 
						 | 
					@ -8,16 +8,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .z3 import *
 | 
					from .z3 import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def subresultants(p, q, x):
 | 
					def subresultants(p, q, x):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Return the non-constant subresultants of 'p' and 'q' with respect to the "variable" 'x'.
 | 
					    Return the non-constant subresultants of 'p' and 'q' with respect to the "variable" 'x'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'p', 'q' and 'x' are Z3 expressions where 'p' and 'q' are arithmetic terms.
 | 
					    'p', 'q' and 'x' are Z3 expressions where 'p' and 'q' are arithmetic terms.
 | 
				
			||||||
    Note that, any subterm that cannot be viewed as a polynomial is assumed to be a variable.
 | 
					    Note that, any subterm that cannot be viewed as a polynomial is assumed to be a variable.
 | 
				
			||||||
    Example: f(a) is a considered to be a variable b in the polynomial       
 | 
					    Example: f(a) is a considered to be a variable b in the polynomial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    f(a)*f(a) + 2*f(a) + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    f(a)*f(a) + 2*f(a) + 1 
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    >>> x, y = Reals('x y')
 | 
					    >>> x, y = Reals('x y')
 | 
				
			||||||
    >>> subresultants(2*x + y, 3*x - 2*y + 2, x)
 | 
					    >>> subresultants(2*x + y, 3*x - 2*y + 2, x)
 | 
				
			||||||
    [-7*y + 4]
 | 
					    [-7*y + 4]
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,7 @@ def subresultants(p, q, x):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return AstVector(Z3_polynomial_subresultants(p.ctx_ref(), p.as_ast(), q.as_ast(), x.as_ast()), p.ctx)
 | 
					    return AstVector(Z3_polynomial_subresultants(p.ctx_ref(), p.as_ast(), q.as_ast(), x.as_ast()), p.ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    import doctest
 | 
					    import doctest
 | 
				
			||||||
    if doctest.testmod().failed:
 | 
					    if doctest.testmod().failed:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
############################################
 | 
					############################################
 | 
				
			||||||
# Copyright (c) 2013 Microsoft Corporation
 | 
					# Copyright (c) 2013 Microsoft Corporation
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# Z3 Python interface for Z3 Real Closed Fields
 | 
					# Z3 Python interface for Z3 Real Closed Fields
 | 
				
			||||||
# that may contain 
 | 
					# that may contain
 | 
				
			||||||
#    - computable transcendentals
 | 
					#    - computable transcendentals
 | 
				
			||||||
#    - infinitesimals
 | 
					#    - infinitesimals
 | 
				
			||||||
#    - algebraic extensions
 | 
					#    - algebraic extensions
 | 
				
			||||||
| 
						 | 
					@ -14,42 +14,48 @@ from .z3core import *
 | 
				
			||||||
from .z3printer import *
 | 
					from .z3printer import *
 | 
				
			||||||
from fractions import Fraction
 | 
					from fractions import Fraction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _to_rcfnum(num, ctx=None):
 | 
					def _to_rcfnum(num, ctx=None):
 | 
				
			||||||
    if isinstance(num, RCFNum):
 | 
					    if isinstance(num, RCFNum):
 | 
				
			||||||
        return num
 | 
					        return num
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return RCFNum(num, ctx)
 | 
					        return RCFNum(num, ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def Pi(ctx=None):
 | 
					def Pi(ctx=None):
 | 
				
			||||||
    ctx = z3.get_ctx(ctx)
 | 
					    ctx = z3.get_ctx(ctx)
 | 
				
			||||||
    return RCFNum(Z3_rcf_mk_pi(ctx.ref()), ctx)
 | 
					    return RCFNum(Z3_rcf_mk_pi(ctx.ref()), ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def E(ctx=None):
 | 
					def E(ctx=None):
 | 
				
			||||||
    ctx = z3.get_ctx(ctx)
 | 
					    ctx = z3.get_ctx(ctx)
 | 
				
			||||||
    return RCFNum(Z3_rcf_mk_e(ctx.ref()), ctx)
 | 
					    return RCFNum(Z3_rcf_mk_e(ctx.ref()), ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def MkInfinitesimal(name="eps", ctx=None):
 | 
					def MkInfinitesimal(name="eps", ctx=None):
 | 
				
			||||||
    # Todo: remove parameter name.
 | 
					    # Todo: remove parameter name.
 | 
				
			||||||
    # For now, we keep it for backward compatibility.
 | 
					    # For now, we keep it for backward compatibility.
 | 
				
			||||||
    ctx = z3.get_ctx(ctx)
 | 
					    ctx = z3.get_ctx(ctx)
 | 
				
			||||||
    return RCFNum(Z3_rcf_mk_infinitesimal(ctx.ref()), ctx)
 | 
					    return RCFNum(Z3_rcf_mk_infinitesimal(ctx.ref()), ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def MkRoots(p, ctx=None):
 | 
					def MkRoots(p, ctx=None):
 | 
				
			||||||
    ctx = z3.get_ctx(ctx)
 | 
					    ctx = z3.get_ctx(ctx)
 | 
				
			||||||
    num = len(p)
 | 
					    num = len(p)
 | 
				
			||||||
    _tmp = [] 
 | 
					    _tmp = []
 | 
				
			||||||
    _as  = (RCFNumObj * num)()
 | 
					    _as = (RCFNumObj * num)()
 | 
				
			||||||
    _rs  = (RCFNumObj * num)() 
 | 
					    _rs = (RCFNumObj * num)()
 | 
				
			||||||
    for i in range(num):
 | 
					    for i in range(num):
 | 
				
			||||||
        _a = _to_rcfnum(p[i], ctx)
 | 
					        _a = _to_rcfnum(p[i], ctx)
 | 
				
			||||||
        _tmp.append(_a) # prevent GC
 | 
					        _tmp.append(_a)  # prevent GC
 | 
				
			||||||
        _as[i] = _a.num
 | 
					        _as[i] = _a.num
 | 
				
			||||||
    nr = Z3_rcf_mk_roots(ctx.ref(), num, _as, _rs)
 | 
					    nr = Z3_rcf_mk_roots(ctx.ref(), num, _as, _rs)
 | 
				
			||||||
    r  = []
 | 
					    r = []
 | 
				
			||||||
    for i in range(nr):
 | 
					    for i in range(nr):
 | 
				
			||||||
        r.append(RCFNum(_rs[i], ctx))
 | 
					        r.append(RCFNum(_rs[i], ctx))
 | 
				
			||||||
    return r
 | 
					    return r
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RCFNum:
 | 
					class RCFNum:
 | 
				
			||||||
    def __init__(self, num, ctx=None):
 | 
					    def __init__(self, num, ctx=None):
 | 
				
			||||||
        # TODO: add support for converting AST numeral values into RCFNum
 | 
					        # TODO: add support for converting AST numeral values into RCFNum
 | 
				
			||||||
| 
						 | 
					@ -65,7 +71,7 @@ class RCFNum:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def ctx_ref(self):
 | 
					    def ctx_ref(self):
 | 
				
			||||||
        return self.ctx.ref()
 | 
					        return self.ctx.ref()
 | 
				
			||||||
                  
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False, in_html_mode())
 | 
					        return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False, in_html_mode())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,10 +118,10 @@ class RCFNum:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __pow__(self, k):
 | 
					    def __pow__(self, k):
 | 
				
			||||||
        return self.power(k)
 | 
					        return self.power(k)
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
    def decimal(self, prec=5):
 | 
					    def decimal(self, prec=5):
 | 
				
			||||||
        return Z3_rcf_num_to_decimal_string(self.ctx_ref(), self.num, prec)
 | 
					        return Z3_rcf_num_to_decimal_string(self.ctx_ref(), self.num, prec)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    def __lt__(self, other):
 | 
					    def __lt__(self, other):
 | 
				
			||||||
        v = _to_rcfnum(other, self.ctx)
 | 
					        v = _to_rcfnum(other, self.ctx)
 | 
				
			||||||
        return Z3_rcf_lt(self.ctx_ref(), self.num, v.num)
 | 
					        return Z3_rcf_lt(self.ctx_ref(), self.num, v.num)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
############################################
 | 
					############################################
 | 
				
			||||||
# Copyright (c) 2012 Microsoft Corporation
 | 
					# Copyright (c) 2012 Microsoft Corporation
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# Z3 Python interface
 | 
					# Z3 Python interface
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Author: Leonardo de Moura (leonardo)
 | 
					# Author: Leonardo de Moura (leonardo)
 | 
				
			||||||
| 
						 | 
					@ -8,123 +8,234 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ctypes
 | 
					import ctypes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Z3Exception(Exception):
 | 
					class Z3Exception(Exception):
 | 
				
			||||||
    def __init__(self, value):
 | 
					    def __init__(self, value):
 | 
				
			||||||
        self.value = value
 | 
					        self.value = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return str(self.value)
 | 
					        return str(self.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ContextObj(ctypes.c_void_p):
 | 
					class ContextObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, context): self._as_parameter_ = context
 | 
					    def __init__(self, context):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Config(ctypes.c_void_p):
 | 
					class Config(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, config): self._as_parameter_ = config
 | 
					    def __init__(self, config):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Symbol(ctypes.c_void_p):
 | 
					class Symbol(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, symbol): self._as_parameter_ = symbol
 | 
					    def __init__(self, symbol):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = symbol
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Sort(ctypes.c_void_p):
 | 
					class Sort(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, sort): self._as_parameter_ = sort
 | 
					    def __init__(self, sort):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FuncDecl(ctypes.c_void_p):
 | 
					class FuncDecl(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, decl): self._as_parameter_ = decl
 | 
					    def __init__(self, decl):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = decl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Ast(ctypes.c_void_p):
 | 
					class Ast(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, ast): self._as_parameter_ = ast
 | 
					    def __init__(self, ast):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pattern(ctypes.c_void_p):
 | 
					class Pattern(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, pattern): self._as_parameter_ = pattern
 | 
					    def __init__(self, pattern):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = pattern
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Model(ctypes.c_void_p):
 | 
					class Model(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, model): self._as_parameter_ = model
 | 
					    def __init__(self, model):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Literals(ctypes.c_void_p):
 | 
					class Literals(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, literals): self._as_parameter_ = literals
 | 
					    def __init__(self, literals):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Constructor(ctypes.c_void_p):
 | 
					class Constructor(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, constructor): self._as_parameter_ = constructor
 | 
					    def __init__(self, constructor):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = constructor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConstructorList(ctypes.c_void_p):
 | 
					class ConstructorList(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, constructor_list): self._as_parameter_ = constructor_list
 | 
					    def __init__(self, constructor_list):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = constructor_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GoalObj(ctypes.c_void_p):
 | 
					class GoalObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, goal): self._as_parameter_ = goal
 | 
					    def __init__(self, goal):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = goal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TacticObj(ctypes.c_void_p):
 | 
					class TacticObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, tactic): self._as_parameter_ = tactic
 | 
					    def __init__(self, tactic):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = tactic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProbeObj(ctypes.c_void_p):
 | 
					class ProbeObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, probe): self._as_parameter_ = probe
 | 
					    def __init__(self, probe):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = probe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ApplyResultObj(ctypes.c_void_p):
 | 
					class ApplyResultObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, obj): self._as_parameter_ = obj
 | 
					    def __init__(self, obj):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StatsObj(ctypes.c_void_p):
 | 
					class StatsObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, statistics): self._as_parameter_ = statistics
 | 
					    def __init__(self, statistics):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = statistics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SolverObj(ctypes.c_void_p):
 | 
					class SolverObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, solver): self._as_parameter_ = solver
 | 
					    def __init__(self, solver):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = solver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SolverCallbackObj(ctypes.c_void_p):
 | 
					class SolverCallbackObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, solver): self._as_parameter_ = solver
 | 
					    def __init__(self, solver):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = solver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FixedpointObj(ctypes.c_void_p):
 | 
					class FixedpointObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, fixedpoint): self._as_parameter_ = fixedpoint
 | 
					    def __init__(self, fixedpoint):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = fixedpoint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OptimizeObj(ctypes.c_void_p):
 | 
					class OptimizeObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, optimize): self._as_parameter_ = optimize
 | 
					    def __init__(self, optimize):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = optimize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ModelObj(ctypes.c_void_p):
 | 
					class ModelObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, model): self._as_parameter_ = model
 | 
					    def __init__(self, model):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AstVectorObj(ctypes.c_void_p):
 | 
					class AstVectorObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, vector): self._as_parameter_ = vector
 | 
					    def __init__(self, vector):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = vector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AstMapObj(ctypes.c_void_p):
 | 
					class AstMapObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, ast_map): self._as_parameter_ = ast_map
 | 
					    def __init__(self, ast_map):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = ast_map
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Params(ctypes.c_void_p):
 | 
					class Params(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, params): self._as_parameter_ = params
 | 
					    def __init__(self, params):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ParamDescrs(ctypes.c_void_p):
 | 
					class ParamDescrs(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, paramdescrs): self._as_parameter_ = paramdescrs
 | 
					    def __init__(self, paramdescrs):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = paramdescrs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FuncInterpObj(ctypes.c_void_p):
 | 
					class FuncInterpObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, f): self._as_parameter_ = f
 | 
					    def __init__(self, f):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FuncEntryObj(ctypes.c_void_p):
 | 
					class FuncEntryObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, e): self._as_parameter_ = e
 | 
					    def __init__(self, e):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
 | 
					        return obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RCFNumObj(ctypes.c_void_p):
 | 
					class RCFNumObj(ctypes.c_void_p):
 | 
				
			||||||
  def __init__(self, e): self._as_parameter_ = e
 | 
					    def __init__(self, e):
 | 
				
			||||||
  def from_param(obj): return obj
 | 
					        self._as_parameter_ = e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_param(obj):
 | 
				
			||||||
    
 | 
					        return obj
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,21 +1,22 @@
 | 
				
			||||||
############################################
 | 
					############################################
 | 
				
			||||||
# Copyright (c) 2012 Microsoft Corporation
 | 
					# Copyright (c) 2012 Microsoft Corporation
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# Z3 Python interface
 | 
					# Z3 Python interface
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Authors: Leonardo de Moura (leonardo)
 | 
					# Authors: Leonardo de Moura (leonardo)
 | 
				
			||||||
#          ThanhVu (Vu) Nguyen <tnguyen@cs.unm.edu>
 | 
					#          ThanhVu (Vu) Nguyen <tnguyen@cs.unm.edu>
 | 
				
			||||||
############################################
 | 
					############################################
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
Usage:  
 | 
					Usage:
 | 
				
			||||||
import common_z3 as CM_Z3
 | 
					import common_z3 as CM_Z3
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ctypes
 | 
					import ctypes
 | 
				
			||||||
from .z3 import *
 | 
					from .z3 import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def vset(seq, idfun=None, as_list=True):
 | 
					def vset(seq, idfun=None, as_list=True):
 | 
				
			||||||
    # This functions preserves the order of arguments while removing duplicates. 
 | 
					    # This functions preserves the order of arguments while removing duplicates.
 | 
				
			||||||
    # This function is from https://code.google.com/p/common-python-vu/source/browse/vu_common.py
 | 
					    # This function is from https://code.google.com/p/common-python-vu/source/browse/vu_common.py
 | 
				
			||||||
    # (Thanhu's personal code). It has been copied here to avoid a dependency on vu_common.py.
 | 
					    # (Thanhu's personal code). It has been copied here to avoid a dependency on vu_common.py.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -24,36 +25,36 @@ def vset(seq, idfun=None, as_list=True):
 | 
				
			||||||
    >>> vset([[11,2],1, [10,['9',1]],2, 1, [11,2],[3,3],[10,99],1,[10,['9',1]]],idfun=repr)
 | 
					    >>> vset([[11,2],1, [10,['9',1]],2, 1, [11,2],[3,3],[10,99],1,[10,['9',1]]],idfun=repr)
 | 
				
			||||||
    [[11, 2], 1, [10, ['9', 1]], 2, [3, 3], [10, 99]]
 | 
					    [[11, 2], 1, [10, ['9', 1]], 2, [3, 3], [10, 99]]
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
    def _uniq_normal(seq):
 | 
					    def _uniq_normal(seq):
 | 
				
			||||||
        d_ = {}
 | 
					        d_ = {}
 | 
				
			||||||
        for s in seq:
 | 
					        for s in seq:
 | 
				
			||||||
            if s not in d_:
 | 
					            if s not in d_:
 | 
				
			||||||
                d_[s] = None
 | 
					                d_[s] = None
 | 
				
			||||||
                yield s
 | 
					                yield s
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
    def _uniq_idfun(seq,idfun):
 | 
					    def _uniq_idfun(seq, idfun):
 | 
				
			||||||
        d_ = {}
 | 
					        d_ = {}
 | 
				
			||||||
        for s in seq:
 | 
					        for s in seq:
 | 
				
			||||||
            h_ = idfun(s)
 | 
					            h_ = idfun(s)
 | 
				
			||||||
            if h_ not in d_:
 | 
					            if h_ not in d_:
 | 
				
			||||||
                d_[h_] = None
 | 
					                d_[h_] = None
 | 
				
			||||||
                yield s
 | 
					                yield s
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
    if idfun is None:
 | 
					    if idfun is None:
 | 
				
			||||||
        res = _uniq_normal(seq)
 | 
					        res = _uniq_normal(seq)
 | 
				
			||||||
    else: 
 | 
					    else:
 | 
				
			||||||
        res = _uniq_idfun(seq,idfun)
 | 
					        res = _uniq_idfun(seq, idfun)
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
    return list(res) if as_list else res 
 | 
					    return list(res) if as_list else res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_z3_version(as_str=False):
 | 
					def get_z3_version(as_str=False):
 | 
				
			||||||
    major = ctypes.c_uint(0)
 | 
					    major = ctypes.c_uint(0)
 | 
				
			||||||
    minor = ctypes.c_uint(0)
 | 
					    minor = ctypes.c_uint(0)
 | 
				
			||||||
    build = ctypes.c_uint(0)
 | 
					    build = ctypes.c_uint(0)
 | 
				
			||||||
    rev   = ctypes.c_uint(0)
 | 
					    rev = ctypes.c_uint(0)
 | 
				
			||||||
    Z3_get_version(major,minor, build, rev)
 | 
					    Z3_get_version(major, minor, build, rev)
 | 
				
			||||||
    rs = map(int, (major.value, minor.value, build.value, rev.value))
 | 
					    rs = map(int, (major.value, minor.value, build.value, rev.value))
 | 
				
			||||||
    if as_str:
 | 
					    if as_str:
 | 
				
			||||||
        return "{}.{}.{}.{}".format(*rs)
 | 
					        return "{}.{}.{}.{}".format(*rs)
 | 
				
			||||||
| 
						 | 
					@ -64,9 +65,9 @@ def get_z3_version(as_str=False):
 | 
				
			||||||
def ehash(v):
 | 
					def ehash(v):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Returns a 'stronger' hash value than the default hash() method.
 | 
					    Returns a 'stronger' hash value than the default hash() method.
 | 
				
			||||||
    The result from hash() is not enough to distinguish between 2 
 | 
					    The result from hash() is not enough to distinguish between 2
 | 
				
			||||||
    z3 expressions in some cases.
 | 
					    z3 expressions in some cases.
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    Note: the following doctests will fail with Python 2.x as the
 | 
					    Note: the following doctests will fail with Python 2.x as the
 | 
				
			||||||
    default formatting doesn't match that of 3.x.
 | 
					    default formatting doesn't match that of 3.x.
 | 
				
			||||||
    >>> x1 = Bool('x'); x2 = Bool('x'); x3 = Int('x')
 | 
					    >>> x1 = Bool('x'); x2 = Bool('x'); x3 = Int('x')
 | 
				
			||||||
| 
						 | 
					@ -74,7 +75,7 @@ def ehash(v):
 | 
				
			||||||
    783810685 783810685 783810685
 | 
					    783810685 783810685 783810685
 | 
				
			||||||
    >>> print(ehash(x1), ehash(x2), ehash(x3))
 | 
					    >>> print(ehash(x1), ehash(x2), ehash(x3))
 | 
				
			||||||
    x_783810685_1 x_783810685_1 x_783810685_2
 | 
					    x_783810685_1 x_783810685_1 x_783810685_2
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    if z3_debug():
 | 
					    if z3_debug():
 | 
				
			||||||
        assert is_expr(v)
 | 
					        assert is_expr(v)
 | 
				
			||||||
| 
						 | 
					@ -83,10 +84,11 @@ def ehash(v):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
In Z3, variables are called *uninterpreted* consts and 
 | 
					In Z3, variables are called *uninterpreted* consts and
 | 
				
			||||||
variables are *interpreted* consts.
 | 
					variables are *interpreted* consts.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_expr_var(v):
 | 
					def is_expr_var(v):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    EXAMPLES:
 | 
					    EXAMPLES:
 | 
				
			||||||
| 
						 | 
					@ -111,7 +113,8 @@ def is_expr_var(v):
 | 
				
			||||||
    True
 | 
					    True
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return is_const(v) and v.decl().kind()==Z3_OP_UNINTERPRETED
 | 
					    return is_const(v) and v.decl().kind() == Z3_OP_UNINTERPRETED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_expr_val(v):
 | 
					def is_expr_val(v):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -135,13 +138,11 @@ def is_expr_val(v):
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    >>> is_expr_val(SafetyInjection)
 | 
					    >>> is_expr_val(SafetyInjection)
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    """        
 | 
					    """
 | 
				
			||||||
    return is_const(v) and v.decl().kind()!=Z3_OP_UNINTERPRETED
 | 
					    return is_const(v) and v.decl().kind() != Z3_OP_UNINTERPRETED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_vars(f, rs=None):
 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_vars(f, rs = None):
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    >>> x,y = Ints('x y')
 | 
					    >>> x,y = Ints('x y')
 | 
				
			||||||
    >>> a,b = Bools('a b')
 | 
					    >>> a,b = Bools('a b')
 | 
				
			||||||
| 
						 | 
					@ -151,15 +152,15 @@ def get_vars(f, rs = None):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    if rs is None:
 | 
					    if rs is None:
 | 
				
			||||||
        rs = []
 | 
					        rs = []
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    if z3_debug():
 | 
					    if z3_debug():
 | 
				
			||||||
        assert is_expr(f)
 | 
					        assert is_expr(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if is_const(f):
 | 
					    if is_const(f):
 | 
				
			||||||
        if is_expr_val(f):
 | 
					        if is_expr_val(f):
 | 
				
			||||||
            return rs
 | 
					            return rs
 | 
				
			||||||
        else:  #variable
 | 
					        else:  # variable
 | 
				
			||||||
            return vset(rs + [f],str)
 | 
					            return vset(rs + [f], str)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        for f_ in f.children():
 | 
					        for f_ in f.children():
 | 
				
			||||||
| 
						 | 
					@ -168,7 +169,6 @@ def get_vars(f, rs = None):
 | 
				
			||||||
        return vset(rs, str)
 | 
					        return vset(rs, str)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
def mk_var(name, vsort):
 | 
					def mk_var(name, vsort):
 | 
				
			||||||
    if vsort.kind() == Z3_INT_SORT:
 | 
					    if vsort.kind() == Z3_INT_SORT:
 | 
				
			||||||
        v = Int(name)
 | 
					        v = Int(name)
 | 
				
			||||||
| 
						 | 
					@ -179,13 +179,12 @@ def mk_var(name, vsort):
 | 
				
			||||||
    elif vsort.kind() == Z3_DATATYPE_SORT:
 | 
					    elif vsort.kind() == Z3_DATATYPE_SORT:
 | 
				
			||||||
        v = Const(name, vsort)
 | 
					        v = Const(name, vsort)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        raise TypeError('Cannot handle this sort (s: %sid: %d)' %(vsort,vsort.kind()))
 | 
					        raise TypeError("Cannot handle this sort (s: %sid: %d)" % (vsort, vsort.kind()))
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    return v
 | 
					    return v
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def prove(claim, assume=None, verbose=0):
 | 
				
			||||||
def prove(claim,assume=None,verbose=0):
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    >>> r,m = prove(BoolVal(True),verbose=0); r,model_str(m,as_str=False)
 | 
					    >>> r,m = prove(BoolVal(True),verbose=0); r,model_str(m,as_str=False)
 | 
				
			||||||
    (True, None)
 | 
					    (True, None)
 | 
				
			||||||
| 
						 | 
					@ -204,11 +203,11 @@ def prove(claim,assume=None,verbose=0):
 | 
				
			||||||
    AssertionError: Assumption is always False!
 | 
					    AssertionError: Assumption is always False!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> r,m = prove(Implies(x,x),assume=y,verbose=2); r,model_str(m,as_str=False)
 | 
					    >>> r,m = prove(Implies(x,x),assume=y,verbose=2); r,model_str(m,as_str=False)
 | 
				
			||||||
    assume: 
 | 
					    assume:
 | 
				
			||||||
    y
 | 
					    y
 | 
				
			||||||
    claim: 
 | 
					    claim:
 | 
				
			||||||
    Implies(x, x)
 | 
					    Implies(x, x)
 | 
				
			||||||
    to_prove: 
 | 
					    to_prove:
 | 
				
			||||||
    Implies(y, Implies(x, x))
 | 
					    Implies(y, Implies(x, x))
 | 
				
			||||||
    (True, None)
 | 
					    (True, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,52 +235,52 @@ def prove(claim,assume=None,verbose=0):
 | 
				
			||||||
    to_prove = claim
 | 
					    to_prove = claim
 | 
				
			||||||
    if assume:
 | 
					    if assume:
 | 
				
			||||||
        if z3_debug():
 | 
					        if z3_debug():
 | 
				
			||||||
            is_proved,_ = prove(Not(assume))
 | 
					            is_proved, _ = prove(Not(assume))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            def _f():
 | 
					            def _f():
 | 
				
			||||||
                emsg = "Assumption is always False!"
 | 
					                emsg = "Assumption is always False!"
 | 
				
			||||||
                if verbose >= 2:
 | 
					                if verbose >= 2:
 | 
				
			||||||
                    emsg = "{}\n{}".format(assume,emsg)
 | 
					                    emsg = "{}\n{}".format(assume, emsg)
 | 
				
			||||||
                return emsg
 | 
					                return emsg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            assert is_proved==False, _f()
 | 
					            assert is_proved == False, _f()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        to_prove = Implies(assume,to_prove)
 | 
					        to_prove = Implies(assume, to_prove)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if verbose >= 2:
 | 
					    if verbose >= 2:
 | 
				
			||||||
        print('assume: ')
 | 
					        print("assume: ")
 | 
				
			||||||
        print(assume)
 | 
					        print(assume)
 | 
				
			||||||
        print('claim: ')
 | 
					        print("claim: ")
 | 
				
			||||||
        print(claim)
 | 
					        print(claim)
 | 
				
			||||||
        print('to_prove: ')
 | 
					        print("to_prove: ")
 | 
				
			||||||
        print(to_prove)
 | 
					        print(to_prove)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    f = Not(to_prove)
 | 
					    f = Not(to_prove)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    models = get_models(f,k=1)
 | 
					    models = get_models(f, k=1)
 | 
				
			||||||
    if models is None: #unknown
 | 
					    if models is None:  # unknown
 | 
				
			||||||
        print('E: cannot solve !')
 | 
					        print("E: cannot solve !")
 | 
				
			||||||
        return None, None
 | 
					        return None, None
 | 
				
			||||||
    elif models == False: #unsat
 | 
					    elif models == False:  # unsat
 | 
				
			||||||
        return True,None   
 | 
					        return True, None
 | 
				
			||||||
    else: #sat
 | 
					    else:  # sat
 | 
				
			||||||
        if z3_debug():
 | 
					        if z3_debug():
 | 
				
			||||||
            assert isinstance(models,list)
 | 
					            assert isinstance(models, list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if models:
 | 
					        if models:
 | 
				
			||||||
            return False, models[0] #the first counterexample
 | 
					            return False, models[0]  # the first counterexample
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return False, []  #infinite counterexample,models
 | 
					            return False, []  # infinite counterexample,models
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_models(f,k):
 | 
					
 | 
				
			||||||
 | 
					def get_models(f, k):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Returns the first k models satisfiying f.
 | 
					    Returns the first k models satisfiying f.
 | 
				
			||||||
    If f is not satisfiable, returns False.
 | 
					    If f is not satisfiable, returns False.
 | 
				
			||||||
    If f cannot be solved, returns None
 | 
					    If f cannot be solved, returns None
 | 
				
			||||||
    If f is satisfiable, returns the first k models
 | 
					    If f is satisfiable, returns the first k models
 | 
				
			||||||
    Note that if f is a tautology, e.g.\ True, then the result is []
 | 
					    Note that if f is a tautology, e.g.\\ True, then the result is []
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    Based on http://stackoverflow.com/questions/11867611/z3py-checking-all-solutions-for-equation
 | 
					    Based on http://stackoverflow.com/questions/11867611/z3py-checking-all-solutions-for-equation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EXAMPLES:
 | 
					    EXAMPLES:
 | 
				
			||||||
| 
						 | 
					@ -314,7 +313,7 @@ def get_models(f,k):
 | 
				
			||||||
    if z3_debug():
 | 
					    if z3_debug():
 | 
				
			||||||
        assert is_expr(f)
 | 
					        assert is_expr(f)
 | 
				
			||||||
        assert k >= 1
 | 
					        assert k >= 1
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    s = Solver()
 | 
					    s = Solver()
 | 
				
			||||||
    s.add(f)
 | 
					    s.add(f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -323,16 +322,14 @@ def get_models(f,k):
 | 
				
			||||||
    while s.check() == sat and i < k:
 | 
					    while s.check() == sat and i < k:
 | 
				
			||||||
        i = i + 1
 | 
					        i = i + 1
 | 
				
			||||||
        m = s.model()
 | 
					        m = s.model()
 | 
				
			||||||
        if not m: #if m == []
 | 
					        if not m:  # if m == []
 | 
				
			||||||
            break
 | 
					            break
 | 
				
			||||||
        models.append(m)
 | 
					        models.append(m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # create new constraint to block the current model
 | 
				
			||||||
        #create new constraint to block the current model
 | 
					 | 
				
			||||||
        block = Not(And([v() == m[v] for v in m]))
 | 
					        block = Not(And([v() == m[v] for v in m]))
 | 
				
			||||||
        s.add(block)
 | 
					        s.add(block)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if s.check() == unknown:
 | 
					    if s.check() == unknown:
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
    elif s.check() == unsat and i == 0:
 | 
					    elif s.check() == unsat and i == 0:
 | 
				
			||||||
| 
						 | 
					@ -340,7 +337,8 @@ def get_models(f,k):
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return models
 | 
					        return models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_tautology(claim,verbose=0):
 | 
					
 | 
				
			||||||
 | 
					def is_tautology(claim, verbose=0):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    >>> is_tautology(Implies(Bool('x'),Bool('x')))
 | 
					    >>> is_tautology(Implies(Bool('x'),Bool('x')))
 | 
				
			||||||
    True
 | 
					    True
 | 
				
			||||||
| 
						 | 
					@ -355,38 +353,38 @@ def is_tautology(claim,verbose=0):
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return prove(claim=claim,assume=None,verbose=verbose)[0]
 | 
					    return prove(claim=claim, assume=None, verbose=verbose)[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_contradiction(claim,verbose=0):
 | 
					def is_contradiction(claim, verbose=0):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    >>> x,y=Bools('x y')
 | 
					    >>> x,y=Bools('x y')
 | 
				
			||||||
    >>> is_contradiction(BoolVal(False))
 | 
					    >>> is_contradiction(BoolVal(False))
 | 
				
			||||||
    True
 | 
					    True
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> is_contradiction(BoolVal(True))
 | 
					    >>> is_contradiction(BoolVal(True))
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> is_contradiction(x)
 | 
					    >>> is_contradiction(x)
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> is_contradiction(Implies(x,y))
 | 
					    >>> is_contradiction(Implies(x,y))
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> is_contradiction(Implies(x,x))
 | 
					    >>> is_contradiction(Implies(x,x))
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> is_contradiction(And(x,Not(x)))
 | 
					    >>> is_contradiction(And(x,Not(x)))
 | 
				
			||||||
    True
 | 
					    True
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return prove(claim=Not(claim),assume=None,verbose=verbose)[0]
 | 
					    return prove(claim=Not(claim), assume=None, verbose=verbose)[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def exact_one_model(f):
 | 
					def exact_one_model(f):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return True if f has exactly 1 model, False otherwise.
 | 
					    return True if f has exactly 1 model, False otherwise.
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    EXAMPLES:
 | 
					    EXAMPLES:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> x, y = Ints('x y')
 | 
					    >>> x, y = Ints('x y')
 | 
				
			||||||
| 
						 | 
					@ -403,30 +401,29 @@ def exact_one_model(f):
 | 
				
			||||||
    False
 | 
					    False
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    models = get_models(f,k=2)
 | 
					    models = get_models(f, k=2)
 | 
				
			||||||
    if isinstance(models,list):
 | 
					    if isinstance(models, list):
 | 
				
			||||||
        return len(models)==1
 | 
					        return len(models) == 1
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def myBinOp(op,*L):
 | 
					
 | 
				
			||||||
 | 
					def myBinOp(op, *L):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    >>> myAnd(*[Bool('x'),Bool('y')])
 | 
					    >>> myAnd(*[Bool('x'),Bool('y')])
 | 
				
			||||||
    And(x, y)
 | 
					    And(x, y)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> myAnd(*[Bool('x'),None])
 | 
					    >>> myAnd(*[Bool('x'),None])
 | 
				
			||||||
    x
 | 
					    x
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> myAnd(*[Bool('x')])
 | 
					    >>> myAnd(*[Bool('x')])
 | 
				
			||||||
    x
 | 
					    x
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> myAnd(*[])
 | 
					    >>> myAnd(*[])
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> myAnd(Bool('x'),Bool('y'))
 | 
					    >>> myAnd(Bool('x'),Bool('y'))
 | 
				
			||||||
    And(x, y)
 | 
					    And(x, y)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> myAnd(*[Bool('x'),Bool('y')])
 | 
					    >>> myAnd(*[Bool('x'),Bool('y')])
 | 
				
			||||||
    And(x, y)
 | 
					    And(x, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -435,7 +432,7 @@ def myBinOp(op,*L):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> myAnd((Bool('x'),Bool('y')))
 | 
					    >>> myAnd((Bool('x'),Bool('y')))
 | 
				
			||||||
    And(x, y)
 | 
					    And(x, y)
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    >>> myAnd(*[Bool('x'),Bool('y'),True])
 | 
					    >>> myAnd(*[Bool('x'),Bool('y'),True])
 | 
				
			||||||
    Traceback (most recent call last):
 | 
					    Traceback (most recent call last):
 | 
				
			||||||
    ...
 | 
					    ...
 | 
				
			||||||
| 
						 | 
					@ -444,59 +441,62 @@ def myBinOp(op,*L):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if z3_debug():
 | 
					    if z3_debug():
 | 
				
			||||||
        assert op == Z3_OP_OR or op == Z3_OP_AND or op == Z3_OP_IMPLIES
 | 
					        assert op == Z3_OP_OR or op == Z3_OP_AND or op == Z3_OP_IMPLIES
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    if len(L)==1 and (isinstance(L[0],list) or isinstance(L[0],tuple)):
 | 
					    if len(L) == 1 and (isinstance(L[0], list) or isinstance(L[0], tuple)):
 | 
				
			||||||
        L = L[0]
 | 
					        L = L[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if z3_debug():
 | 
					    if z3_debug():
 | 
				
			||||||
        assert all(not isinstance(l,bool) for l in L)
 | 
					        assert all(not isinstance(l, bool) for l in L)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    L = [l for l in L if is_expr(l)]
 | 
					    L = [l for l in L if is_expr(l)]
 | 
				
			||||||
    if L:
 | 
					    if L:
 | 
				
			||||||
        if len(L)==1:
 | 
					        if len(L) == 1:
 | 
				
			||||||
            return L[0]
 | 
					            return L[0]
 | 
				
			||||||
        if op ==  Z3_OP_OR:
 | 
					        if op == Z3_OP_OR:
 | 
				
			||||||
            return Or(L)
 | 
					            return Or(L)
 | 
				
			||||||
        if op == Z3_OP_AND:
 | 
					        if op == Z3_OP_AND:
 | 
				
			||||||
            return And(L)        
 | 
					            return And(L)
 | 
				
			||||||
        return Implies(L[0],L[1])
 | 
					        return Implies(L[0], L[1])
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def myAnd(*L):
 | 
					def myAnd(*L):
 | 
				
			||||||
    return myBinOp(Z3_OP_AND,*L)
 | 
					    return myBinOp(Z3_OP_AND, *L)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def myOr(*L):
 | 
					def myOr(*L):
 | 
				
			||||||
    return myBinOp(Z3_OP_OR,*L)
 | 
					    return myBinOp(Z3_OP_OR, *L)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def myImplies(a,b):
 | 
					 | 
				
			||||||
    return myBinOp(Z3_OP_IMPLIES,[a,b])
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Iff = lambda f: And(Implies(f[0],f[1]),Implies(f[1],f[0]))
 | 
					def myImplies(a, b):
 | 
				
			||||||
 | 
					    return myBinOp(Z3_OP_IMPLIES, [a, b])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def model_str(m,as_str=True):
 | 
					
 | 
				
			||||||
 | 
					def Iff(f):
 | 
				
			||||||
 | 
					    return And(Implies(f[0], f[1]), Implies(f[1], f[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def model_str(m, as_str=True):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Returned a 'sorted' model (so that it's easier to see)
 | 
					    Returned a 'sorted' model (so that it's easier to see)
 | 
				
			||||||
    The model is sorted by its key, 
 | 
					    The model is sorted by its key,
 | 
				
			||||||
    e.g. if the model is y = 3 , x = 10, then the result is 
 | 
					    e.g. if the model is y = 3 , x = 10, then the result is
 | 
				
			||||||
    x = 10, y = 3
 | 
					    x = 10, y = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EXAMPLES:
 | 
					    EXAMPLES:
 | 
				
			||||||
    see doctest exampels from function prove() 
 | 
					    see doctest exampels from function prove()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    if z3_debug():
 | 
					    if z3_debug():
 | 
				
			||||||
        assert m is None or m == [] or isinstance(m,ModelRef)
 | 
					        assert m is None or m == [] or isinstance(m, ModelRef)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if m :
 | 
					    if m:
 | 
				
			||||||
        vs = [(v,m[v]) for v in m]
 | 
					        vs = [(v, m[v]) for v in m]
 | 
				
			||||||
        vs = sorted(vs,key=lambda a,_: str(a))
 | 
					        vs = sorted(vs, key=lambda a, _: str(a))
 | 
				
			||||||
        if as_str:
 | 
					        if as_str:
 | 
				
			||||||
            return '\n'.join(['{} = {}'.format(k,v) for (k,v) in vs])
 | 
					            return "\n".join(["{} = {}".format(k, v) for (k, v) in vs])
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return vs
 | 
					            return vs
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return str(m) if as_str else m
 | 
					        return str(m) if as_str else m
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue