Вопрос или проблема
import Lean1.Basic
structure ArrayN (n : Nat) (α : Type) where
array : { array : Array α // array.size = n }
class Hash (HashType: Type) where
hashSize: Nat
hash: x -> ArrayN (hashSize) UInt8
structure Private (Key: Type) (HashType: Type) [Hash HashType] where
keys: ArrayN (Hash.hashSize HashType) Key
structure Public (HashType: Type) [Hash HashType] where
hashes:
let n := Hash.hashSize HashType
ArrayN n (ArrayN n UInt8)
def Public.fromPrivate {K: Type} {HashType: Type} [Hash HashType] (priv: Private K HashType): Public HashType := {
hashes := priv.keys.array.map (λ key => hash key)
}
Код выше дает
недопустимое поле 'map', окружение не содержит 'Subtype.map'
priv.keys.array
имеет тип
{ array // array.size = Hash.hashSize HashType }
У меня небольшая проблема с работой с зависимыми типами. Как мне поступить? Я знаю, что мне нужно получить доступ к внутреннему Array из ArrayN
, чтобы у него был .map
, но я не знаю как.
Также, вероятно, мне нужно будет доказать, что возвращаемый результат имеет тип Public, но я тоже не знаю как.
Ответ или решение
Пример зависимого типа в Lean4: Решение проблемы с ArrayN
и доступом к полям
В Lean4, работа с зависимыми типами может быть немного запутанной, особенно для тех, кто только начинает исследовать эту область. В данном ответе я помогу разобраться с ошибкой, связанной с использованием типа ArrayN
и доступом к его внутреннему массиву в контексте вашего вопроса.
Понимание ошибки
Ошибка, с которой вы столкнулись, связана с тем, что вы пытаетесь применить метод .map
к полю array
структуры ArrayN
, которая сама по себе является зависимым типом. В Lean4 доступ к полям этих типов требует более явного указания типа, поскольку у вас нет прямого доступа к массиву без учета условий размера, определенного в зависимости n
.
Решение проблемы
Чтобы использовать метод .map
для внутреннего массива, нужно немного изменить вашу функцию Public.fromPrivate
. Вместо того чтобы пытаться вызвать map
напрямую на priv.keys.array
, вам нужно извлечь массив и тогда применить .map
.
Вот исправленная версия вашей функции:
def Public.fromPrivate {K: Type} {HashType: Type} [Hash HashType] (priv: Private K HashType): Public HashType := {
hashes := let innerArray := priv.keys.array.get -- Извлекаем внутренний массив
innerArray.map (λ key => Hash.hash key) -- Применяем map к внутреннему массиву
}
Здесь мы используем let innerArray := priv.keys.array.get
, чтобы получить доступ к внутреннему массиву типа Array α
, и только после этого вызываем map
, передавая функцию хеширования.
Доказательство, что результат соответствует типу Public
Теперь, когда мы правильно извлекли внутренний массив и применили к нему метод map
, структура Public
будет инициализирована корректно. Доказательство того, что возвращаемый результат соответствует типу Public
, будет автоматическим в Lean, основанным на том, что вы соблюдаете все предшествующие определения типов и свойства классов. Когда вы вызываете конструктор Public
, будет проверено, что hashes
имеет правильный тип, благодаря зависимым типам.
Заключение
Работа с зависимыми типами в Lean4 требует внимательного обращения с типами и явного доступа к полям. Извлечение внутреннего массива из зависимого типа, такого как ArrayN
, делает вашу функцию fromPrivate
правильной и позволяет вам избежать ошибок компиляции.
Теперь вы можете успешно использовать хеши для создания Public
типа из Private
, и при этом ваши виды остаются корректными. Если у вас есть дополнительные вопросы или вам нужна дополнительная помощь в Lean4, не стесняйтесь обращаться!