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

Quelle  Digits.thy

  Sprache: Isabelle
 

theory Digits
  imports Complex_Main
begin

section Representation of integers in different bases

text 

text  First, we look at some useful lemmas for splitting sums.
lemma split_sum_first_elt_less: assumes "n<m" 
  shows "(i{n..<m}. f i) = f n + (i{Suc n ..<m}. f i)"
  using sum.atLeast_Suc_lessThan assms by blast

lemma split_sum_mid_less: assumes "i<(n::nat)"
  shows "(j<n. f j) = (j<i. f j) + (j=i..<n. f j)"
proof -
  have "(j<n. f j) = (j{..<i} {i..<n}. f j)"
    using i < n by (intro sum.cong) auto
  also have " = (j<i. f j) + (j=i..<n. f j)"
    by (subst sum.union_disjoint) auto
  finally show "(j<n. f j) = (j<i. f j) + (j=i..<n. f j)" .
qed

text In order to use representation of numbers in a basis base and to calculate the conversion
  and from integers, we introduce the following locale.

locale digits =
  fixes base :: nat
  assumes base_pos: "base > 0"
begin

text Conversion from basis base to integers: from_digits n d

 begin{tabular}{lcp{8cm}}
 n:& nat& length of representation in basis base\\
 d:& nat ==> nat& function of digits in basis base where d i is the $i$-th digit in basis base\\
 output:& nat& natural number corresponding to $d(n-1) \dots d(0)$ as integer\\
 end{tabular}
 

fun from_digits :: "nat ==> (nat ==> nat) ==> nat" where
  "from_digits 0 d = 0"
"from_digits (Suc n) d = d 0 + base * from_digits n (d Suc)"

text Alternative definition using sum:
lemma from_digits_altdef: "from_digits n d = (i<n. d i * base ^ i)"
  by (induction n d rule: from_digits.induct)
     (auto simp add: sum.lessThan_Suc_shift o_def sum_distrib_left 
       sum_distrib_right mult_ac simp del: sum.lessThan_Suc)

text Digit in basis base of some integer number: digit x i

 begin{tabular}{lcp{8cm}}
 x:& nat& integer\\
 i:& nat& index\\
 output:& nat& $i$-th digit of representation in basis base of $x$\\
 end{tabular}
 

fun digit :: "nat ==> nat ==> nat" where
  "digit x 0 = x mod base"
"digit x (Suc i) = digit (x div base) i"

text Alternative definition using divisor and modulo:
lemma digit_altdef: "digit x i = (x div (base ^ i)) mod base"
  by (induction x i rule: digit.induct) (auto simp: div_mult2_eq) 

text Every digit must be smaller that the base.
lemma digit_less_base: "digit x i < base"
  using base_pos by (auto simp: digit_altdef)

text A representation in basis base of length $n$ must be less than $base ^ n$.
lemma from_digits_less: 
  assumes "i<n. d i < base" 
  shows "from_digits n d < base ^ n"
using assms proof (induct n d rule: from_digits.induct)
  case (2 n d)
  have "from_digits n (d Suc) base ^ n -1" using 2 
    by (metis One_nat_def Suc_leI Suc_pred base_pos comp_apply 
        less_Suc_eq_le zero_less_power)
  moreover have "d 0 base -1" using 2 
    by (metis One_nat_def Suc_pred base_pos less_Suc_eq_0_disj 
        less_Suc_eq_le)
  ultimately have "d 0 + base * from_digits n (d Suc)
      base - 1 + base * (base^(n) - 1)"
    by (simp add: add_mono_thms_linordered_semiring(1))
  then show "from_digits (Suc n) d < base ^ Suc n" 
    using base_pos by (auto simp:comp_def) 
    (metis Suc_pred add_gr_0 le_imp_less_Suc mult_Suc_right 
      zero_less_power)
qed auto

text Lemmas for mod and div in number systems of basis base:
lemma mod_base:  assumes "i. i<n ==> d i < base" "n>0"
  shows "from_digits n d mod base = d 0 "
proof -
  have "(i<n. d i * base ^ i) mod base =
          (i<n. d i * base ^ i mod base) mod base"  
  by (subst mod_sum_eq[symmetric]) simp
  then show ?thesis using assms 
      sum.lessThan_Suc_shift[of "(λi. d i * base ^ i mod base)" "n-1"]
    unfolding from_digits_altdef by simp
qed

lemma mod_base_i:  
  assumes "i. i<n ==> d i < base" "n>0" "i<n"
  shows "(j=i..<n. d j * base ^ (j-i)) mod base = d i "
