Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Zeckendorf/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 15 kB image not shown  

Quelle  Zeckendorf.thy

  Sprache: Isabelle
 

section Zeckendorf's Theorem

theory Zeckendorf

imports 
  Main
  "HOL-Number_Theory.Number_Theory"

begin

subsection Definitions
text 
 Formulate auxiliary definitions. An increasing sequence is a predicate of a function $f$
 together with a set $I$. $f$ is an increasing sequence on $I$, if $f(x)+1 < f(x+1)$
 for all $x \in I$. This definition is used to ensure that the Fibonacci numbers in the sum are
 non-consecutive.
 

definition is_fib :: "nat ==> bool" where
  "is_fib n = ( i. n = fib i)"

definition le_fib_idx_set :: "nat ==> nat set" where
  "le_fib_idx_set n = {i .fib i < n}"

definition inc_seq_on :: "(nat ==> nat) ==> nat set ==> bool" where
  "inc_seq_on f I = ( n I. f(Suc n) > Suc(f n))"

definition fib_idx_set :: "nat ==> nat set" where
  "fib_idx_set n = {i. fib i = n}"

subsection Auxiliary Lemmas

lemma fib_values[simp]:
  "fib 3 = 2"
  "fib 4 = 3"
  "fib 5 = 5"
  "fib 6 = 8"
  by(auto simp: numeral_Bit0 numeral_eq_Suc)

lemma fib_strict_mono: "i 2 ==> fib i < fib (Suc i)"
  using fib_mono by(induct i, simp, fastforce)

lemma smaller_index_implies_fib_le: "i < j ==> fib(Suc i) fib j"
  using fib_mono by (induct j, auto)

lemma fib_index_strict_mono : "i 2 ==> j > i ==> fib j > fib i"
  by(induct i, simp, metis Suc_leI fib_mono fib_strict_mono nle_le nless_le)

lemma fib_implies_is_fib: "fib i = n ==> is_fib n"
  using is_fib_def by auto

lemma zero_fib_unique_idx: "n = fib i ==> n = fib 0 ==> i = 0"
  using fib_neq_0_nat fib_idx_set_def by fastforce

lemma zero_fib_equiv: "fib i = 0 i = 0"
  using zero_fib_unique_idx by auto

lemma one_fib_idxs: "fib i = Suc 0 ==> i = Suc 0 i = Suc(Suc 0)"
  using Fib.fib0 One_nat_def Suc_1 eq_imp_le fib_2 fib_index_strict_mono less_2_cases nat_neq_iff by metis

lemma ge_two_eq_fib_implies_eq_idx: "n 2 ==> n = fib i ==> n = fib j ==> i = j"
  using fib_index_strict_mono fib_mono Suc_1 fib_2 nle_le nless_le not_less_eq by metis

lemma ge_two_fib_unique_idx: "fib i 2 ==> fib i = fib j ==> i = j"
  using ge_two_eq_fib_implies_eq_idx by auto

lemma no_fib_lower_bound: "¬ is_fib n ==> n 4"
proof(rule ccontr)
  assume "¬ is_fib n" "¬ 4 n"
  hence "n {0,1,2,3}" by auto
  have "is_fib 0" "is_fib 1" "is_fib 2" "is_fib 3"
    using fib0 fib1 fib_values fib_implies_is_fib by blast+
  then show False
    using ¬ is_fib n n {0,1,2,3} by blast
qed

lemma pos_fib_has_idx_ge_two: "n > 0 ==> is_fib n ==> ( i. i 2 fib i = n)"
  unfolding is_fib_def by (metis One_nat_def fib_2 fib_mono less_eq_Suc_le nle_le)

lemma finite_fib0_idx: "finite({i. fib i = 0})"
  using zero_fib_unique_idx finite_nat_set_iff_bounded by auto

lemma finite_fib1_idx: "finite({i. fib i = 1})"
  using one_fib_idxs finite_nat_set_iff_bounded by auto

lemma finite_fib_ge_two_idx: "n 2 ==> finite({i. fib i = n})"
  using ge_two_fib_unique_idx finite_nat_set_iff_bounded by auto

lemma finite_fib_index: "finite({i. fib i = n})"
  using finite_fib0_idx finite_fib1_idx finite_fib_ge_two_idx by(rule nat_induct2, auto)

lemma no_fib_implies_zero_in_le_idx_set: "¬ is_fib n ==> 0 {i. fib i < n}"
  using no_fib_lower_bound by fastforce

lemma no_fib_implies_le_fib_idx_set: "¬ is_fib n ==> {i. fib i < n} {}"
  using no_fib_implies_zero_in_le_idx_set by blast

