证明更复杂的基数的基数

时间:2017-02-19 20:23:54

标签: isabelle

假设我有一个涉及三个连词{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,也不适合autosledgehammer。)

1 个答案:

答案 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":{}}); 更强大。