Coq';s的数学证明语言:在if条件下重写

Coq';s的数学证明语言:在if条件下重写,coq,Coq,我试图学习Coq的数学证明语言,但我在试图证明某些东西时遇到了一些麻烦,我将其简化为以下愚蠢的陈述: Lemma foo: forall b: bool, b = true -> (if b then 0 else 1) = 0. 以下是我的尝试: proof. let b: bool. let H: (b = true). 此时,证明状态为: b : bool H : b = true ============================ thesis :

我试图学习Coq的数学证明语言,但我在试图证明某些东西时遇到了一些麻烦,我将其简化为以下愚蠢的陈述:

Lemma foo: forall b: bool, b = true -> (if b then 0 else 1) = 0.
以下是我的尝试:

proof.
  let b: bool.
  let H: (b = true).
此时,证明状态为:

  b : bool
  H : b = true
  ============================
  thesis := 
   (if b then 0 else 1) = 0
现在我想把
if
条件
b
重写为
true
,以便能够证明论文。然而,这两种方法都是“迈出的一小步”

以及“更大的一步”

警告失败:理由不足。
我认为在这种情况下重写没有任何问题,因为正常的
重写->H
策略也会这样做

我还可以通过将
if
包装到函数中,使其正常工作:

Definition ite (cond: bool) (a b: nat) := if cond then a else b.
Lemma bar: forall b: bool, b = true -> (ite b 0 1) = 0.
proof.
  let b: bool. let H: (b = true).
  have (ite b 0 1 = ite true 0 1) by H. thus ~= 0.
end proof.
当然,这不是很好。我做错什么了吗?有没有办法挽救我的原始证据?这只是数学证明语言实现的一个缺点吗

我注意到本手册第11.3.3节中可能有一个相关示例(见):

a:=false:bool
b:=真的:布尔
H:错
============================
论文:=
如果b为真,否则为假
重新考虑这个论点是否正确。

但是我不知道如何将
b:=true
部分放到上下文中。

关键字
proof
似乎进入了声明性的证明模式。相反,关键字
Proof
进入一种必须的证明模式。在第二种情况下,我们可以很容易地证明如下

Lemma foo: forall b: bool, b = true -> (if b then 0 else 1) = 0.                                     
Proof.                                                                                              
  intros b H.                                                                                       
  rewrite H.                                                                                        
  reflexivity.                                                                                      
Qed.  

在第一种情况下,我没有答案。我尝试了许多与你类似的方法,但一次又一次地发现同样的问题。也许更熟悉陈述式证明的人可以给出完整的答案。如果您找到了解决方案,请告诉我们

一种可能的解决方案是在
b
上对每个案例使用
(请参阅):

我还尝试重新创建参考手册示例的验证状态,您可以使用
define

Lemma manual_11_3_3 :
  if false then True else False ->
  if true then True else False.
proof.
  define a as false.
  define b as true.
  assume H : (if a then True else False).
  reconsider H as False.
  reconsider thesis as True.
Abort.

是的,这种“声明模式”是Coq手册第11章所称的“数学证明语言”。我喜欢这种证明方式,这是我与伊莎贝尔/霍尔合作时熟悉的。这就是为什么我现在特别想学习它;我已经知道战术语言,并且知道这个证明是微不足道的;-)这是有道理的。我很高兴安东能帮忙。遗憾的是,声明性语言的这个简单特性似乎无法直接工作!我暂时“接受”这一点,因为这可能是最好的方式,即使它不是我所希望的重写(我仍然认为应该被允许)。在我的示例中,
define
确实将a
b
放在上下文中,但将原始的
b
重命名为
b0
。它不允许我利用
b
是真的这一已知事实。所以这似乎不是一条路要走。谢谢(1) 是的,这只是一个解决办法。人们似乎不使用陈述式语言,而你观察到的行为并没有提高它的受欢迎程度。(2) 事实上,
define
foo
中没有用处——我添加它是为了回应“我不知道如何将
b:=true
部分放到上下文中”。基本上,
define
的工作原理类似于
set
策略。我不使用Coq,但我知道构造演算:等式类型只是莱布尼兹等式的一个表达式,使用2阶多态性和属性相关量化编码。这允许您,给定任何lambda抽象λ(x:A)t:A->B和等式见证p:a0=a1来推断t[x:=a0]=t[x:=a1]——您需要的证明结构就是pλ(x:A)t。不幸的是,我认为Coq放弃了使用这种等式类型的表示。
  a := false : bool
  b := true : bool
  H : False
  ============================
  thesis :=
  if b then True else False

Coq <  reconsider thesis as True.
Lemma foo: forall b: bool, b = true -> (if b then 0 else 1) = 0.                                     
Proof.                                                                                              
  intros b H.                                                                                       
  rewrite H.                                                                                        
  reflexivity.                                                                                      
Qed.  
Lemma foo:
  forall b: bool, b = true -> (if b then 0 else 1) = 0.
proof.
  let b : bool.
  per cases on b.
    suppose it is true. thus thesis.
    suppose it is false. thus thesis.
  end cases.
end proof.
Qed.
Lemma manual_11_3_3 :
  if false then True else False ->
  if true then True else False.
proof.
  define a as false.
  define b as true.
  assume H : (if a then True else False).
  reconsider H as False.
  reconsider thesis as True.
Abort.