Я пытаюсь написать доказательство существования простой факторизации чисел. Он предназначен для образования, поэтому каждая функция определена, мы стараемся не использовать Изабель, встроенную в функции. Вот мой код:Доказательство существования простой факторизации (образовательной)
(* 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))
?
Заранее благодарю вас за помощь.
Большое спасибо за ваш ответ! Это очень полезно. Однако у меня есть некоторые сомнения относительно разделения. Как бы вы определили «divi» без использования undefined? Возвращение «Может быть, нат»? –
@Hector, это была бы идея преследовать, которая будет использовать тип 'nat option', но в целом это не сделало бы все необыкновенно легким. Вместо «undefined» вы можете просто установить его равным 0. Затем либо выяснить, как сделать «divi m 0 = 0» значимым, либо поставить условия в ваших теоремах, чтобы исключить этот случай. Ваш 'divi' выключен на 1. Я думаю, что' m
Неопределенность в общей логике, такой как HOL, сложна. Определение 'x/0 = undefined' совершенно разумно, так как оставляет его неопределенным.Однако прошлый опыт показал, что делать это не имеет никаких преимуществ; определение 'x/0 = 0', с другой стороны, полезно, потому что многие хорошие законы деления все еще сохраняются. Возвращение деления «nat option» кажется очевидным решением, но тогда вам нужно постоянно поднимать другие арифметические операции (например, сложение и умножение) на «nat option», что очень утомительно. –