lemma finite_smaller_fibs: "finite({i. fib i < n})"
proof(induct n)
  case (Suc n)
  moreover have "{i. fib i < Suc n} = {i. fib i < n} {i. fib i = n}" by auto
  moreover have "finite({i. fib i = n})" using finite_fib_index by auto
  ultimately show ?case  by auto
qed simp

lemma nat_ge_2_fib_idx_bound: "2 n ==> fib i n ==> n < fib (Suc i) ==> 2 i"
  by (metis One_nat_def fib_1 fib_2 le_Suc_eq less_2_cases linorder_not_le not_less_eq)

lemma inc_seq_on_aux: "inc_seq_on c {0..k - 1} ==> n - fib i < fib (i-1) ==> fib (c k) < fib i ==>
                       (n - fib i) = ( i=0..k. fib (c i)) ==> Suc (c k) < i"
  by (metis fib_mono bot_nat_0.extremum diff_Suc_1 leD le_SucE linorder_le_less_linear not_add_less1 sum.last_plus)

lemma inc_seq_zero_at_start: "inc_seq_on c {0..k-1} ==> c k = 0 ==> k = 0"
  unfolding inc_seq_on_def
  by (metis One_nat_def Suc_pred atLeast0AtMost atMost_iff less_nat_zero_code not_gr_zero order.refl)

lemma fib_sum_zero_equiv: "( i=n..m::nat . fib (c i)) = 0 ( i{n..m}. c i = 0)"
  using finite_atLeastAtMost sum_eq_0_iff zero_fib_equiv by auto

lemma fib_idx_ge_two_fib_sum_not_zero: "n m ==> i{n..m::nat}. c i 2 ==> ¬ ( i=n..m. fib (c i)) = 0"
  by (rule ccontr, simp add: fib_sum_zero_equiv)

