0

私の SMT プログラムの 1 つで、実数を使用しています。小数点以下 5/6 桁のみが必要ですが、この数値にはほぼ無限の数の解が可能であるため、効率を上げるために実数の精度を制限する必要があります。たとえば、実数の可能な評価は次のようになりますが、小数点以下の最初の 7 桁を取る場合はすべて同じです。

1197325/13631488 = 0.087835238530......

19157213/218103808 = 0.087835298134......

153257613/1744830464 = 0.087835245980......

1226060865/13958643712 = 0.087835243186......

SMT ソルバーがこれら 4 つの数値をすべて 1 つの数値と見なすようにします (検索スペースを減らすため)。実数の精度を制御する方法はありますか?

以下に示すように、上記の問題をプログラムで (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());
}

しかし、うまくいきませんでした。誰でもこの問題を解決するのを手伝ってもらえますか? 前もって感謝します。

4

1 に答える 1