Reputation: 267
I'm trying to do proofs over dependent functions, and I'm running into a snag.
So let's say we have a theorem f-equal
f-equal : ∀ {A B} {f : A → B} {x y : A} → x ≡ y → f x ≡ f y
f-equal refl = refl
I'm trying to prove a more general notion of equality preservation over dependent functions, and running into a snag. Namely, the type
Π-equal : ∀ {A} {B : A → Set} {f : {a : A} → B a} {x y : A} →
x ≡ y → f x ≡ f y
is making the compiler unhappy, because it can't figure out that f x and f y are of the same type. This seems like it oughta be a fixable issue. Is it?
note; the equivalence relation used is defined like this:
data _≡_ {A : Set}(x : A) : A → Set where
refl : x ≡ x
Upvotes: 3
Views: 401
Reputation: 30103
It can be handled by heterogeneous equality, which can be imported from Relation.Binary.HeterogeneousEquality
:
data _≅_ {ℓ} {A : Set ℓ} (x : A) : {B : Set ℓ} → B → Set ℓ where
refl : x ≅ x
Intuitively, het. equality carries evidence about the equality of the types involved as well as the equality of values.
You can find analogues for functions for standard equality (subst
, trans
, cong
, etc.) in the module. Also, you can convert back and forth standard and het. equality using ≅-to-≡
and ≡-to-≅
, but only when the types on the sides are demonstrably equal.
Note that the "rewrite" syntax can't be used with het. equality.
Alternatively, we can use standard equality with one of the sides coerced to the appropriate type:
Π-equal :
∀ {A : Set} {B : A → Set}{f : ∀ a → B a}{x y : A} → (p : x ≡ y) → subst B p (f x) ≡ f y
Π-equal refl = refl
This approach is actually equivalent to het. equality, but I find het. equality much easier to work with.
Upvotes: 2
Reputation: 12725
You can explicitly change the type of f x
:
Π-equal : ∀ {α β} {A : Set α} {B : A -> Set β} {f : (x : A) -> B x} {x y : A}
-> (p : x ≡ y) -> P.subst B p (f x) ≡ f y
Π-equal refl = refl
Or
Π-equal'T : ∀ {α β} {A : Set α} {B : A -> Set β} -> ((x : A) -> B x) -> (x y : A) -> x ≡ y -> Set β
Π-equal'T f x y p with f x | f y
...| fx | fy rewrite p = fx ≡ fy
Π-equal' : ∀ {α β} {A : Set α} {B : A -> Set β} {f : (x : A) -> B x} {x y : A}
-> (p : x ≡ y) -> Π-equal'T f x y p
Π-equal' refl = refl
Or you can use heterogeneous equality:
Π-equal'' : ∀ {α β} {A : Set α} {B : A -> Set β} {f : (x : A) -> B x} {x y : A}
-> x ≡ y -> f x ≅ f y
Π-equal'' refl = refl
The subst
function also can be useful, here is it's type (C-c C-d P.subst
in Emacs):
{a p : .Agda.Primitive.Level} {A : Set a} (P : A → Set p)
{x y : A} →
x ≡ y → P x → P y
Imports used:
open import Relation.Binary.PropositionalEquality as P
open import Relation.Binary.HeterogeneousEquality as H
BTW, your f-equal
is cong
in the standard library.
Upvotes: 7