lemma one_unique_fib_sum: "inc_seq_on c {0..k-1} ==> i{0..k}. c i 2 ==> ( i=0..k. fib (c i)) = 1 k = 0 c 0 = 2"
proof
  assume assms: "(i = 0..k. fib (c i)) = 1" "inc_seq_on c {0..k-1}" "i{0..k}. c i 2"
  hence "fib (c 0) + (i = 1..k. fib (c i)) = 1" by (simp add: sum.atLeast_Suc_atMost)
  moreover have "fib (c 0) 1" using assms fib_neq_0_nat[of "c 0"by force
  ultimately show "k = 0 c 0 = 2"
    using fib_idx_ge_two_fib_sum_not_zero[of 1 k c] assms add_is_1 one_fib_idxs by(cases "k=0", fastforce, auto)
qed simp

lemma no_fib_betw_fibs: 
  assumes "¬ is_fib n"
  shows " i. fib i < n n < fib (Suc i)"
proof - 
  have finite_le_fib: "finite {i. fib i < n}" using finite_smaller_fibs by auto
  obtain i where max_def: "i = Max {i. fib i < n}" by blast
  show " i. fib i < n n < fib (Suc i)"
  proof(intro exI conjI)
    have "(Suc i) {i. fib i < n}" using max_def Max_ge Suc_n_not_le_n finite_le_fib by blast
    thus "fib (Suc i) > n" 
      using ¬ is_fib n fib_implies_is_fib linorder_less_linear by blast
  qed(insert max_def Max_in ¬ is_fib n finite_le_fib no_fib_implies_le_fib_idx_set, auto)
qed

lemma betw_fibs: 
  shows " i. fib i n fib(Suc i) > n"   
proof(cases "is_fib n")
  case True
  then obtain i where a: "n = fib i" unfolding is_fib_def by auto
  then show ?thesis
    by (metis fib1 Suc_le_eq fib_2 fib_mono fib_strict_mono le0 le_eq_less_or_eq not_less_eq_eq)
qed(insert no_fib_betw_fibs, force)

text 
 Proof that the sum of non-consecutive Fibonacci numbers with largest member $F_i$ is strictly
 less then $F_{i+1}$. This lemma is used for the uniqueness proof.
 

lemma fib_sum_upper_bound:
  assumes "inc_seq_on c {0..k-1}" "i{0..k}. c i 2"
  shows "( i=0..k. fib (c i)) < fib (Suc (c k))"
proof(insert assms, induct "c k" arbitrary: k rule: nat_less_induct)
  case 1
  then show ?case
  proof(cases "c k")
    case (Suc _)
    show ?thesis
    proof(cases k)
      case k_Suc: (Suc _)
      hence  ck_bounds: "c(k-1) + 1 < c k" "c(k-1) < c k"
        using 1(2unfolding inc_seq_on_def by (force)+
      moreover have "(i = 0..k. fib (c i)) = fib(c k) + (i = 0..k-1. fib (c i))" 
        using k_Suc by simp
      moreover have "(i = 0..(k-1). fib (c i)) < fib (Suc (c (k-1)))" 
        using ck_bounds(21 unfolding inc_seq_on_def by auto
      ultimately show ?thesis 
        using Suc smaller_index_implies_fib_le by fastforce
    qed(simp add: fib_index_strict_mono assms(2))
  qed(insert inc_seq_zero_at_start[OF 1(2)], auto)
qed

lemma last_fib_sum_index_constraint:
  assumes "n 2" "n = ( i=0..k. fib (c i))" "inc_seq_on c {0..k-1}" 
  assumes "i{0..k}. c i 2" "fib i n" "fib(Suc i) > n"
  shows "c k = i"
proof -
  have "2 i" using assms(1,5,6) nat_ge_2_fib_idx_bound by simp 
  have "c k > i False"
    using smaller_index_implies_fib_le assms 
    by (metis bot_nat_0.extremum leD sum.last_plus trans_le_add1)
  moreover have "c k < i False"
  proof 
    assume "c k < i"
    have seq: "inc_seq_on c {0..k - 1 - 1}" "i{0..k-1}. 2 c i"
      using assms unfolding inc_seq_on_def by simp+
    have "k > 0"
      by(rule ccontr, insert c k < i assms fib_index_strict_mono leD, auto)
    hence "c (k-1) + 1 < c k" "c (k-1) + 3 i"
      using c k < i assms unfolding inc_seq_on_def by force+
    have "(i = 0..k-1. fib (c i)) + fib (c k) = (i = 0..k. fib (c i))"
      using sum.atLeast0_atMost_Suc Suc_pred'[OF k > 0by metis
    moreover have "fib (Suc (c (k-1))) fib (i-2)"
      using c k < i c (k-1) + 1 < c k by (simp add: fib_mono)
    moreover have "fib (c k) fib (i-1)"
      using c k < i fib_mono by fastforce
    ultimately have "(i = 0..k. fib (c i)) < fib (i-1) + fib (i-2)"
      using assms c k < i k > 0 fib_sum_upper_bound[OF seq(1) seq(2)] by simp
    hence "(i = 0..k. fib (c i)) < fib i"
      using fib.simps(3)[of "i-2"] assms(4c k < i
      by (metis add_2_eq_Suc diff_Suc_1 2 i le_add_diff_inverse)
    then show False
      using assms by simp
    qed
    ultimately show ?thesis by simp
  qed

subsection Theorem
text 
 Now, both parts of Zeckendorf's Theorem can be proven. Firstly, the existence of an increasing
 sequence for a positive integer $N$ such that the corresponding Fibonacci numbers sum up to $N$
 is proven. Then, the uniqueness of such an increasing sequence is proven.
 

lemma fib_implies_zeckendorf:
  assumes "is_fib n" "n > 0"
  shows " c k. n = ( i=0..k. fib(c i)) inc_seq_on c {0..k-1} ( i{0..k}. c i 2)" 
proof - 
  from assms obtain i where i_def: "fib i = n" "i 2" using pos_fib_has_idx_ge_two by auto
  define c where c_def: "(c :: nat ==> nat) = (λ n::nat. if n = 0 then i else i + 3)"
  from i_def have "n = (i = 0..0. fib (c i))" by (simp add: c_def) 
  moreover have "inc_seq_on c {0..0}" by (simp add: c_def inc_seq_on_def)
  ultimately show " c k. n = ( i=0..k. fib(c i)) inc_seq_on c {0..k-1} ( i{0..k}. c i 2)"
    using i_def c_def by fastforce
qed

theorem zeckendorf_existence:
  assumes "n > 0"
  shows " c k. n = ( i=0..k. fib (c i)) inc_seq_on c {0..k-1} (i{0..k}. c i 2)" 
  using assms
proof(induct n rule: nat_less_induct)
  case (1 n)
  then show ?case
  proof(cases "is_fib n")
    case False
    obtain i where bounds: "fib i < n" "n < fib (Suc i)" "i > 0"
      using no_fib_betw_fibs 1(2) False by force
    then obtain c k where seq: "(n - fib i) = ( i=0..k. fib (c i))" "inc_seq_on c {0..k-1}" " i{0..k}. c i 2"
      using 1 fib_neq_0_nat zero_less_diff diff_less by metis
    let ?c' = "(λ n. if n = k+1 then i else c n)"
    have diff_le_fib: "n - fib i < fib(i-1)"
      using bounds fib2 not0_implies_Suc[of i] by auto
    hence ck_lt_fib: "fib (c k) < fib i" 
      using fib_Suc_mono[of "i-1"] bounds by (simp add: sum.last_plus seq)
    have "inc_seq_on ?c' {0..k}"
      using inc_seq_on_aux[OF seq(2) diff_le_fib ck_lt_fib seq(1)] One_nat_def 
            inc_seq_on_def leI seq by force
    moreover have "n = ( i=0..k+1. fib (?c' i))" 
      using bounds seq by simp
    moreover have " i {0..k+1}. ?c' i 2" 
      using seq bounds fib2 not0_implies_Suc[of i] atLeastAtMost_iff 
            diff_is_0_eq' less_nat_zero_code not_less_eq_eq by fastforce
    ultimately show ?thesis by fastforce
  qed(insert fib_implies_zeckendorf, auto)
qed

lemma fib_unique_fib_sum:
  fixes k :: nat
  assumes "n 2" "inc_seq_on c {0..k-1}" "i{0..k}. c i 2" 
  assumes "n = fib i"
  shows "n = (i=0..k. fib (c i)) k = 0 c 0 = i"
proof
  assume ass: "n = (i = 0..k. fib (c i))"
  obtain j where bounds: "fib j n" "fib(Suc j) > n" "j 2" 
    using betw_fibs assms nat_ge_2_fib_idx_bound by blast
  have idx_eq: "c k = j"
    using last_fib_sum_index_constraint assms(1-3) ass bounds by simp
  have "i = j"
    using bounds ass assms 
    by (metis Suc_leI fib_mono ge_two_fib_unique_idx le_neq_implies_less linorder_not_le)
  have "k > 0 fib i = fib i + (i = 0..k-1. fib (c i))"
    using ass assms by (metis idx_eq One_nat_def Suc_pred i = j add.commute sum.atLeast0_atMost_Suc)
  hence "k > 0 False"
    using fib_idx_ge_two_fib_sum_not_zero[of 0 "k-1" c] assms by auto
  then show "k = 0 c 0 = i" using i = j idx_eq by simp
qed(auto simp: assms)

theorem zeckendorf_unique:
  assumes "n > 0"
  assumes "n = ( i=0..k. fib (c i))" "inc_seq_on c {0..k-1}" "i{0..k}. c i 2" 
  assumes "n = ( i=0..k'. fib (c' i))" "inc_seq_on c' {0..k'-1}" "i{0..k'}. c' i 2"
  shows "k = k' ( i {0..k}. c i = c' i)"
  using assms
proof(induct n arbitrary: k k' rule: nat_less_induct)
  case IH: (1 n)
  consider "n = 0" | "n = 1" | "n 2" by linarith
  then show ?case
  proof(cases)
    case 3
    obtain i where bounds: "fib i n" "fib(Suc i) > n" "2 i" 
      using betw_fibs nat_ge_2_fib_idx_bound 3 by blast
    have last_idx_eq: "c' k' = i" "c k = i" "c' k' = c k"
      using last_fib_sum_index_constraint[OF 3] IH(6-8) IH(3-5) bounds by blast+
    then show ?thesis
    proof(cases "is_fib n")
      case True
      hence "fib i = n" 
        unfolding is_fib_def using bounds IH(2-8) fib_mono leD nle_le not_less_eq_eq by metis
      hence "k = 0" "c 0 = i" "k' = 0" "c' 0 = i"
        using fib_unique_fib_sum 3 IH(3-8by metis+
        then show ?thesis by simp
    next
      case False
      have "k > 0" 
        using IH(3) False unfolding is_fib_def by fastforce
      have "k' > 0"
        using IH(6) False  unfolding is_fib_def by fastforce
      have "0 < n - fib (c k)" using False bounds last_idx_eq(2unfolding is_fib_def by fastforce
      moreover have "n - fib (c k) < n" 
        using bounds last_idx_eq by (simp add: dual_order.strict_trans1 fib_neq_0_nat)
      moreover have "n - fib (c k) = (i = 0..k-1. fib (c i))" 
        using sum.atLeast0_atMost_Suc[of "λ i. fib (c i)" "k-1"] Suc_diff_1 k > 0 IH(3by simp
      moreover have "n - fib (c' k' ) = (i = 0..k'-1. fib (c' i))" 
        using sum.atLeast0_atMost_Suc[of "λ i. fib (c' i)" "k'-1"] Suc_diff_1 k' > 0 IH(6by simp
      moreover have "inc_seq_on c {0..k-1 - 1}" "i{0..k-1}. 2 c i"
        using IH(4,5unfolding inc_seq_on_def by auto
      moreover have "inc_seq_on c' {0..k'-1 - 1}" "i{0..k'-1}. 2 c' i"
        using IH(7,8unfolding inc_seq_on_def by auto
      ultimately have "k-1 = k'-1 (i{0..k-1}. c i = c' i)"
        using IH(1unfolding last_idx_eq by blast 
      then show ?thesis
        using IH(1) last_idx_eq by (metis One_nat_def Suc_pred 0 < k' 0 < k atLeastAtMost_iff le_Suc_eq)
    qed
  qed(insert IH one_unique_fib_sum, auto)
qed

end

Messung V0.5 in Prozent
C=81 H=94 G=87

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.