Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何同时使用Z3py和Sympy_Python_Z3_Sympy_Z3py - Fatal编程技术网

Python 如何同时使用Z3py和Sympy

Python 如何同时使用Z3py和Sympy,python,z3,sympy,z3py,Python,Z3,Sympy,Z3py,我正在尝试对矩阵执行一些符号计算(将符号作为矩阵的一个条目),然后我将有一些可能的解决方案。我的目标是根据约束选择解决方案/解决方案 例如,M是一个矩阵,其中有一个元素作为符号。 这个矩阵有两个特征值,一个是正的,一个是负的。使用z3,我试图找出唯一的负值,但我无法做到这一点,因为a被定义为一个符号,除非我将其转换为实值,否则我无法将其作为约束写入 我该怎么办?有没有办法将(符号)转换为实数或整数,以便我可以将其用作约束s.add(a>0) 从sympy导入* 从z3进口* 从数学导入* a=符

我正在尝试对矩阵执行一些符号计算(将符号作为矩阵的一个条目),然后我将有一些可能的解决方案。我的目标是根据约束选择解决方案/解决方案

例如,
M
是一个矩阵,其中有一个元素作为
符号
。 这个矩阵有两个特征值,一个是正的,一个是负的。使用z3,我试图找出唯一的负值,但我无法做到这一点,因为a被定义为一个符号,除非我将其转换为实值,否则我无法将其作为约束写入

我该怎么办?有没有办法将(符号)转换为实数或整数,以便我可以将其用作约束
s.add(a>0)

从sympy导入*
从z3进口*
从数学导入*
a=符号('a')
M=矩阵([[a,2],[3,4]])M=M.本征值();
s=解算器()

