TL; DR:在Agda中,给定a : A
和proof : A == B
,我可以获得元素a : B
吗?
在我不断尝试学习Agda的过程中,我创建了以下Prime : nat -> Set
数据类型,它是对自然原始性的见证。
Prime zero = False
Prime (succ zero) = False
Prime (succ (succ n)) = forall {i : nat} -> divides i p -> i <N p -> zero <N i -> i == (succ zero)
where
p = succ (succ n)
下面:
False
是没有构造函数的数据类型; divides a b
是一种数据类型,其中包含k
; a * k = b
a <N b
是一种数据类型,其中包含k
; a + k = b
==
是相等类型,只有一个构造函数refl
; zero : nat
和succ : nat -> nat
以明显的方式定义自然数。我成功展示了Prime (succ (succ zero))
的成员,并证明Prime (succ (succ (succ (succ zero)))))
声明暗示False
。
现在我试图证明素数大于1:
primesAreGreaterThanOne : (p : Sg nat Prime) -> (succ zero <N value p)
,其中
Sg A pred
是依赖对(p, pred(p))
,其中p : A
; value : Sg A pred -> A
提取值并丢弃证明。我已经证明了订单的三分法:对于所有a, b
,a <N b
,a == b
或b <N a
都是如此。 (我希望,这个引理应该帮助我们避免任何被排除在中间的问题。)因此,通过对succ zero
和value p
之间的排序关系进行逐项处理,我已经简化为我有一个p == zero
的证明和Prime p
的证明以及Prime zero
被定义为假的陈述。
现在,当然,这些陈述是矛盾的:因为我有p == zero
的证据,我可以展示Prime p == Prime zero
类型的居民,因此我有一个{{1}的居民}。
但是我怎样才能把我的元素Prime p == False
(proof : Prime p
的第二个组成部分的证明)和“投”到p : Sg nat Prime
元素?这些类型在命题上是平等的,但在判断上并不相同。
答案 0 :(得分:3)
事实证明这很容易; Just Do It(tm)。
typeCast : {a : _} {A : Set a} {B : Set a} (el : A) (pr : A == B) -> B
typeCast {a} {A} {.A} elt refl = elt
答案 1 :(得分:2)
我想指出一些关于这一特定主题的理论背景。
Agda的核心是MartinLöf的逻辑框架(LF),它是一种极小依赖类型的lambda演算,它为我们提供了依赖函数。总的来说,Agda基于内涵ML类型理论。
在LF中,有一个称为类型转换规则的规则,其中指出了
Γ ⊢ t : A Γ ⊢ A = B
--------------------------
Γ ⊢ t : B
这强制了类型相等的术语。通过计算(beta)和扩展性(eta)确定两种类型在定义上相等。
编辑以澄清: 在内涵TT中,判断性平等和命题平等是分开的,命题平等不会给你带来判断力。如果你想要一个给出两个命题上相等的项的规则在判断上也是相等的,那么你将处于一个扩展TT中,这通常是不受欢迎的,因为它使类型检查不可判定。因此,在内联TT中,并非总是如此。