在我的一個SMT項目中,我使用了一個真正的術語。爲了提高效率,我需要限制實數的精度,因爲對於這個數來說,可能有幾乎無窮多的解,儘管只需要小數點後5/6位。例如,實數的可能估值可以如下,儘管如果我們取小數點後的前七位數字,所有的都是相同的。我們可以限制Z3中實項的精度嗎?
一千三百六十三萬一千四百八十八分之一百一十九萬七千三百二十五= 0.087835238530 ......
218103808分之19157213= 0.087835298134 ......
1744830464分之153257613= 0.087835245980 ......
1226060865/13958643712 = 0.087835243186 ......
我希望SMT解算器將所有這四個數字視爲一個數字(以便搜索空間減少)。有沒有辦法控制實數的精度?
我以編程方式嘗試(使用Z3 Dot Net API)來解決上述問題,如下所示。這裏DelBP [j]是一個真正的術語。
{
BoolExpr[] _Exprs = new BoolExpr[nBuses];
for (j = 1; j <= nBuses; j++)
{
_Exprs[j - 1] = z3.MkEq(DelBP[j], z3.MkDiv(z3.MkInt2Real(DelBP_A[j]), z3.MkInt2Real(DelBP_B[j])));
}
BoolExpr Expr = z3.MkAnd(_Exprs);
s.Assert(Expr);
tw.WriteLine("(assert {0})", Expr.ToString());
}
{
BoolExpr[] _Exprs = new BoolExpr[nBuses];
for (j = 1; j <= nBuses; j++)
{
_Exprs[j - 1] = z3.MkAnd(z3.MkGe(DelBP_A[j], z3.MkInt(1)),
z3.MkLe(DelBP_A[j], z3.MkInt(10000)));
}
BoolExpr Expr = z3.MkAnd(_Exprs);
s.Assert(Expr);
tw.WriteLine("(assert {0})", Expr.ToString());
}
{
BoolExpr[] _Exprs = new BoolExpr[nBuses];
for (j = 1; j <= nBuses; j++)
{
_Exprs[j - 1] = z3.MkAnd(z3.MkGe(DelBP_B[j], z3.MkInt(1)),
z3.MkLe(DelBP_B[j], z3.MkInt(10000)));
}
BoolExpr Expr = z3.MkAnd(_Exprs);
s.Assert(Expr);
tw.WriteLine("(assert {0})", Expr.ToString());
}
但是,它沒有奏效。任何人都可以幫我解決這個問題嗎?先謝謝你。
感謝您的回覆。我不能使用Integer術語,因爲我的實際問題需要浮點值。我已經應用第三種方法來查看通過爲精度添加約束條件可以得到多少不同的結果。但是,我的程序包括第二部分,這取決於這些潛在的價值。我不想將這兩部分分開並以編程方式將它們合併(即在模型外部)。我認爲你的第二個建議可能會起作用。你能提供給我任何鏈接或詳細的建議,可以幫助我更多地瞭解這一點嗎? – Ashiq
我認爲Z3 Dot Net API不支持IEEE浮點數。可以? – Ashiq
FP支持相當新穎,如果只有SMT-Lib暫時受支持,這並不會讓我感到意外。但其中一位Z3人需要證實這一點。有關更多信息,請參閱http://stackoverflow.com/questions/15181211/qf-fpa-does-z3-support-ieee-754-arithmetic。 –