Каждый раз, когда вы используете rewrite
, целью является тип (формула), чей собственный тип - Prop
.Таким образом, эффект тактической воли rewrite
отбрасывается, потому что часть термина, в которой он имел место, была отброшена.
инструмент извлечения не смотрит на тактику: он удаляет выражения, тип которых имеет тип Prop
от срока, который будет выполнен.Вся система спроектирована таким образом, что эти выражения не должны влиять на вычисления.
В некотором смысле, это различие между проверкой во время компиляции и проверкой во время выполнения.Все доказательства, которые вы делаете в Coq, - это проверки во время компиляции, во время выполнения их не нужно переделывать, поэтому они удаляются из кода.Сортировка Prop
используется для пометки вычислений, которые происходят только во время компиляции и не влияют на выполнение во время выполнения.
Вы можете каким-то образом предсказать содержимое извлеченной программы на Haskell с помощьюглядя на результат Print div_q_r.
Результат содержит экземпляры existT
и экземпляр exist
.Тип existT
:
forall (A : Type) (P : A -> Type) (x : A), P x -> {x : A & P x}
Обозначение {x : A & P x}
для @sigT A P
.В свою очередь тип sigT
равен
forall A : Type, (A -> Type) -> Type
Тип existT P xx pp
равен @sigT A P
, а тип последнего - Type
.В результате инструмент извлечения решает, что этот термин содержит данные, которые важны во время выполнения.Более того, второй компонент sigT A P
имеет тип P xx
, который сам имеет тип Type
, так что это также важно во время выполнения: он не будет отброшен.
Теперь давайте обратим наше вниманиедо выражения вида exist _ _
.Такое выражение имеет тип @sig A P
и sig
имеет тип:
forall A: Type, (A -> Prop) -> Type
Таким образом, выражение exist Q y qq
содержит y
, тип которого имеет тип Type
и qq
, тип которого Q y
и имеет тип Prop
.Информация о том, как вычислять y
, будет храниться во время выполнения, но информация о том, как вычислять qq
, отбрасывается.
Если вы хотите знать, где rewrite
оказал влияние в доказательстве, выНужно только искать экземпляры eq_ind
и eq_ind_r
в результате Print div_q_r.
. Вы увидите, что эти экземпляры являются подтермами третьего аргумента операторов exist
.Это причина, почему они не появляются в конечном результате.Это не потому, что извлечение имеет специальную обработку перезаписей, а потому, что оно имеет специальное поведение для типов типов Prop
(мы также называем это sort Prop
).
Можно построить функции, в которых rewrite
оставляет след в результате извлечения, но я не уверен, что эти функции работают в Haskell правильно.
Definition nat_type n :=
match n with O => nat | S p => bool end.
Definition strange n : nat_type (n * 0).
rewrite Nat.mul_0_r.
exact n.
Defined.