Skip to main content

Posts about Discrete Structures

Subcategories:

Pigeonhole principle

Prove the pigeonhole principle; that is, if \(S\) is a finite set and \(T\) and \(U\) are subsets of \(S\) such that the number of elements of \(S\) is less than the sum of the number of elements of \(T\) and \(U\), then the intersection of \(T\) and \(U\) is non-empty.

To do this, complete the following Lean4 theory:

import Mathlib.Data.Finset.Card

open Finset

variable [DecidableEq α]
variable {s t u : Finset α}

set_option pp.fieldNotation false

example
  (hts : t ⊆ s)
  (hus : u ⊆ s)
  (hstu : card s < card t + card u)
  : Finset.Nonempty (t ∩ u) :=
by sorry

Read more…

Proofs of ∑k<n. 2ᵏ = 2ⁿ-1

Prove that \[ 1 + 2 + 2^2 + 2^3 + ... + 2^{n-1} = 2^n - 1 \]

To do this, complete the following Lean4 theory:

import Mathlib.Tactic

open Finset Nat

variable (n : ℕ)

example :
  ∑ k in range n, 2^k = 2^n - 1 :=
by sorry

Read more…

Proofs of "∑i<n. i = n(n-1)/2"

Gauss's formula for the sum of the first natural numbers is \[ 0 + 1 + 2 + ... + (n-1) = \dfrac{n(n-1)}{2} \] that is, \[ \sum_{i < n} i = \dfrac{n(n-1)}{2} \]

In a previous exercise, this formula was proven by induction. Another way to prove it, without using induction, is the following: The sum can be written in two ways \begin{align} S &= &0 &+ &1 &+ &2 &+ ... &+ &(n-3) &+ &(n-2) &+ &(n-1) \newline S &= &(n-1) &+ &(n-2) &+ &(n-3) &+ ... &+ &2 &+ &1 &+ &0 \end{align} By adding, we observe that each pair of numbers in the same column sums to (n-1), and since there are n columns in total, it follows that \[ 2S = n(n-1) \] which proves the formula.

Prove Gauss's formula by following the above procedure.

To do this, complete the following Lean4 theory:

import Mathlib.Algebra.BigOperators.Intervals
import Mathlib.Tactic

open Finset Nat

variable (n i : ℕ)

example :
  ∑ i ∈ range n, i = n * (n - 1) / 2 :=
by sorry

Read more…

Proofs of "flatten (mirror a) = reverse (flatten a)"

The tree corresponding to

    3
   / \
  2   4
 / \
1   5

can be represented by the term

Node 3 (Node 2 (Leaf 1) (Leaf 5)) (Leaf 4)

using the datatype defined by

   inductive Tree' (α : Type) : Type
     | Leaf : α → Tree' α
     | Node : α → Tree' α → Tree' α → Tree' α

The mirror image of the previous tree is

  3
 / \
4   2
   / \
  5   1

and the list obtained by flattening it (traversing it in infix order) is

[4, 3, 5, 2, 1]

The definition of the function that calculates the mirror image is

   def mirror : Tree' α → Tree' α
     | Leaf x     => Leaf x
     | Node x l r => Node x (mirror r) (mirror l)

and the one that flattens the tree is

   def flatten : Tree' α → List α
     | Leaf x     => [x]
     | Node x l r => (flatten l) ++ [x] ++ (flatten r)

Prove that

   flatten (mirror a) = reverse (flatten a)

To do this, complete the following Lean4 theory:

import Mathlib.Tactic

open List

variable {α : Type}

set_option pp.fieldNotation false

inductive Tree' (α : Type) : Type
  | Leaf : α → Tree' α
  | Node : α → Tree' α → Tree' α → Tree' α

namespace Tree'

