完整的证明,如果最后一个列表元素不在列表中,那么前置将不会这样

时间:2018-08-04 20:01:55

标签: idris

已经完成了《与Idris进行类型驱动的开发》一书的练习9.1,我无法获得完整的证明之一。练习是使isLast函数起作用。它应返回一个值是List的最后一个值的证明。它可以工作,但是不幸的是notLastInTailEqNotLast并不总能实现。

data Last : List a -> a -> Type where
     LastOne : Last [value] value
     LastCons : (prf : Last xs value) -> Last (x :: xs) value

lastNotNil : Last [] value -> Void
lastNotNil _ impossible

lastNotEq : (contra : (lastValue = value) -> Void) -> Last [lastValue] value -> Void
lastNotEq contra LastOne = contra Refl
lastNotEq _ (LastCons LastOne) impossible
lastNotEq _ (LastCons (LastCons _)) impossible

notLastInTailEqNotLast : (notLastInTail : Last xs value -> Void) ->
                         Last (y :: xs) value -> Void
notLastInTailEqNotLast notLastInTail LastOne = ?hole
notLastInTailEqNotLast notLastInTail (LastCons prf) = notLastInTail prf


isLast : DecEq a => (xs : List a) -> (value : a) -> Dec (Last xs value)
isLast [] value = No lastNotNil
isLast [lastValue] value = case decEq lastValue value of
  Yes Refl => Yes LastOne
  No contra => No (lastNotEq contra)
isLast (x :: xs) value = case isLast xs value of
  Yes last => Yes (LastCons last)
  No notLastInTail => No (notLastInTailEqNotLast notLastInTail)

如何填写?hole

我在这里看到了解决方案:https://github.com/edwinb/TypeDD-Samples/blob/master/Chapter9/Exercises/ex_9_1.idr。我了解如何使用lastNotCons解决我的问题,并且我的解决方案也可以那样工作,但这似乎是一种解决方法。我想提供的证明对我来说似乎微不足道:如果我有一个元素不是列表中的最后一个元素的证明,那么附加了该列表的另一个列表仍不会将该元素作为列表中的最后一个元素(即{{ 1}})。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

不可能证明Widget functionWidgetComposition() => Text('hello'); class MyWidgetComposition extends StatelessWidget { Widget build(BuildContext context) => Text('hello'); } ,因为它是不正确的。这是一个反例:notLastInTailEqNotLast不是空白列表0的最后一个元素,但是如果将[]放在空白列表的前面,您会突然发现0是空白列表的最后一个元素。新列表的最后一个元素。

另一种查看方法是,当您尝试填写0时,您将?hole作为目标,因此这必须表示您在上下文中应该有矛盾,但是上下文看起来像这样

Void

但是您唯一的矛盾候选人是`-- phTy : Type value : phTy notLastInTail : Last [] value -> Void --------------------------------------- 。如果斜视其类型,您会发现它只是您的notLastInTail定理,也就是说,这并不矛盾。