2013-06-11 70 views

回答

0

AFAIK,Z3没有内置函数来访问列表的最后一个元素。由于SMT-Lib2不支持递归函数(请参阅this answer),因此您必须自行声明并公开未解释的last_element函数。

声明:

(declare-fun last_element ((List Int) (Int)) Bool) 

公理 “没有最后一个元素”:

(assert (forall ((x Int)) (! 
    (not (last_element nil x)) 
    :pattern ((last_element nil x)) 
))) 

公理“如果XS是列表X:无然后Xxs“的最后一个元素”:

(assert (forall ((xs (List Int)) (x Int)) (! 
    (implies 
    (= xs (insert x nil)) 
    (last_element xs x)) 
    :pattern ((last_element xs x)) 
))) 

公理 “如果XXS尾的最后一个元素,那么它也是XS本身的最后一个元素”:

(assert (forall ((xs (List Int)) (x Int)) (! 
    (implies 
    (last_element (tail xs) x) 
    (last_element xs x)) 
    :pattern ((last_element xs x)) 
))) 

看到这个rise4fun-link一个例。


请注意:基于模型量词实例化的连接示例开关(MBQI,见Z3 guide),并且因此依赖于E-匹配。这也是提供显式模式的原因,请参阅this question。如果你想给MBQI一个尝试,你可能不得不改变公理化,但我几乎不了解MBQI。

+1

感谢您的回答!但如果我们将'(assert(not(last_element xs 3)))'改为'(assert(last_element xs 3))',我们也会获得UNSAT。为什么? – user2475120

+0

@ user2475120对不起,我的坏。第三个公理使用了'iff'而不是'implies',这与'xs = x:nil'情况下的第一个公理相矛盾。 –

相关问题