[Agda] Problem with propositional equality (or my understanding of it)

José Pedro Magalhães jpm at cs.uu.nl
Wed Aug 31 16:10:38 CEST 2011


Hi all,

(This post is in literate Agda.)

I hit a problem in Agda where I expect two ways of proving the same
thing to be equivalent, but Agda doesn't believe me. Let's say I
have the following two universes:

\begin{code}
module Test where

open import Data.Unit
open import Data.Maybe

data U₁ : Set where
  Z₁ : U₁
  S₁ : U₁ → U₁

⟦_⟧₁ : U₁ → Set
⟦ Z₁   ⟧₁ = ⊤
⟦ S₁ x ⟧₁ = Maybe ⟦ x ⟧₁

data U₂ : Set where
  Z₂ : U₂
  S₂ : U₂ → U₂

⟦_⟧₂ : U₂ → Set
⟦ Z₂   ⟧₂ = ⊤
⟦ S₂ x ⟧₂ = Maybe ⟦ x ⟧₂
\end{code}

It's pretty clear they are equivalent. Let's show that:

\begin{code}
U₁→U₂ : U₁ → U₂
U₁→U₂ Z₁     = Z₂
U₁→U₂ (S₁ x) = S₂ (U₁→U₂ x)

open import Relation.Binary.PropositionalEquality public

⟦⟧₁≡⟦⟧₂ : (C : U₁) → ⟦ C ⟧₁ ≡ ⟦ U₁→U₂ C ⟧₂
⟦⟧₁≡⟦⟧₂ Z₁     = refl
⟦⟧₁≡⟦⟧₂ (S₁ x) = cong Maybe (⟦⟧₁≡⟦⟧₂ x)
\end{code}

Now let's define a function on interpretations of the first universe,
to be used later. This function is nothing more than a "deep" identity:
\begin{code}
id₁ : (C : U₁) → ⟦ C ⟧₁ → ⟦ C ⟧₁
id₁ Z₁     tt       = tt
id₁ (S₁ x) (just y) = just (id₁ x y)
id₁ (S₁ x) nothing  = nothing
\end{code}

Alright. Now let's write conversion functions between the two universes.
Since we have a proof of equivalence of their interpretations, we reuse it:
\begin{code}
module FirstTry where

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

  ⟦⟧₁→⟦⟧₂ : (C : U₁) → ⟦ C ⟧₁ → ⟦ U₁→U₂ C ⟧₂
  ⟦⟧₁→⟦⟧₂ C = ≡→ (⟦⟧₁≡⟦⟧₂ C)
\end{code}

So far so good. Now let's prove that we can remove applications of
our identity function:
\begin{code}
  prop : (C : U₁) → (x : ⟦ C ⟧₁) → ⟦⟧₁→⟦⟧₂ C (id₁ C x) ≡ ⟦⟧₁→⟦⟧₂ C x
  prop Z₁     tt       = refl
  prop (S₁ x) (just y) = cong {!just!} (prop x y)
  prop (S₁ x) nothing  = refl
\end{code}

Unfortunately Agda does not accept the term in the hole, saying:
  just (≡→ (⟦⟧₁≡⟦⟧₂ x) (id₁ x y)) !=
  ≡→ (cong Maybe (⟦⟧₁≡⟦⟧₂ x)) (id₁ (S₁ x) (just y)) of type
  Maybe ⟦ U₁→U₂ x ⟧₂
  when checking that the expression cong ? (prop x y) has type
  ⟦⟧₁→⟦⟧₂ (S₁ x) (id₁ (S₁ x) (just y)) ≡ ⟦⟧₁→⟦⟧₂ (S₁ x) (just y)

This seems to be caused by us having written the function ⟦⟧₁→⟦⟧₂ using
⟦⟧₁≡⟦⟧₂. What if we write it by induction on the universe codes instead?
\begin{code}
module SecondTry where

  ⟦⟧₁→⟦⟧₂ : (C : U₁) → ⟦ C ⟧₁ → ⟦ U₁→U₂ C ⟧₂
  ⟦⟧₁→⟦⟧₂ Z₁     tt       = tt
  ⟦⟧₁→⟦⟧₂ (S₁ x) (just y) = just (⟦⟧₁→⟦⟧₂ x y)
  ⟦⟧₁→⟦⟧₂ (S₁ x) nothing  = nothing

  prop : (C : U₁) → (x : ⟦ C ⟧₁) → ⟦⟧₁→⟦⟧₂ C (id₁ C x) ≡ ⟦⟧₁→⟦⟧₂ C x
  prop Z₁     tt       = refl
  prop (S₁ x) (just y) = cong just (prop x y)
  prop (S₁ x) nothing  = refl
\end{code}

Now we can define prop as expected.

My question is: why?


Thanks,
Pedro


More information about the Agda mailing list