假设我有一个涉及三个连词{k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2}
的集合。
我如何在Isabelle中证明这个集合的基数是1? (即只有k = 6有gcd 3 6 = 2.)即,我怎样才能证明lemma a_set : "card {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = 1"
?
再次使用sledgehammer
(或try
)不会产生结果 - 我发现很难找到我需要提供的证明方法,以使它们能够证明。 (即使删除,例如gcd 3 k = 2
,也不适合auto
或sledgehammer
。)
答案 0 :(得分:2)
你的命题不正确。您描述的集合实际上是空的,如gcd 3 6 = 3
。大锤可以证明基数是零而没有问题,虽然结果证明再次有点难看,正如Sledgehammer证明的情况一样:
lemma "card {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = 0"
by (metis (mono_tags, lifting) card.empty coprime_Suc_nat
empty_Collect_eq eval_nat_numeral(3) gcd_nat.left_idem
numeral_One numeral_eq_iff semiring_norm(85))
让我们手工完成,只是为了说明如何做到这一点。这些类型的证据往往会变得有点难看,特别是当你不熟悉系统时。
lemma "{k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = {}"
proof safe
fix x :: nat
assume "x > 2" "x ≤ 7" "gcd 3 x = 2"
from ‹x > 2› and ‹x ≤ 7› have "x = 3 ∨ x = 4 ∨ x = 5 ∨ x = 6 ∨ x = 7" by auto
with ‹gcd 3 x = 2› show "x ∈ {}" by (auto simp: gcd_non_0_nat)
qed
另一种更简单的方法(也可能是更可疑的方式)是使用eval
。这使用代码生成器作为oracle,即它将表达式编译为ML代码,编译它,运行它,查看结果是否为True
,然后将其作为定理接受而不通过Isabelle内核,如同正常的证明。在我看来,在使用它之前应该三思而后行,但对于玩具的例子,它完全没问题:
lemma "card {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = 0"
proof -
have "{k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = Set.filter (λk. gcd 3 k = 2) {2<..7}"
by (simp add: Set.filter_def)
also have "card … = 0" by eval
finally show ?thesis .
qed
请注意,我必须首先按下该组(使用Set.filter
而不是设置理解),以便eval
接受它。 (代码生成可能有点棘手)
<强>更新强>
对于评论中的其他陈述,证据必须如下所示:
lemma "{k::nat. 0<k ∧ k ≤ 5 ∧ gcd 5 k = 1} = {1,2,3,4}"
proof (intro equalityI subsetI)
fix x :: nat
assume x: "x ∈ {k. 0 < k ∧ k ≤ 5 ∧ coprime 5 k}"
from x have "x = 1 ∨ x = 2 ∨ x = 3 ∨ x = 4 ∨ x = 5" by auto
with x show "x ∈ {1,2,3,4}" by (auto simp: gcd_non_0_nat)
qed (auto simp: gcd_non_0_nat)
这看起来如此不同的原因是因为目标的右侧不再仅仅是{}
,所以safe
表现不同并且产生了相当复杂的子目标(只是看看proof safe
之后的证明状态。对于intro equalityI subsetI
,我们基本上只是说我们希望通过证明A = B
来证明a ∈ A ⟹ a ∈ B
,然后通过证明a
来证明safe
。这可能比Ember.TEMPLATES["test/fixtures/simple"] = Ember.HTMLBars.template({"id":null,"block":"{\"statements\":[[\"open-element\",\"p\",[]],[\"flush-element\"],[\"text\",\"Hello, my name is \"],[\"append\",[\"unknown\",[\"name\"]],false],[\"text\",\".\"],[\"close-element\"]],\"locals\":[],\"named\":[],\"yields\":[],\"blocks\":[],\"hasPartials\":false}","meta":{}});
更强大。