UIP (and equivalents like axiom K) must be added axiomatically in Coq if it is desired:
uip : ∀ A (x y: A) (p q: x = y), p = q
This is surprising, since it appears obvious from the definition of equality, which only has one constructor. (This of course rests on the interpretation that an inductive definition in Coq captures all elements of its type).
When one tries to prove UIP, one gets stuck on the reflexive subcase:
uip_refl : ∀ A (x: A) (h: x = x), h = eq_refl x
We might hope the following term would be an appropriate proof term:
fun A (x: A) (h: x = x) =>
match h as h0 in (_ = a) return (h0 = eq_refl x) with
| eq_refl _ => eq_refl (eq_refl x)
end
This fails because it is ill-typed. We know that h: x = x, but when we match on the term, we lose the reflexivity information and it is generalized to h0: x = a. As a result, our return type h0 = eq_refl x is ill-typed.
Why is it that the match construct generalizes our type here? Would a non-generalizing alternative be tractable?