可以很容易地像这样对教会进行编码:
Definition prod (X Y:Set) : Set := forall (Z : Set), (X -> Y -> Z) -> Z.
Definition pair (X Y:Set)(x:X)(y:Y) : prod X Y := fun Z xy => xy x y.
Definition pair_rec (X Y Z:Set)(p:X->Y->Z) (xy : prod X Y) : Z := xy Z p.
Definition fst (X Y:Set)(xy:prod X Y) : X := pair_rec X Y X (fun x y => x) xy.
Definition snd (X Y:Set)(xy:prod X Y) : Y := pair_rec X Y Y (fun x y => y) xy.
然后试图将其概括为这样的依赖对:
Definition dprod (X:Set)(Y:X->Set) : Set :=
forall (Z : Set), (forall (x:X),Y x->Z)->Z.
Definition dpair (X:Set)(Y:X->Set)(x:X)(y:Y x) : dprod X Y :=
fun Z xy => xy x y.
Definition dpair_rec (X:Set)(Y:X->Set)(Z:Set)(p:forall (x:X),Y x->Z)
(xy : dprod X Y) : Z := xy Z p.
Definition dfst (X:Set)(Y:X->Set)(xy:dprod X Y) : X :=
dpair_rec X Y X (fun x y => x) xy.
Definition dsnd (X:Set)(Y:X->Set)(xy:dprod X Y) : Y (dfst X Y xy) :=
dpair_rec X Y (Y (dfst X Y xy)) (fun x y => y) xy.
但是最后一个定义失败并显示错误消息:
In environment
X : Set
Y : X -> Set
xy : dprod X Y
x : X
y : Y x
The term "y" has type "Y x"
while it is expected to have type
"Y (dfst X Y xy)".
我了解这里的问题。但是,解决方案是什么?换句话说,如何对依赖对进行教会编码?
答案 0 :(得分:2)
首先,让我们正确使用术语。
您所说的dprod
实际上是一个“依赖总和”,而“依赖乘积”是您可能会想调用“依赖函数”的东西。这样做的原因是,依赖函数会泛化常规产品,您只需要巧妙地使用Bool
:
prod : Set -> Set -> Set
prod A B = (b : Bool) -> case b of { True -> A; False -> B; }
{-
The type-theoretic notation would be:
prod A B = Π Bool (\b -> case b of { True -> A; False -> B; })
-}
mkPair : (A B : Set) -> A -> B -> prod A B
mkPair A B x y = \b -> case b of { True -> x; False -> y; }
elimProd : (A B Z : Set) -> (A -> B -> Z) -> prod A B -> Z
elimProd A B Z f p = f (p True) (p False)
本着同样的精神,从属对(通常表示为Σ
)概括了常规和:
sum : Set -> Set -> Set
sum A B = Σ Bool (\b -> case b of { True -> A; False -> B; })
mkLeft : (A B : Set) -> A -> sum A B
mkLeft A B x = (True, x)
mkRight : (A B : Set) -> B -> sum A B
mkRight A B y = (False, y)
elimSum : (A B Z : Set) -> (A -> Z) -> (B -> Z) -> sum A B -> Z
elimSum A B Z f _ (True, x) = f x
elimSum A B Z _ g (False, y) = g y
这可能令人困惑,但是,另一方面,Π A (\_ -> B)
是常规函数的类型,而Σ A (\_ -> B)
是常规对的类型(例如,参见here )。
所以,再次:
您的问题可以通过以下方式改写:
是否存在通过依积乘积的教会编码?
这在Math.StackExchange上已经被问过了,这里的an answer与您的编码基本相同。
但是,阅读此答案的注释后,您会发现它显然缺少预期的归纳原理。还有一个类似的问题,但是关于自然数的教堂编码,this answer(尤其是评论)有点解释了为什么Coq或Agda不足以推导出归纳原理,您需要其他假设,例如参数化。还有另一种类似的question on MathOverflow,尽管对于Agda / Coq的特定情况,答案并没有给出明确的“是”或“否”,但它们暗示这可能是不可能的。
最后,我不得不提到,与当今许多其他类型理论问题一样,显然HoTT is the answer。引用Mike Shulman的博客文章开头:
在这篇文章中,我将辩称,在对Awodey-Frey-Speight的先前工作进行改进的基础上,可以使用具有完全依赖归纳原理的强制性编码来定义(更高)归纳类型-尤其是,在没有任何归类的情况下消除所有类型族截断假设-在普通的(强制性的)HoTT书中,没有任何进一步的修饰。
(尽管您将获得的(强制性)编码几乎不能称为教堂编码。)
答案 1 :(得分:0)
在Coq或Agda中无法对教会相关的对进行编码。
好吧,当我们想到同质元组
AxA
时,这也可以是 被理解为函数2 -> A
。这也适用于异构 使用相关函数Pi x:2.if x then A else B
的AxB之类的元组。 但是,下一个逻辑步骤是Sigma x:A.B x
,这没有用 表示为函数(除非我们接受非常依赖 我认为这与类型理论的精神背道而驰的功能)。 因此,在我看来,从->
到Pi
的概括 从x
到Sigma
是主要的元素,而元组可以 被表示为功能是次要的。 -Thorsten Altenkirch博士,在Agda邮件列表中的某处
可以找到here,这是Thorsten提到的非常依赖的函数编码(请注意,这不是有效的Agda,只是“疯狂依赖”类型理论的类似Agda的语法)。