【发布时间】:2014-06-08 10:58:42
【问题描述】:
我正在写一篇关于依赖类型有用性的本科论文。 我正在尝试构造一个容器,它只能构造成一个排序列表,以便证明它是按构造排序的:
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),我希望能得到一些帮助。我可能依赖一个不成立的假设,但我没有看到它。
我还想鼓励您提供一个更好的解决方案来构建排序列表(也许是一个带有证明值的普通列表,它是排序的?)
【问题讨论】:
-
我在 Agda 有答案,我应该发布吗?
-
我认为您无法编写这些证明,因为您的
SortedList类型对于复杂的排序来说过于 blind。例如,当Ord类型类没有任何证明义务时,您无法证明类似transitivity : Ord a => {x : a} -> So (x <= y) -> So (y <= z) -> So (x <= z)的内容。 -
您可以通过将
a固定为例如Nat并使用x `LTE` y之类的命题而不是So (x <= y)。