如果Code Contracts静态检查器能够检查算术绑定吗?

时间:2009-08-07 11:38:33

标签: static-analysis math code-contracts

(同样posted on the MSDN forum - 但据我所知,这并没有太大的流量。)

我一直在尝试提供AssertAssume的示例。这是我得到的代码:

public static int RollDice(Random rng)
{
    Contract.Ensures(Contract.Result<int>() >= 2 &&
                     Contract.Result<int>() <= 12);

    if (rng == null)
    {
        rng = new Random();
    }
    Contract.Assert(rng != null);

    int firstRoll = rng.Next(1, 7);
    Contract.Assume(firstRoll >= 1 && firstRoll <= 6);

    int secondRoll = rng.Next(1, 7);
    Contract.Assume(secondRoll >= 1 && secondRoll <= 6);

    return firstRoll + secondRoll;
}

(关于能够传入空引用而不是现有Random引用的业务当然是纯粹的教学法。)

我曾希望如果检查员知道firstRollsecondRoll各自都在[1, 6]范围内,那么就可以确定总和在[2, 12]范围内1}}。

这是一个无理的希望吗?我意识到这是一项棘手的事情,确切地说明可能会发生什么......但我希望检查器足够聪明:)

如果现在不支持此功能,那么有没有人知道它是否可能在近期的未来得到支持?

编辑:我现在发现静态检查器中有很复杂的算术选项。使用“高级”文本框,我可以从Visual Studio中试用它们,但据我所知,对它们的作用没有合适的解释。

2 个答案:

答案 0 :(得分:14)

我在MSDN论坛上得到了答案。事实证明我几乎就在那里。基本上,如果你拆分“和”合同,静态检查工作会更好。因此,如果我们将代码更改为:

public static int RollDice(Random rng)
{
    Contract.Ensures(Contract.Result<int>() >= 2);
    Contract.Ensures(Contract.Result<int>() <= 12);

    if (rng == null)
    {
        rng = new Random();
    }
    Contract.Assert(rng != null);

    int firstRoll = rng.Next(1, 7);
    Contract.Assume(firstRoll >= 1);
    Contract.Assume(firstRoll <= 6);
    int secondRoll = rng.Next(1, 7);
    Contract.Assume(secondRoll >= 1);
    Contract.Assume(secondRoll <= 6);

    return firstRoll + secondRoll;
}

没有任何问题。这也意味着该示例更有用,因为它突出了检查器 在分离出的合同中更好地工作的重点。

答案 1 :(得分:1)

我不了解MS Contracts Checker工具,但范围分析是一种标准的静态分析技术;它广泛用于商业静态分析工具,以验证下标表达是合法的。

MS Research在此类静态分析方面有良好的记录,因此我希望将此范围分析作为合同检查器的目标,即使目前尚未检查过。