Действительно ли это - ошибка в статическом средстве проверки контракта?

Если я пишу это:

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 || count > 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;

Ожидалось бы, что те два утверждения были эквивалентны, но статическое средство проверки рассматривает их по-другому.

(Я использую бету 2 VS10 между прочим),

6
задан R. Martinho Fernandes 17 December 2009 в 16:09
поделиться

2 ответа

Я бы не ожидал, что этот очень сложный прувер находится в полностью рабочем состоянии, поскольку это всего лишь бета-версия. Я думаю, что это ошибка или, по крайней мере, вопрос, который стоит обсудить с разработчиками, потому что это очень простая вещь для автоматической статической проверки.

В любом случае, судя по всему, маркер обеспечения просто указывает, есть ли Статическая проверка контрактов может проверить это условие или нет. Это не означает, что условие недействительно, это просто означает, что оно не может найти доказательства.

Я был бы гораздо более обеспокоен случаями, когда говорится, что что-то гарантировано, что является недопустимым. Это будет считаться ошибкой!

1
ответ дан 17 December 2019 в 22:13
поделиться

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.

0
ответ дан 17 December 2019 в 22:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: