foldrImpl和证明

时间:2019-04-23 19:30:26

标签: fold proof idris dependent-type

我在代码中经常使用Vect数据类型。通常,我发现自己不得不证明一些涉及使用foldr的Vects上的库函数的事情。由于foldr是在foldrImpl之上实现的,因此如果我尝试通过在目标中出现的漏洞来检查证明上下文。我的问题是,idris似乎无法评估目标类型中的foldrImpl(与总体检查器不知道某个函数的总和类似),这使我陷入了证明。

通常,我对这个问题的解决方案是定义我自己的库函数版本,该函数从头开始折叠。但这显然不方便,因为:(i)我必须对库中已经存在的函数进行编码; (ii)这使我不会在以后打算证明的任何定义中使用折叠。

举一个具体的例子,请考虑我要证明以下内容

lemma_take_head : {x : a} -> 
                  {xs : List a} -> 
                  {ls : Vect len (List a)} ->  
                   concat ((x :: xs) :: ls) = x :: (concat (xs :: ls))
lemma_take_head {ls = []} = Refl
lemma_take_head {ls = l :: ls} = ?h2

使用我的concat版本,这就像返回Refl一样容易。但是对于折叠的库版本,当Vect最不利时,我们得到以下上下文:

  a : Type
  l : List a
  x : a
  xs : List a
  len : Nat
  ls : Vect len (List a)
--------------------------------------
h2 : foldrImpl (\meth, meth => meth ++ meth) [] (\x1 => x :: xs ++ l ++ x1) ls = x :: foldrImpl (\meth, meth => meth ++ meth) [] (\x1 => xs ++ l ++ x1) ls

一旦证明到了这样的程度,有没有办法继续证明?还是唯一一种不使用折叠方式重新实现功能的解决方案?

0 个答案:

没有答案