我试图写出数字素数分解存在的证明。它意味着教育,所以每个功能都被定义,我们尽量不使用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))
?
提前感谢您的帮助。
答案 0 :(得分:0)
一个简短的回答是,您在定义suma
时遇到了一个基本错误。它应该是这个(我猜):
primrec suma::"nat ⇒ nat ⇒ nat" where
"suma 0 n = n" |
"suma (Suc x) n = Suc (suma x n)"
我的长篇答案与如何使用value
,nitpick
和sledgehammer
有关,以确定您是否在正确的轨道上。
如果你无法证明某事,可以快速尝试sledgehammer
。如果sledgehammer
完全没有返回任何内容,那么尝试nitpick
是一个好主意。
如果nitpick
找到了一个反例,那么这是一个很好的指标,表明您的猜想是错误的,但不能保证。由undefined
,THE
和SOME
引起的未指定的定义可能会导致该定义,或者不会定义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::nat
是nat
。如果你从未定义它,例如使用公理,那么你就不能说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)
后果?关于这一点,可以有无限多的笑话,无限小的幽默。