使用Haskell Z3 API进行相互递归的数据类型声明

时间:2017-03-07 18:59:11

标签: haskell z3 smt

我正在尝试使用这个Haskell包:

https://hackage.haskell.org/package/z3

是Z3 C API的包装器,用于处理相互递归的数据类型。作为测试,我试图将以下SMT2脚本转换为Haskell函数。

(declare-datatypes () ((X (a (y Y)) ac)
                  (Y (b (x X)) bc)))

(declare-const a_v (X))
(declare-const b_v (Y))

(assert (= a_v (a b_v)))

(check-sat)
(get-model)

目前,我能找到最接近的方法是:

mutuallyRecursive :: IO (Result, Maybe Model)
mutuallyRecursive = evalZ3 mutuallyRecursive'
    where
        mutuallyRecursive' :: Z3 (Result, Maybe Model)
        mutuallyRecursive' = do
            x' <- mkStringSymbol "X"
            y' <- mkStringSymbol "Y"
            _x <- mkStringSymbol "x"
            _y <- mkStringSymbol "y"

            a' <- mkStringSymbol "a"
            ac' <- mkStringSymbol "ac"
            b' <- mkStringSymbol "b"
            bc' <- mkStringSymbol "bc"

            is_a <- mkStringSymbol "is-a"
            is_ac <- mkStringSymbol "is-ac"
            is_b <- mkStringSymbol "is-b"
            is_bc <- mkStringSymbol "is-bc"

            b <- mkConstructor b' is_b [] --Should contain an X
            bc <- mkConstructor bc' is_bc []
            y <- mkDatatype y' [b, bc]

            a  <- mkConstructor a' is_a [(_x, Just y, 0)]
            ac <- mkConstructor ac' is_ac []
            x <- mkDatatype x' [a, ac]

            a_v' <- mkStringSymbol "a_v"
            b_v' <- mkStringSymbol "b_v"
            a_v <- mkConst a_v' x
            b_v <- mkConst b_v' y

            [a_func, _] <- getDatatypeSortConstructors x
            a_b_v <- mkApp a_func [b_v]

            assert =<< mkEq a_v a_b_v

            solverCheckAndGetModel

请注意,数据类型为Y的构造函数b在我的Haskell实现中是不正确的。它缺少类型X的参数。但是,我不能直接包含排序X,因为它尚未声明。但是如果我交换了X和Y定义的顺序,我明显遇到了同样的问题,只是逆转了(即,我需要,但不能在X中引用Y.)

基于此页面上的MkConstructor定义(涉及C api,而不是Haskell api):

http://z3prover.github.io/api/html/class_microsoft_1_1_z3_1_1_context.html#a2a421919ab766bf028ec422723b42e37

我想也许我必须将[(symbol,Nothing,#)]形式的东西传递给mkConstructor,其中#是数据类型X的一些非零标识符。但我不是百分之百确定这是正确的,并且即使是,我也不知道如何获得#。任何帮助解决这个问题将不胜感激。

0 个答案:

没有答案