这是静态合约检查器中的错误吗?

发布于 2024-08-15 09:06:32 字数 1698 浏览 1 评论 0原文

如果我这样写:

public sealed class Foo
{
    private int count;
    private object owner;
    private void Bar()
    {
        Contract.Requires(count > 0);
        Contract.Ensures(owner == null || count > 0);

        if (count == 1)
            owner = null;
        --count;
    }
}

静态合约检查器可以证明所有断言。

但如果我这样写:

public sealed class Foo
{
    private int count;
    private object owner;
    private void Bar()
    {
        Contract.Requires(count > 0);
        Contract.Ensures(owner == null || count > 0);

        --count;
        if (count == 0)
            owner = null;
    }
}

它声明后置条件 owner == null ||计数> 0 未经证实。

我想我可以证明第二种形式不违反这个后置条件:

// { count > 0 } it's required
--count;
// { count == 0 || count > 0 } if it was 1, it's now zero, otherwise it's still greater than zero
if (count == 0)
{
    // { count == 0 } the if condition is true
    owner = null;
    // { count == 0 && owner == null } assignment works
}
// { count == 0 && owner == null || count != 0 && count > 0 } either the if was entered or not
// { owner == null || count > 0 } we can assume a weaker postcondition

我的证明有问题吗?

我在证明中添加了断言,作为对代码的 Contract.Assert 调用,我得出的结论是,如果我仅添加这一断言,它就能够证明后置条件:

--count;
Contract.Assert(count == 0 || count > 0)
if (count == 0)
    owner = null;

但是,如果我现在更改以“更自然”的方式进行相同的断言,它会失败:

--count;
Contract.Assert(count >= 0)
if (count == 0)
    owner = null;

预计这两个断言是等效的,但静态检查器以不同的方式对待它们。

(顺便说一句,我正在使用 VS10 的 beta 2)

If I write this:

public sealed class Foo
{
    private int count;
    private object owner;
    private void Bar()
    {
        Contract.Requires(count > 0);
        Contract.Ensures(owner == null || count > 0);

        if (count == 1)
            owner = null;
        --count;
    }
}

The static contract checker can prove all assertions.

But if I write this instead:

public sealed class Foo
{
    private int count;
    private object owner;
    private void Bar()
    {
        Contract.Requires(count > 0);
        Contract.Ensures(owner == null || count > 0);

        --count;
        if (count == 0)
            owner = null;
    }
}

It claims the postcondition owner == null || count > 0 is unproven.

I think I can prove the second form does not violate this postcondition:

// { count > 0 } it's required
--count;
// { count == 0 || count > 0 } if it was 1, it's now zero, otherwise it's still greater than zero
if (count == 0)
{
    // { count == 0 } the if condition is true
    owner = null;
    // { count == 0 && owner == null } assignment works
}
// { count == 0 && owner == null || count != 0 && count > 0 } either the if was entered or not
// { owner == null || count > 0 } we can assume a weaker postcondition

Is something wrong with my proof?

I added the assertions in my proof as Contract.Assert calls to the code, and I came to the conclusion that if I add just this one, it manages to prove the postcondition:

--count;
Contract.Assert(count == 0 || count > 0)
if (count == 0)
    owner = null;

But, if I now change that same assertion to a "more natural" way, it fails:

--count;
Contract.Assert(count >= 0)
if (count == 0)
    owner = null;

It would be expected that those two assertions were equivalent, but the static checker treats them differently.

(I'm using beta 2 of VS10 by the way)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

滴情不沾 2024-08-22 09:06:32

我不希望这个高度复杂的证明器处于完全工作状态,因为它毕竟只是一个测试版。我认为这是一个错误,或者至少是值得向开发人员提出的一点,因为自动静态检查是一件非常简单的事情。

不管怎样,从表面上看,确保标记只是用来说明静态合约检查器是否能够确保条件。这并不意味着条件无效,只是意味着找不到证据。

我会更担心它说某些内容是无效的。 将被视为一个错误!

I wouldn't expect this highly complex prover thing to be in a fully working state yet since it's just a beta after all. I think it is a bug or at least a point worth raising with the developers, because this is a very simple thing to static check automatically.

Anyway, by the looks of things, the ensures marker is just there to say whether the static contract checker is able to ensure the condition or not. This does not imply that the condition is not valid, it just means it can't find a proof.

I would be much more worried about cases where it says something is ensured which is invalid. That would count as a bug!

肥爪爪 2024-08-22 09:06:32

警告:我对 .net 合约系统的细节一无所知

然而,我可以告诉你:实际上不可能(参见停止问题)为与系统支持的断言一样丰富的断言生成一个完整的证明者。

那么:这是一个错误吗?不。

另一方面,似乎有理由认为这可能是证明者的实现者可能想要添加到他们的系统中的常见情况。

Caveat: I know absolutely nothing about the specifics of the .net contract system.

However, I can tell you this: it's literally not possible (cf. halting problem) to produce a complete prover for assertions as rich as the one that it appears this system supports.

So: is this a bug? No.

On the other hand, it seems plausible to suggest that this might be a common case that the implementors of the prover might want to add to their system.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文