我正在撰写一篇本科论文,关于依赖类型的实用性。 我试图构建一个容器,只能构建成排序列表,以证明它是通过构造而排序的:
import Data.So
mutual
data SortedList : (a : Type) -> {ord : Ord a) -> Type where
SNil : SortedList a
SMore : (ord : Ord a) => (el: a) -> (xs : SortedList a) -> So (canPrepend el xs) -> SortedList a
canPrepend : Ord a => a -> SortedList a -> Bool
canPrepend el SNil = True
canPrepend el (SMore x xs prf) = el <= x
SMore
需要一个运行时证明,证明要插入的元素小于或等于排序列表中最小(第一个)元素。
为了对未排序的列表进行排序,我创建了一个函数sinsert
,它接受一个已排序的列表并插入一个元素,并返回一个已排序的列表:
sinsert : (ord : Ord a) => SortedList a {ord} -> a -> SortedList a {ord}
sinsert SNil el = SMore el SNil Oh
sinsert (SMore x xs prf) el = either
(\p =>
-- if el <= x we can prepend it directly
SMore el (SMore x xs prf) p
)
(\np =>
-- if not (el <= x) then we have to insert it in the tail somewhere
-- does not (el <= x) imply el > x ???
-- we construct a new tail by inserting el into xs
let (SMore nx nxs nprf) = (sinsert xs el) in
-- we get two cases:
-- 1) el was prepended to xs and is now the
-- smalest element in the new tail
-- we know that el == nx
-- therefor we can substitute el with nx
-- and we get nx > x and this also means
-- x < nx and also x <= nx and we can
-- prepend x to the new tail
-- 2) el was inserted somewhere deeper in the
-- tail. The first element of the new tail
-- nx is the same as it was in the original
-- tail, therefor we can prepend x to the
-- new tail based on the old proof `prf`
either
(\pp =>
SMore x (SMore nx nxs nprf) ?iins21
)
(\npp =>
SMore x (SMore nx nxs nprf) ?iins22
) (choose (el == nx))
) (choose (el <= x))
我在构建证明时遇到了麻烦(?iins21
,?iins22
),希望能得到一些帮助。我可能在依赖一个不成立的假设,但我没有看出来。
我还想鼓励您提供更好的解决方案来构建排序列表(也许是一个普通列表,并附带一个证明值表明它已经排序?)
SortedList
类型对于排序的复杂性太过“盲目”。例如,当Ord
类型类没有任何证明义务时,你无法证明像transitivity : Ord a => {x : a} -> So (x <= y) -> So (y <= z) -> So (x <= z)
这样的东西。 - Cactusa
固定为例如Nat
并使用像x\
LTE`y这样的命题来代替
So(x<=y)`,从而可能取得更大的进展。 - Cactus