Различные выходные данные компиляции Dany для предложения свидетеля при компиляции с использованием VSC и автономного компилятора

У меня есть этот простой код, который использует предложение свидетеля для инициализации значения по умолчанию для переменной n. При компиляции с использованием автономной версии компилятора я получаю ожидаемое поведение, которое является значением свидетеля по умолчанию.

type Pos = i: int | i > 0 witness 1
method Main()
{ 
  var n:Pos;
  print "n:",n;
}

В справочном руководстве Dafny об этом ясно сказано,

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

Однако, когда я компилирую тот же код с помощью кода Visual Studio, он застревает при попытке инициализировать переменную. Он жалуется с сообщением об ошибке,

«переменная 'n', на которую распространяются правила определенного присваивания, может быть здесь неинициализирована"

Выход терминала,

PS C:\Users\Acer.vscode\extensions\dafny-lang.ide-vscode-3.0.9\out\resources\4.0.0\github\dafny> & "C:\Program Files\dotnet6\dotnet.exe" c:\Users\Acer.vscode\extensions\dafny-lang.ide-vscode-3.0.9\out\resources\4.0.0\github\dafny\Dafny.dll запустите "e:\witness\witnessexample.dfy"

e:/witness/witnessexample.dfy(12,14): ошибка: здесь может быть неинициализирована переменная 'n', на которую распространяются правила определенного присваивания.

В настоящее время отдельной версией Dafny является 4.0.0.50303.

Возможно ли, что версия Dafny.dll несовместима с Dafny.exe?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я подозреваю, что процитированный вами абзац, вероятно, относится только к контексту проверки, а не к скомпилированному контексту. Это означает, что если вы пытаетесь проверить различные свойства, компилятор доберется до этого значения по умолчанию для инициализации при проверке операторов. Компилятор проверки проверяет значения, чтобы убедиться, что свойства допустимы.

Однако, если вы добавите утверждение в функцию.

method Main()
{ 
  var n:Pos;
  assert n == 1;
  print "n:",n;
}

Вы можете видеть, что Дафни не предполагает, что 1 является значением переменной по умолчанию.

Ваш комментарий не отвечает на вопрос. Спецификация ясна в отношении использования свидетеля для инициализации переменной со значением по умолчанию. Автономная компиляция не жалуется, в то время как VSC жалуется на неинициализацию n. Что касается утверждения, кажется, что свидетель не эффективен в утверждениях-призраках, и спецификации Дафни этого не предполагают.

Abdallah Rayhan 03.04.2023 03:37

Ну это ваша интерпретация. Я не в команде разработчиков Dafny, но если вы считаете, что это ошибка в Dafny 4.0, вы должны опубликовать это как проблему на github Dafny. github.com/dafny-lang/dafny/issues

Hath995 03.04.2023 14:00
Ответ принят как подходящий

Объяснение

Проблема, с которой вы столкнулись, заключается в том, что правила определенного назначения Dafny изменились в Dafny 4.0, см. https://github.com/dafny-lang/ide-vscode/wiki/Quick-migration-guide-from-Dafny-3. .X-to-Dafny-4.0#определенное-назначение.

Когда вы используете VS Code, вы получаете новое, более строгое правило. Вы также получаете это более строгое правило в новом интерфейсе командной строки (в этом интерфейсе командной строки используются такие глаголы, как verify и run). Например, вы увидите ту же ошибку, если попытаетесь

dafny verify test.dfy

Однако устаревший интерфейс командной строки (то есть без использования такого глагола) по-прежнему использует старое смягченное правило определенного назначения. Следовательно, команда

dafny test.dfy

не дает никакой ошибки.

Что делать

Обычно ответом на ошибку определенного присваивания является ручная инициализация переменной. Однако, если вы согласны с тем, что Дафни выбирает произвольное значение для локальной переменной n, вы можете использовать присваивание n := *;. Поскольку Pos является типом с автоматической инициализацией (то есть компилятор знает, что тип непустой, и знает какой-то способ инициализации переменной), присваивание n := *; будет удовлетворять правилу определенного присваивания.

Больше информации

Если вам нужно старое правило (которое я не рекомендую, если только у вас нет устаревшего кода Dafny, который вы пытаетесь перенести в Dafny 4.0), вы можете использовать опцию --relax-definite-assignment с новым интерфейсом командной строки. Если вы хотите строгое правило с устаревшим интерфейсом командной строки, используйте опцию /definiteAssignment:4.

Последнее замечание. Предложение, которое вы цитируете из справочного руководства, сбивает с толку. (Я сообщу об ошибке, чтобы исправить ее.) Предложение witness не объявляет значение по умолчанию. Он только объявляет примерное значение, которое используется в качестве доказательства того, что существует значение, которое компилятор может использовать для инициализации переменных. Язык не гарантирует, что вы получите именно это значение. Показательный пример: верификатор пометит второе утверждение в следующем коде как ошибку, потому что нет гарантии, что выбранное значение будет 1.

type Pos = i: int | i > 0 witness 1

method Main()
{ 
  var n: Pos := *;
  assert n > 0; // yes, the verifier proves this assertion
  assert n == 1; // error: variable n can be any value of type Pos, not necessarily 1
  print "n:", n;
}

Ошибка документации отправлена ​​как github.com/dafny-lang/dafny/issues/3834.

Rustan Leino 03.04.2023 20:44

Это проясняет. Я предполагаю, что «можно использовать» является источником путаницы. Вероятно, "компилятор может, но не обязательно использовать для инициализации" больше похоже на это.

Abdallah Rayhan 04.04.2023 16:39

Другие вопросы по теме