酸洗Z3 Python对象

时间:2013-01-30 03:54:46

标签: python z3 pickle

是否支持对未来版本进行酸洗(或序列化)Z3对象?我目前正在尝试将Z3 Python API生成的模型挑选到一个文件中,并且我收到错误消息ctypes objects containing pointers cannot be pickled,我认为这意味着Python API仅仅是Z3 DLL的包装。

或者是否有更好的方法将Z3 Python API生成的对象保存到文件中以供将来使用?

谢谢!

1 个答案:

答案 0 :(得分:2)

是的,Z3 Python API是Z3共享库(即Windows上的DLL)的包装器。 将方法__getstate__()__setstate(state)__添加到包含公式,模型等的Z3 Python对象是可行的。如果这些方法可用,Python pickler将使用它们。 因此,原则上可以添加此功能。也就是说,我们可以添加Z3 API(C API)程序,用于将Z3表达式/公式和模块编码/解码为字节流。然后,这些API用于实现__getstate__()__setstate(state)__。有一些细节:

  • 共享:假设我们有一个Z3表达式的Python列表,这些表达式共享很多子表达式。 Python pickler将为列表的每个元素调用__getstate__(),Z3将多次编码共享子表达式。问题在于,对于Python,每个Z3表达式都是“blob”,并且Z3编码器/序列化器不知道这些不同的表达式是更大的Python数据结构的一部分。因此,用户在挑选包含对许多不同Z3对象的引用的Python对象时应该小心。请注意,在某些情况下,很容易解决此问题。例如,我们可以使用Z3 ASTVector而不是Z3表达式的Python列表。然后,Z3可以将ASTVector编码为一个大的“blob”,其中每个共享子表达式只编码一次。

  • Z3对象(例如表达式和模型)与上下文相关联。请注意,Python API中的大多数过程都有一个额外的ctx参数。例如,Int('x')在默认上下文中创建名为x的整数变量,Int('x', ctx)在上下文ctx中创建它。多个上下文很有用,因为我们可以从不同的执行线程同时访问它们。当我们取消对Z3对象的去除时,我们必须决定在哪个上下文中存储它。可能性是设置指定要使用的上下文的全局参数。如果未设置,则使用默认上下文。 这不是一个完美的解决方案。假设我们有一个Python数据结构,其中包含对来自不同上下文的Z3表达式的引用,我们腌制它。然后,当我们解开数据时,所有表达式都将被添加到相同的Z3上下文中。也许,这不是一个大问题,因为大多数用户只使用一个Z3上下文,而使用多个上下文的用户通常不会在同一个Python对象中存储来自不同上下文的表达式的引用。

请随时提出替代解决方案。 Z3团队中没有一个人是Python专家。