proof -
  have "(j=i..<n. d j * base ^ (j-i)) mod base =
        (j=i..<n. d j * base ^ (j-i) mod base) mod base"  
    by (subst mod_sum_eq[symmetric]) simp
  then show ?thesis 
    using assms split_sum_first_elt_less[where 
        f = "(λj. d j * base ^ (j-i) mod base)"
    unfolding from_digits_altdef by simp
qed

lemma div_base_i: 
  assumes "i. i<n ==> d i < base" "n>0" "i<n"
  shows "from_digits n d div (base ^i) = (j=i..<n. d j * base ^ (j-i))"
  unfolding from_digits_altdef proof -
  have base_exp: "base^(j) = base^(j-i) * base^i" 
    if "j{i..<n}" for j 
    by (metis Nat.add_diff_assoc2 add_diff_cancel_right' atLeastLessThan_iff 
        power_add that)
  have first:"(j<i. d j * base ^ j)< base ^ i" 
    using assms from_digits_less[where n="i"
    unfolding from_digits_altdef by auto
  have "(j<n. d j * base ^ j) =
          (j<i. d j * base ^ j) + (j=i..<n. d j * base ^ j)" 
    using assms split_sum_mid_less[where f="(λj. d j * base^j)"by auto
  then have split_sum: "(j<n. d j * base ^ j) =
      (j<i. d j * base ^ j) + base^i * (j=i..<n. d j * base ^ (j-i))"
    using base_exp mult.assoc sum_distrib_right 
    by (smt (z3) mult.commute sum.cong)
  then show "(i<n. d i * base ^ i) div base ^ i =
              (j = i..<n. d j * base ^ (j - i))" 
    using first by (simp add:split_sum base_pos)
qed



text Conversions are inverse to each other.
lemma digit_from_digits:
  assumes "j. j<n ==> d j < base" "n>0" "i<n"
  shows   "digit (from_digits n d) i = d i"
  using assms proof (cases "i=0")
  case True
  then show ?thesis 
    by (simp add: assms(1) assms(2) digits.mod_base digits_axioms)
next
  case False
  have "from_digits n d div base^i mod base = d i" 
    using assms by (auto simp add: div_base_i mod_base_i) 
  then show "digit (from_digits n d) i = d i" 
    unfolding digit_altdef by auto
qed

lemma div_distrib: assumes "i<n" 
  shows "(a*base^n + b) div base^i mod base = b div base^i mod base"
proof -
  have "base^i dvd (a*base^n)" using assms 
    by (simp add: le_imp_power_dvd)
  moreover have "a*base^n div base^i mod base = 0" 
    by (metis Suc_leI assms dvd_imp_mod_0 dvd_mult 
        dvd_mult_imp_div le_imp_power_dvd power_Suc)
  ultimately show ?thesis
    by (metis add.right_neutral div_mult_mod_eq 
        div_plus_div_distrib_dvd_left mod_mult_self3)
qed

lemma from_digits_digit:
  assumes "x < base ^ n"
  shows   "from_digits n (digit x) = x"
  using assms unfolding digit_altdef from_digits_altdef 
proof (induction n arbitrary: x)
  case 0
  then show ?case by simp
next
  case (Suc n)
  define x_less where "x_less = x mod base^n"
  define x_n where "x_n = x div base^n"
  have "x_less < base^n" 
    using x_less_def base_pos mod_less_divisor by presburger
  then have IH_x_less:
    "(i<n. x_less div base ^ i mod base * base ^ i) = x_less" 
    using Suc.IH by simp
  have "x_n < base" using x<base^Suc n
    by auto (metis less_mult_imp_div_less x_n_def)
  then have "x_n mod base = x_n" by simp
  have x_less_i_eq_x_i:"x mod base^n div base ^i mod base =
    x div base^i mod base" if "i<n" for i
  proof -
    have "x div base^i mod base =
          ((x div base^n) * base^n + x mod base^n) div base^i mod base"
      using div_mult_mod_eq[of x "base^n"by simp
    also have " = x mod base^n div base^i mod base" 
      using div_distrib[where a="x div base^n" and b = "x mod base^n"]
        that by auto
    finally show ?thesis by simp
  qed
  have "x = (x_n mod base)*base^n + x_less" 
    unfolding x_n mod base=x_n
    using x_n_def x_less_def div_mod_decomp by blast 
  also have " = (x div base^n mod base) * base^n +
                (i<n. x div base ^ i mod base * base ^ i)"
    using IH_x_less x_less_def x_less_i_eq_x_i x_n_def by auto
  finally show ?case using sum.atMost_Suc 
    by (simp add: add.commute)
qed

text Stronger formulation of above lemma.
lemma from_digits_digit': 
  "from_digits n (digit x) = x mod (base ^ n)"
  unfolding from_digits_altdef digit_altdef 
proof (induction n arbitrary: x)
  case 0
  then show ?case by simp
next
  case (Suc n)
  define x_less where "x_less = x mod base^n"
  define x_n where "x_n = x div base^n mod base"
  have "x_less < base^n" using x_less_def base_pos 
      mod_less_divisor by presburger
  then have IH_x_less:
    "(i<n. x_less div base ^ i mod base * base ^ i) = x_less" 
    using Suc.IH by simp
  have "x_n < base" using base_pos mod_less_divisor x_n_def 
    by blast
  then have "x_n mod base = x_n" by simp
  have x_less_i_eq_x_i:"x mod base^n div base ^i mod base =
    x div base^i mod base" if "i<n" for i
  proof -
    have "x div base^i mod base =
      ((x div base^n) * base^n + x mod base^n) div base^i mod base"
      using div_mult_mod_eq[of x "base^n"by simp
    also have " = x mod base^n div base^i mod base" 
      using div_distrib[where a="x div base^n" and b = "x mod base^n"
        that by auto
    finally show ?thesis by simp
  qed
  have "x mod base^Suc n = x_n*base^n + x_less" 
    by (metis mod_mult2_eq mult.commute power_Suc2 x_less_def x_n_def)
  also have " = (x div base^n mod base) * base^n +
                (i<n. x div base ^ i mod base * base ^ i)"
    using IH_x_less x_less_def x_less_i_eq_x_i x_n_def by auto
  finally show ?case using sum.atMost_Suc 
    by (simp add: add.commute)
qed

end
end

Messung V0.5 in Prozent
C=90 H=97 G=93

¤ Dauer der Verarbeitung: 0.5 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.