Pergunta

(Também publicado de o fórum MSDN -. mas isso não ficar muito tráfego, tanto quanto eu posso ver)

Eu tenho tentado dar um exemplo de Assert e Assume. Aqui está o código que eu tenho:

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

(O negócio de ser capaz de passar em uma referência nula em vez de uma referência Random existente é puramente pedagógica, é claro.)

Eu esperava que, se o verificador sabia que firstRoll e secondRoll foram, cada um na [1, 6] gama, seria capaz de trabalhar que a soma estava no [2, 12] gama.

Esta é uma esperança razoável? Sei que é um negócio complicado, trabalhando para fora exatamente o que pode acontecer ... mas eu estava esperando o verificador seria suficiente inteligente:)

Se isto não é suportado agora, alguém aqui sabe se é susceptível de ser suportado no futuro próximo-ish?

EDIT: Descobri agora que há opções muito complicado para a aritmética no verificador estático. Usando a caixa de texto "avançado" Eu posso testá-los a partir do Visual Studio, mas não há nenhuma explicação razoável de que eles fazem, tanto quanto eu posso dizer.

Foi útil?

Solução

Eu tive uma resposta no fórum MSDN. Acontece que eu estava quase lá. Basicamente o verificador estático funciona melhor se você dividir out "e-ed" contratos. Então, se nós mudar o código para isso:

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

que funciona sem quaisquer problemas. Significa, também, o exemplo é ainda mais útil, como destaca o próprio ponto que o verificador faz trabalho melhor com contratos separados para fora.

Outras dicas

Eu não sei sobre o MS Contratos ferramenta Verificador, mas a análise gama é uma técnica de análise estática padrão; é amplamente utilizado em ferramentas de análise estática comerciais para verificar que as expressões de subscrito são legais.

MS Research tem um registro bom caminho neste tipo de análise estática, e assim eu esperaria fazer tal análise intervalo para ser uma meta dos Contratos Checker, mesmo que atualmente não marcada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top