z3py:如何提高以下代码的时间效率

z3py:如何提高以下代码的时间效率,z3,smt,z3py,inference,Z3,Smt,Z3py,Inference,这是一个简化的代码,使用了与z3py代码类似的实现思想,解决了另一个更复杂的问题,运行大约需要1分钟 下面代码的直觉是将inputArray中的整数数组转换为定义为EnumSort的月份数组,这本质上是为了推断monthArray的模型 from z3 import * s = Solver() Month,(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)=EnumSort('Month',['Jan','Feb','Mar','Apr','M

这是一个简化的代码,使用了与z3py代码类似的实现思想,解决了另一个更复杂的问题,运行大约需要1分钟

下面代码的直觉是将inputArray中的整数数组转换为定义为EnumSort的月份数组,这本质上是为了推断monthArray的模型

from z3 import *
s = Solver()

Month,(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)=EnumSort('Month',['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'])
monthArray = Array('monthArray',IntSort(), Month)
inputArray = Array('inputArray',IntSort(),IntSort())
tempArray = Array('tempArray',IntSort(),IntSort())

intArray = [1,3,6,7,8,3,5,6,3,12,11,5,2,5,7,3,7,3,2,7,12,4,5,1,10,9]
for idx,num in enumerate(intArray):
    tempArray = Store(tempArray,idx,num)

s.add(inputArray==tempArray)

length = Int('length')
s.add(length == len(intArray))
i = Int('i')
s.add(ForAll(i,Implies(And(i>=0,i<length),And(
    Implies(inputArray[i]==1,monthArray[i]==Jan),
    Implies(inputArray[i]==2,monthArray[i]==Feb),
    Implies(inputArray[i]==3,monthArray[i]==Mar),
    Implies(inputArray[i]==4,monthArray[i]==Apr),
    Implies(inputArray[i]==5,monthArray[i]==May),
    Implies(inputArray[i]==6,monthArray[i]==Jun),
    Implies(inputArray[i]==7,monthArray[i]==Jul),
    Implies(inputArray[i]==8,monthArray[i]==Aug),
    Implies(inputArray[i]==9,monthArray[i]==Sep),
    Implies(inputArray[i]==10,monthArray[i]==Oct),
    Implies(inputArray[i]==11,monthArray[i]==Nov),
    Implies(inputArray[i]==12,monthArray[i]==Dec)
    ))))

print s.check()
print s.model()
从z3导入*
s=解算器()
月份,(一月、二月、三月、四月、五月、六月、七月、八月、九月、十月、十一月、十二月)=枚举排序('Month',['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'))
monthArray=Array('monthArray',IntSort(),Month)
inputArray=数组('inputArray',IntSort(),IntSort())
tempArray=Array('tempArray',IntSort(),IntSort())
intArray=[1,3,6,7,8,3,5,6,3,12,11,5,2,5,7,3,3,2,7,12,4,5,1,10,9]
对于idx,枚举中的num(intArray):
tempArray=Store(tempArray,idx,num)
s、 添加(inputArray==tempArray)
长度=Int('length')
s、 加(长度==长度(整数))
i=Int('i')
s、 添加(对于所有(i,意味着(i>=0,i=(选择输入阵列i)12)(=(选择蒙塔雷i)十二月)))
(让($x175(=>(=(选择输入阵列i)11)(=(选择蒙塔雷i)11月)))
(让($x178(=>(=(选择输入阵列i)10)(=(选择蒙塔雷i)十月)))
(let($x181(=>(=(选择输入阵列i)9)(=(选择蒙塔雷i)九月)))
(let($x184(=>(=(选择输入阵列i)8)(=(选择蒙塔雷i)8月)))
(let($x187(=>(=(选择输入阵列i)7)(=(选择蒙塔雷i)7月)))
(let($x190(=>(=(选择输入阵列i)6)(=(选择蒙塔雷i)六月)))
(让($x193(=>(=(选择输入阵列i)5)(=(选择蒙塔雷i)五月)))
(让($x196(=>(=(选择输入阵列i)4)(=(选择蒙塔雷i)四月)))
(let($x199(=>(=(选择输入阵列i)3)(=(选择蒙塔雷i)三月)))
(let($x202(=>(=(选择输入阵列i)2)(=(选择蒙塔雷i)2月)))
(let($x205(=>(=(选择输入阵列i)1)(=(选择蒙塔雷i)一月)))
(=>(和(>=i0)(
在我的例子中,我发现使用“qflia”(无量词线性整数算术)解算器而不是一般的解算器“solver()”,可以将效率提高约3倍

如果你展开量词,这个问题应该马上解决。令人惊讶的是,这是如此缓慢的量词。这应该只需要几次MBQI迭代。我感谢您的回复。你能说得更清楚些吗?我不太懂“扩展量词”。谢谢。现在你有“所有i.p(i)”。把它改成“p(0)&&p(1)&&&…”。谢谢。但在我的实际问题中,长度也是可以推断出来的。所以我不能写“p(0)&&p(1)&&…”,因为我不知道有多少个p(I)。你知道我可能会使用什么策略或其他解决方法吗?我对量词几乎没有经验。让我们看看是否有专家来回答。
(set-info :status unknown)
(declare-datatypes () ((Month (Jan ) (Feb ) (Mar ) (Apr ) (May ) (Jun ) (Jul ) (Aug ) (Sep ) (Oct ) (Nov ) (Dec ))))
(declare-fun inputArray () (Array Int Int))
(declare-fun length () Int)
(declare-fun monthArray () (Array Int Month))
(assert
(= (select inputArray 0) 1))
(assert
(= (select inputArray 1) 3))
(assert
(= (select inputArray 2) 6))
(assert
(= (select inputArray 3) 7))
(assert
(= (select inputArray 4) 8))
(assert
(= (select inputArray 5) 3))
(assert
(= (select inputArray 6) 5))
(assert
(= (select inputArray 7) 6))
(assert
(= (select inputArray 8) 3))
(assert
(= (select inputArray 9) 12))
(assert
(= (select inputArray 10) 11))
(assert
(= (select inputArray 11) 5))
(assert
(= (select inputArray 12) 2))
(assert
(= (select inputArray 13) 5))
(assert
(= (select inputArray 14) 7))
(assert
(= (select inputArray 15) 3))
(assert
(= (select inputArray 16) 7))
(assert
(= (select inputArray 17) 3))
(assert
(= (select inputArray 18) 2))
(assert
(= (select inputArray 19) 7))
(assert
(= (select inputArray 20) 12))
(assert
(= (select inputArray 21) 4))
(assert
(= (select inputArray 22) 5))
(assert
(= (select inputArray 23) 1))
(assert
(= (select inputArray 24) 10))
(assert
(= (select inputArray 25) 9))
(assert
(= length 26))
(assert
(forall ((i Int) )(let (($x172 (=> (= (select inputArray i) 12) (= (select monthArray i) Dec))))
(let (($x175 (=> (= (select inputArray i) 11) (= (select monthArray i) Nov))))
(let (($x178 (=> (= (select inputArray i) 10) (= (select monthArray i) Oct))))
(let (($x181 (=> (= (select inputArray i) 9) (= (select monthArray i) Sep))))
(let (($x184 (=> (= (select inputArray i) 8) (= (select monthArray i) Aug))))
(let (($x187 (=> (= (select inputArray i) 7) (= (select monthArray i) Jul))))
(let (($x190 (=> (= (select inputArray i) 6) (= (select monthArray i) Jun))))
(let (($x193 (=> (= (select inputArray i) 5) (= (select monthArray i) May))))
(let (($x196 (=> (= (select inputArray i) 4) (= (select monthArray i) Apr))))
(let (($x199 (=> (= (select inputArray i) 3) (= (select monthArray i) Mar))))
(let (($x202 (=> (= (select inputArray i) 2) (= (select monthArray i) Feb))))
(let (($x205 (=> (= (select inputArray i) 1) (= (select monthArray i) Jan))))
(=> (and (>= i 0) (< i length)) (and $x205 $x202 $x199 $x196 $x193 $x190 $x187 $x184 $x181 $x178 $x175 $x172)))))))))))))))
)
(check-sat)