素数因子化存在的证明(教育)

时间:2015-09-30 15:05:26

标签: proof isabelle

我试图写出数字素数分解存在的证明。它意味着教育,所以每个功能都被定义,我们尽量不使用Isabelle内置的功能。这是我的代码:

(* addition*)
primrec suma::"nat ⇒ nat ⇒ nat" where
"suma 0 n = 0" |
"suma (Suc x) n = Suc (suma x n)"

primrec pred::"nat ⇒ nat" where
"pred 0 = 0" |
"pred (Suc x) = x"

(* substraction *)
primrec resta::"nat ⇒ nat ⇒ nat" where
"resta m 0 = m" |
"resta m (Suc x) = pred (resta m x)"

primrec mult::"nat ⇒ nat ⇒ nat" where
"mult 0 m = 0" |
"mult (Suc x) m = suma m (mult x m)"

lemma less_pred [simp]: "(x < y) ⟶ (pred x < y)"
proof (induct x)
case 0 then show ?case by simp
next
case (Suc x) then show ?case by simp
qed

lemma less_n_pred [simp]: "∀n::nat. (n ≠ 0) ⟶ (pred n < n)"
proof
fix n::nat show "n ≠ 0 ⟶ pred n < n" by (induct n) simp_all
qed

lemma less_resta [simp]: "(m > 0 ∧ n > 0) ⟶ (resta m n < m)"
proof (induct n)
case 0 then show ?case by simp_all
next
case (Suc x) then show ?case by force
qed

fun divi::"nat ⇒ nat ⇒ nat" where
"divi m n = (if n = 0 then
                undefined
            else
              if m = 0 
                then 0 
              else Suc (divi (resta m n) n))"

fun modulo::"nat ⇒ nat ⇒ nat" where
"modulo m n = (if n = 0 then
                undefined
            else
              if m < n 
                then m 
              else modulo (resta m n) n)"

definition divide::"nat ⇒ nat ⇒ bool" where
"divide m n = (modulo n m = 0)"

primrec numTo :: "nat ⇒ nat list" where
"numTo 0 = []" |
"numTo (Suc x) = (Suc x)#(numTo x)" 

primrec filter:: "'a list ⇒ ('a ⇒ bool) ⇒ 'a list" where
"filter [] p = []" |
"filter (x#xs) p = (if p x then x#(filter xs p) else filter xs p)"

definition divisores::"nat ⇒ nat list" where
"divisores n = (filter (numTo n) (λm. divide m n))"

definition is_prime::"nat ⇒ bool" where
"is_prime n = (length (divisores n) = 2)"

primrec all_prime::"nat list ⇒ bool" where
"all_prime [] = True" |
"all_prime (x#xs) = (is_prime x ∧ all_prime xs)"

primrec prod_list::"nat list ⇒ nat" where
"prod_list [] = 1" |
"prod_list (x#xs) = mult x (prod_list xs)"

lemma mult_num: "∀n::nat. n>1 ∧ ¬ is_prime n ⟶ (∃x y::nat. x < n ∧ y < n ∧ mult x y = n)"
proof
fix n::nat
(* This lemma might be useful? *)

theorem exists_prime_factor: "∀n::nat. (n > 1 ⟶ (∃xs::nat list. prod_list xs = n ∧ all_prime xs))"
proof
  fix n::nat
  show "(n > 1 ⟶ (∃xs::nat list. prod_list xs = n ∧ all_prime xs))"
  proof (induct n rule: less_induct)
 (* How can i prove this? *)

我怎样才能证明定理exists_prime_factor:∀n::nat. (n > 1 ⟶ (∃xs::nat list. prod_list xs = n ∧ all_prime xs))

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

一个简短的回答是,您在定义suma时遇到了一个基本错误。它应该是这个(我猜):

primrec suma::"nat ⇒ nat ⇒ nat" where
  "suma 0 n = n" |
  "suma (Suc x) n = Suc (suma x n)"

我的长篇答案与如何使用valuenitpicksledgehammer有关,以确定您是否在正确的轨道上。

如果你无法证明某事,可以快速尝试sledgehammer。如果sledgehammer完全没有返回任何内容,那么尝试nitpick是一个好主意。

如果nitpick找到了一个反例,那么这是一个很好的指标,表明您的猜想是错误的,但不能保证。由undefinedTHESOME引起的未指定的定义可能会导致该定义,或者不会定义primrec的所有案例。

使用value快速检查您的功能

使用value是我试图解决问题的最终结果,而没有完全整理所有逻辑。

value "mult 2 2" (* Suc (Suc 0) *)

从那里,它终于看到了明显的。

使用value查看您的功能是否正常工作,但这要求代码生成器可以简化value输入。

使用nitpick,它是免费的

对于这样的事情,我想看看sledgehammer是否可以起作用。

首先,最好摆脱外部量词,如下:

theorem exists_prime_factor: 
  "n > 1 --> (∃xs::nat list. prod_list xs = n ∧ all_prime xs)"
  apply(induct n, auto)
  sledgehammer
  oops

sledgehammer根本没有返回任何内容时,猜测结果为假,或者您需要帮助它。

Nitpick给了我n = 2的反例,但它说它可能是虚假,你在定义中使用undefined可能会弄乱nitpick

最后,我在nitpick上运行了lemma mult_num,它给了我一个n = 4的反例。

要尝试的一件事是证明你的定理的否定,这肯定证明你的定理是错误的。我试图证明这一点:

theorem
  "(x >= 4) | (y >= 4) | ~(mult x y = 4)"

最后,我说,&#34;嗯,让我们尝试一些简单的事情&#34;:

value "mult 2 2"

那是回归2,这最终帮助我看到了明显的。

未定义可能不是您认为的

我专门寻找混乱nitpick的东西,其中一个是使用undefined,例如你的函数:

fun divi::"nat ⇒ nat ⇒ nat" where
  "divi m n = (if n = 0 then undefined
               else if m = 0 then 0 
               else Suc (divi (resta m n) n))"

这是value无法帮助您的示例。它无法简化这一点:

value "divi 3 0" (* divi (Suc (Suc (Suc 0))) 0  *)

如果您按照过去对Isabelle / HOL术语的讨论,一些专家希望将undefined称为underspecified

这里,这个定理无法证明:

theorem "divi n 0 ~= (1::nat)"
  apply(induct n, auto)
oops

Nitpick找到了一个反例:

theorem "divi n 0 ~= (1::nat)"
  nitpick (*
  Nitpick found a counterexample:

  Free variable:
    n = 1
*)
oops

但是,它与此相同的反例:

theorem "divi n 0 = (1::nat)"
  nitpick
oops

为什么这一切?因为undefined::natnat。如果你从未定义它,例如使用公理,那么你就不能说nat等于什么,尽管它必须等于某个唯一的nat

44怎么样?

theorem "(divi n 0 = 44) <-> undefined = (44::nat)"
  by(simp)

似乎n = 1023456的可能性非常小。

theorem "(divi n 0 = 1023456) <-> undefined = (1023456::nat)"
  by(simp)

后果?关于这一点,可以有无限多的笑话,无限小的幽默。