Вот вариант вашего кода, который делает то, что вы хотите:
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
влияет на две вещи: (а) типы переменных, введенные в шаблоны слева от rewrite
;(б) тип цели.Если вы посмотрите на ваш rewrite
, когда он вступит в силу, f x
не будет найдено, поэтому он ничего не делает.Мой rewrite
, с другой стороны, меняет тип fx : 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
будет иметь неправильный тип, и поэтому мы возвращаемся к проблеме того, что эти принуждения загрязняютнаши типы.Это не обязательно нарушает условия сделки, но усложняет ситуацию.Поэтому я советую избегать разнородных отношений, если это возможно.