variable (a l r : Tree' α)
variable (x : α)

def mirror : Tree' α → Tree' α
  | Leaf x     => Leaf x
  | Node x l r => Node x (mirror r) (mirror l)

def flatten : Tree' α → List α
  | Leaf x     => [x]
  | Node x l r => (flatten l) ++ [x] ++ (flatten r)

example :
  flatten (mirror a) = reverse (flatten a) :=
by sorry

Read more…

Proofs that the mirror function of binary trees is involutive

The tree corresponding to

    3
   / \
  2   4
 / \
1   5

can be represented by the term

Node 3 (Node 2 (Leaf 1) (Leaf 5)) (Leaf 4)

using the datatype defined by

   inductive Tree' (α : Type) : Type
     | Leaf : α → Tree' α
     | Node : α → Tree' α → Tree' α → Tree' α

The mirror image of the previous tree is

  3
 / \
4   2
   / \
  5   1

whose term is

Node 3 (Leaf 4) (Node 2 (Leaf 5) (Leaf 1))

The definition of the function that calculates the mirror image is

   def mirror : Tree' α → Tree' α
     | (Leaf x)     => Leaf x
     | (Node x l r) => Node x (mirror r) (mirror l)

Prove that the mirror function is involutive; that is,

   mirror (mirror a) = a

To do this, complete the following Lean4 theory:

import Mathlib.Tactic

variable {α : Type}

set_option pp.fieldNotation false

inductive Tree' (α : Type) : Type
  | Leaf : α → Tree' α
  | Node : α → Tree' α → Tree' α → Tree' α

namespace Tree'

variable (a l r : Tree' α)
variable (x : α)

def mirror : Tree' α → Tree' α
  | (Leaf x)     => Leaf x
  | (Node x l r) => Node x (mirror r) (mirror l)

example :
  mirror (mirror a) = a :=
by sorry

end Tree'

Read more…

Equivalence of reverse definitions

In Lean4, the function

    reverse : List α → List α

is defined such that (reverse xs) is the list obtained by reversing the order of elements in xs, such that the first element becomes the last, the second element becomes the second to last, and so on, resulting in a new list with the same elements but in the opposite sequence. For example,

reverse  [3,2,5,1] = [1,5,2,3]

Its definition is

    def reverseAux : List α → List α → List α
      | [],    ys => ys
      | x::xs, ys => reverseAux xs (x::ys)

    def reverse (xs : List α) : List α :=
      reverseAux xs []

The following lemmas characterize its behavior:

    reverseAux_nil : reverseAux [] ys = ys
    reverseAux_cons : reverseAux (x::xs) ys = reverseAux xs (x::ys)

An alternative definition is

    def reverse2 : List α → List α
      | []        => []
      | (x :: xs) => reverse2 xs ++ [x]

Prove that the two definitions are equivalent; that is,

    reverse xs = reverse2 xs

To do this, complete the following Lean4 theory:

import Mathlib.Data.List.Basic
open List

variable {α : Type}
variable (xs : List α)

example : reverse xs = reverse2 xs :=
by sorry

Read more…

Proofs of take n xs ++ drop n xs = xs

In Lean4, the functions

    take : Nat → List α → Nat
    drop : Nat → List α → Nat
    (++) : List α → List α → List α

are defined such that

  • (take n xs) is the list consisting of the first n elements of xs. For example,

    take 2 [3,5,1,9,7] = [3,5]
    
  • (drop n xs) is the list containing all elements of xs except the first n elements. For example,

    drop 2 [3,5,1,9,7] = [1,9,7]
    
  • (xs ++ ys) is the list obtained by concatenating xs and ys. For example,

    [3,5] ++ [1,9,7] = [3,5,1,9,7]
    

These functions are characterized by the following lemmas:

take_zero      : take 0 xs = []
take_nil       : take n [] = []
take_cons      : take (succ n) (x :: xs) = x :: take n xs
drop_zero      : drop 0 xs = xs
drop_nil       : drop n [] = []
drop_succ_cons : drop (n + 1) (x :: xs) = drop n xs
nil_append     : [] ++ ys = ys
cons_append    : (x :: xs) ++ y = x :: (xs ++ ys)

Prove that

take n xs ++ drop n xs = xs

To do this, complete the following Lean4 theory:

import Mathlib.Data.List.Basic
import Mathlib.Tactic
open List Nat

variable {α : Type}
variable (n : ℕ)
variable (x : α)
variable (xs : List α)

example : take n xs ++ drop n xs = xs :=
by sorry

Read more…

Proofs of the equality length(xs ++ ys) = length(xs) + length(ys)

In Lean, the functions

    length : List α → Nat
    (++)   : List α → List α → List α

are defined such that

  • (length xs) is the length of xs. For example,

    length [2,3,5,3] = 4
    
  • (xs ++ ys) is the list obtained by concatenating xs and ys. For example.

    [1,2] ++ [2,3,5,3] = [1,2,2,3,5,3]
    

These functions are characterized by the following lemmas:

length_nil  : length [] = 0
length_cons : length (x :: xs) = length xs + 1
nil_append  : [] ++ ys = ys
cons_append : (x :: xs) ++ y = x :: (xs ++ ys)

To prove that

length (xs ++ ys) = length xs + length ys

To that end, complete the following Lean4 theory

import Mathlib.Tactic
open List

variable {α : Type}
variable (xs ys : List α)

example :
  length (xs ++ ys) = length xs + length ys :=
by sorry

Read more…