Python 设置字符串约束的解算器
我正在尝试使用python中的z3实现一个问题(需要字符串操作)的解算器。 我试过阅读,但是没有足够的信息。我也试过阅读,但我找不到一种方法使我的例子起作用 我想设定:Python 设置字符串约束的解算器,python,z3,z3py,Python,Z3,Z3py,我正在尝试使用python中的z3实现一个问题(需要字符串操作)的解算器。 我试过阅读,但是没有足够的信息。我也试过阅读,但我找不到一种方法使我的例子起作用 我想设定: len(string) = 8 string[6] = 'a' string_possible_characters = '3456789a' string.count("6") = 2 在这种情况下,使用itertools(置换+组合)这样的工具更好吗?z3可以相对轻松地解决此类问题。关于API的使用有一点学习曲线,但它非常
len(string) = 8
string[6] = 'a'
string_possible_characters = '3456789a'
string.count("6") = 2
在这种情况下,使用itertools(置换+组合)这样的工具更好吗?z3可以相对轻松地解决此类问题。关于API的使用有一点学习曲线,但它非常值得投资。话虽如此,如果您的约束相对简单且字符串很短,那么使用常规编程枚举它们并检查约束是一种快速有效的选择。但对于更长的字符串和更复杂的约束,z3将是解决此类问题的最佳选择 下面是我将如何用Python编写您的示例:
#将z3纳入范围
从z3进口*
#找一个解算器
s=解算器()
#创建一个符号字符串
string=string('string')
#len(字符串)=8
s、 加(长度(字符串)==8)
#字符串[6]=“a”
s、 加法(SubSeq(string,6,1)=StringVal('a'))
#字符串\可能的\字符='3456789a'
chars=Union('345789a'中c的[Re(StringVal(c)])#注意我故意遗漏了6!
六=Re(StringVal('6'))
#string.count(“6”)=2
#创建正好匹配两个事件的正则表达式
#6和其他位置允许的任何其他字符
模板=Concat(星(字符),六,星(字符),六,星(字符))
#断言字符串与模板匹配
s、 添加(InRe(字符串、模板))
#得到一个模型
res=s.check()
如果res==sat:
打印s.model()
其他:
打印“解算器说:”,
打印资源
当我运行它时,我得到:
[string = "634436a9"]
满足你所有的约束条件。可以基于此模板构建其他约束的模型。API的相关部分如下所示:
请注意,Python并不是唯一一个提供Z3正则表达式和字符串访问的API;几乎所有其他到z3的高级绑定都包含某种级别的支持,包括C/C++/Java/Haskell等。根据这些绑定提供的抽象,这些约束甚至可能更容易编程。例如,以下是使用SBV Haskell软件包编写的相同问题,该软件包使用z3作为底层解算器:
{-#语言重载字符串}
导入数据.SBV
将限定的Data.SBV.String作为S导入
导入Data.SBV.RegExp
p::IO SatResult
p=sat$do s是否有一种更优雅的方法来创建接受StringVal('x')n次出现的正则表达式?例如:如果我必须检查2次出现的“d”,4次出现的“a”和2次出现的“m”,该怎么办?我应该创建三个不同的模板并将它们添加到解算器中吗?感谢您的全面回答。正则表达式语言相当有限;你得到的只是API中的内容。您必须使用它为您的问题构造适当的正则表达式。当然,您拥有宿主语言(Python/Haskell等)的强大功能,因此可以编写函数来为您构造此类正则表达式。
*Main> p
Satisfiable. Model:
string = "649576a8" :: String