apply
не то, что вы хотите. Цитирование из документации ,
Применяемая тактика пытается сопоставить текущую цель с выводом типа термина. Если это удастся, то эта тактика возвращает столько подцелей, сколько и числа независимых объектов типа термина.
Применить создаст подцели для каждого (независимого) аргумента, который в вашемКейс включает в себя Is_true x
(в дополнение к цели, которая у вас уже есть: Is_true y
).
Вместо этого вы можете сделать некоторую хитрость, чтобы подражать поведению apply
, заменяющему гипотезу, но лучше контролироватьнад новой гипотезой.
Ltac elim_Is_true :=
match goal with
| H : Is_true (implb ?x ?y) |- _ =>
(* Generate a new name for a temporary hypothesis *)
let H' := fresh in
(* rename the old hypothesis to this new name *)
rename H into H';
(* replace the goal with (Is_true x -> Is_true y) -> ?Goal *)
generalize (proj2 (Is_true_implb_impl x y) H');
(* intro (Is_true x -> Is_true y) with the old name *)
intro H;
(* Get rid of the old hypothesis *)
clear H'
| _ => idtac
end.
Мы используем proj2 (Is_true_implb_impl x y) H'
, потому что мы хотим <-
часть тогда и только тогда, когда.
Это можно абстрагировать с помощью тактики, подобнойэто:
Tactic Notation "ng_apply" constr(X) "in" constr(H) :=
let H' := fresh in
rename H into H';
generalize (X H'); intro H;
clear H'.
Теперь elim_Is_true
можно переписать как
Ltac elim_Is_true :=
lazymatch goal with
| H : Is_true (implb ?x ?y) |- _ =>
ng_apply (proj2 (Is_true_implb_impl x y)) in H
end.
(«ng» в ng_apply
означает отсутствие дополнительных целей)
Вы можете эмулировать некоторые действия apply
, используя более сложные ltacs. Например, эта версия дублирует поведение apply
с типами кортежей (например, <->
). Это означает, что мы можем упростить до ng_apply (Is_true_implb_impl x y) in H
.
Ltac ng_apply X H :=
first [
let X' := fresh in let Y := fresh in let Z := fresh in
set (X' := X);
destruct X' as [Y Z] in X';
first [ng_apply Y H | ng_apply Z H];
clear Y; clear Z
| let H' := fresh in
rename H into H';
generalize (X H');
intro H;
clear H'
].
Возможно, можно ng_apply
предоставить некоторые аргументы, но я не смог заставить его работать с деструктуризацией кортежей.