我想证明
∀ {ℓ} {A B C D : Set ℓ} → (A → B) ≡ (C → D) → A ≡ C
(和codomain类似)。
如果我有一个返回函数类型域的函数domain
,我可以将证明写为
cong domain
但我不认为写这样的功能是可能的。
有没有办法做到这一点?
答案 0 :(得分:3)
几个月前我在Agda邮件列表上提出了一个非常类似的问题,请参阅:http://permalink.gmane.org/gmane.comp.lang.agda/5624。简短的回答是你无法在阿格达证明这一点。
技术原因是Agda内部用于模式匹配的统一算法不包括(A → B) ≡ (C → D)
形式问题的情况,因此这个定义不会出现问题:
cong-domain : ∀ {ℓ} {A B C D : Set ℓ} → (A → B) ≡ (C → D) → A ≡ C
cong-domain refl = refl
直接定义函数domain
也是不可能的。想一想:什么应该是不是函数类型的类型的域,例如Bool
?
你无法证明这一点的深层原因在于它与同伦类型理论的单一公理不相容。在Guillaume Brunerie在我的邮件中给出的答案中,他给出了以下示例:考虑两种类型Bool -> Bool
和Unit -> (Bool + Bool)
。两者都有4个元素,因此我们可以使用单价公理来给出类型Bool -> Bool ≡ Unit -> (Bool + Bool)
的证明(实际上有24种不同的证明)。但显然我们不想要Bool ≡ Unit
!因此,在存在单值的情况下,我们不能假设相等的函数类型具有相等的域。
最后,我通过在需要的地方传递类型A ≡ C
的额外参数来'解决'这个问题。我知道这不太理想,但也许你也可以这样做。
我还应该注意,Agda确实包含了一个内射类型构造函数的选项,您可以通过将{-# OPTIONS --injective-type-constructors #-}
放在.agda文件的顶部来启用它。这允许您例如从A ≡ B
证明List A ≡ List B
,但遗憾的是,这仅适用于List
等类型构造函数,而不适用于函数类型。
您当然可以在https://code.google.com/p/agda/issues/list处发出功能请求,向Agda添加选项--injective-function-types
。此选项与单值不兼容,但--injective-type-constructors
也是如此,但对于许多应用程序而言,这不是一个真正的问题。我觉得主要的Agda开发人员通常对这些请求非常开放,并且很快将它们添加到Agda的开发版本中。