Idris:有没有办法在等式证明中引用抽象变量?
Idris: Is there a way to reference an abstracted variable in an equality proof?
问题的最简单示例(但不是我可以展示的唯一示例)是:假设我得到了一个高阶函数 f : (a -> b) -> c
。我想证明 f = (\g => f (\x => g x))
.
根据我自己的推理,它应该非常简单:只需应用 eta-equivalence 两次(一次在内部,然后在外部)。
如果我想证明 f = (\x => f x)
,一个简单的 Refl
就足够了:这让我想到 "Idris knows about eta-equivalence"。但话又说回来,同样的解决方案对 f = (\g => f (\x => g x))
.
不起作用
那时,我尝试使用 rewrite
,但找不到在 (\g => f (\x => g x))
中引用 g
的方法:
lemma : {g : a -> b} -> g = (\x => g x)
lemma = Refl
theorem : {f : (a -> b) -> c} ->
f = (\g => f (\x => g x))
theorem = rewrite (lemma {g = _}) in Refl
但是,当然,伊德里斯无法弄清楚 _
应该是什么,我也不知道。
当然,这可以进一步简化为证明 (\g => f g) = (\g => f (\x => g x))
的问题,因为 Idris 知道相等性是可传递的并且知道 eta 等价性(至少当它不是 "hidden" 在 lambda 抽象中).
我开始相信我正在经历的事情正在以某种方式发生,因为 Idris 不知道可扩展性:是否有任何其他方法可以证明这一点(无需调整我正在使用的平等概念,例如如使用 setoids)?
我正在使用来自 git 的 Idris 1.3.2。
你可以假设外延性:
postulate
funext : {f, g : a -> b} -> ((x : a) -> f x = g x) -> f = g
theorem : {f : (a -> b) -> c} -> f = (\g => f (\x => g x))
theorem = funext $ \g => Refl
问题的最简单示例(但不是我可以展示的唯一示例)是:假设我得到了一个高阶函数 f : (a -> b) -> c
。我想证明 f = (\g => f (\x => g x))
.
根据我自己的推理,它应该非常简单:只需应用 eta-equivalence 两次(一次在内部,然后在外部)。
如果我想证明 f = (\x => f x)
,一个简单的 Refl
就足够了:这让我想到 "Idris knows about eta-equivalence"。但话又说回来,同样的解决方案对 f = (\g => f (\x => g x))
.
那时,我尝试使用 rewrite
,但找不到在 (\g => f (\x => g x))
中引用 g
的方法:
lemma : {g : a -> b} -> g = (\x => g x)
lemma = Refl
theorem : {f : (a -> b) -> c} ->
f = (\g => f (\x => g x))
theorem = rewrite (lemma {g = _}) in Refl
但是,当然,伊德里斯无法弄清楚 _
应该是什么,我也不知道。
当然,这可以进一步简化为证明 (\g => f g) = (\g => f (\x => g x))
的问题,因为 Idris 知道相等性是可传递的并且知道 eta 等价性(至少当它不是 "hidden" 在 lambda 抽象中).
我开始相信我正在经历的事情正在以某种方式发生,因为 Idris 不知道可扩展性:是否有任何其他方法可以证明这一点(无需调整我正在使用的平等概念,例如如使用 setoids)?
我正在使用来自 git 的 Idris 1.3.2。
你可以假设外延性:
postulate
funext : {f, g : a -> b} -> ((x : a) -> f x = g x) -> f = g
theorem : {f : (a -> b) -> c} -> f = (\g => f (\x => g x))
theorem = funext $ \g => Refl