Функция Dafny, недопустимое логическое выражение в цикле while

Я новичок в Dafny и получаю некоторые ошибки, которые не могу понять.

  • в моей программе Dafny для insertionSort (код находится здесь), я не понимаю, почему я получаю invalid logical expression on В то время как цикл над переменной i. while (i < |input|)
  • в том же коде в части подкачки (input[j := b]; input[j-1 := a];) также я получаю expected method call, found expression. Согласно учебнику input[j:=b] заменяет индекс j ввода seq значением b

person Amir-Mousavi    schedule 21.05.2018    source источник


Ответы (1)


Первая ошибка заключается в том, что вы объявлены function, а не method. В Dafny тело function должно быть выражением, а не последовательностью операторов. Итак, когда синтаксический анализатор видит ключевое слово «пока», он понимает, что что-то не так (поскольку «пока» не может быть частью оператора) и выдает сообщение об ошибке. Я не уверен, почему сообщение об ошибке относится к «логическому» выражению.

В любом случае, вы можете решить эту проблему, объявив method, а не function.

Вам нужен метод, потому что вы используете императивный алгоритм, а не функциональный алгоритм. Это правда, что вам нужна подпрограмма, которая вычисляет свои выходные данные как функцию своих входных данных без побочных эффектов. Но в Dafny вы по-прежнему используете для этого method, когда вы хотите сделать это с помощью императивных конструкций, таких как присваивания и циклы while.


Вторая проблема заключается в том, что input[j := b] является выражением, тогда как синтаксический анализатор ожидал оператора. Вы можете исправить это, переписав input[j := b]; input[j-1 := a]; как input := input[j:=b]; input := input[j-1];.


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

method insertionSort(input:seq<int>)
// The next line declares a variable you can assign to.
// It also declares that the final value of this variable is the result
// of the method.
returns( output : seq<int> )
    // No reads clause is needed.
    requires |input|>0
    // In the following I changed "input" to "output" a few places
    ensures perm(output,old(input))
    ensures sortedBetween(output, 0, |output|) // 0 to input.Length = whole input

{
    output := input ;
    // From here on I changed your "input" to "output" most places
    var i := 1;
    while (i < |output|) 
        invariant perm(output,old(input))
        invariant 1 <= i <= |output|
        invariant sortedBetween(output, 0, i)       
        decreases |output|-i
    {
        ...
            output := output[j := b];
            output := output[j-1 := a];
            j := j-1;
        ...
    }
}

Кстати, поскольку входные параметры изменить нельзя, везде, где у вас есть old(input), вы можете просто использовать input. Они означают одно и то же.

person Theodore Norvell    schedule 21.05.2018
comment
Спасибо за Ваш ответ. вот проблема, которая гарантирует, что перед назначением ввода для вывода (выход: = ввод) не выполняется. должен ли я переместить их все как инвариантные внутрь тела метода? - person Amir-Mousavi; 22.05.2018
comment
поэтому в этом случае пост-условие не выполняется, и инвариант perm(output,old(output)) говорит: возможное нарушение предварительного условия функции - person Amir-Mousavi; 22.05.2018
comment
Ваш вопрос касался синтаксических ошибок, поэтому я дал достаточно ответа, чтобы привести вас к моменту, когда код пройдет проверку синтаксиса и другие проверки, которые необходимо пройти, прежде чем код можно будет отправить верификатору. Теперь, когда код попадает к верификатору, вы получаете ошибки проверки. Ниже приведены некоторые краткие ответы на эти новые вопросы. - person Theodore Norvell; 23.05.2018
comment
«обеспечивает» назначение ввода для вывода (выход: = ввод) не выполняется. Несмотря на то, что гарантия предшествует телу, ожидается, что она будет истинной после того, как тело будет завершено. В любом случае оставьте гарантии там, где они есть. Предложения requires и ensures — это все, от чего могут зависеть вызывающие методы. - person Theodore Norvell; 23.05.2018
comment
инвариант perm(output,old(output)) говорит: возможно нарушение предусловия функции. Вам может понадобиться другой инвариант, чтобы сказать, что длина output такая же, как длина input. Поместите его раньше, чем тот, у которого проблема с предварительным условием. - person Theodore Norvell; 23.05.2018
comment
в этом случае пост-условие не выполняется. Я думаю, что это следствие того, что инвариант не проверяется. В любом случае убедитесь, что все инварианты проверяются, прежде чем беспокоиться о постусловиях. - person Theodore Norvell; 23.05.2018
comment
большое спасибо за твою помощь. Также я только что узнал о «свежем» ключевом слове, которое очень помогло и изменило инварианты. Спасибо еще раз - person Amir-Mousavi; 23.05.2018