Coq 将假设替换为隐含,而不添加其前提作为子目标
这是我为使用Coq 将假设替换为隐含,而不添加其前提作为子目标,coq,Coq,这是我为使用而尝试构建的自动化的一部分。我有一个引理Is\u true\u implb\u impl:(Is\u true x->Is\u true y)Is\u true(implb x y)。我有一个形式为Is\u true(implb?x?y)的假设H,我使用Ltac elim\u Is\u true:=匹配目标…。当我在H中应用Is\u true\u impb\u impl x y时(如果我没有用x和y进行实例化,它将无法匹配),那么假设将更改为Is\u true y,我将Is\u tr
而尝试构建的自动化的一部分。我有一个引理Is\u true\u implb\u impl:(Is\u true x->Is\u true y)Is\u true(implb x y)。
我有一个形式为Is\u true(implb?x?y)
的假设H,我使用Ltac elim\u Is\u true:=匹配目标…
。当我在H中应用Is\u true\u impb\u impl x y
时(如果我没有用x和y进行实例化,它将无法匹配),那么假设将更改为Is\u true y
,我将Is\u true x
作为一个新的子目标。(我试图通过编写一个断言Is\u true x->Is\u true y
的策略来解决这个问题,但这也失败了,因为我无法找出如何证明断言,在断言不起作用后使用假设
)。有什么方法可以让我把H变成Is\u true x->Is\u true y
?在与其他的循环中执行此操作的另一个问题是_true
消除,即表单的新子目标是_true
与匹配目标,但该策略无法对其应用任何规则
一个示例片段演示了我正在尝试做的事情:
From Coq Require Export Init.Datatypes.
From Coq Require Export Bool.Bool.
Lemma Is_true_implb_impl x y :
(Is_true x -> Is_true y) <-> Is_true (implb x y).
Proof.
destruct x; simpl; split; intros H.
- apply H. apply I.
- intros H'. assumption.
- apply I.
- intros H'. exfalso. assumption.
Qed.
Ltac elim_Is_true :=
match goal with
(* FAILS: *)
(* | [H : Is_true (implb ?x ?y) |- _] => apply Is_true_implb_impl in H *)
| [H : Is_true (implb ?x ?y) |- _] => apply (Is_true_implb_impl x y) in H
| _ => idtac
end.
Example test x y :
Is_true x -> Is_true (implb x y) -> Is_true y.
Proof.
intros H1 H2. elim_Is_true.
(* In this case this is useful but in other cases I do not yet want to add
the premise as a subgoal *)
Abort.
来自Coq的需要导出Init.Datatypes。
从Coq需要导出Bool.Bool。
引理是真的
(Is_true x->Is_true y)Is_true(implb x y)。
证据
破坏x;单纯形;分裂介绍H。
-应用,应用。
-介绍H’。假定
-申请我。
-介绍H’。埃克斯法索。假定
Qed。
Ltac elim_是真的:=
将目标与
(*失败:)
(*|[H:Is_true(implb?x?y)|-|]=>apply Is_true_implb_impl in H*)
|[H:Is_true(implb?x?y)|-]=>在H中应用(Is_true_implb?u impl x y)
|_uz=>idtac
终止
示例测试x y:
是真x->是真(implb x y)->是真y。
证据
简介H1H2。埃利姆是真的。
(*在这种情况下,这很有用,但在其他情况下,我还不想添加
前提作为子目标*)
中止
应用
不是你想要的。引用
应用的策略试图将当前目标与术语类型的结论相匹配。如果成功,那么该策略返回的子目标数与术语类型的非依赖前提数相同
Apply将为每个(非依赖)参数生成子目标,在您的情况下,包括Is\u true x
(除了您已有的目标:Is\u true y
)
相反,你所能做的是模仿应用的假设替换行为,但更好地控制新假设是什么
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\u true\u implb\u 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'.
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.
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'
].