Подобные проблемы объясняют, почему многие предпочитают избегать зависимых типов в Coq.Я отвечу на ваш вопрос в случае сигма-типа Coq {x : T & S x}
, который можно обобщить для других зависимых записей.
Мы можем выразить равенство, которому зависимый компонент пары должен удовлетворять, через приведениефункция:
Definition cast {T} (S : T -> Type) {a b : T} (p : a = b) : S a -> S b :=
match p with eq_refl => fun a => a end.
Definition eq_sig T (S : T -> Type) (a b : T) x y
(p : existT S a x = existT S b y) :
{q : a = b & cast S q x = y} :=
match p in _ = z return {q : a = projT1 z & cast S q x = projT2 z} with
| eq_refl => existT _ eq_refl eq_refl
end.
Функция cast
позволяет использовать равенство p : a = b
для приведения от S a
к S b
.Лемма eq_sig
, которую я определил с помощью проверочного термина, говорит, что при равенстве p
между двумя зависимыми парами existT S a x
и existT S b y
я могу создать другую зависимую пару, содержащую:
Равенство q : a = b
и
доказательство того, что x
и y
равны после приведения .
С аналогичным определением мы можем предоставить принцип доказательства "индукции" при доказательстве равенства между зависимыми парами:
Definition eq_sig_elim T (S : T -> Type) (a b : T) x y
(p : existT S a x = existT S b y) :
forall (R : forall c, S c -> Prop), R a x -> R b y :=
match p in _ = z return forall (R : forall c, S c -> Prop), R a x -> R _ (projT2 z) with
| eq_refl => fun R H => H
end.
Форма леммы аналогичнаeq_sig
, но на этот раз он говорит, что при наличии такого равенства мы можем доказать произвольный зависимый предикат R b y
, предоставив доказательство R a x
.
Используя такоезависимые принципы могут быть неудобными.Задача состоит в том, чтобы найти такой R
, который позволит вам выразить вашу цель: в приведенном выше типе результата тип второго аргумента R
является параметрическим по отношению к первому аргументу.Во многих случаях, представляющих интерес, первый компонент второго члена, y
, не является переменной, но имеет особую форму, которая может помешать прямому обобщению.