Agda:在类型定义中重写而不是显式强制?

时间:2019-02-08 11:09:18

标签: agda coercion rewriting

在处理Agda中的类型相等问题时,通常有必要使用手工制作的强制方式强制居民使用这些类型

coerce : ∀ {ℓ} {A B : Set ℓ} → A ≡ B → A → B
coerce refl x = x

here讨论过,有时可以通过重写来避免显式强制使用术语。我想知道这种技术在定义类型时是否效果很好。因此,我写了一个小例子,其中f,g : A → Set是两个(在特定情况下)相等的依赖类型和一个属性p : A → Set,其中p x声明每个元素y : f x等于每个元素{{ 1}},即z : g x。可以预料到,由于y ≡ zy : f x并不具有相同的先验类型,所以最后一个等式是错误类型,但是我希望重写可以允​​许它。像这样:

z : g x

但是即使改写建议被接受,错误仍然存​​在。因此,有没有一种方法可以使Agda在不使用显式强制的情况下接受此定义,例如

open import Relation.Binary.PropositionalEquality

postulate A : Set
postulate B : Set
postulate f : A → Set
postulate g : A → Set
postulate f≡g : ∀ {x} → (f x) ≡ (g x)

p : {x : A} → Set
p {x} rewrite f≡g {x} = (y : f x ) (z : g x) → y ≡ z

谢谢

1 个答案:

答案 0 :(得分:1)

这是您的代码的变体,可以满足您的要求:

open import Relation.Binary.PropositionalEquality

postulate
  A : Set
  f : A → Set
  g : A → Set
  f≡g : ∀ x → f x ≡ g x

p : (x : A) → Set
p x = ∀ y z → R y z
  where
    R : f x → g x → Set
    R fx gx rewrite f≡g x = fx ≡ gx

为什么当您的版本不可用时,该功能为什么起作用? rewrite影响两件事:(a)在rewrite左侧模式中引入的变量类型; (b)目标类型。如果您查看自己的rewrite,当它生效时,找不到f x,因此它什么也没做。另一方面,我的rewritefx : f x的类型更改为g x,因为fx是在rewrite之前引入的。


但是,如果这对您有很大帮助,我会感到惊讶。根据我的经验,无论您使用什么技巧,异类平等(即不同类型的事物之间的平等)仍然很烦人。例如,考虑您的想法的这种变化,我们通过重写来定义类型R

R : ∀ {x} → f x → g x → Set
R {x} fx gx rewrite f≡g x = fx ≡ gx

R是一种“看起来”自反的异类关系。但是,最能说明反射性的是

coerce : {A B : Set} → A ≡ B → A → B
coerce refl x = x

R-refl : ∀ {x} {fx : f x} → R fx (coerce (f≡g x) fx)
R-refl {x} rewrite f≡g x = refl

如果没有coerce,则fx的类型将是错误的,因此我们回到了这样的问题:我们的强制性会污染我们的类型。这不一定是破坏交易的事情,但是会使事情复杂化。因此,我的建议是尽可能避免异类关系。