Haskell `结构微积分中的Refl'thing?
在具有类型扩展名的语言中,例如Haskell `结构微积分中的Refl'thing?,haskell,functional-programming,equality,dependent-type,morte,Haskell,Functional Programming,Equality,Dependent Type,Morte,在具有类型扩展名的语言中,例如Agda、Idris或Haskell,有一种类似于以下的=类型 data a :~: b where Refl :: a :~: a a:~:b表示a和b是相同的 这种类型可以在or(基于构造演算的编程语言)中定义吗?CoC中a:~:b的标准Church编码是: (a :~: b) = forall (P :: * -> * -> *). (forall c :: *. P c c) -> P a b Refl
Agda
、Idris
或Haskell
,有一种类似于以下的=
类型
data a :~: b where
Refl :: a :~: a
a:~:b
表示a
和b
是相同的
这种类型可以在or(基于构造演算的编程语言)中定义吗?CoC中
a:~:b
的标准Church编码是:
(a :~: b) =
forall (P :: * -> * -> *).
(forall c :: *. P c c) ->
P a b
Refl
being
Refl a :: a :~: a
Refl a =
\ (P :: * -> * -> *)
(h :: forall (c::*). P c c) ->
h a
以上规定了类型之间的相等性。为了使术语之间相等,关系必须采用附加参数t:*
,其中ab::t
((:~:) t a b) =
forall (P :: t -> t -> *).
(forall c :: t. P c c) ->
P a b
Refl t a :: (:~:) t a a
Refl t a =
\ (P :: t -> t -> *)
(h :: forall (c :: t). P c c) ->
h a
其中,\/
是pi构造函数,\
是lambda构造函数
我认为Church Scott编码的思想是将类型定义为其消除规则,将其构造函数定义为其引入规则
或
都是一个很好的例子:
either : * -> * -> *
either = \a : *. \b : *. \/r : *. (a -> r) -> (b -> r) -> r
left : \/a : *. \/b : *. a -> either a b
left = \a : *. \b : *. \x : a. \r : *. \left1 : (a -> r). \right1 : (b -> r). left1 x
right : \/a : *. \/b : *. b -> either a b
right = \a : *. \b : *. \y : b. \r : *. \left1 : (a -> r). \right1 : (b -> r). right1 y
或
被定义为析取的消除规则
根据这个想法,eqn a x y
必须定义为利布尼兹规则\/p:(a->*)。Px->Py
,因为方程的消去法则是利布尼兹法则
+)
1!=0
:
bottom : *
bottom = \/r : *. r
nat : *
nat = \/r : *. r -> (r -> r) -> r
zero : nat
zero = \r : *. \z : r. \s : (r -> r). z
succ : nat -> nat
succ = \n : nat. \r : *. \z : r. \s : (r -> r). s (n r z s)
id : \/a : *. a -> a
id = \a : *. \x : a. x
eqn : \/a : *. a -> a -> *
eqn = \a : *. \x : a. \y : a. \/p : (a -> *). p x -> p y
refl : \/a : *. \/x : a. eqn a x x
refl = \a : *. \x : a. \p : (a -> *). id (p x)
goal : eqn nat (succ zero) zero -> bottom
goal = \one_is_zero : (\/p : (nat -> *). p (succ zero) -> p zero). \r : *. one_is_zero (\n : nat. n * r (\a : *. r -> a)) (id r)
每个感应类型都可以用CoC编码,但没有相关的依赖消除原理(非依赖消除可用)。(还要注意,
a:~:b
是一种类型,但Refl
是一个值。)构造演算是lambda立方体的“顶部”。哈斯凯尔、爱格达和伊德里斯“低于”CoC。因此,CoC更具表现力这一简单事实应该是可能的。(有人可能会指出我在这个推论中是否错了?@Bakuriu事实上,Agda/Coq超出了CoC,因为它们也允许具有依赖消除的归纳类型,而CoC缺乏这种类型。Agda还证明了Streicher的公理K,这意味着相同等式的任何两个证明p,q
必须相等(p=q
)——在CoC或Coq(又称CiC)中不可用@chi:我还应该注意到Coq中的非指示性Prop
,以及Agda和Idris中的归纳递归是远远超出lambda立方体的特性。@AndrásKovács有趣。然而,*
在CoC中不是很有意义吗?很有趣。有没有可能像您在其他语言中所做的那样,从0:~:1
推导出矛盾?(哦,等等,我明白了。只要做一个等式函数,它返回()
而不是True,返回Void
而不是false。我认为这会起作用。)(另外,我明白了这是如何很容易推广到其他GADT。)@PyRulez是的。对于教堂数字,0fx=x
和1fx=fx
(对其他类型参数进行模化)。使用它,您可以使0(const-True)False=False
和1(const-True)False=True
。假设0:~:1
并取py=(x(const-True)False)(y(const-True)False)
,我们可以证明False-True
。你能补充一些解释吗?请看这里您需要id
做什么?@PyRulez只是为了美女好的。这个定义是对称的吗?@PyRulez是的,是对称的。为了表明定义是对称的,推导a:://code>,x:a
,y:a
|-eqn a x y->eqn a y x
就足够了。设h:eqn a x y
。由于方程a x y
=\/p:(a->*)。px->py
,我们可以从h:\/p:(a->*)导出eqnax->eqnayx
。Px->Py
,放置p
:=\z:a。等式a z x
。应用reflax:eqnax
,我们得到了eqnayx
的一个证明。Q.E.D。
bottom : *
bottom = \/r : *. r
nat : *
nat = \/r : *. r -> (r -> r) -> r
zero : nat
zero = \r : *. \z : r. \s : (r -> r). z
succ : nat -> nat
succ = \n : nat. \r : *. \z : r. \s : (r -> r). s (n r z s)
id : \/a : *. a -> a
id = \a : *. \x : a. x
eqn : \/a : *. a -> a -> *
eqn = \a : *. \x : a. \y : a. \/p : (a -> *). p x -> p y
refl : \/a : *. \/x : a. eqn a x x
refl = \a : *. \x : a. \p : (a -> *). id (p x)
goal : eqn nat (succ zero) zero -> bottom
goal = \one_is_zero : (\/p : (nat -> *). p (succ zero) -> p zero). \r : *. one_is_zero (\n : nat. n * r (\a : *. r -> a)) (id r)