通用列表的长度函数

时间:2012-06-19 14:25:35

标签: list function generics z3 axiom

This post展示了如何对Z3内置列表的长度函数进行公理化。但是,该函数是特定于排序的(此处为Int),不适用于bool或自定义排序列表。

; declare len as an uninterpreted function
(declare-fun len ((List Int)) Int)

; assert defining equations for len as an axiom
(assert (forall ((xs (List Int)))
  (ite (= nil xs)
    (= 0 (len xs))
    (= (+ 1 (len (tail xs))) (len xs)))))

编码排序通用列表函数的最智能方法是什么? (如果我没记错的话,函数本身就不是通用的。)

2 个答案:

答案 0 :(得分:2)

SMT 2.0格式或Z3 支持SMT 2.0脚本中的参数公理。一种替代方法是使用程序化API。您可以创建为给定排序创建len公理的函数。以下是使用Python API如何执行此操作的示例。

http://rise4fun.com/Z3Py/vNa

from z3 import *
def MkList(sort):
    List = Datatype('List')
    List.declare('insert', ('head', sort), ('tail', List))
    List.declare('nil')
    return List.create()


def MkLen(sort):
    List = MkList(sort)
    Len  = Function('len', List, IntSort())
    x    = Const('x', List)
    Ax   = ForAll(x, If(x == List.nil, Len(x) == 0, Len(x) == 1 + Len(List.tail(x))))
    return (Len, [Ax])

IntList = MkList(IntSort())
IntLen,  IntLenAxioms = MkLen(IntSort())
print IntLenAxioms
s = Solver()
l1 = Const('l1', IntList)
s.add(IntLenAxioms)
s.add(IntLen(l1) == 0)
s.add(l1 == IntList.insert(10, IntList.nil))
print s.check()

答案 1 :(得分:0)

您可以使用排序。 len函数是在用户定义的排序T的通用列表上定义的。只有第一个define-sort链接TInt类型。

(define-sort T () Int)
(define-sort MyList() (List T))

(declare-const listlen Int)
(declare-const a MyList)
(declare-const b MyList)
(declare-const c MyList)
(declare-const d MyList)
(declare-const e MyList)

(define-fun-rec len((l MyList)) Int
    (ite
        (= l nil)
        0
        (+ (len (tail l)) 1)
    )
)
(assert (= a nil))
(assert (= b (insert 2 a)))
(assert (= c (insert 8 b)))
(assert (= d (insert 6 c)))
(assert (= e (insert 10 d)))

(assert (= listlen (len e)))

(check-sat)
(get-model)