Idris重写没有改变类型

时间:2018-05-15 13:24:23

标签: idris

我正在努力证明这一点 将Vect分成三部分后, 每个部分的长度都不如原始矢量。 这是我的实施:

||| Split into three parts: two lists and a single element
data Sp : Type -> Type where
 MkSp : List a -> a -> List a -> Sp a

||| cons an element into the left list
spConsL : a -> Sp a -> Sp a
spConsL x (MkSp xs y ys) = MkSp (x :: xs) y ys

||| split a vector according to a predicate
sp : (a -> Bool) -> Bool -> Vect (S l) a -> Sp a
sp f b (x :: []) = MkSp [] x []
sp f False (x :: (y :: xs)) =
  let s' = sp f (f x) (y :: xs)
  in  spConsL x s'
sp f True (x :: xs) = MkSp [] x (toList xs)

||| get the left list from a split
lSp : Sp a -> List a
lSp (MkSp xs x ys) = xs


spConsLEq : {x : a} -> {s : Sp a} ->
            x :: (lSp s) = lSp (spConsL x s)
spConsLEq {x} {s = (MkSp xs y ys)} = Refl


lSpLTE : (vect : Vect (S len) a) ->
         (p : a -> Bool) ->
         (b : Bool) ->
         length (lSp (sp p b vect)) `LTE` S len
lSpLTE (x :: []) p b = LTEZero
lSpLTE (x :: (y :: xs)) p True = LTEZero
lSpLTE (x :: (y :: xs)) p False =
  let ih = lSpLTE (y :: xs) p (p x)
  in  rewrite sym spConsLEq in
      ?lSpLTE_rhs_1

但不幸的是,idris会引发错误:

rewriting
  lSp (spConsL x s) to x :: lSp s
did not change type
  (length
    (lSp (spConsL x (sp p (p x) (y :: xs)))))
  `LTE`
  (S (S len))

即使我将s引入如下,仍然会出现错误

rewrite sym $ spConsLEq {s = sp p (p x) (y :: xs)}

那为什么不能在这里重写工作呢?

1 个答案:

答案 0 :(得分:0)

对于"为什么没有令人满意的答案?"问题,但你非常接近完整的证据。通过以下修改,重写成功:

let ih = lSpLTE (y :: xs) p (p x)
    rule = spConsLEq {x} {s = sp p (p x) (y :: xs)}
in rewrite sym rule in ?hole

LTESucc ih代替洞来完成证明:

rewrite sym eq in LTESucc ih

因此似乎必须向{s}提供{x}spConsLEq,并且LTESucc充分发挥以下引理的作用:

lemma : {xs : List a} -> LTE (length xs) k -> LTE (length (_ :: xs)) (S k)
lemma = LTESucc