我有一个定义为
的类型Inductive bits : nat -> Set :=
| bitsNil : bits 0
| bitsCons : forall {l}, bool -> bits l -> bits (S l).
我试图证明:
Lemma emptyIsAlwaysNil : forall {a: bits 0}, a = bitsNil.
在intros
之后,我已经尝试constructor 1
,case a
,intuition
,但无济于事。 case a
似乎是最接近的,但它会出错:
Abstracting over the terms "0" and "a" leads to a term
fun (n : nat) (a0 : bits n) => a0 = bitsNil
which is ill-typed.
Reason is: Illegal application:
The term "@eq" of type "forall A : Type, A -> A -> Prop"
cannot be applied to the terms
"bits n" : "Set"
"a0" : "bits n"
"bitsNil" : "bits 0"
The 3rd term has type "bits 0" which should be coercible to
"bits n".
听起来它无法确定任意长度的位向量是否等于零长度的位向量,因为它们在类型级别上是不同的。这是对的吗?
答案 0 :(得分:3)
是的,您基本上是正确的:具体来说,不是类型检查是Coq尝试在match
上构建a:bits 0
(这是{{1} 1}}确实):case
案例有一个错误的结论。
这是一个没有公理的证明。关键的想法是手动将语句概括为任何bitsCons
(我无法弄清楚如何使用策略来执行此操作;它们都会依赖于依赖关系)。然后,无论n = 0
是什么,等式证明都会进行结论类型检查,我们可以解除n
案例,因为我们有bitsCons
。在更困难的n = S n'
情况下,我们使用bitsNil
,这是Axiom K的结果,但是当类型索引(在这种情况下为eq_rect_eq_dec
)具有可判定的相等性时可以证明。如果没有具有可判定的相等性的公理,您可以查看Coq standard library documentation以了解其他一些事情。
nat
你不需要来自Require PeanoNat.
Require Import Eqdep_dec.
Import EqNotations.
Inductive bits : nat -> Set :=
| bitsNil : bits 0
| bitsCons : forall {l}, bool -> bits l -> bits (S l).
Lemma emptyIsAlwaysNil_general :
forall n (H: n = 0) {a: bits n},
rew [bits] H in a = bitsNil.
Proof.
intros.
induction a; simpl.
(* bitsNil *)
rewrite <- eq_rect_eq_dec; auto.
apply PeanoNat.Nat.eq_dec.
(* bitsCons - derive a contradiction *)
exfalso; discriminate H.
Qed.
Lemma emptyIsAlwaysNil : forall {a: bits 0},
a = bitsNil.
Proof.
intros.
change a with (rew [bits] eq_refl in a).
apply emptyIsAlwaysNil_general.
Qed.
的{{1}}符号(它只包含rew H in x
,等式递归原理),但我发现它使事情更具可读性。< / p>
然而,如果你愿意使用公理,你可以更简单地证明这个定理,特别是EqNotations
(更多细节参见CPDT's equality chapter),从那以后你可以使用{{1 }或eq_rect
:
JMeq_eq
答案 1 :(得分:2)
这是一个简单的证明(借鉴this Coq Club thread):
$opts = array(
"replies" => array("Lock", "Locked"),
"flagged" => array(null, "Ignore"),
"deleted" => array("Delete", "Deleted")
);
foreach ($opts as $key => $values) {
if ($row[$key] == 1) {
echo "<input type=\"submit\" value=\"{$values[1]}\">";
} else {
if ($values[0]) {
echo "<input type=\"submit\" value=\"{values[0]}\">";
}
}
}
以下是Coq构建的内容:
Definition emptyIsAlwaysNil {a: bits 0} : a = bitsNil :=
match a with bitsNil => eq_refl end.
Opaque emptyIsAlwaysNil.