s、 添加(m一种可能性是将sympy表达式转换为stings,修改它们以表示z3表达式,然后调用python的eval将它们计算为z3表达式。更准确地说:

  • 将Symphy表达式转换为字符串。只需调用Python的str(),即可从Symphy表达式生成字符串

  • 将不等/等号附加到每个字符串(“>0”、“小于0”、“大于等于0”或“”)中
    eval
    exec
    的替代方法是遍历sympy表达式并构造相应的z3表达式。下面是一些代码:

    from z3 import Real, Sqrt 
    from sympy.core import Mul, Expr, Add, Pow, Symbol, Number
    
    def sympy_to_z3(sympy_var_list, sympy_exp):
        'convert a sympy expression to a z3 expression. This returns (z3_vars, z3_expression)'
    
        z3_vars = []
        z3_var_map = {}
    
        for var in sympy_var_list:
            name = var.name
            z3_var = Real(name)
            z3_var_map[name] = z3_var
            z3_vars.append(z3_var)
    
        result_exp = _sympy_to_z3_rec(z3_var_map, sympy_exp)
    
        return z3_vars, result_exp
    
    def _sympy_to_z3_rec(var_map, e):
        'recursive call for sympy_to_z3()'
    
        rv = None
    
        if not isinstance(e, Expr):
            raise RuntimeError("Expected sympy Expr: " + repr(e))
    
        if isinstance(e, Symbol):
            rv = var_map.get(e.name)
    
            if rv == None:
                raise RuntimeError("No var was corresponds to symbol '" + str(e) + "'")
    
        elif isinstance(e, Number):
            rv = float(e)
        elif isinstance(e, Mul):
            rv = _sympy_to_z3_rec(var_map, e.args[0])
    
            for child in e.args[1:]:
                rv *= _sympy_to_z3_rec(var_map, child)
        elif isinstance(e, Add):
            rv = _sympy_to_z3_rec(var_map, e.args[0])
    
            for child in e.args[1:]:
                rv += _sympy_to_z3_rec(var_map, child)
        elif isinstance(e, Pow):
            term = _sympy_to_z3_rec(var_map, e.args[0])
            exponent = _sympy_to_z3_rec(var_map, e.args[1])
    
            if exponent == 0.5:
                # sqrt
                rv = Sqrt(term)
            else:
                rv = term**exponent
    
        if rv == None:
            raise RuntimeError("Type '" + str(type(e)) + "' is not yet implemented for convertion to a z3 expresion. " + \
                                "Subexpression was '" + str(e) + "'.")
    
        return rv
    
    下面是一个使用代码的示例:

    from sympy import symbols
    from z3 import Solver, sat
    
    var_list = x, y = symbols("x y")
    
    sympy_exp = -x**2 + y + 1
    z3_vars, z3_exp = sympy_to_z3(var_list, sympy_exp)
    
    z3_x = z3_vars[0]
    z3_y = z3_vars[1]
    
    s = Solver()
    s.add(z3_exp == 0) # add a constraint with converted expression
    s.add(z3_y >= 0) # add an extra constraint
    
    result = s.check()
    
    if result == sat:
        m = s.model()
    
        print "SAT at x={}, y={}".format(m[z3_x], m[z3_y])
    else:
        print "UNSAT"
    
    运行此命令将生成解决约束的输出
    y>=0
    -x^2+y+1==0


    SAT at x=2,y=3

    我正在尝试运行此代码,但它在最后一行识别出一个错误。请指定您为str\u ineq\u list和syms传递的参数值。我将检查哪里出错,并相应地修改/澄清答案。
    from z3 import Real, Sqrt 
    from sympy.core import Mul, Expr, Add, Pow, Symbol, Number
    
    def sympy_to_z3(sympy_var_list, sympy_exp):
        'convert a sympy expression to a z3 expression. This returns (z3_vars, z3_expression)'
    
        z3_vars = []
        z3_var_map = {}
    
        for var in sympy_var_list:
            name = var.name
            z3_var = Real(name)
            z3_var_map[name] = z3_var
            z3_vars.append(z3_var)
    
        result_exp = _sympy_to_z3_rec(z3_var_map, sympy_exp)
    
        return z3_vars, result_exp
    
    def _sympy_to_z3_rec(var_map, e):
        'recursive call for sympy_to_z3()'
    
        rv = None
    
        if not isinstance(e, Expr):
            raise RuntimeError("Expected sympy Expr: " + repr(e))
    
        if isinstance(e, Symbol):
            rv = var_map.get(e.name)
    
            if rv == None:
                raise RuntimeError("No var was corresponds to symbol '" + str(e) + "'")
    
        elif isinstance(e, Number):
            rv = float(e)
        elif isinstance(e, Mul):
            rv = _sympy_to_z3_rec(var_map, e.args[0])
    
            for child in e.args[1:]:
                rv *= _sympy_to_z3_rec(var_map, child)
        elif isinstance(e, Add):
            rv = _sympy_to_z3_rec(var_map, e.args[0])
    
            for child in e.args[1:]:
                rv += _sympy_to_z3_rec(var_map, child)
        elif isinstance(e, Pow):
            term = _sympy_to_z3_rec(var_map, e.args[0])
            exponent = _sympy_to_z3_rec(var_map, e.args[1])
    
            if exponent == 0.5:
                # sqrt
                rv = Sqrt(term)
            else:
                rv = term**exponent
    
        if rv == None:
            raise RuntimeError("Type '" + str(type(e)) + "' is not yet implemented for convertion to a z3 expresion. " + \
                                "Subexpression was '" + str(e) + "'.")
    
        return rv
    
    from sympy import symbols
    from z3 import Solver, sat
    
    var_list = x, y = symbols("x y")
    
    sympy_exp = -x**2 + y + 1
    z3_vars, z3_exp = sympy_to_z3(var_list, sympy_exp)
    
    z3_x = z3_vars[0]
    z3_y = z3_vars[1]
    
    s = Solver()
    s.add(z3_exp == 0) # add a constraint with converted expression
    s.add(z3_y >= 0) # add an extra constraint
    
    result = s.check()
    
    if result == sat:
        m = s.model()
    
        print "SAT at x={}, y={}".format(m[z3_x], m[z3_y])
    else:
        print "UNSAT"