我怎样才能使用我在Idris中制作的证明来通知编译器我的类型签名是否正确?

时间:2018-06-16 02:09:37

标签: idris proof-of-correctness

我在idris中有一个函数计数,定义为:

count : Eq a => a -> Vect n a -> Nat
count x [] = Z
count x (y::ys) = with (x == y)
  | True = S (count x ys)
  | False = count x ys

最大值计数的证明可以返回:

countLTELen : Eq a => (x : a) -> (l : Vect n a) -> LTE (count x l) n
countLTELen x [] = lteRefl
countLteLen x (y::ys) with (x == y)
  | True = LTESucc (countLTELen x ys)
  | False = lteSuccRight (countLTELen x ys)

这一切都很好。我现在想编写一个从列表中删除所有元素的函数,removeAll:

removeAll : Eq a => (x : a) -> (l : Vect n a) -> Vect (n - (count x l)) a
removeAll x [] = []
removeAll x (y::ys) with (x == y)
  | True = removeAll x ys
  | False = x :: removeAll x ys

但是这个定义给出了一个错误:

   |
56 | removeAll : Eq a => (x : a) -> (l : Vect n a) -> Vect (n - (count x l)) a
   |                                                          ^
When checking type of Proof.removeAll:
When checking argument smaller to function Prelude.Nat.-:
    Can't find a value of type 
            LTE (count a n constraint x l) n

如何使用我的证据告知Idris此类型签名是否正确?

1 个答案:

答案 0 :(得分:4)

目前,Idris无法找到{auto smaller : LTE n m}的证据(-)

所以要么你需要明确:

removeAll : Eq a => (x : a) -> (l : Vect n a) ->
                    Vect ((-) {smaller=countLTELen x l} n (count x l) ) a

或者,因为smallerauto - 参数,您可以将编译器提示给您的校对函数。然后,当auto - 为LTE (count x l) n找到值时,将尝试此功能。

%hint
countLTELen : Eq a => (x : a) -> (l : Vect n a) -> LTE (count x l) n