Idris rewrite does not happen

偶尔善良 提交于 2020-01-03 20:47:25

问题


import Data.Vect
import Data.Vect.Quantifiers

sameKeys : Vect n (lbl, Type) -> Vect n (lbl, Type) -> Type
sameKeys xs ys = All (uncurry (=)) (zip (map fst xs) (map fst ys))

g : {xs,ys : Vect n (lbl, Type)} -> sameKeys xs ys -> map (\b => fst b) xs = map (\b => fst b) ys
g {xs = []} {ys = []} [] = Refl
g {xs = x::xs} {ys = y::ys} (p::ps) = rewrite g ps in ?q

This is the error I see:

*main> :load main.idr
Type checking ./main.idr
main.idr:57:3:When checking right hand side of g with expected type
        map (\b => fst b) (x :: xs) = map (\b6 => fst b6) (y :: ys)

rewriting
    Data.Vect.Vect n implementation of Prelude.Functor.Functor, method map (\b => fst b) xs
to
    Data.Vect.Vect n implementation of Prelude.Functor.Functor, method map (\b6 => fst b6) ys
did not change type
    fst x :: Data.Vect.Vect n implementation of Prelude.Functor.Functor, method map (\b => fst b) xs = fst y :: Data.Vect.Vect n implementation of Prelude.Functor.Functor, method map (\b6 => fst b6) ys
Holes: Main.g

Why does it not rewrite it?


回答1:


This is happening because Idris somehow fails to infer the correct implicit arguments to g, instead it introduces fresh vectors in the context.

As a workaround I can suggest to prove it as follows. First, we'll need a congruence lemma for two-argument functions:

total
cong2 : {f : a -> b -> c} -> (a1 = a2) -> (b1 = b2) -> f a1 b1 = f a2 b2
cong2 Refl Refl = Refl

Now the proof of the original lemma is trivial:

total
g : sameKeys xs ys -> map (\b => fst b) xs = map (\b => fst b) ys
g {xs = []} {ys = []} x = Refl
g {xs = x :: xs} {ys = y :: ys} (p :: ps) = cong2 p $ g ps


来源:https://stackoverflow.com/questions/46575191/idris-rewrite-does-not-happen

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!