2013-06-11 111 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'情況下的第一個公理相矛盾。 –

相關問題