I'd be interested in seeing the following as judgemental equalities:
A generalized generalized eta rule that [match] commutes with any function which is polymorphic over the indices of the inductive data type. So, for example, with [paths] which has two parameters ([A : Type] and [x : A]) and one index (of type A), the rule is
∀ A (x y : A) (P : ∀ a, x = a → Type) (f : ∀ a (p : x = a), P a p) (p : x = y),
f _ p
= match p as p0 in (_ = y0) return (P y0 p0) with
| idpath ⇒ f _ idpah
end.
and for [JMeq], the rule is
∀ A (x : A) (P : ∀ B (b : B), JMeq x b → Type) (f : ∀ B (y : B) (p : JMeq x y) → P B y p) B (y : B) (p : JMeq x y),
f _ _ p
= match p as p0 in (@JMeq _ _ B0 y0) return (P B0 y0 p0) with
| JMeq_refl ⇒ f _ _ JMeq_refl
end.
and for [sum], the rule is
∀ A B (P : A + B → Type) (f : ∀ x, P x) (x : A + B),
f x
= match x as x0 return P x0 with
| inl a ⇒ f (inl a)
| inr b ⇒ f (inr b)
end.
By combining the case that [f] is a constructor applied to projections with the case that [f] is the identity, I think this rule suffices to obtain eta for records.
----------------------
[transport_compose : ∀ {A B x y} (P : B → Type) (f : A → B) (p : x = y) (z : P (f x)), transport (fun x0 => P (f x0)) p z = transport P (ap f p) z], or, in [match]es,
match p in (_ = x0) return (P (f x0)) with
| idpath => z
end
= match (match p in (_ = x0) return (f x = f x0) with idpath => idpath end) in (_ = fx0) return (P fx0) with
| idpath => z
end
----------------------
I'd also like to see a generalization of transport_compose, which I haven't figured out the details of yet, which makes [inverse (inverse p) = p] a judgemental equality for all paths p.
----------------------
The following (partial) computation rule for matching on higher inductive types:
Given a higher inductive type [T] and a path constructor [p : a = b], any match of the form
match p in (_ = y) return (P (match y with a => c | b => d | p => f end)) with
| idpath => g
end
should be convertible with
match f in (_ = y) return (P y) with
| idpath => g
end
In terms of [transport : ∀ {A} (P : A → Type) {x y} (p : x = y), P x → P y], this says that
transport (fun y : T => P (T_elim (a_case := c) (b_case := d) (p_case := f) y) p
should be convertible with
transport (fun y => P y) f
----------------------
I might like some sort of judgemental rule about what to do if the argument to the return clause of a match/the argument to the first non-implicit argument to transport is used multiple times, as in "transport (fun y => y x = y z) ...", and how to split this up into multiple nested matches over the same path. I wonder if something like this would make, e.g., "projT1_path_sigma : forall {A} {P : A -> Type} {u v : exists x, P x} (p : u .1 = v .1) (q : transport P p u .2 = v .2), (path_sigma P u v p q) ..1 = p" a judgemental equality. But I haven't thought about this one enough to say much.
-Jason