在假设中,我有一个自然数不能为零。当我们加上这个数时 到另一个函数,其输出也是自然数。我必须证明这两个等于零的值相加的结果是错误的。我不应该讨论f,因为在非零项中加任何东西,等于零就是错误的陈述。
`H:(m =?0)=假
(f + m =?0)=假`
答案 0 :(得分:2)
Require Import Lia.
rewrite !Nat.eqb_neq; lia.
我很抱歉出现这个问题。从历史上看,Coq中有关平等的大多数推理都是通过eq
概念,用符号m = n
完成的,而不是您在此依赖的布尔相等性。同样重要的是要知道Coq具有“不平等”或“不平等”的特定表示法:m <> n
代表~ (m = n)
。
因此,如果您添加键入以下语句,则会有一个简单的解决方案:
Require Import Arith Lia.
Lemma example1 f m : m <> 0 -> f + m <> 0.
Proof. lia. Qed.
不幸的是,这不适用于您表达陈述的方式:
Lemma example2 f m : (m =? 0) = false -> (f + m =? 0) = false.
Proof.
Fail lia.
如果使用以下模式调用Search
,则会看到布尔比较表达式在逻辑上等同于基本等式,但前提是要使用特定的定理来表达这一点:
Search (_ =? _).
Nat.eqb_refl: forall x : nat, (x =? x) = true
beq_nat_refl: forall n : nat, true = (n =? n)
Nat.eqb_sym: forall x y : nat, (x =? y) = (y =? x)
Nat.eqb_spec: forall x y : nat, Bool.reflect (x = y) (x =? y)
beq_nat_eq: forall n m : nat, true = (n =? m) -> n = m
beq_nat_true: forall n m : nat, (n =? m) = true -> n = m
Nat.eqb_eq: forall n m : nat, (n =? m) = true <-> n = m
beq_nat_false: forall n m : nat, (n =? m) = false -> n <> m
Nat.eqb_neq: forall x y : nat, (x =? y) = false <-> x <> y
Nat.pow2_bits_eqb: forall n m : nat, Nat.testbit (2 ^ n) m = (n =? m)
Nat.bit0_eqb: forall a : nat, Nat.testbit a 0 = (a mod 2 =? 1)
Nat.eqb_compare:
forall x y : nat, (x =? y) = match x ?= y with
| Eq => true
| _ => false
end
Nat.setbit_eqb:
forall a n m : nat,
Nat.testbit (Nat.setbit a n) m = ((n =? m) || Nat.testbit a m)%bool
Nat.clearbit_eqb:
forall a n m : nat,
Nat.testbit (Nat.clearbit a n) m = (Nat.testbit a m && negb (n =? m))%bool
Nat.testbit_eqb: forall a n : nat, Nat.testbit a n = ((a / 2 ^ n) mod 2 =? 1)
但是没有一个定理可以表达加法等于0等于加法的相互作用。您还可以使用更精确的模式来看到这一定理。
Search (_ =? _) 0 (_ + _).
这不返回任何内容。
另一方面,如果您键入
Search (_ = _) 0 (_ + _).
您会看到许多定理,其中之一与您的问题有关。
Nat.eq_add_0: forall n m : nat, n + m = 0 <-> n = 0 /\ m = 0
如果用_ = _
而不是_ =? _
表示,那么这足以解决问题。因此,要解决您的特定问题,我们首先需要将使用_ =? _
的比较转换为等式语句,然后使用可用的定理进行逻辑推理。在第一个搜索结果中,我们有适合您情况的定理Nat.eqb_neq
。继续上面example2
的证明,我们可以写:
Rewrite !Nat.eqb_neq.
The goal becomes:
f, m : nat
============================
m <> 0 -> f + m <> 0
现在,我们可以使用定理Nat.eq_add_0
进行逻辑推理。
rewrite Nat.eq_add_0.
我们可以一步步完成证明。
intros mn0 [fis0 mis0]; case mn0; assumption.
我们还可以要求自动工具为我们完成证明:
tauto.
但是在时间上往后走一点,我们也可以在用Nat.eqb_neq重写后观察该语句。这是线性算术中的一条语句(它包含比较,自然数,并且变量之间无积)。该声明属于该理论的策略范围,现在最常用的是lia
。