簡體   English   中英

在z3 smt2中使用整數除法時未知

[英]unknown when using a integer division in z3 smt2

我試圖找到函數penta(n)=(n *(3n -1))/ 2的解決方案,其中對於所有正數,penta(z)= penta(a)+ penta(b)。 在整數除法(div)成為定義的一部分之前,這種方法一直有效,但是在定義中添加整數除法后,我要么超時,要么未知 我期望得到8,7,4。對我做錯了什么有任何想法嗎?

(declare-const a Int)
(declare-const b Int)
(declare-const z Int)

(define-fun penta ((n Int)) Int (div (* (- (* 3 n ) 1) n) 2) )  

(assert (= (penta z) (+ (penta a) (penta b))  ))
(assert (> a 1))
(assert (> b 1))
(assert (> z 1))

(check-sat)
(get-model)

我正在使用http://rise4fun.com/Z3網站上的版本和4.1(x64)版本。

主要問題是該問題在兩個非數字參數之間使用整數乘法。 對於一般的丟番圖問題,沒有決策程序,因此Z3會盡力而為,這不利於模型枚舉。

當您不使用整數除法時,Z3將基於將問題轉換為有限域位向量以查找模型的方式嘗試部分啟發式。 它通過對公式執行語法檢查來調用此啟發式方法。 使用運算符(div..2)時語法檢查失敗。 您可以進行編碼(div x 2),因此啟發式方法可以通過引入新鮮變量並對它們進行邊界來解決問題:

(declare-const penta_z Int)
(declare-const penta_a Int)
(declare-const penta_b Int)
(assert (or (= (* 2 penta_z) (penta z)) (= (+ 1 (* 2 penta_z)) (penta z))))
(assert (or (= (* 2 penta_a) (penta a)) (= (+ 1 (* 2 penta_a)) (penta a))))
(assert (or (= (* 2 penta_b) (penta b)) (= (+ 1 (* 2 penta_b)) (penta b))))
(assert (= penta_z (+ penta_a penta_b)  ))
(assert (> a 1))
(assert (> b 1))
(assert (> z 1))
(assert (>= penta_z 0))
(assert (<= penta_z 100))

您也可以使用位向量直接編碼問題,盡管這開始容易出錯,因為您必須處理如何處理溢出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM