Coq true=false区分失败,没有基本相等

Coq true=false区分失败,没有基本相等,coq,coq-tactic,Coq,Coq Tactic,我试图证明以下几点,我认为我有正确的解决方法,列举了b的所有情况,所有单参数布尔函数f应该是4个函数加上2个布尔值,通过彻底破坏一切来证明这一点 Theorem example : forall (f : bool -> bool) (b : bool), f (f b) = b. Proof. intros. destruct (f (f b)). - destruct b. + reflexivity. + Fail discriminate.

我试图证明以下几点,我认为我有正确的解决方法,列举了b的所有情况,所有单参数布尔函数f应该是4个函数加上2个布尔值,通过彻底破坏一切来证明这一点

Theorem example :
  forall (f : bool -> bool) (b : bool),
  f (f b) = b.
Proof.
  intros.
  destruct (f (f b)).
  - destruct b. 
    + reflexivity. 
    + Fail discriminate. admit. 
  - destruct b eqn:Hqebb.
    + Fail discriminate. admit. 
    + reflexivity.  
Qed.
但是,当我尝试在第2步和第3步进行区分时,如果为false=true,则会出现以下错误:

Ltac call to "discriminate" failed.
No primitive equality found.
我以前在归纳类型中使用过Decriminate,它按预期工作,所以我很惊讶它在布尔类型中不起作用。你知道为什么吗?

只有当你的上下文中有一个假设,即等同于以不同构造器开始的归纳类型的术语时,区别策略才会起作用。执行第一次调用discriminate时,上下文如下所示:

f : bool -> bool
============================
true = false
正如您所看到的,上下文中不包含任何平等假设,因此歧视不能做任何事情。要解决这个问题,您需要使用销毁策略的eqn:选项,以便Coq在上下文中记录所有相关事实。例如,如果你打电话

destruct b eqn:H.
b是bool类型,那么除了像往常一样生成两个子目标外,Coq还会添加假设H:b=true和H:b=false

我很感激你改变了你的问题,但我只想指出你现在提出的定理是不可证明的。将其应用于您的原始问题应该不会太困难。

只有在您的上下文中有一个假设,即等同于以不同构造器开始的归纳类型的术语时,区分策略才会起作用。执行第一次调用discriminate时,上下文如下所示:

f : bool -> bool
============================
true = false
正如您所看到的,上下文中不包含任何平等假设,因此歧视不能做任何事情。要解决这个问题,您需要使用销毁策略的eqn:选项,以便Coq在上下文中记录所有相关事实。例如,如果你打电话

destruct b eqn:H.
b是bool类型,那么除了像往常一样生成两个子目标外,Coq还会添加假设H:b=true和H:b=false

我很感激你改变了你的问题,但我只想指出你现在提出的定理是不可证明的。将这一点与你原来的问题相适应应该不会太困难。

如果你有一个不可能的假设true=false,你可以使用discriminate来完成目标。在你坚持的目标中,你被要求证明真=假。没有任何战术可以做到这一点,这是一项不可能完成的任务

您使用的特定示例定理实际上是错误的:

Theorem not_example:
  ~ forall (f : bool -> bool) (b : bool), f (f b) = b.
Proof.  
  intros H.
  specialize (H (fun _ => true) false).
  simpl in H.
  discriminate.
Qed.
但总的来说,正如Arthur所说,实现这一点的方法是使用eqn:选项进行解构,记住相关的方程。这里有一个证明脚本,它主要证明了你的定理,除了错误的情况:

Theorem example :
  forall (f : bool -> bool) (b : bool),
  f (f b) = b.
Proof.
  intros.
  destruct (f true) eqn:?; destruct (f false) eqn:?; destruct b; try congruence.
如果你有一个假设真=假,这是不可能的,你可以使用歧视来完成目标。在你坚持的目标中,你被要求证明真=假。没有任何战术可以做到这一点,这是一项不可能完成的任务

您使用的特定示例定理实际上是错误的:

Theorem not_example:
  ~ forall (f : bool -> bool) (b : bool), f (f b) = b.
Proof.  
  intros H.
  specialize (H (fun _ => true) false).
  simpl in H.
  discriminate.
Qed.
但总的来说,正如Arthur所说,实现这一点的方法是使用eqn:选项进行解构,记住相关的方程。这里有一个证明脚本,它主要证明了你的定理,除了错误的情况:

Theorem example :
  forall (f : bool -> bool) (b : bool),
  f (f b) = b.
Proof.
  intros.
  destruct (f true) eqn:?; destruct (f false) eqn:?; destruct b; try congruence.

有趣的是,我仍然不明白为什么不能立即将true=false标记为不可能。根据布尔的定义:=true | false,它们不可能相等。我的印象是,Discrime的工作原理与反转类似,因为类型定义的关系,构造函数不可能匹配。事实上,它们不可能相等:Discrime的工作就是在出现这些情况时进行识别。问题是,1它要求这些矛盾出现在你的语境中,2 Coq不够聪明,不足以知道你可能想在你的语境中留下的所有信息;你需要明确地说出来。您也可以始终使用eqn修饰符调用destruct,但在处理更复杂的证明时,这会很快使上下文不可读。有趣的是,我仍然不明白为什么不能立即将true=false标记为不可能。根据布尔的定义:=true | false,它们不可能相等。我的印象是,Discrime的工作原理与反转类似,因为类型定义的关系,构造函数不可能匹配。事实上,它们不可能相等:Discrime的工作就是在出现这些情况时进行识别。问题是,1它要求这些矛盾出现在你的语境中,2 Coq不够聪明,不足以知道你可能想在你的语境中留下的所有信息;你需要明确地说出来。您也可以始终使用eqn修饰符调用destruct,但在处理更复杂的证明时,这会很快使上下文不可读。这是同一个问题。A. s说,我们可以证明这样的东西:fB=fB。这是同一个问题。如前所述,我们可以证明这样的东西:fB=fB。