Как мне написать тактику, которая ведет себя как "уничтожить... как"?
В coq, destruct
у тактики есть вариант, принимающий "конъюнктивную дизъюнктивную модель введения", которая позволяет пользователю присваивать имена вводимым переменным даже при распаковке сложных индуктивных типов.
Язык Ltac в coq позволяет пользователю создавать собственные тактики. Я хотел бы написать (на самом деле, сохранить) тактику, которая делает что-то, прежде чем передать контроль destruct
,
Я хотел бы, чтобы моя пользовательская тактика позволяла (или требовала, в зависимости от того, что проще) пользователю предоставить шаблон введения, который моя тактика может передать destruct
,
Какой синтаксис Ltac выполняет это?
1 ответ
Вы можете использовать тактические обозначения, описанные в справочном руководстве. Например,
Tactic Notation "foo" simple_intropattern(bar) :=
match goal with
| H : ?A /\ ?B |- _ =>
destruct H as bar
end.
Goal True /\ True /\ True -> True.
intros. foo (HA & HB & HC).
simple_intropattern
директива поручает Coq интерпретировать bar
как образец вступления. Таким образом, призыв к foo
результаты в вызове destruct H as (HA & HB & HC)
,
Вот более длинный пример, показывающий более сложную модель введения.
Tactic Notation "my_destruct" hyp(H) "as" simple_intropattern(pattern) :=
destruct H as pattern.
Inductive wondrous : nat -> Prop :=
| one : wondrous 1
| half : forall n k : nat, n = 2 * k -> wondrous k -> wondrous n
| triple_one : forall n k : nat, 3 * n + 1 = k -> wondrous k -> wondrous n.
Lemma oneness : forall n : nat, n = 0 \/ wondrous n.
Proof.
intro n.
induction n as [ | n IH_n ].
(* n = 0 *)
left. reflexivity.
(* n <> 0 *)
right. my_destruct IH_n as
[ H_n_zero
| [
| n' k H_half H_wondrous_k
| n' k H_triple_one H_wondrous_k ] ].
Admitted.
Мы можем проверить одну из сгенерированных целей, чтобы увидеть, как используются имена.
oneness < Show 4.
subgoal 4 is:
n : nat
n' : nat
k : nat
H_triple_one : 3 * n' + 1 = k
H_wondrous_k : wondrous k
============================
wondrous (S n')