Idris 如何证明((x::xs)=(y::ys))给定的(x=y)&;(xs=ys)

Idris 如何证明((x::xs)=(y::ys))给定的(x=y)&;(xs=ys),idris,Idris,我正在学习伊德里斯,我有一个小问题 我正在做《Idris类型驱动开发》一书第8.3章的练习2。关键是为您自己的向量实现DecEq。这就是我取得的成绩: data Vect : Nat -> Type -> Type where Nil : Vect 0 elem (::) : elem -> Vect n elem -> Vect (S n) elem headUnequal : {xs : Vect n a} -> {ys : Vect n a} -&g

我正在学习伊德里斯,我有一个小问题

我正在做《Idris类型驱动开发》一书第8.3章的练习2。关键是为您自己的
向量
实现
DecEq
。这就是我取得的成绩:

data Vect : Nat -> Type -> Type where
  Nil : Vect 0 elem
  (::) : elem -> Vect n elem -> Vect (S n) elem

headUnequal : {xs : Vect n a} -> {ys : Vect n a} -> (contra : (x = y) -> Void) -> ((x :: xs) = (y :: ys)) -> Void
headUnequal contra Refl = contra Refl

tailsUnequal : {xs : Vect n a} -> {ys : Vect n a} -> (contra : (xs = ys) -> Void) -> ((x :: xs) = (y :: ys)) -> Void
tailsUnequal contra Refl = contra Refl

headAndTailEq : {xs : Vect n a} -> {ys : Vect n a} -> (xEqY : x = y) -> (xsEqYs : xs = ys) -> ((x :: xs) = (y :: ys))
headAndTailEq xEqY xsEqYs = ?hole

implementation DecEq a => DecEq (Vect n a) where
  decEq [] [] = Yes Refl
  decEq (x :: xs) (y :: ys) =
    case decEq x y of
      No xNeqY => No $ headUnequal xNeqY
      Yes xEqY => case decEq xs ys of
        No xsNeqYs => No $ tailsUnequal xsNeqYs
        Yes xsEqYs => Yes $ headAndTailEq xEqY xsEqYs
如何填充
?孔

我在
https://github.com/edwinb/TypeDD-Samples/blob/master/Chapter8/Exercises/ex_8_3.idr
。有了这些知识,我可以使我的解决方案发挥作用:

implementation DecEq a => DecEq (Vect n a) where
  decEq [] [] = Yes Refl
  decEq (x :: xs) (y :: ys) =
    case decEq x y of
      No xNeqY => No $ headUnequal xNeqY
      Yes Refl => case decEq xs ys of
        No xsNeqYs => No $ tailsUnequal xsNeqYs
        Yes Refl => Yes Refl
但老实说,这为什么有效?为什么只有在我不说出校样名称的情况下,最终的
Yes Refl
才有效


谢谢大家!

重要的区别在于
案例中的值匹配,而不是校样的命名。如果您使用

  decEq (x :: xs) (y :: ys) =
    case decEq x y of
      No xNeqY => No $ headUnequal xNeqY
      Yes Refl => ?hole
您将看到,
?孔
只需要
Dec(x::xs=x::ys)
。另一方面,在您的版本中,
?hole
Dec(x::xs=y::ys)

这里,
xEqY:x=y
。Idris对
=
没有特别的理解,因此这仅仅意味着存在一个类型为
x=y
的值
xEqY
(并且没有进一步检查
xEqY
)。如果在
Refl
上进行匹配,IDRI可以统一
x
y
,因为
Refl
x=x
的构造函数-值相同。因此,您可以通过模式匹配获得更多信息;不是不透明的变量名,而是一个具体的值。根据经验法则:在右手边有足够的信息之前,始终进行模式匹配

这样,您的证明也可以轻松实现:

headAndTailEq : {xs : Vect n a} -> {ys : Vect n a} -> (xEqY : x = y) -> (xsEqYs : xs = ys) -> ((x :: xs) = (y :: ys))
headAndTailEq Refl Refl = Refl

谢谢!我假设因为
=
只有一个构造函数,所以效果是一样的。只有一个构造函数并不保证你能真正构造一个值。3=5是有效类型,但不能使用Refl为此构造值。但是在
Yes xEqY
中已经有一个值,因此它必须是
Yes Refl
。所以我想这是可以推断出来的,尽管我还没有考虑所有的后果。
headAndTailEq : {xs : Vect n a} -> {ys : Vect n a} -> (xEqY : x = y) -> (xsEqYs : xs = ys) -> ((x :: xs) = (y :: ys))
headAndTailEq Refl Refl = Refl