Agda - Интерактивное построение доказательств - Как использовать синтаксис дыр?
Извините за странное название, я понятия не имею, как на самом деле названы эти концепции.
Я слежу за Agda
учебник и есть раздел, объясняющий, как индуктивно строить доказательства: https://plfa.github.io/Induction/
Довольно здорово, что вы можете шаг за шагом расширять доказательство и получить дыру (это { }0
) обновите его содержимое, чтобы сообщить вам, что происходит. Однако объясняется только, как это сделать при использованииrewrite
синтаксис.
Как это работает, когда я хочу "вручную" провести доказательство в пределах begin
блок, например:
+-assoc : ∀ (m n p : ℕ) → (m + n) + p ≡ m + (n + p)
+-assoc zero n p =
begin
(zero + n) + p
≡⟨⟩ n + p
≡⟨⟩ zero + (n + p)
∎
+-assoc (suc m) n p =
begin
(suc m + n) + p
≡⟨⟩ suc (m + n) + p
≡⟨⟩ suc ((m + n) + p)
≡⟨ cong suc (+-assoc m n p) ⟩
suc (m + (n + p))
≡⟨⟩ suc m + (n + p)
∎
Проблема в следующем. Начнем с утверждения и начала доказательств:
+-assoc : ∀ (m n p : ℕ) → (m + n) + p ≡ m + (n + p)
+-assoc m n p = ?
Это оценивается как:
+-assoc : ∀ (m n p : ℕ) → (m + n) + p ≡ m + (n + p)
+-assoc m n p = { }0
В этом случае я хочу провести доказательство по индукции, поэтому я разделю их, используя C-c C-c
используя переменную m
:
+-assoc : ∀ (m n p : ℕ) → (m + n) + p ≡ m + (n + p)
+-assoc zero n p = { }0
+-assoc (suc m) n p = { }1
Базовый случай тривиален и заменяется на refl
после разрешения с помощью C-c C-r
. Однако индуктивный корпус (отверстие 1) требует доработки. Как я могу это повернуть{ }1
отверстие в следующей конструкции, чтобы провести доказательство:
begin
-- my proof
∎
Мой редактор (spacemacs) говорит { }1
только для чтения. Я не могу его удалить, только вставляю что-то между фигурными скобками. Я могу удалить его принудительно, но это явно не предназначено.
Что вы должны сделать, чтобы превратить дыру в begin
блок? Что-то вроде этого
{ begin }1
не работает и приводит к сообщению об ошибке
Спасибо!
РЕДАКТИРОВАТЬ:
Итак, похоже, работает следующее:
{ begin ? }1
Это превращается в это:
+-assoc : ∀ (m n p : ℕ) → (m + n) + p ≡ m + (n + p)
+-assoc zero n p = refl
+-assoc (suc m) n p = begin { }0
Это прогресс:D. Но теперь я не могу понять, где поставить фактические шаги доказательства:
...
+-assoc (suc m) n p = begin (suc m + n) + p { }0
-- or
+-assoc (suc m) n p = begin { (suc m + n) + p }0
Ни один из них не работает
1 ответ
{ }1
только для чтения
Это сообщение отображается в двух случаях:
- вы пытаетесь удалить дыру с помощью Backspace, что не сработает. Однако вы можете использовать C-backspace, если отверстие пусто
- вы пытаетесь отредактировать пустое отверстие в режиме вставки / перезаписи, что тоже не сработает
Практическое правило: вы всегда очищаете отверстие с помощью C-c C-SPC
с выражением типа, равного цели. В вашем случае это означает, что начинать сbegin ?
, затем давая (suc m + n) + p ≡⟨⟩ ?
и так далее.
Есть два способа улучшить отверстие:
C-c C-r
: создает для вас новые дыры при задании функции. Например, с этой настройкой:test : Bool test = {!!}
если вы напечатаете
not
в дыреtest : Bool test = {!not!}
и доработайте, вы получите
test : Bool test = not {!!}
т.е. новое отверстие создается автоматически для аргумента.
Таким образом или исправляя дыру, Agda также переформатирует ваш код так, как ей нравится, что мне не нравится, поэтому я обычно не использую его.
C-c C-SPC
: не создает новых дыр для аргументов и не переформатирует ваш код