Спасибо за ваши вопросы.
1) Да, есть сейчас.Сегодня я зарегистрировал изменение в компиляторе, которое позволяет писать
Calculation.create_Sum(A, B)
вместо предыдущего
new Calculation(new Calculation_Sum(A, B))
Если тип данных имеет параметры типа, они идут сразу после имени типа.
2) Вы можете избежать искаженных имен, таких как _0_DafnyCalculation_Compile
, предоставив свои собственные через {:extern YourNameGoesHere}
, которые можно размещать в объявлениях, таких как модули, классы и методы.(Если некоторые объявления не поддерживают :extern
там, где вам это нужно, пожалуйста, сообщите об этом как об ошибке.)
(В последнее время я работал над некоторыми изменениями компилятора. Возможно, я смогуво многих случаях автоматически удаляем префикс _0_
или суффикс _Compile
. Посмотрим.)
3) Если вы используете тип Дафни int
, то вы должны использовать BigInteger
какупоминается.Но если вы хотите использовать собственные целочисленные типы, вы можете объявить свои собственные целочисленные типы в Dafny.Например,
newtype int32 = x | -0x8000_0000 <= x < 0x8000_0000
объявляет тип Дафни int32
, значения которого находятся в данном диапазоне.(В этом примере x
подразумевается как тип int
, но вы также можете явно указать тип, например newtype int32 = x: int | ...
.) Компилятор Dafny замечает, что этот диапазон помещается в 32-разрядное целое число со знаком (записываетсяint
в C #) и, следовательно, скомпилирует ваш тип Dafny int32
в C # int
.Это работает для всех собственных целочисленных типов .NET.
Если по какой-то причине вы хотите использовать больший собственный целочисленный тип, чем позволяет ваш диапазон, то вы можете указать, что вы хотите, с помощью атрибута :nativeType
.Например,
newtype {:nativeType "short"} byteStoredUsing16Bits = x | -128 <= x < 128
будет использовать .NET short
для хранения вашего типа byteStoredUsing16Bits
.Без атрибута :nativeType
компилятор Dafny выберет тип .NET sbyte
для byteStoredUsing16Bits
.
Вы также можете использовать {:nativeType false}
с newtype
, чтобы сказать, что вы не хотитекомпилятор должен использовать собственное целое число (но вместо этого использовать BigInteger
как обычно).
Обратите внимание, что объявление newtype
позволяет вам определять ваши собственные целочисленные типы, но они несовместимы со стандартом Дафни int
.Основная причина использования newtype
, в отличие от объявления типа поднабора (с использованием ключевого слова type
вместо newtype
), состоит в том, чтобы позволить компилятору использовать другое представление.Если вам нужно выполнить преобразование между различными целочисленными типами, используйте оператор as
.Следующий фрагмент кода иллюстрирует:
var x: int := 70;
var y: int32 := x as int32;
var z: byteStoredUsing16Bits := y as byteStoredUsing16Bits;
x := z as int;
Математически оператор as
является функцией частичной идентичности.То есть as
никогда не изменяет значение, и верификатор проверит, что ваше преобразование получено из значения, которое существует в типе назначения.(В качестве упражнения измените 70
в примере на 700
и посмотрите, как проверяет жалобщик.)
Также обратите внимание, что все промежуточные выражения типа newtype
должны также соответствовать любому предикатууказать.
Растан