Доказательство равенства не о чем говорить. Когда вы выполняете сопоставление с образцом в конструкторе, он может уточнить другие аргументы (и их типы). В вашем случае n-n≡0 n
должен уточнить n - n
, но такого выражения нет, и Agda выдает вам это (немного озадачивающее) сообщение об ошибке.
Вы можете исправить это, введя выражение в with
:
∣-refl : ∀ {n} → n ∣ n
∣-refl {n} with n - n | n-n≡0 n
... | ._ | refl = ?
Мы можем более подробно рассказать о левой части, это хорошо показывает, как происходит уточнение:
∣-refl {n} with n - n | n-n≡0 n
∣-refl {n} | .zero | refl = ?
Однако, когда вы пытаетесь заполнить остальную часть определения:
∣-refl {n} with n - n | n-n≡0 n
∣-refl {n} | .zero | refl = n-d∣d 0∣d
Проверка типов снова не согласна. Почему это так? n-d∣d
должен иметь тип (n - n) ∣ n → n ∣ n
, а 0∣d
- тип 0 ∣ n
. Но ждать! Разве мы не только что показали, что n - n
на самом деле 0
?
Проблема с сопоставлением с образцом и его уточнением заключается в том, что это происходит только один раз, правая часть не будет затронута вообще (это, кстати, одна из причин, по которой у нас есть inspect
механизм). Как мы с этим справляемся?
Есть функция под названием subst
, которая принимает что-то типа P a
, доказательство того, что a ≡ b
и дает нам P b
. Обратите внимание: если мы заменим λ x → x ∣ n
на P
, zero
на a
и n - n
на b
, мы получим функцию, которая принимает zero ∣ n
и дает нам n - n ∣ n
(для подходящего доказательства, конечно).
И действительно:
∣-refl {n} = n-d∣d (subst (λ x → x ∣ n) (sym (n-n≡0 n)) 0∣d)
Это определение принято: тип subst ... 0∣d
- n - n ∣ n
, что подходит для ввода n-d∣d
. Обратите внимание, что нам также нужно доказательство того, что zero ≡ n - n
, но у нас есть n - n ≡ zero
- здесь мы используем тот факт, что ≡
является симметричным (sym
).
Для полноты, вот определение subst
:
subst : ∀ {a p} {A : Set a} (P : A → Set p) {x y} →
x ≡ y → P x → P y
subst _ refl p = p
person
Vitus
schedule
19.12.2013