{-# OPTIONS --cubical-compatible #-}
module Padova2025.ProvingBasics.Termination.Ordering where
The standard ordering on the natural numbers#
open import Padova2025.ProgrammingBasics.Naturals.Base
open import Padova2025.ProgrammingBasics.Naturals.Arithmetic
open import Padova2025.ProgrammingBasics.Lists
open import Padova2025.ProvingBasics.Negation
open import Padova2025.ProvingBasics.Connectives.Disjunction
open import Padova2025.ProvingBasics.Connectives.More
open import Padova2025.ProvingBasics.Equality.Base
open import Padova2025.ProvingBasics.Equality.General
open import Padova2025.ProvingBasics.Equality.NaturalNumbers
In this module, we introduce the standard ordering _≤_ on the
natural numbers, together with its variants _<_, _≥_ and _>_,
and verify their basic properties.
infix 4 _≤_ _<_ _≥_ _>_
data _≤_ : ℕ → ℕ → Set where
z≤n : {n : ℕ} → zero ≤ n
s≤s : {n m : ℕ} → (n≤m : n ≤ m) → succ n ≤ succ m
_<_ : ℕ → ℕ → Set
n < m = succ n ≤ m
_>_ : ℕ → ℕ → Set
n > m = m < n
_≥_ : ℕ → ℕ → Set
n ≥ m = m ≤ n
Exercise: Reflexivity, transitivity and antisymmetry#
≤-refl≤-refl : {a : ℕ} → a ≤ a
≤-refl = {!!}
≤-trans≤-trans : {a b c : ℕ} → a ≤ b → b ≤ c → a ≤ c
≤-trans = {!!}
≤-antisymm≤-antisymm : {a b : ℕ} → a ≤ b → b ≤ a → a ≡ b
≤-antisymm = {!!}
<-irreflexive<-irreflexive : {a : ℕ} → a < a → ⊥
<-irreflexive = {!!}
<-irreflexive'<-irreflexive' : {a b : ℕ} → a ≤ b → b < a → ⊥
<-irreflexive' = {!!}
<-irreflexive''<-irreflexive'' : {a b : ℕ} → a < b → b < a → ⊥
<-irreflexive'' = {!!}
≡⇒≤≡⇒≤ : {a b : ℕ} → a ≡ b → a ≤ b
≡⇒≤ = {!!}
Exercise: Decision procedures#
≤-<-connex≤-<-connex : (a b : ℕ) → a ≤ b ⊎ b < a
≤-<-connex = {!!}
Perhaps surprisingly, this exercise and the next exercise can both be
solved on autopilot. Judiciously use C-c C-c, C-c C-a and the
with keyword to pattern match on the result of a suitable recursive
call.
<-cmp<-cmp : (a b : ℕ) → a ≡ b ⊎ (a < b ⊎ a > b)
<-cmp = {!!}
Reference solution
<-cmp : (a b : ℕ) → a ≡ b ⊎ (a < b ⊎ a > b)
<-cmp zero zero = left refl
<-cmp zero (succ b) = right (left (s≤s z≤n))
<-cmp (succ a) zero = right (right (s≤s z≤n))
<-cmp (succ a) (succ b) with <-cmp a b
... | left a≡b = left (cong succ a≡b)
... | right (left a<b) = right (left (s≤s a<b))
... | right (right a>b) = right (right (s≤s a>b))
dec-≤dec-≤ : (a b : ℕ) → Dec (a ≤ b)
dec-≤ = {!!}
dec-<dec-< : (a b : ℕ) → Dec (a < b)
dec-< = {!!}
Exercise: Ordering properties of several functions#
succ-monotone : {a b : ℕ} → a ≤ b → succ a ≤ succ b
succ-monotone = s≤s
pred-monotonepred-monotone : {a b : ℕ} → a ≤ b → pred a ≤ pred b
pred-monotone = {!!}
succ-inflationarysucc-inflationary : (a : ℕ) → a ≤ succ a
succ-inflationary = {!!}
twice-inflationarytwice-inflationary : (a : ℕ) → a ≤ twice a
twice-inflationary = {!!}
Reference solution
twice-inflationary : (a : ℕ) → a ≤ twice a
twice-inflationary zero = z≤n
twice-inflationary (succ a) = ≤-trans (succ-inflationary (succ a)) (succ-monotone (succ-monotone (twice-inflationary a)))
max-inflationaryₗmax-inflationaryₗ : (a b : ℕ) → a ≤ max a b
max-inflationaryₗ = {!!}
max-inflationaryᵣmax-inflationaryᵣ : (a b : ℕ) → b ≤ max a b
max-inflationaryᵣ = {!!}
+-monotone+-monotone : {a a' b b' : ℕ} → a ≤ b → a' ≤ b' → a + a' ≤ b + b'
+-monotone = {!!}
+-inflationaryₗ+-inflationaryₗ : (a b : ℕ) → a ≤ a + b
+-inflationaryₗ = {!!}
+-inflationaryᵣ+-inflationaryᵣ : (a b : ℕ) → b ≤ a + b
+-inflationaryᵣ = {!!}
Exercise: Maximum of a list#
maximum : List ℕ → ℕ
maximum [] = zero
maximum (x ∷ xs) = max x (maximum xs)
maximum-≥ : (k : ℕ) (xs : List ℕ) → k ∈ xs → k ≤ maximum xs
maximum-≥ k (x ∷ xs) (here refl) = max-inflationaryₗ x (maximum xs)
maximum-≥ k (x ∷ xs) (there p) = ≤-trans (maximum-≥ k xs p) (max-inflationaryᵣ x (maximum xs))
Exercise: Halving#
half-≤half-≤ : (x : ℕ) → half x ≤ x
half-≤ = {!!}
half-<half-< : (x : ℕ) → half (succ x) < succ x
half-< = {!!}
Exercise: Subtraction decreases#
open import Padova2025.ProvingBasics.EvenOdd
monus-≤monus-≤ : (a b : ℕ) → a ≥ b → a ∸ b ≤ a
monus-≤ = {!!}
monus-<monus-< : (a b : ℕ) → IsPositive b → a ≥ b → a ∸ b < a
monus-< = {!!}
Infinitude of the even numbers#
open import Padova2025.ProvingBasics.Connectives.Existential
open import Padova2025.ProvingBasics.Connectives.Conjunction
open import Padova2025.ProvingBasics.EvenOdd
open import Padova2025.ProvingBasics.Equality.NaturalNumbers
A particularly positive way of expressing that there are infinitely many even numbers is as follows: Beyond every natural number, there is an even natural number. Let us state and prove this fact in Agda.
Even-infiniteEven-infinite : (x : ℕ) → ∃[ y ] (y ≥ x × Even y)
Even-infinite = {!!}
Reference solution
Even-infinite : (x : ℕ) → ∃[ y ] (y ≥ x × Even y)
Even-infinite x = twice x , twice-inflationary x , twice-even x
-- Alternatively, more economically, providing `x` or `succ x` instead
-- of `twice x` as witness:
-- Even-infinite x with even-or-odd x
-- ... | left xeven = x , ≤-refl , xeven
-- ... | right xodd = succ x , succ-inflationary x , succ-odd xodd
Infinitude of the natural numbers#
open import Padova2025.ProvingBasics.Connectives.Existential
One among several ways to express that there are infinitely many natural numbers is as follows: For every finite list of natural numbers, there is a natural number not in that list. We can formalize and prove this assertion as follows.
ℕ-infiniteℕ-infinite : (xs : List ℕ) → ∃[ x ] x ∉ xs
ℕ-infinite xs = succ (sum xs) , λ p → <-irreflexive (go p)
where
go : {xs : List ℕ} {y : ℕ} → y ∈ xs → y < succ (sum xs)
go (here refl) = {!!}
go (there p) = {!!}
Reference solution
ℕ-infinite : (xs : List ℕ) → ∃[ x ] x ∉ xs
ℕ-infinite xs = succ (sum xs) , λ p → <-irreflexive (go p)
where
go : {xs : List ℕ} {y : ℕ} → y ∈ xs → y < succ (sum xs)
go (here refl) = succ-monotone (≤-trans (≡⇒≤ (sym (+-zero _))) (+-monotone ≤-refl z≤n))
go (there p) = ≤-trans (go p) (succ-monotone (+-monotone z≤n ≤-refl))
Exercise: An alternative definition of the strict ordering relation#
Occasionally the following alternative definition of the strict less-than relation is useful.
data _<'_ : ℕ → ℕ → Set where
base' : {n : ℕ} → n <' succ n
step' : {a b : ℕ} → a <' b → a <' succ b
z<'sz<'s : {x : ℕ} → zero <' succ x
z<'s = {!!}
s<'ss<'s : {x y : ℕ} → x <' y → succ x <' succ y
s<'s = {!!}
<⇒<'<⇒<' : {x y : ℕ} → x < y → x <' y
<⇒<' = {!!}
<'⇒<<'⇒< : {x y : ℕ} → x <' y → x < y
<'⇒< = {!!}
Exercise: Indexing#
lookuplookup : {P : ℕ → Set} {n m : ℕ} → All P (downFrom n) → m < n → P m
lookup = {!!}