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)))))
编码排序通用列表函数的最智能方法是什么? (如果我没记错的话,函数本身就不是通用的。)
答案 0 :(得分:2)
SMT 2.0格式或Z3 不支持SMT 2.0脚本中的参数公理。一种替代方法是使用程序化API。您可以创建为给定排序创建len
公理的函数。以下是使用Python API如何执行此操作的示例。
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
链接T
到Int
类型。
(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)