Я новичок в зависимых типах и, имея опыт работы с Haskell, медленно изучаю Idris. В качестве упражнения я хочу написать кодировку Хаффмана. В настоящее время я пытаюсь написать доказательство того, что «сглаживание» дерева кода дает префиксный код, но застрял с квантификаторами.
У меня есть простое индуктивное предположение, что один список является префиксом другого:
using (xs : List a, ys : List a)
data Prefix : List a -> List a -> Type where
pEmpty : Prefix Nil ys
pNext : (x : a) -> Prefix xs ys -> Prefix (x :: xs) (x :: ys)
Это верный подход? Или что-то вроде "xs является префиксом ys, если существует zs, такое что xs ++ zs = ys" будет лучше?
Правильно ли было ввести квантификатор forall (насколько я понимаю, в Агде это будет что-то вроде
pNext : ∀ {x xs ys} → Prefix xs ys → Prefix (x :: xs) (y :: ys)
)? Должен ли первый аргумент pNext быть неявным? Каковы семантические различия между двумя вариантами?
Затем я хочу построить один для вектора, где ни один из элементов не образует префикс другого:
data PrefVect : Vect n (List a) -> Type where
Пустой вектор не имеет префиксов:
pvEmpty : PrefVect Nil
и учитывая элемент x, вектор xs и доказательства того, что ни один элемент xs не является префиксом x (и наоборот), x :: xs будет обладать этим свойством:
pvNext : (x : [a]) -> (xs : Vect n [a]) ->
All (\y => Not (Prefix x y)) xs ->
All (\y => Not (Prefix y x)) xs ->
PrefVect (x :: xs)
Это недопустимый тип, который я надеюсь исправить после того, как разберусь с первым, но есть аналогичный вопрос о квантификаторах в pvNext: допустим ли этот вариант, или есть лучший способ сформировать «отрицание отношения»?
Спасибо.