Coq 如何自动生成";“好”;存在假设分解时的名称

Coq 如何自动生成";“好”;存在假设分解时的名称,coq,Coq,我有一个存在假设,比如: H : exists (a : A) (b : B) (c : C), P a b c 我想将其分解为: a : A b : B c : C H0 : P a b c 策略分解[ex]H;清除H就是这样做的,只是变量的名称变为x,x0和x1,而不是a,b,c。有没有办法分解这个假设,自动生成“好”的名字(就像intros为所有(a:a)(b:b)(c:c),P a b c)的目标所采用的方法一样?可以手动给出名字 Goal forall (t : Type) (p

我有一个存在假设,比如:

H : exists (a : A) (b : B) (c : C), P a b c
我想将其分解为:

a : A
b : B
c : C
H0 : P a b c

策略
分解[ex]H;清除H
就是这样做的,只是变量的名称变为
x
x0
x1
,而不是
a
b
c
。有没有办法分解这个假设,自动生成“好”的名字(就像
intros
为所有(a:a)(b:b)(c:c),P a b c)的
目标所采用的方法一样?

可以手动给出名字

Goal forall (t : Type) (p : t -> Prop) (q : Prop), (exists x : t, p x) -> q.
Proof. intros ? ? ? h1. elim h1. intros x h2. Abort.

Goal forall (t : Type) (p : t -> Prop) (q : Prop), (exists x : t, p x) -> q.
Proof. intros ? ? ? h1. inversion h1 as [x h2]. Abort.

Goal forall (t : Type) (p : t -> Prop) (q : Prop), (exists x : t, p x) -> q.
Proof. intros ? ? ? h1. destruct h1 as [x h2]. Abort.

Goal forall (t : Type) (p : t -> Prop) (q : Prop), (exists x : t, p x) -> q.
Proof. intros ? ? ? h1. induction h1 as [x h2]. Abort.

Goal forall (t : Type) (p : t -> Prop) (q : Prop), (exists x : t, p x) -> q.
Proof. intros ? ? ? [x h]. Abort.
好的,我想我(在一些帮助下)做到了你想要的:

Parameter A B C : Type.
Parameter P : A -> B -> C -> Prop.
Parameter Q : Prop.

(* This will try to match an hypothesis named h with 'exists u: T, P' 
   and return the name of 'u' *)
Ltac extract_name h :=
  match goal with
    | [h : ?A |- _ ] => 
      match A with
        | @ex ?T ?P => match P with
                          | fun u => _ => u
                   end
   end
end.

(* 'smart' destruct using the name we just computed *)
Ltac one_destruct h :=
   let a := extract_name h in
   destruct h as [a h].

Goal (exists (a:A) (b:B) (c:C), P a b c) -> Q.
intros H.
repeat (one_destruct H).
(* the goal is now
1 subgoals
a : A
b : B
c : C
H : P a b c
______________________________________(1/1)
Q
*)
我不是一个熟练的Ltac用户,所以这可能不是完全完美的。使用风险自负:)

最好的,
V.

可以生成一个保证不会与任何现有名称冲突的名称。你不会事先知道这个名字是什么,但你仍然可以在战术中使用它。但我认为它没有那么好。您可以使用
idtac
打印它

Goal forall (t : Type) (p : t -> Prop) (q : Prop), (forall x : t, p x -> q) -> (exists x : t, p x) -> q.
Proof.
intros ? ? ? h.
let h := fresh "h" in idtac h; intros h; case h.
let h := fresh "h" in idtac h; intros x h.
firstorder.
Qed.
以下策略(Vinz解决方案的简化、整理和更正版本)达到了预期的效果

Ltac decompose_ex H :=
  repeat match type of H with
           | ex (fun x => _) =>
             let x := fresh x in
             destruct H as [x H]
         end.

它不是直接链接的,但它只是让您知道,使用用于coq的emacs compagny模式,您可以为
简介
实现类似的功能(我不确定它是否适用于
销毁
思想)


要做到这一点,只需使用安装compagny coq(它非常强大,您应该试试)。然后,当您在文件中添加一些简介时,只需编写
简介
然后按
,它将自动完成。我不确定名称是否总是最好的,但至少它是确定的,如果您在之前或之后添加几行,它不会中断。

使用Ltac可能是可行的,但我不太了解它。作为我的Coq文件的常规规则,我尝试手动命名大多数假设,从不依赖Coq的自动命名。这使得脚本更加健壮。例如,在您的特殊情况下,您可以将H分解为[a b c HPabc]
。在学习Coq时,有经验的人多次告诉我,不要依赖Coq对变量的自动命名!然而,在这种情况下,我的证明并不依赖于这些名称,因为后续的策略将通过模式匹配来确定名称。但是我仍然希望名称是“好的”,以便在手动检查证明状态时使我的生活更轻松。有几十个变量都被命名为
xN
,这会让事情变得很难理解。我明白了,也许Coq俱乐部的一些Coq/Ltac大师可以帮助你:祝你好运!是的,但我正在寻找一种自动生成这些名称的解决方案,因为这段代码将在Ltac定义中使用,该定义将应用于具有不同数量变量的假设。啊哈!我曾尝试过这样做,但无法找出与存在类型匹配的语法。(我想我使用的是
fun?x=>\uuu
而不是
fun x=>\uu
)。您的解决方案有一个错误:如果名称
a
正在使用中,那么
一次解构将失败。现在我在回答中修复了这个错误,使用
let a:=fresh a
生成一个新名称(对于某个整数
N
,它将是
a
aN
),但这并不能回答问题。产生“好”的名字是问题的关键。