diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2018-11-23 17:29:46 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2018-11-23 17:29:46 -0700 |
commit | 5a91775bd7c909bbaf3b3c8ee964136961a5146d (patch) | |
tree | cea89f085c1382f1567ff71a30b6f953708dc6a9 /src/Data/Nat | |
parent | 5d2b156377dce5bdca65b14639306eaed3ac3a92 (diff) | |
parent | a19b25a865b2000bbd3acd909f5951a5407c1eec (diff) |
Merge tag 'upstream/0.17'
Upstream version 0.17
# gpg: Signature made Fri 23 Nov 2018 05:29:18 PM MST
# gpg: using RSA key 9B917007AE030E36E4FC248B695B7AE4BF066240
# gpg: issuer "spwhitton@spwhitton.name"
# gpg: Good signature from "Sean Whitton <spwhitton@spwhitton.name>" [ultimate]
# Primary key fingerprint: 8DC2 487E 51AB DD90 B5C4 753F 0F56 D055 3B6D 411B
# Subkey fingerprint: 9B91 7007 AE03 0E36 E4FC 248B 695B 7AE4 BF06 6240
Diffstat (limited to 'src/Data/Nat')
-rw-r--r-- | src/Data/Nat/Base.agda | 144 | ||||
-rw-r--r-- | src/Data/Nat/Coprimality.agda | 53 | ||||
-rw-r--r-- | src/Data/Nat/DivMod.agda | 203 | ||||
-rw-r--r-- | src/Data/Nat/DivMod/Core.agda | 102 | ||||
-rw-r--r-- | src/Data/Nat/DivMod/Unsafe.agda | 45 | ||||
-rw-r--r-- | src/Data/Nat/Divisibility.agda | 207 | ||||
-rw-r--r-- | src/Data/Nat/GCD.agda | 42 | ||||
-rw-r--r-- | src/Data/Nat/GCD/Lemmas.agda | 76 | ||||
-rw-r--r-- | src/Data/Nat/InfinitelyOften.agda | 41 | ||||
-rw-r--r-- | src/Data/Nat/LCM.agda | 11 | ||||
-rw-r--r-- | src/Data/Nat/Literals.agda | 17 | ||||
-rw-r--r-- | src/Data/Nat/Primality.agda | 22 | ||||
-rw-r--r-- | src/Data/Nat/Properties.agda | 763 | ||||
-rw-r--r-- | src/Data/Nat/Solver.agda | 21 | ||||
-rw-r--r-- | src/Data/Nat/Unsafe.agda | 13 |
15 files changed, 1246 insertions, 514 deletions
diff --git a/src/Data/Nat/Base.agda b/src/Data/Nat/Base.agda index 52367e1..2136fcf 100644 --- a/src/Data/Nat/Base.agda +++ b/src/Data/Nat/Base.agda @@ -6,92 +6,56 @@ module Data.Nat.Base where -import Level using (zero) -open import Function using (_∘_) +open import Level using (0ℓ) +open import Function using (_∘_; flip) open import Relation.Binary open import Relation.Binary.Core open import Relation.Binary.PropositionalEquality.Core -import Relation.Binary.PropositionalEquality.TrustMe as TrustMe -open import Relation.Nullary using (¬_; Dec; yes; no) - -infix 4 _≤_ _<_ _≥_ _>_ _≰_ _≮_ _≱_ _≯_ +open import Relation.Binary.PropositionalEquality +open import Relation.Nullary using (¬_) ------------------------------------------------------------------------ -- The types open import Agda.Builtin.Nat public - using ( zero; suc; _+_; _*_ ) - renaming ( Nat to ℕ - ; _-_ to _∸_ ) + using (zero; suc) renaming (Nat to ℕ) -data _≤_ : Rel ℕ Level.zero where +------------------------------------------------------------------------ +-- Standard ordering relations + +infix 4 _≤_ _<_ _≥_ _>_ _≰_ _≮_ _≱_ _≯_ + +data _≤_ : Rel ℕ 0ℓ where z≤n : ∀ {n} → zero ≤ n s≤s : ∀ {m n} (m≤n : m ≤ n) → suc m ≤ suc n -_<_ : Rel ℕ Level.zero +_<_ : Rel ℕ 0ℓ m < n = suc m ≤ n -_≥_ : Rel ℕ Level.zero +_≥_ : Rel ℕ 0ℓ m ≥ n = n ≤ m -_>_ : Rel ℕ Level.zero +_>_ : Rel ℕ 0ℓ m > n = n < m -_≰_ : Rel ℕ Level.zero +_≰_ : Rel ℕ 0ℓ a ≰ b = ¬ a ≤ b -_≮_ : Rel ℕ Level.zero +_≮_ : Rel ℕ 0ℓ a ≮ b = ¬ a < b -_≱_ : Rel ℕ Level.zero +_≱_ : Rel ℕ 0ℓ a ≱ b = ¬ a ≥ b -_≯_ : Rel ℕ Level.zero +_≯_ : Rel ℕ 0ℓ a ≯ b = ¬ a > b --- The following, alternative definition of _≤_ is more suitable for --- well-founded induction (see Induction.Nat). - -infix 4 _≤′_ _<′_ _≥′_ _>′_ - -data _≤′_ (m : ℕ) : ℕ → Set where - ≤′-refl : m ≤′ m - ≤′-step : ∀ {n} (m≤′n : m ≤′ n) → m ≤′ suc n - -_<′_ : Rel ℕ Level.zero -m <′ n = suc m ≤′ n - -_≥′_ : Rel ℕ Level.zero -m ≥′ n = n ≤′ m - -_>′_ : Rel ℕ Level.zero -m >′ n = n <′ m - --- Another alternative definition of _≤_. - -record _≤″_ (m n : ℕ) : Set where - constructor less-than-or-equal - field - {k} : ℕ - proof : m + k ≡ n - -infix 4 _≤″_ _<″_ _≥″_ _>″_ - -_<″_ : Rel ℕ Level.zero -m <″ n = suc m ≤″ n - -_≥″_ : Rel ℕ Level.zero -m ≥″ n = n ≤″ m - -_>″_ : Rel ℕ Level.zero -m >″ n = n <″ m - -erase : ∀ {m n} → m ≤″ n → m ≤″ n -erase (less-than-or-equal eq) = less-than-or-equal (TrustMe.erase eq) - ------------------------------------------------------------------------ -- Arithmetic +open import Agda.Builtin.Nat public + using (_+_; _*_ ) renaming (_-_ to _∸_) + pred : ℕ → ℕ pred zero = zero pred (suc n) = n @@ -137,33 +101,57 @@ _^_ : ℕ → ℕ → ℕ x ^ zero = 1 x ^ suc n = x * x ^ n +-- Distance + +∣_-_∣ : ℕ → ℕ → ℕ +∣ zero - y ∣ = y +∣ x - zero ∣ = x +∣ suc x - suc y ∣ = ∣ x - y ∣ + ------------------------------------------------------------------------ --- Queries +-- The following, alternative definition of _≤_ is more suitable for +-- well-founded induction (see Induction.Nat). -infix 4 _≟_ _≤?_ +infix 4 _≤′_ _<′_ _≥′_ _>′_ -_≟_ : Decidable {A = ℕ} _≡_ -zero ≟ zero = yes refl -suc m ≟ suc n with m ≟ n -suc m ≟ suc .m | yes refl = yes refl -suc m ≟ suc n | no prf = no (prf ∘ (λ p → subst (λ x → m ≡ pred x) p refl)) -zero ≟ suc n = no λ() -suc m ≟ zero = no λ() +data _≤′_ (m : ℕ) : ℕ → Set where + ≤′-refl : m ≤′ m + ≤′-step : ∀ {n} (m≤′n : m ≤′ n) → m ≤′ suc n -≤-pred : ∀ {m n} → suc m ≤ suc n → m ≤ n -≤-pred (s≤s m≤n) = m≤n +_<′_ : Rel ℕ 0ℓ +m <′ n = suc m ≤′ n -_≤?_ : Decidable _≤_ -zero ≤? _ = yes z≤n -suc m ≤? zero = no λ() -suc m ≤? suc n with m ≤? n -... | yes m≤n = yes (s≤s m≤n) -... | no m≰n = no (m≰n ∘ ≤-pred) +_≥′_ : Rel ℕ 0ℓ +m ≥′ n = n ≤′ m + +_>′_ : Rel ℕ 0ℓ +m >′ n = n <′ m +------------------------------------------------------------------------ +-- Another alternative definition of _≤_. + +record _≤″_ (m n : ℕ) : Set where + constructor less-than-or-equal + field + {k} : ℕ + proof : m + k ≡ n + +infix 4 _≤″_ _<″_ _≥″_ _>″_ + +_<″_ : Rel ℕ 0ℓ +m <″ n = suc m ≤″ n + +_≥″_ : Rel ℕ 0ℓ +m ≥″ n = n ≤″ m + +_>″_ : Rel ℕ 0ℓ +m >″ n = n <″ m + +------------------------------------------------------------------------ -- A comparison view. Taken from "View from the left" -- (McBride/McKinna); details may differ. -data Ordering : Rel ℕ Level.zero where +data Ordering : Rel ℕ 0ℓ where less : ∀ m k → Ordering m (suc (m + k)) equal : ∀ m → Ordering m m greater : ∀ m k → Ordering (suc (m + k)) m @@ -173,6 +161,6 @@ compare zero zero = equal zero compare (suc m) zero = greater zero m compare zero (suc n) = less zero n compare (suc m) (suc n) with compare m n -compare (suc .m) (suc .(suc m + k)) | less m k = less (suc m) k -compare (suc .m) (suc .m) | equal m = equal (suc m) -compare (suc .(suc m + k)) (suc .m) | greater m k = greater (suc m) k +... | less m k = less (suc m) k +... | equal m = equal (suc m) +... | greater n k = greater (suc n) k diff --git a/src/Data/Nat/Coprimality.agda b/src/Data/Nat/Coprimality.agda index 85ed06c..19fdbf5 100644 --- a/src/Data/Nat/Coprimality.agda +++ b/src/Data/Nat/Coprimality.agda @@ -8,27 +8,25 @@ module Data.Nat.Coprimality where open import Data.Empty open import Data.Fin using (toℕ; fromℕ≤) -open import Data.Fin.Properties as FinProp +open import Data.Fin.Properties using (toℕ-fromℕ≤) open import Data.Nat -open import Data.Nat.Primality -import Data.Nat.Properties as NatProp -open import Data.Nat.Divisibility as Div +open import Data.Nat.Divisibility open import Data.Nat.GCD open import Data.Nat.GCD.Lemmas +open import Data.Nat.Primality +open import Data.Nat.Properties open import Data.Product as Prod open import Function -open import Relation.Binary.PropositionalEquality as PropEq - using (_≡_; _≢_; refl) +open import Level using (0ℓ) +open import Relation.Binary.PropositionalEquality as P + using (_≡_; _≢_; refl; cong; subst; module ≡-Reasoning) open import Relation.Nullary open import Relation.Binary -open import Algebra -private - module P = Poset Div.poset -- Coprime m n is inhabited iff m and n are coprime (relatively -- prime), i.e. if their only common divisor is 1. -Coprime : (m n : ℕ) → Set +Coprime : Rel ℕ 0ℓ Coprime m n = ∀ {i} → i ∣ m × i ∣ n → i ≡ 1 -- Coprime numbers have 1 as their gcd. @@ -37,15 +35,14 @@ coprime-gcd : ∀ {m n} → Coprime m n → GCD m n 1 coprime-gcd {m} {n} c = GCD.is (1∣ m , 1∣ n) greatest where greatest : ∀ {d} → d ∣ m × d ∣ n → d ∣ 1 - greatest cd with c cd - greatest .{1} cd | refl = 1∣ 1 + greatest cd with c cd + ... | refl = 1∣ 1 -- If two numbers have 1 as their gcd, then they are coprime. gcd-coprime : ∀ {m n} → GCD m n 1 → Coprime m n gcd-coprime g cd with GCD.greatest g cd -gcd-coprime g cd | divides q eq = - NatProp.i*j≡1⇒j≡1 q _ (PropEq.sym eq) +... | divides q eq = i*j≡1⇒j≡1 q _ (P.sym eq) -- Coprime is decidable. @@ -59,12 +56,12 @@ private coprime? : Decidable Coprime coprime? i j with gcd i j ... | (0 , g) = no (0≢1 ∘ GCD.unique g ∘ coprime-gcd) -... | (1 , g) = yes (λ {i} → gcd-coprime g {i}) +... | (1 , g) = yes (gcd-coprime g) ... | (suc (suc d) , g) = no (2+≢1 ∘ GCD.unique g ∘ coprime-gcd) -- The coprimality relation is symmetric. -sym : ∀ {m n} → Coprime m n → Coprime n m +sym : Symmetric Coprime sym c = c ∘ swap -- Everything is coprime to 1. @@ -75,12 +72,12 @@ sym c = c ∘ swap -- Nothing except for 1 is coprime to 0. 0-coprimeTo-1 : ∀ {m} → Coprime 0 m → m ≡ 1 -0-coprimeTo-1 {m} c = c (m ∣0 , P.refl) +0-coprimeTo-1 {m} c = c (m ∣0 , ∣-refl) -- If m and n are coprime, then n + m and n are also coprime. coprime-+ : ∀ {m n} → Coprime m n → Coprime (n + m) n -coprime-+ c (d₁ , d₂) = c (∣-∸ d₁ d₂ , d₂) +coprime-+ c (d₁ , d₂) = c (∣m+n∣m⇒∣n d₁ d₂ , d₂) -- If the "gcd" in Bézout's identity is non-zero, then the "other" -- divisors are coprime. @@ -125,14 +122,13 @@ data GCD′ : ℕ → ℕ → ℕ → Set where gcd-gcd′ : ∀ {d m n} → GCD m n d → GCD′ m n d gcd-gcd′ g with GCD.commonDivisor g gcd-gcd′ {zero} g | (divides q₁ refl , divides q₂ refl) - with q₁ * 0 | NatProp.*-comm 0 q₁ - | q₂ * 0 | NatProp.*-comm 0 q₂ -... | .0 | refl | .0 | refl = gcd-* 1 1 (1-coprimeTo 1) + with q₁ * 0 | *-comm 0 q₁ | q₂ * 0 | *-comm 0 q₂ +... | .0 | refl | .0 | refl = gcd-* 1 1 (1-coprimeTo 1) gcd-gcd′ {suc d} g | (divides q₁ refl , divides q₂ refl) = gcd-* q₁ q₂ (Bézout-coprime (Bézout.identity g)) gcd′-gcd : ∀ {m n d} → GCD′ m n d → GCD m n d -gcd′-gcd (gcd-* q₁ q₂ c) = GCD.is (∣-* q₁ , ∣-* q₂) (coprime-factors c) +gcd′-gcd (gcd-* q₁ q₂ c) = GCD.is (n∣m*n q₁ , n∣m*n q₂) (coprime-factors c) -- Calculates (the alternative representation of) the gcd of the -- arguments. @@ -149,11 +145,11 @@ prime⇒coprime 1 () _ _ _ _ prime⇒coprime (suc (suc m)) _ 0 () _ _ prime⇒coprime (suc (suc m)) _ _ _ _ {1} _ = refl prime⇒coprime (suc (suc m)) p _ _ _ {0} (divides q 2+m≡q*0 , _) = - ⊥-elim $ NatProp.i+1+j≢i 0 (begin + ⊥-elim $ i+1+j≢i 0 (begin 2 + m ≡⟨ 2+m≡q*0 ⟩ - q * 0 ≡⟨ proj₂ NatProp.*-zero q ⟩ + q * 0 ≡⟨ *-zeroʳ q ⟩ 0 ∎) - where open PropEq.≡-Reasoning + where open ≡-Reasoning prime⇒coprime (suc (suc m)) p (suc n) _ 1+n<2+m {suc (suc i)} (2+i∣2+m , 2+i∣1+n) = ⊥-elim (p _ 2+i′∣2+m) @@ -163,10 +159,9 @@ prime⇒coprime (suc (suc m)) p (suc n) _ 1+n<2+m {suc (suc i)} 3 + i ≤⟨ s≤s (∣⇒≤ 2+i∣1+n) ⟩ 2 + n ≤⟨ 1+n<2+m ⟩ 2 + m ∎) - where open NatProp.≤-Reasoning + where open ≤-Reasoning 2+i′∣2+m : 2 + toℕ (fromℕ≤ i<m) ∣ 2 + m - 2+i′∣2+m = PropEq.subst - (λ j → j ∣ 2 + m) - (PropEq.sym (PropEq.cong (_+_ 2) (FinProp.toℕ-fromℕ≤ i<m))) + 2+i′∣2+m = subst (_∣ 2 + m) + (P.sym (cong (2 +_) (toℕ-fromℕ≤ i<m))) 2+i∣2+m diff --git a/src/Data/Nat/DivMod.agda b/src/Data/Nat/DivMod.agda index a07726f..746e97e 100644 --- a/src/Data/Nat/DivMod.agda +++ b/src/Data/Nat/DivMod.agda @@ -6,143 +6,102 @@ module Data.Nat.DivMod where -open import Data.Fin as Fin using (Fin; toℕ) -import Data.Fin.Properties as FinP -open import Data.Nat as Nat -open import Data.Nat.Properties -open import Relation.Nullary.Decidable -open import Relation.Binary.PropositionalEquality as P using (_≡_) -import Relation.Binary.PropositionalEquality.TrustMe as TrustMe - using (erase) - -open import Agda.Builtin.Nat using ( div-helper; mod-helper ) +open import Agda.Builtin.Nat using (div-helper; mod-helper) -open SemiringSolver -open P.≡-Reasoning -open ≤-Reasoning - renaming (begin_ to start_; _∎ to _□; _≡⟨_⟩_ to _≡⟨_⟩′_) +open import Data.Fin using (Fin; toℕ; fromℕ≤) +open import Data.Fin.Properties using (toℕ-fromℕ≤) +open import Data.Nat as Nat +open import Data.Nat.DivMod.Core +open import Data.Nat.Properties using (≤⇒≤″; +-assoc; +-comm; +-identityʳ) +open import Function using (_$_) +open import Relation.Nullary.Decidable using (False) +open import Relation.Binary.PropositionalEquality -infixl 7 _div_ _mod_ _divMod_ +open ≡-Reasoning --- A specification of integer division. +------------------------------------------------------------------------ +-- Basic operations -record DivMod (dividend divisor : ℕ) : Set where - constructor result - field - quotient : ℕ - remainder : Fin divisor - property : dividend ≡ toℕ remainder + quotient * divisor +infixl 7 _div_ _%_ --- Integer division. +-- Integer division _div_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → ℕ -(d div 0) {} -(d div suc s) = div-helper 0 s d s - --- The remainder after integer division. +(a div 0) {} +(a div suc n) = div-helper 0 n a n -private - -- The remainder is not too large. +-- Integer remainder (mod) - mod-lemma : (acc d n : ℕ) → - let s = acc + n in - mod-helper acc s d n ≤ s +_%_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → ℕ +(a % 0) {} +(a % suc n) = mod-helper 0 n a n - mod-lemma acc zero n = start - acc ≤⟨ m≤m+n acc n ⟩ - acc + n □ +------------------------------------------------------------------------ +-- Properties + +a≡a%n+[a/n]*n : ∀ a n → a ≡ a % suc n + (a div (suc n)) * suc n +a≡a%n+[a/n]*n a n = division-lemma 0 0 a n + +a%1≡0 : ∀ a → a % 1 ≡ 0 +a%1≡0 = a[modₕ]1≡0 + +a%n<n : ∀ a n → a % suc n < suc n +a%n<n a n = s≤s (a[modₕ]n<n 0 a n) + +n%n≡0 : ∀ n → suc n % suc n ≡ 0 +n%n≡0 n = n[modₕ]n≡0 0 n + +a%n%n≡a%n : ∀ a n → a % suc n % suc n ≡ a % suc n +a%n%n≡a%n a n = modₕ-idem 0 a n + +[a+n]%n≡a%n : ∀ a n → (a + suc n) % suc n ≡ a % suc n +[a+n]%n≡a%n a n = a+n[modₕ]n≡a[modₕ]n 0 a n + +[a+kn]%n≡a%n : ∀ a k n → (a + k * (suc n)) % suc n ≡ a % suc n +[a+kn]%n≡a%n a zero n = cong (_% suc n) (+-identityʳ a) +[a+kn]%n≡a%n a (suc k) n = begin + (a + (m + k * m)) % m ≡⟨ cong (_% m) (sym (+-assoc a m (k * m))) ⟩ + (a + m + k * m) % m ≡⟨ [a+kn]%n≡a%n (a + m) k n ⟩ + (a + m) % m ≡⟨ [a+n]%n≡a%n a n ⟩ + a % m ∎ + where m = suc n + +kn%n≡0 : ∀ k n → k * (suc n) % suc n ≡ 0 +kn%n≡0 = [a+kn]%n≡a%n 0 + +%-distribˡ-+ : ∀ a b n → (a + b) % suc n ≡ (a % suc n + b % suc n) % suc n +%-distribˡ-+ a b n = begin + (a + b) % m ≡⟨ cong (λ v → (v + b) % m) (a≡a%n+[a/n]*n a n) ⟩ + (a % m + a div m * m + b) % m ≡⟨ cong (_% m) (+-assoc (a % m) _ b) ⟩ + (a % m + (a div m * m + b)) % m ≡⟨ cong (λ v → (a % m + v) % m) (+-comm _ b) ⟩ + (a % m + (b + a div m * m)) % m ≡⟨ cong (_% m) (sym (+-assoc (a % m) b _)) ⟩ + (a % m + b + a div m * m) % m ≡⟨ [a+kn]%n≡a%n (a % m + b) (a div m) n ⟩ + (a % m + b) % m ≡⟨ cong (λ v → (a % m + v) % m) (a≡a%n+[a/n]*n b n) ⟩ + (a % m + (b % m + (b div m) * m)) % m ≡⟨ sym (cong (_% m) (+-assoc (a % m) (b % m) _)) ⟩ + (a % m + b % m + (b div m) * m) % m ≡⟨ [a+kn]%n≡a%n (a % m + b % m) (b div m) n ⟩ + (a % m + b % m) % m ∎ + where m = suc n - mod-lemma acc (suc d) zero = start - mod-helper zero (acc + 0) d (acc + 0) ≤⟨ mod-lemma zero d (acc + 0) ⟩ - acc + 0 □ +------------------------------------------------------------------------ +-- A specification of integer division. - mod-lemma acc (suc d) (suc n) = - P.subst (λ x → mod-helper (suc acc) x d n ≤ x) - (P.sym (+-suc acc n)) - (mod-lemma (suc acc) d n) +record DivMod (dividend divisor : ℕ) : Set where + constructor result + field + quotient : ℕ + remainder : Fin divisor + property : dividend ≡ toℕ remainder + quotient * divisor _mod_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → Fin divisor -(d mod 0) {} -(d mod suc s) = - Fin.fromℕ≤″ (mod-helper 0 s d s) - (Nat.erase (≤⇒≤″ (s≤s (mod-lemma 0 d s)))) - --- Integer division with remainder. - -private - - -- The quotient and remainder are related to the dividend and - -- divisor in the right way. - - division-lemma : - (mod-acc div-acc d n : ℕ) → - let s = mod-acc + n in - mod-acc + div-acc * suc s + d - ≡ - mod-helper mod-acc s d n + div-helper div-acc s d n * suc s - - division-lemma mod-acc div-acc zero n = begin - - mod-acc + div-acc * suc s + zero ≡⟨ +-identityʳ _ ⟩ - - mod-acc + div-acc * suc s ∎ - - where s = mod-acc + n - - division-lemma mod-acc div-acc (suc d) zero = begin - - mod-acc + div-acc * suc s + suc d ≡⟨ solve 3 - (λ mod-acc div-acc d → - let s = mod-acc :+ con 0 in - mod-acc :+ div-acc :* (con 1 :+ s) :+ (con 1 :+ d) - := - (con 1 :+ div-acc) :* (con 1 :+ s) :+ d) - P.refl mod-acc div-acc d ⟩ - suc div-acc * suc s + d ≡⟨ division-lemma zero (suc div-acc) d s ⟩ - - mod-helper zero s d s + - div-helper (suc div-acc) s d s * suc s ≡⟨⟩ - - mod-helper mod-acc s (suc d) zero + - div-helper div-acc s (suc d) zero * suc s ∎ - - where s = mod-acc + 0 - - division-lemma mod-acc div-acc (suc d) (suc n) = begin - - mod-acc + div-acc * suc s + suc d ≡⟨ solve 4 - (λ mod-acc div-acc n d → - mod-acc :+ div-acc :* (con 1 :+ (mod-acc :+ (con 1 :+ n))) :+ (con 1 :+ d) - := - con 1 :+ mod-acc :+ div-acc :* (con 2 :+ mod-acc :+ n) :+ d) - P.refl mod-acc div-acc n d ⟩ - suc mod-acc + div-acc * suc s′ + d ≡⟨ division-lemma (suc mod-acc) div-acc d n ⟩ - - mod-helper (suc mod-acc) s′ d n + - div-helper div-acc s′ d n * suc s′ ≡⟨ P.cong (λ s → mod-helper (suc mod-acc) s d n + - div-helper div-acc s d n * suc s) - (P.sym (+-suc mod-acc n)) ⟩ - - mod-helper (suc mod-acc) s d n + - div-helper div-acc s d n * suc s ≡⟨⟩ - - mod-helper mod-acc s (suc d) (suc n) + - div-helper div-acc s (suc d) (suc n) * suc s ∎ - - where - s = mod-acc + suc n - s′ = suc mod-acc + n +(a mod 0) {} +(a mod suc n) = fromℕ≤ (a%n<n a n) _divMod_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → DivMod dividend divisor -(d divMod 0) {} -(d divMod suc s) = - result (d div suc s) (d mod suc s) (TrustMe.erase (begin - d ≡⟨ division-lemma 0 0 d s ⟩ - mod-helper 0 s d s + div-helper 0 s d s * suc s ≡⟨ P.cong₂ _+_ (P.sym (FinP.toℕ-fromℕ≤ lemma)) P.refl ⟩ - toℕ (Fin.fromℕ≤ lemma) + div-helper 0 s d s * suc s ≡⟨ P.cong (λ n → toℕ n + div-helper 0 s d s * suc s) - (FinP.fromℕ≤≡fromℕ≤″ lemma _) ⟩ - toℕ (Fin.fromℕ≤″ _ lemma′) + div-helper 0 s d s * suc s ∎)) +(a divMod 0) {} +(a divMod suc n) = result (a div suc n) (a mod suc n) $ begin + a ≡⟨ a≡a%n+[a/n]*n a n ⟩ + a % suc n + [a/n]*n ≡⟨ cong (_+ [a/n]*n) (sym (toℕ-fromℕ≤ (a%n<n a n))) ⟩ + toℕ (fromℕ≤ (a%n<n a n)) + [a/n]*n ∎ where - lemma = s≤s (mod-lemma 0 d s) - lemma′ = Nat.erase (≤⇒≤″ lemma) + [a/n]*n = a div suc n * suc n diff --git a/src/Data/Nat/DivMod/Core.agda b/src/Data/Nat/DivMod/Core.agda new file mode 100644 index 0000000..dfd6eb1 --- /dev/null +++ b/src/Data/Nat/DivMod/Core.agda @@ -0,0 +1,102 @@ +------------------------------------------------------------------------ +-- The Agda standard library +-- +-- Core lemmas for division and modulus operations +------------------------------------------------------------------------ + +module Data.Nat.DivMod.Core where + +open import Agda.Builtin.Nat using () + renaming (div-helper to divₕ; mod-helper to modₕ) + +open import Data.Nat +open import Data.Nat.Properties +open import Relation.Binary.PropositionalEquality + +open ≡-Reasoning + +------------------------------------------------------------------------- +-- mod lemmas + +modₕ-skipTo0 : ∀ acc n a b → modₕ acc n (b + a) a ≡ modₕ (a + acc) n b 0 +modₕ-skipTo0 acc n zero b = cong (λ v → modₕ acc n v 0) (+-identityʳ b) +modₕ-skipTo0 acc n (suc a) b = begin + modₕ acc n (b + suc a) (suc a) ≡⟨ cong (λ v → modₕ acc n v (suc a)) (+-suc b a) ⟩ + modₕ acc n (suc b + a) (suc a) ≡⟨⟩ + modₕ (suc acc) n (b + a) a ≡⟨ modₕ-skipTo0 (suc acc) n a b ⟩ + modₕ (a + suc acc) n b 0 ≡⟨ cong (λ v → modₕ v n b 0) (+-suc a acc) ⟩ + modₕ (suc a + acc) n b 0 ∎ + +modₕ-skipToEnd : ∀ acc n a b → modₕ acc n a (a + b) ≡ acc + a +modₕ-skipToEnd acc n zero b = sym (+-identityʳ acc) +modₕ-skipToEnd acc n (suc a) b = begin + modₕ (suc acc) n a (a + b) ≡⟨ modₕ-skipToEnd (suc acc) n a b ⟩ + suc acc + a ≡⟨ sym (+-suc acc a) ⟩ + acc + suc a ∎ + +a[modₕ]1≡0 : ∀ a → modₕ 0 0 a 0 ≡ 0 +a[modₕ]1≡0 zero = refl +a[modₕ]1≡0 (suc a) = a[modₕ]1≡0 a + +n[modₕ]n≡0 : ∀ acc v → modₕ acc (acc + v) (suc v) v ≡ 0 +n[modₕ]n≡0 acc v = modₕ-skipTo0 acc (acc + v) v 1 + +a[modₕ]n<n : ∀ acc d n → modₕ acc (acc + n) d n ≤ acc + n +a[modₕ]n<n acc zero n = m≤m+n acc n +a[modₕ]n<n acc (suc d) zero = a[modₕ]n<n zero d (acc + 0) +a[modₕ]n<n acc (suc d) (suc n) + rewrite +-suc acc n = a[modₕ]n<n (suc acc) d n + +modₕ-idem : ∀ acc a n → modₕ 0 (acc + n) (modₕ acc (acc + n) a n) (acc + n) ≡ modₕ acc (acc + n) a n +modₕ-idem acc zero n = modₕ-skipToEnd 0 (acc + n) acc n +modₕ-idem acc (suc a) zero rewrite +-identityʳ acc = modₕ-idem 0 a acc +modₕ-idem acc (suc a) (suc n) rewrite +-suc acc n = modₕ-idem (suc acc) a n + +a+n[modₕ]n≡a[modₕ]n : ∀ acc a n → modₕ acc (acc + n) (acc + a + suc n) n ≡ modₕ acc (acc + n) a n +a+n[modₕ]n≡a[modₕ]n acc zero n rewrite +-identityʳ acc = begin + modₕ acc (acc + n) (acc + suc n) n ≡⟨ cong (λ v → modₕ acc (acc + n) v n) (+-suc acc n) ⟩ + modₕ acc (acc + n) (suc acc + n) n ≡⟨ modₕ-skipTo0 acc (acc + n) n (suc acc) ⟩ + modₕ (acc + n) (acc + n) (suc acc) 0 ≡⟨⟩ + modₕ 0 (acc + n) acc (acc + n) ≡⟨ modₕ-skipToEnd 0 (acc + n) acc n ⟩ + acc ∎ +a+n[modₕ]n≡a[modₕ]n acc (suc a) zero rewrite +-identityʳ acc = begin + modₕ acc acc (acc + suc a + 1) 0 ≡⟨ cong (λ v → modₕ acc acc v 0) (+-comm (acc + suc a) 1) ⟩ + modₕ acc acc (1 + (acc + suc a)) 0 ≡⟨⟩ + modₕ 0 acc (acc + suc a) acc ≡⟨ cong (λ v → modₕ 0 acc v acc) (+-comm acc (suc a)) ⟩ + modₕ 0 acc (suc a + acc) acc ≡⟨ cong (λ v → modₕ 0 acc v acc) (sym (+-suc a acc)) ⟩ + modₕ 0 acc (a + suc acc) acc ≡⟨ a+n[modₕ]n≡a[modₕ]n 0 a acc ⟩ + modₕ 0 acc a acc ∎ +a+n[modₕ]n≡a[modₕ]n acc (suc a) (suc n) rewrite +-suc acc n = begin + mod₁ (acc + suc a + (2 + n)) (suc n) ≡⟨ cong (λ v → mod₁ (v + suc (suc n)) (suc n)) (+-suc acc a) ⟩ + mod₁ (suc acc + a + (2 + n)) (suc n) ≡⟨⟩ + mod₂ (acc + a + (2 + n)) n ≡⟨ cong (λ v → mod₂ v n) (sym (+-assoc (acc + a) 1 (suc n))) ⟩ + mod₂ (acc + a + 1 + suc n) n ≡⟨ cong (λ v → mod₂ (v + suc n) n) (+-comm (acc + a) 1) ⟩ + mod₂ (suc acc + a + suc n) n ≡⟨ a+n[modₕ]n≡a[modₕ]n (suc acc) a n ⟩ + mod₂ a n ∎ + where + mod₁ = modₕ acc (suc acc + n) + mod₂ = modₕ (suc acc) (suc acc + n) + +------------------------------------------------------------------------- +-- division lemmas + +-- The quotient and remainder are related to the dividend and +-- divisor in the right way. + +division-lemma : ∀ accᵐ accᵈ d n → + accᵐ + accᵈ * suc (accᵐ + n) + d ≡ + modₕ accᵐ (accᵐ + n) d n + divₕ accᵈ (accᵐ + n) d n * suc (accᵐ + n) +division-lemma accᵐ accᵈ zero n = +-identityʳ _ +division-lemma accᵐ accᵈ (suc d) zero rewrite +-identityʳ accᵐ = begin + accᵐ + accᵈ * suc accᵐ + suc d ≡⟨ +-suc _ d ⟩ + suc accᵈ * suc accᵐ + d ≡⟨ division-lemma zero (suc accᵈ) d accᵐ ⟩ + modₕ 0 accᵐ d accᵐ + + divₕ (suc accᵈ) accᵐ d accᵐ * suc accᵐ ≡⟨⟩ + modₕ accᵐ accᵐ (suc d) 0 + + divₕ accᵈ accᵐ (suc d) 0 * suc accᵐ ∎ +division-lemma accᵐ accᵈ (suc d) (suc n) rewrite +-suc accᵐ n = begin + accᵐ + accᵈ * m + suc d ≡⟨ +-suc _ d ⟩ + suc (accᵐ + accᵈ * m + d) ≡⟨ division-lemma (suc accᵐ) accᵈ d n ⟩ + modₕ _ _ d n + divₕ accᵈ _ d n * m ∎ + where + m = 2 + accᵐ + n diff --git a/src/Data/Nat/DivMod/Unsafe.agda b/src/Data/Nat/DivMod/Unsafe.agda new file mode 100644 index 0000000..4e852d1 --- /dev/null +++ b/src/Data/Nat/DivMod/Unsafe.agda @@ -0,0 +1,45 @@ +------------------------------------------------------------------------ +-- The Agda standard library +-- +-- More efficient (and unsafe) mod and divMod operations +------------------------------------------------------------------------ + +module Data.Nat.DivMod.Unsafe where + +open import Data.Nat using (ℕ; _+_; _*_; _≟_; zero; suc) +open import Data.Nat.DivMod hiding (_mod_; _divMod_) +open import Data.Nat.Properties using (≤⇒≤″) +import Data.Nat.Unsafe as NatUnsafe +open import Data.Fin using (Fin; toℕ; fromℕ≤″) +open import Data.Fin.Properties using (toℕ-fromℕ≤″) +open import Function using (_$_) +open import Relation.Nullary.Decidable using (False) +open import Relation.Binary.PropositionalEquality + using (refl; sym; cong; module ≡-Reasoning) +import Relation.Binary.PropositionalEquality.TrustMe as TrustMe + using (erase) + +open ≡-Reasoning + +infixl 7 _mod_ _divMod_ + +------------------------------------------------------------------------ +-- Certified modulus + +_mod_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → Fin divisor +(a mod 0) {} +(a mod suc n) = fromℕ≤″ (a % suc n) (NatUnsafe.erase (≤⇒≤″ (a%n<n a n))) + +------------------------------------------------------------------------ +-- Returns modulus and division result with correctness proof + +_divMod_ : (dividend divisor : ℕ) {≢0 : False (divisor ≟ 0)} → + DivMod dividend divisor +(a divMod 0) {} +(a divMod suc n) = result (a div suc n) (a mod suc n) $ TrustMe.erase $ begin + a ≡⟨ a≡a%n+[a/n]*n a n ⟩ + a % suc n + [a/n]*n ≡⟨ cong (_+ [a/n]*n) (sym (toℕ-fromℕ≤″ lemma′)) ⟩ + toℕ (fromℕ≤″ _ lemma′) + [a/n]*n ∎ + where + lemma′ = NatUnsafe.erase (≤⇒≤″ (a%n<n a n)) + [a/n]*n = a div suc n * suc n diff --git a/src/Data/Nat/Divisibility.agda b/src/Data/Nat/Divisibility.agda index 8faaa60..ac6a544 100644 --- a/src/Data/Nat/Divisibility.agda +++ b/src/Data/Nat/Divisibility.agda @@ -6,20 +6,24 @@ module Data.Nat.Divisibility where +open import Algebra open import Data.Nat as Nat open import Data.Nat.DivMod open import Data.Nat.Properties +open import Data.Nat.Solver open import Data.Fin using (Fin; zero; suc; toℕ) import Data.Fin.Properties as FP -open SemiringSolver -open import Algebra open import Data.Product +open import Function +open import Function.Equivalence using (_⇔_; equivalence) open import Relation.Nullary +import Relation.Nullary.Decidable as Dec open import Relation.Binary import Relation.Binary.PartialOrderReasoning as PartialOrderReasoning open import Relation.Binary.PropositionalEquality as PropEq using (_≡_; _≢_; refl; sym; trans; cong; cong₂; subst) -open import Function + +open +-*-Solver ------------------------------------------------------------------------ -- m ∣ n is inhabited iff m divides n. Some sources, like Hardy and @@ -30,8 +34,10 @@ open import Function infix 4 _∣_ _∤_ -data _∣_ : ℕ → ℕ → Set where - divides : {m n : ℕ} (q : ℕ) (eq : n ≡ q * m) → m ∣ n +record _∣_ (m n : ℕ) : Set where + constructor divides + field quotient : ℕ + equality : n ≡ quotient * m _∤_ : Rel ℕ _ m ∤ n = ¬ (m ∣ n) @@ -61,11 +67,10 @@ quotient (divides q _) = q divides (q * p) (sym (*-assoc q p _)) ∣-antisym : Antisymmetric _≡_ _∣_ -∣-antisym (divides {n = zero} _ _) (divides q refl) = *-comm q 0 -∣-antisym (divides p eq) (divides {n = zero} _ _) = - trans (*-comm 0 p) (sym eq) -∣-antisym (divides {n = suc _} p eq₁) (divides {n = suc _} q eq₂) = - ≤-antisym (∣⇒≤ (divides p eq₁)) (∣⇒≤ (divides q eq₂)) +∣-antisym {m} {0} _ (divides q eq) = trans eq (*-comm q 0) +∣-antisym {0} {n} (divides p eq) _ = sym (trans eq (*-comm p 0)) +∣-antisym {suc m} {suc n} (divides p eq₁) (divides q eq₂) = + ≤-antisym (∣⇒≤ (divides p eq₁)) (∣⇒≤ (divides q eq₂)) ∣-isPreorder : IsPreorder _≡_ _∣_ ∣-isPreorder = record @@ -89,7 +94,8 @@ poset = record } module ∣-Reasoning = PartialOrderReasoning poset - renaming (_≤⟨_⟩_ to _∣⟨_⟩_; _≈⟨_⟩_ to _≡⟨_⟩_) + hiding (_≈⟨_⟩_) + renaming (_≤⟨_⟩_ to _∣⟨_⟩_) ------------------------------------------------------------------------ -- Simple properties of _∣_ @@ -105,8 +111,11 @@ n ∣0 = divides 0 refl n∣n : ∀ {n} → n ∣ n n∣n = ∣-refl -n|m*n : ∀ m {n} → n ∣ m * n -n|m*n m = divides m refl +n∣m*n : ∀ m {n} → n ∣ m * n +n∣m*n m = divides m refl + +m∣m*n : ∀ {m} n → m ∣ m * n +m∣m*n n = divides n (*-comm _ n) 0∣⇒≡0 : ∀ {n} → 0 ∣ n → n ≡ 0 0∣⇒≡0 {n} 0∣n = ∣-antisym (n ∣0) 0∣n @@ -117,92 +126,128 @@ n|m*n m = divides m refl ------------------------------------------------------------------------ -- Operators and divisibility -∣m∣n⇒∣m+n : ∀ {i m n} → i ∣ m → i ∣ n → i ∣ m + n -∣m∣n⇒∣m+n (divides p refl) (divides q refl) = - divides (p + q) (sym (*-distribʳ-+ _ p q)) - -∣m+n|m⇒|n : ∀ {i m n} → i ∣ m + n → i ∣ m → i ∣ n -∣m+n|m⇒|n {i} {m} {n} (divides p m+n≡p*i) (divides q m≡q*i) = - divides (p ∸ q) (begin - n ≡⟨ sym (m+n∸n≡m n m) ⟩ - n + m ∸ m ≡⟨ cong (_∸ m) (+-comm n m) ⟩ - m + n ∸ m ≡⟨ cong₂ _∸_ m+n≡p*i m≡q*i ⟩ - p * i ∸ q * i ≡⟨ sym (*-distribʳ-∸ i p q) ⟩ - (p ∸ q) * i ∎) - where open PropEq.≡-Reasoning +module _ where + + open PropEq.≡-Reasoning + + ∣m⇒∣m*n : ∀ {i m} n → i ∣ m → i ∣ m * n + ∣m⇒∣m*n {i} {m} n (divides q eq) = divides (q * n) $ begin + m * n ≡⟨ cong (_* n) eq ⟩ + q * i * n ≡⟨ *-assoc q i n ⟩ + q * (i * n) ≡⟨ cong (q *_) (*-comm i n) ⟩ + q * (n * i) ≡⟨ sym (*-assoc q n i) ⟩ + q * n * i ∎ + + ∣n⇒∣m*n : ∀ {i} m {n} → i ∣ n → i ∣ m * n + ∣n⇒∣m*n {i} m {n} (divides q eq) = divides (m * q) $ begin + m * n ≡⟨ cong (m *_) eq ⟩ + m * (q * i) ≡⟨ sym (*-assoc m q i) ⟩ + m * q * i ∎ + + ∣m∣n⇒∣m+n : ∀ {i m n} → i ∣ m → i ∣ n → i ∣ m + n + ∣m∣n⇒∣m+n (divides p refl) (divides q refl) = + divides (p + q) (sym (*-distribʳ-+ _ p q)) + + ∣m+n∣m⇒∣n : ∀ {i m n} → i ∣ m + n → i ∣ m → i ∣ n + ∣m+n∣m⇒∣n {i} {m} {n} (divides p m+n≡p*i) (divides q m≡q*i) = + divides (p ∸ q) $ begin + n ≡⟨ sym (m+n∸n≡m n m) ⟩ + n + m ∸ m ≡⟨ cong (_∸ m) (+-comm n m) ⟩ + m + n ∸ m ≡⟨ cong₂ _∸_ m+n≡p*i m≡q*i ⟩ + p * i ∸ q * i ≡⟨ sym (*-distribʳ-∸ i p q) ⟩ + (p ∸ q) * i ∎ + + ∣m∸n∣n⇒∣m : ∀ i {m n} → n ≤ m → i ∣ m ∸ n → i ∣ n → i ∣ m + ∣m∸n∣n⇒∣m i {m} {n} n≤m (divides p m∸n≡p*i) (divides q n≡q*o) = + divides (p + q) $ begin + m ≡⟨ sym (m+n∸m≡n n≤m) ⟩ + n + (m ∸ n) ≡⟨ +-comm n (m ∸ n) ⟩ + m ∸ n + n ≡⟨ cong₂ _+_ m∸n≡p*i n≡q*o ⟩ + p * i + q * i ≡⟨ sym (*-distribʳ-+ i p q) ⟩ + (p + q) * i ∎ + + *-cong : ∀ {i j} k → i ∣ j → k * i ∣ k * j + *-cong {i} {j} k (divides q j≡q*i) = divides q $ begin + k * j ≡⟨ cong (_*_ k) j≡q*i ⟩ + k * (q * i) ≡⟨ sym (*-assoc k q i) ⟩ + (k * q) * i ≡⟨ cong (_* i) (*-comm k q) ⟩ + (q * k) * i ≡⟨ *-assoc q k i ⟩ + q * (k * i) ∎ + + /-cong : ∀ {i j} k → suc k * i ∣ suc k * j → i ∣ j + /-cong {i} {j} k (divides q eq) = + divides q (*-cancelʳ-≡ j (q * i) (begin + j * (suc k) ≡⟨ *-comm j (suc k) ⟩ + (suc k) * j ≡⟨ eq ⟩ + q * ((suc k) * i) ≡⟨ cong (q *_) (*-comm (suc k) i) ⟩ + q * (i * (suc k)) ≡⟨ sym (*-assoc q i (suc k)) ⟩ + (q * i) * (suc k) ∎)) + + m%n≡0⇒n∣m : ∀ m n → m % (suc n) ≡ 0 → suc n ∣ m + m%n≡0⇒n∣m m n eq = divides (m div (suc n)) (begin + m ≡⟨ a≡a%n+[a/n]*n m n ⟩ + m % (suc n) + m div (suc n) * (suc n) ≡⟨ cong₂ _+_ eq refl ⟩ + m div (suc n) * (suc n) ∎) + + n∣m⇒m%n≡0 : ∀ m n → suc n ∣ m → m % (suc n) ≡ 0 + n∣m⇒m%n≡0 m n (divides v eq) = begin + m % (suc n) ≡⟨ cong (_% (suc n)) eq ⟩ + (v * suc n) % (suc n) ≡⟨ kn%n≡0 v n ⟩ + 0 ∎ + + m%n≡0⇔n∣m : ∀ m n → m % (suc n) ≡ 0 ⇔ suc n ∣ m + m%n≡0⇔n∣m m n = equivalence (m%n≡0⇒n∣m m n) (n∣m⇒m%n≡0 m n) -∣m∸n∣n⇒∣m : ∀ i {m n} → n ≤ m → i ∣ m ∸ n → i ∣ n → i ∣ m -∣m∸n∣n⇒∣m i {m} {n} n≤m (divides p m∸n≡p*i) (divides q n≡q*o) = - divides (p + q) (begin - m ≡⟨ sym (m+n∸m≡n n≤m) ⟩ - n + (m ∸ n) ≡⟨ +-comm n (m ∸ n) ⟩ - m ∸ n + n ≡⟨ cong₂ _+_ m∸n≡p*i n≡q*o ⟩ - p * i + q * i ≡⟨ sym (*-distribʳ-+ i p q) ⟩ - (p + q) * i ∎) - where open PropEq.≡-Reasoning +-- Divisibility is decidable. -*-cong : ∀ {i j} k → i ∣ j → k * i ∣ k * j -*-cong {i} {j} k (divides q j≡q*i) = divides q (begin - k * j ≡⟨ cong (_*_ k) j≡q*i ⟩ - k * (q * i) ≡⟨ sym (*-assoc k q i) ⟩ - (k * q) * i ≡⟨ cong (_* i) (*-comm k q) ⟩ - (q * k) * i ≡⟨ *-assoc q k i ⟩ - q * (k * i) ∎) - where open PropEq.≡-Reasoning +infix 4 _∣?_ -/-cong : ∀ {i j} k → suc k * i ∣ suc k * j → i ∣ j -/-cong {i} {j} k (divides q eq) = - divides q (*-cancelʳ-≡ j (q * i) (begin - j * (suc k) ≡⟨ *-comm j (suc k) ⟩ - (suc k) * j ≡⟨ eq ⟩ - q * ((suc k) * i) ≡⟨ cong (q *_) (*-comm (suc k) i) ⟩ - q * (i * (suc k)) ≡⟨ sym (*-assoc q i (suc k)) ⟩ - (q * i) * (suc k) ∎)) - where open PropEq.≡-Reasoning +_∣?_ : Decidable _∣_ +zero ∣? zero = yes (0 ∣0) +zero ∣? suc m = no ((λ()) ∘′ 0∣⇒≡0) +suc n ∣? m = Dec.map (m%n≡0⇔n∣m m n) (m % (suc n) ≟ 0) --- If the remainder after division is non-zero, then the divisor does --- not divide the dividend. +------------------------------------------------------------------------ +-- DEPRECATED - please use new names as continuing support for the old +-- names is not guaranteed. -nonZeroDivisor-lemma - : ∀ m q (r : Fin (1 + m)) → toℕ r ≢ 0 → - 1 + m ∤ toℕ r + q * (1 + m) +∣-+ = ∣m∣n⇒∣m+n +{-# WARNING_ON_USAGE ∣-+ +"Warning: ∣-+ was deprecated in v0.14. +Please use ∣m∣n⇒∣m+n instead." +#-} +∣-∸ = ∣m+n∣m⇒∣n +{-# WARNING_ON_USAGE ∣-∸ +"Warning: ∣-∸ was deprecated in v0.14. +Please use ∣m+n∣m⇒∣n instead." +#-} +∣-* = n∣m*n +{-# WARNING_ON_USAGE ∣-* +"Warning: ∣-* was deprecated in v0.14. +Please use n∣m*n instead." +#-} + +nonZeroDivisor-lemma : ∀ m q (r : Fin (1 + m)) → toℕ r ≢ 0 → + 1 + m ∤ toℕ r + q * (1 + m) nonZeroDivisor-lemma m zero r r≢zero (divides zero eq) = r≢zero $ begin toℕ r ≡⟨ sym (*-identityˡ (toℕ r)) ⟩ 1 * toℕ r ≡⟨ eq ⟩ 0 ∎ where open PropEq.≡-Reasoning nonZeroDivisor-lemma m zero r r≢zero (divides (suc q) eq) = - ¬i+1+j≤i m $ begin + i+1+j≰i m $ begin m + suc (q * suc m) ≡⟨ +-suc m (q * suc m) ⟩ suc (m + q * suc m) ≡⟨ sym eq ⟩ 1 * toℕ r ≡⟨ *-identityˡ (toℕ r) ⟩ - toℕ r ≤⟨ ≤-pred $ FP.bounded r ⟩ + toℕ r ≤⟨ FP.toℕ≤pred[n] r ⟩ m ∎ where open ≤-Reasoning nonZeroDivisor-lemma m (suc q) r r≢zero d = - nonZeroDivisor-lemma m q r r≢zero (∣m+n|m⇒|n d' ∣-refl) + nonZeroDivisor-lemma m q r r≢zero (∣m+n∣m⇒∣n d' ∣-refl) where lem = solve 3 (λ m r q → r :+ (m :+ q) := m :+ (r :+ q)) refl (suc m) (toℕ r) (q * suc m) d' = subst (1 + m ∣_) lem d - --- Divisibility is decidable. - -infix 4 _∣?_ - -_∣?_ : Decidable _∣_ -zero ∣? zero = yes (0 ∣0) -zero ∣? suc n = no ((λ()) ∘′ 0∣⇒≡0) -suc m ∣? n with n divMod suc m -suc m ∣? .(q * suc m) | result q zero refl = - yes $ divides q refl -suc m ∣? .(1 + toℕ r + q * suc m) | result q (suc r) refl = - no $ nonZeroDivisor-lemma m q (suc r) (λ()) - ------------------------------------------------------------------------- --- DEPRECATED - please use new names as continuing support for the old --- names is not guaranteed. - -∣-+ = ∣m∣n⇒∣m+n -∣-∸ = ∣m+n|m⇒|n -∣-* = n|m*n +{-# WARNING_ON_USAGE nonZeroDivisor-lemma +"Warning: nonZeroDivisor-lemma was deprecated in v0.17." +#-} diff --git a/src/Data/Nat/GCD.agda b/src/Data/Nat/GCD.agda index de37813..a8ad363 100644 --- a/src/Data/Nat/GCD.agda +++ b/src/Data/Nat/GCD.agda @@ -7,17 +7,17 @@ module Data.Nat.GCD where open import Data.Nat -open import Data.Nat.Divisibility as Div -open import Relation.Binary -private module P = Poset Div.poset +open import Data.Nat.Divisibility +open import Data.Nat.GCD.Lemmas +open import Data.Nat.Properties using (+-suc) open import Data.Product -open import Relation.Binary.PropositionalEquality as PropEq using (_≡_; subst) -open import Relation.Nullary using (Dec; yes; no) +open import Function open import Induction -open import Induction.Nat using (<′-Rec; <′-rec-builder) +open import Induction.Nat using (<′-Rec; <′-recBuilder) open import Induction.Lexicographic -open import Function -open import Data.Nat.GCD.Lemmas +open import Relation.Binary +open import Relation.Binary.PropositionalEquality as P using (_≡_; subst) +open import Relation.Nullary using (Dec; yes; no) ------------------------------------------------------------------------ -- Greatest common divisor @@ -42,7 +42,7 @@ module GCD where -- The gcd is unique. unique : ∀ {d₁ d₂ m n} → GCD m n d₁ → GCD m n d₂ → d₁ ≡ d₂ - unique d₁ d₂ = P.antisym (GCD.greatest d₂ (GCD.commonDivisor d₁)) + unique d₁ d₂ = ∣-antisym (GCD.greatest d₂ (GCD.commonDivisor d₁)) (GCD.greatest d₁ (GCD.commonDivisor d₂)) -- The gcd relation is "symmetric". @@ -53,12 +53,12 @@ module GCD where -- The gcd relation is "reflexive". refl : ∀ {n} → GCD n n n - refl = is (P.refl , P.refl) proj₁ + refl = is (∣-refl , ∣-refl) proj₁ -- The GCD of 0 and n is n. base : ∀ {n} → GCD 0 n n - base {n} = is (n ∣0 , P.refl) proj₂ + base {n} = is (n ∣0 , ∣-refl) proj₂ -- If d is the gcd of n and k, then it is also the gcd of n and -- n + k. @@ -68,7 +68,7 @@ module GCD where step {n} {k} {d} g | (d₁ , d₂) = is (d₁ , ∣m∣n⇒∣m+n d₁ d₂) greatest′ where greatest′ : ∀ {d′} → d′ ∣ n × d′ ∣ n + k → d′ ∣ d - greatest′ (d₁ , d₂) = GCD.greatest g (d₁ , ∣m+n|m⇒|n d₂ d₁) + greatest′ (d₁ , d₂) = GCD.greatest g (d₁ , ∣m+n∣m⇒∣n d₂ d₁) open GCD public using (GCD) hiding (module GCD) @@ -99,10 +99,10 @@ module Bézout where sym (-+ x y eq) = +- y x eq refl : ∀ {d} → Identity d d d - refl = -+ 0 1 PropEq.refl + refl = -+ 0 1 P.refl base : ∀ {d} → Identity d 0 d - base = -+ 0 1 PropEq.refl + base = -+ 0 1 P.refl private infixl 7 _⊕_ @@ -143,7 +143,7 @@ module Bézout where stepˡ : ∀ {n k} → Lemma n (suc k) → Lemma n (suc (n + k)) stepˡ {n} {k} (result d g b) = - PropEq.subst (Lemma n) (lem₀ n k) $ + subst (Lemma n) (+-suc n k) $ result d (GCD.step g) (Identity.step b) stepʳ : ∀ {n k} → Lemma (suc k) n → Lemma (suc (n + k)) n @@ -155,7 +155,7 @@ module Bézout where -- Euclidean algorithm. lemma : (m n : ℕ) → Lemma m n - lemma m n = build [ <′-rec-builder ⊗ <′-rec-builder ] P gcd (m , n) + lemma m n = build [ <′-recBuilder ⊗ <′-recBuilder ] P gcd (m , n) where P : ℕ × ℕ → Set P (m , n) = Lemma m n @@ -176,19 +176,19 @@ module Bézout where identity : ∀ {m n d} → GCD m n d → Identity d m n identity {m} {n} g with lemma m n - identity g | result d g′ b with GCD.unique g g′ - identity g | result d g′ b | PropEq.refl = b + ... | result d g′ b with GCD.unique g g′ + ... | P.refl = b -- Calculates the gcd of the arguments. gcd : (m n : ℕ) → ∃ λ d → GCD m n d gcd m n with Bézout.lemma m n -gcd m n | Bézout.result d g _ = (d , g) +... | Bézout.result d g _ = (d , g) -- gcd as a proposition is decidable gcd? : (m n d : ℕ) → Dec (GCD m n d) gcd? m n d with gcd m n ... | d′ , p with d′ ≟ d -... | no ¬g = no (λ p′ → ¬g (GCD.unique p p′)) -... | yes g = yes (subst (GCD m n) g p) +... | no ¬g = no (¬g ∘ GCD.unique p) +... | yes g = yes (subst (GCD m n) g p) diff --git a/src/Data/Nat/GCD/Lemmas.agda b/src/Data/Nat/GCD/Lemmas.agda index 188e7d4..b0f3ff2 100644 --- a/src/Data/Nat/GCD/Lemmas.agda +++ b/src/Data/Nat/GCD/Lemmas.agda @@ -7,23 +7,41 @@ module Data.Nat.GCD.Lemmas where open import Data.Nat -import Data.Nat.Properties as NatProp -open NatProp.SemiringSolver +open import Data.Nat.Properties +open import Data.Nat.Solver +open import Function open import Relation.Binary.PropositionalEquality + +open +-*-Solver open ≡-Reasoning -open import Function -lem₀ = solve 2 (λ n k → n :+ (con 1 :+ k) := con 1 :+ n :+ k) refl +private + distrib-comm : ∀ x k n → x * k + x * n ≡ x * (n + k) + distrib-comm = + solve 3 (λ x k n → x :* k :+ x :* n := x :* (n :+ k)) refl + + distrib-comm₂ : ∀ d x k n → d + x * (n + k) ≡ d + x * k + x * n + distrib-comm₂ = + solve 4 (λ d x k n → d :+ x :* (n :+ k) := d :+ x :* k :+ x :* n) refl + +-- Other properties +-- TODO: Can this proof be simplified? An automatic solver which can +-- handle ∸ would be nice... +lem₀ : ∀ i j m n → i * m ≡ j * m + n → (i ∸ j) * m ≡ n +lem₀ i j m n eq = begin + (i ∸ j) * m ≡⟨ *-distribʳ-∸ m i j ⟩ + (i * m) ∸ (j * m) ≡⟨ cong (_∸ j * m) eq ⟩ + (j * m + n) ∸ (j * m) ≡⟨ cong (_∸ j * m) (+-comm (j * m) n) ⟩ + (n + j * m) ∸ (j * m) ≡⟨ m+n∸n≡m n (j * m) ⟩ + n ∎ lem₁ : ∀ i j → 2 + i ≤′ 2 + j + i -lem₁ i j = NatProp.≤⇒≤′ $ s≤s $ s≤s $ NatProp.n≤m+n j i +lem₁ i j = ≤⇒≤′ $ s≤s $ s≤s $ n≤m+n j i lem₂ : ∀ d x {k n} → d + x * k ≡ x * n → d + x * (n + k) ≡ 2 * x * n lem₂ d x {k} {n} eq = begin - d + x * (n + k) ≡⟨ solve 4 (λ d x n k → d :+ x :* (n :+ k) - := d :+ x :* k :+ x :* n) - refl d x n k ⟩ + d + x * (n + k) ≡⟨ distrib-comm₂ d x k n ⟩ d + x * k + x * n ≡⟨ cong₂ _+_ eq refl ⟩ x * n + x * n ≡⟨ solve 3 (λ x n k → x :* n :+ x :* n := con 2 :* x :* n) @@ -34,10 +52,8 @@ lem₃ : ∀ d x {i k n} → d + (1 + x + i) * k ≡ x * n → d + (1 + x + i) * (n + k) ≡ (1 + 2 * x + i) * n lem₃ d x {i} {k} {n} eq = begin - d + y * (n + k) ≡⟨ solve 4 (λ d y n k → d :+ y :* (n :+ k) - := (d :+ y :* k) :+ y :* n) - refl d y n k ⟩ - (d + y * k) + y * n ≡⟨ cong₂ _+_ eq refl ⟩ + d + y * (n + k) ≡⟨ distrib-comm₂ d y k n ⟩ + d + y * k + y * n ≡⟨ cong₂ _+_ eq refl ⟩ x * n + y * n ≡⟨ solve 3 (λ x n i → x :* n :+ (con 1 :+ x :+ i) :* n := (con 1 :+ con 2 :* x :+ i) :* n) refl x n i ⟩ @@ -48,19 +64,13 @@ lem₄ : ∀ d y {k i} n → d + y * k ≡ (1 + y + i) * n → d + y * (n + k) ≡ (1 + 2 * y + i) * n lem₄ d y {k} {i} n eq = begin - d + y * (n + k) ≡⟨ solve 4 (λ d y n k → d :+ y :* (n :+ k) - := d :+ y :* k :+ y :* n) - refl d y n k ⟩ + d + y * (n + k) ≡⟨ distrib-comm₂ d y k n ⟩ d + y * k + y * n ≡⟨ cong₂ _+_ eq refl ⟩ (1 + y + i) * n + y * n ≡⟨ solve 3 (λ y i n → (con 1 :+ y :+ i) :* n :+ y :* n := (con 1 :+ con 2 :* y :+ i) :* n) refl y i n ⟩ (1 + 2 * y + i) * n ∎ -private - distrib-comm = - solve 3 (λ x k n → x :* k :+ x :* n := x :* (n :+ k)) refl - lem₅ : ∀ d x {n k} → d + x * n ≡ x * k → d + 2 * x * n ≡ x * (n + k) @@ -99,13 +109,13 @@ lem₈ : ∀ {i j k q} x y → 1 + y * j ≡ x * i → j * k ≡ q * i → k ≡ (x * k ∸ y * q) * i lem₈ {i} {j} {k} {q} x y eq eq′ = - sym (NatProp.im≡jm+n⇒[i∸j]m≡n (x * k) (y * q) i k lemma) + sym (lem₀ (x * k) (y * q) i k lemma) where lemma = begin x * k * i ≡⟨ solve 3 (λ x k i → x :* k :* i := x :* i :* k) refl x k i ⟩ - x * i * k ≡⟨ cong (λ n → n * k) (sym eq) ⟩ + x * i * k ≡⟨ cong (_* k) (sym eq) ⟩ (1 + y * j) * k ≡⟨ solve 3 (λ y j k → (con 1 :+ y :* j) :* k := y :* (j :* k) :+ k) refl y j k ⟩ @@ -119,7 +129,7 @@ lem₉ : ∀ {i j k q} x y → 1 + x * i ≡ y * j → j * k ≡ q * i → k ≡ (y * q ∸ x * k) * i lem₉ {i} {j} {k} {q} x y eq eq′ = - sym (NatProp.im≡jm+n⇒[i∸j]m≡n (y * q) (x * k) i k lemma) + sym (lem₀ (y * q) (x * k) i k lemma) where lem = solve 3 (λ a b c → a :* b :* c := b :* c :* a) refl lemma = begin @@ -136,9 +146,9 @@ lem₁₀ : ∀ {a′} b c {d} e f → let a = suc a′ in a + b * (c * d * a) ≡ e * (f * d * a) → d ≡ 1 lem₁₀ {a′} b c {d} e f eq = - NatProp.i*j≡1⇒j≡1 (e * f ∸ b * c) d - (NatProp.im≡jm+n⇒[i∸j]m≡n (e * f) (b * c) d 1 - (NatProp.*-cancelʳ-≡ (e * f * d) (b * c * d + 1) (begin + i*j≡1⇒j≡1 (e * f ∸ b * c) d + (lem₀ (e * f) (b * c) d 1 + (*-cancelʳ-≡ (e * f * d) (b * c * d + 1) (begin e * f * d * a ≡⟨ solve 4 (λ e f d a → e :* f :* d :* a := e :* (f :* d :* a)) refl e f d a ⟩ @@ -153,18 +163,14 @@ lem₁₁ : ∀ {i j m n k d} x y → 1 + y * j ≡ x * i → i * k ≡ m * d → j * k ≡ n * d → k ≡ (x * m ∸ y * n) * d lem₁₁ {i} {j} {m} {n} {k} {d} x y eq eq₁ eq₂ = - sym (NatProp.im≡jm+n⇒[i∸j]m≡n (x * m) (y * n) d k lemma) - where - assoc = solve 3 (λ x y z → x :* y :* z := x :* (y :* z)) refl - - lemma = begin - x * m * d ≡⟨ assoc x m d ⟩ - x * (m * d) ≡⟨ cong (_*_ x) (sym eq₁) ⟩ - x * (i * k) ≡⟨ sym (assoc x i k) ⟩ + sym (lem₀ (x * m) (y * n) d k (begin + x * m * d ≡⟨ *-assoc x m d ⟩ + x * (m * d) ≡⟨ cong (x *_) (sym eq₁) ⟩ + x * (i * k) ≡⟨ sym (*-assoc x i k) ⟩ x * i * k ≡⟨ cong₂ _*_ (sym eq) refl ⟩ (1 + y * j) * k ≡⟨ solve 3 (λ y j k → (con 1 :+ y :* j) :* k := y :* (j :* k) :+ k) refl y j k ⟩ y * (j * k) + k ≡⟨ cong (λ p → y * p + k) eq₂ ⟩ - y * (n * d) + k ≡⟨ cong₂ _+_ (sym $ assoc y n d) refl ⟩ - y * n * d + k ∎ + y * (n * d) + k ≡⟨ cong₂ _+_ (sym $ *-assoc y n d) refl ⟩ + y * n * d + k ∎)) diff --git a/src/Data/Nat/InfinitelyOften.agda b/src/Data/Nat/InfinitelyOften.agda index dfeb6c7..f3e6883 100644 --- a/src/Data/Nat/InfinitelyOften.agda +++ b/src/Data/Nat/InfinitelyOften.agda @@ -6,30 +6,34 @@ module Data.Nat.InfinitelyOften where -import Level -open import Algebra -open import Category.Monad -open import Data.Empty -open import Function +open import Category.Monad using (RawMonad) +open import Level using (0ℓ) +open import Data.Empty using (⊥-elim) open import Data.Nat open import Data.Nat.Properties open import Data.Product as Prod hiding (map) open import Data.Sum hiding (map) +open import Function open import Relation.Binary.PropositionalEquality -open import Relation.Nullary -open import Relation.Nullary.Negation -open import Relation.Unary using (_∪_; _⊆_) -open RawMonad (¬¬-Monad {p = Level.zero}) +open import Relation.Nullary using (¬_) +open import Relation.Nullary.Negation using (¬¬-Monad; call/cc) +open import Relation.Unary using (Pred; _∪_; _⊆_) +open RawMonad (¬¬-Monad {p = 0ℓ}) -- Only true finitely often. -Fin : (ℕ → Set) → Set +Fin : ∀ {ℓ} → Pred ℕ ℓ → Set ℓ Fin P = ∃ λ i → ∀ j → i ≤ j → ¬ P j +-- A non-constructive definition of "true infinitely often". + +Inf : ∀ {ℓ} → Pred ℕ ℓ → Set ℓ +Inf P = ¬ Fin P + -- Fin is preserved by binary sums. -_∪-Fin_ : ∀ {P Q} → Fin P → Fin Q → Fin (P ∪ Q) -_∪-Fin_ {P} {Q} (i , ¬p) (j , ¬q) = (i ⊔ j , helper) +_∪-Fin_ : ∀ {ℓp ℓq P Q} → Fin {ℓp} P → Fin {ℓq} Q → Fin (P ∪ Q) +_∪-Fin_ {P = P} {Q} (i , ¬p) (j , ¬q) = (i ⊔ j , helper) where open ≤-Reasoning @@ -44,11 +48,6 @@ _∪-Fin_ {P} {Q} (i , ¬p) (j , ¬q) = (i ⊔ j , helper) i ⊔ j ≤⟨ i⊔j≤k ⟩ k ∎) q --- A non-constructive definition of "true infinitely often". - -Inf : (ℕ → Set) → Set -Inf P = ¬ Fin P - -- Inf commutes with binary sums (in the double-negation monad). commutes-with-∪ : ∀ {P Q} → Inf (P ∪ Q) → ¬ ¬ (Inf P ⊎ Inf Q) @@ -59,14 +58,14 @@ commutes-with-∪ p∪q = -- Inf is functorial. -map : ∀ {P Q} → P ⊆ Q → Inf P → Inf Q +map : ∀ {ℓp ℓq P Q} → P ⊆ Q → Inf {ℓp} P → Inf {ℓq} Q map P⊆Q ¬fin = ¬fin ∘ Prod.map id (λ fin j i≤j → fin j i≤j ∘ P⊆Q) -- Inf is upwards closed. -up : ∀ {P} n → Inf P → Inf (P ∘ _+_ n) +up : ∀ {ℓ P} n → Inf {ℓ} P → Inf (P ∘ _+_ n) up zero = id -up {P} (suc n) = up n ∘ up₁ +up {P = P} (suc n) = up n ∘ up₁ where up₁ : Inf P → Inf (P ∘ suc) up₁ ¬fin (i , fin) = ¬fin (suc i , helper) @@ -76,7 +75,7 @@ up {P} (suc n) = up n ∘ up₁ -- A witness. -witness : ∀ {P} → Inf P → ¬ ¬ ∃ P +witness : ∀ {ℓ P} → Inf {ℓ} P → ¬ ¬ ∃ P witness ¬fin ¬p = ¬fin (0 , λ i _ Pi → ¬p (i , Pi)) -- Two different witnesses. diff --git a/src/Data/Nat/LCM.agda b/src/Data/Nat/LCM.agda index e044d33..e0688c6 100644 --- a/src/Data/Nat/LCM.agda +++ b/src/Data/Nat/LCM.agda @@ -6,9 +6,10 @@ module Data.Nat.LCM where +open import Algebra open import Data.Nat -import Data.Nat.Properties as NatProp -open NatProp.SemiringSolver +open import Data.Nat.Properties +open import Data.Nat.Solver open import Data.Nat.GCD open import Data.Nat.Divisibility as Div open import Data.Nat.Coprimality as Coprime @@ -16,8 +17,10 @@ open import Data.Product open import Function open import Relation.Binary.PropositionalEquality as PropEq using (_≡_; refl) -open import Algebra open import Relation.Binary + +open +-*-Solver + private module P = Poset Div.poset @@ -90,7 +93,7 @@ lcm .(q₁ * d) .(q₂ * d) | (d , gcd-* q₁ q₂ q₁-q₂-coprime) = q₂∣q₃ : q₂ ∣ q₃ q₂∣q₃ = coprime-divisor (Coprime.sym q₁-q₂-coprime) - (divides q₄ $ NatProp.*-cancelʳ-≡ _ _ (begin + (divides q₄ $ *-cancelʳ-≡ _ _ (begin q₁ * q₃ * d′ ≡⟨ lem₁ q₁ q₃ d′ ⟩ q₃ * (q₁ * d′) ≡⟨ PropEq.sym eq₃ ⟩ m ≡⟨ eq₄ ⟩ diff --git a/src/Data/Nat/Literals.agda b/src/Data/Nat/Literals.agda new file mode 100644 index 0000000..b084a3c --- /dev/null +++ b/src/Data/Nat/Literals.agda @@ -0,0 +1,17 @@ +------------------------------------------------------------------------ +-- The Agda standard library +-- +-- Natural Literals +------------------------------------------------------------------------ + +module Data.Nat.Literals where + +open import Agda.Builtin.FromNat +open import Agda.Builtin.Nat +open import Data.Unit + +number : Number Nat +number = record + { Constraint = λ _ → ⊤ + ; fromNat = λ n → n + } diff --git a/src/Data/Nat/Primality.agda b/src/Data/Nat/Primality.agda index b632f9e..4ab2fa6 100644 --- a/src/Data/Nat/Primality.agda +++ b/src/Data/Nat/Primality.agda @@ -6,29 +6,29 @@ module Data.Nat.Primality where -open import Data.Empty -open import Data.Fin as Fin hiding (_+_) -open import Data.Fin.Dec -open import Data.Nat -open import Data.Nat.Divisibility -open import Relation.Nullary -open import Relation.Nullary.Decidable -open import Relation.Nullary.Negation -open import Relation.Unary +open import Data.Empty using (⊥) +open import Data.Fin using (Fin; toℕ) +open import Data.Fin.Properties using (all?) +open import Data.Nat using (ℕ; suc; _+_) +open import Data.Nat.Divisibility using (_∤_; _∣?_) +open import Relation.Nullary using (yes; no) +open import Relation.Nullary.Decidable using (from-yes) +open import Relation.Nullary.Negation using (¬?) +open import Relation.Unary using (Decidable) -- Definition of primality. Prime : ℕ → Set Prime 0 = ⊥ Prime 1 = ⊥ -Prime (suc (suc n)) = (i : Fin n) → ¬ (2 + Fin.toℕ i ∣ 2 + n) +Prime (suc (suc n)) = (i : Fin n) → 2 + toℕ i ∤ 2 + n -- Decision procedure for primality. prime? : Decidable Prime prime? 0 = no λ() prime? 1 = no λ() -prime? (suc (suc n)) = all? λ _ → ¬? (_ ∣? _) +prime? (suc (suc n)) = all? (λ _ → ¬? (_ ∣? _)) private diff --git a/src/Data/Nat/Properties.agda b/src/Data/Nat/Properties.agda index f3df5b3..9e9ebf3 100644 --- a/src/Data/Nat/Properties.agda +++ b/src/Data/Nat/Properties.agda @@ -9,24 +9,26 @@ module Data.Nat.Properties where -open import Relation.Binary -open import Function open import Algebra -import Algebra.RingSolver.Simple as Solver -import Algebra.RingSolver.AlmostCommutativeRing as ACR -open import Algebra.Structures -open import Data.Nat as Nat +open import Algebra.Morphism +open import Function +open import Function.Injection using (_↣_) +open import Data.Nat.Base open import Data.Product open import Data.Sum +open import Level using (0ℓ) +open import Relation.Binary +open import Relation.Binary.PropositionalEquality open import Relation.Nullary +open import Relation.Nullary.Decidable using (via-injection; map′) open import Relation.Nullary.Negation using (contradiction) -open import Relation.Binary.PropositionalEquality + open import Algebra.FunctionProperties (_≡_ {A = ℕ}) hiding (LeftCancellative; RightCancellative; Cancellative) open import Algebra.FunctionProperties using (LeftCancellative; RightCancellative; Cancellative) open import Algebra.FunctionProperties.Consequences (setoid ℕ) - +open import Algebra.Structures (_≡_ {A = ℕ}) open ≡-Reasoning ------------------------------------------------------------------------ @@ -35,13 +37,23 @@ open ≡-Reasoning suc-injective : ∀ {m n} → suc m ≡ suc n → m ≡ n suc-injective refl = refl +infix 4 _≟_ + +_≟_ : Decidable {A = ℕ} _≡_ +zero ≟ zero = yes refl +zero ≟ suc n = no λ() +suc m ≟ zero = no λ() +suc m ≟ suc n with m ≟ n +... | yes refl = yes refl +... | no m≢n = no (m≢n ∘ suc-injective) + ≡-isDecEquivalence : IsDecEquivalence (_≡_ {A = ℕ}) ≡-isDecEquivalence = record { isEquivalence = isEquivalence ; _≟_ = _≟_ } -≡-decSetoid : DecSetoid _ _ +≡-decSetoid : DecSetoid 0ℓ 0ℓ ≡-decSetoid = record { Carrier = ℕ ; _≈_ = _≡_ @@ -51,6 +63,9 @@ suc-injective refl = refl ------------------------------------------------------------------------ -- Properties of _≤_ +≤-pred : ∀ {m n} → suc m ≤ suc n → m ≤ n +≤-pred (s≤s m≤n) = m≤n + -- Relation-theoretic properties of _≤_ ≤-reflexive : _≡_ ⇒ _≤_ ≤-reflexive {zero} refl = z≤n @@ -75,6 +90,18 @@ suc-injective refl = refl ... | inj₁ m≤n = inj₁ (s≤s m≤n) ... | inj₂ n≤m = inj₂ (s≤s n≤m) +infix 4 _≤?_ _≥?_ + +_≤?_ : Decidable _≤_ +zero ≤? _ = yes z≤n +suc m ≤? zero = no λ() +suc m ≤? suc n with m ≤? n +... | yes m≤n = yes (s≤s m≤n) +... | no m≰n = no (m≰n ∘ ≤-pred) + +_≥?_ : Decidable _≥_ +_≥?_ = flip _≤?_ + ≤-isPreorder : IsPreorder _≡_ _≤_ ≤-isPreorder = record { isEquivalence = isEquivalence @@ -82,7 +109,7 @@ suc-injective refl = refl ; trans = ≤-trans } -≤-preorder : Preorder _ _ _ +≤-preorder : Preorder 0ℓ 0ℓ 0ℓ ≤-preorder = record { isPreorder = ≤-isPreorder } @@ -93,13 +120,18 @@ suc-injective refl = refl ; antisym = ≤-antisym } +≤-poset : Poset 0ℓ 0ℓ 0ℓ +≤-poset = record + { isPartialOrder = ≤-isPartialOrder + } + ≤-isTotalOrder : IsTotalOrder _≡_ _≤_ ≤-isTotalOrder = record { isPartialOrder = ≤-isPartialOrder ; total = ≤-total } -≤-totalOrder : TotalOrder _ _ _ +≤-totalOrder : TotalOrder 0ℓ 0ℓ 0ℓ ≤-totalOrder = record { isTotalOrder = ≤-isTotalOrder } @@ -111,12 +143,19 @@ suc-injective refl = refl ; _≤?_ = _≤?_ } -≤-decTotalOrder : DecTotalOrder _ _ _ +≤-decTotalOrder : DecTotalOrder 0ℓ 0ℓ 0ℓ ≤-decTotalOrder = record { isDecTotalOrder = ≤-isDecTotalOrder } -- Other properties of _≤_ +s≤s-injective : ∀ {m n} {p q : m ≤ n} → s≤s p ≡ s≤s q → p ≡ q +s≤s-injective refl = refl + +≤-irrelevance : Irrelevant _≤_ +≤-irrelevance z≤n z≤n = refl +≤-irrelevance (s≤s m≤n₁) (s≤s m≤n₂) = cong s≤s (≤-irrelevance m≤n₁ m≤n₂) + ≤-step : ∀ {m n} → m ≤ n → m ≤ 1 + n ≤-step z≤n = z≤n ≤-step (s≤s m≤n) = s≤s (≤-step m≤n) @@ -124,9 +163,12 @@ suc-injective refl = refl n≤1+n : ∀ n → n ≤ 1 + n n≤1+n _ = ≤-step ≤-refl -1+n≰n : ∀ {n} → ¬ 1 + n ≤ n +1+n≰n : ∀ {n} → 1 + n ≰ n 1+n≰n (s≤s le) = 1+n≰n le +n≤0⇒n≡0 : ∀ {n} → n ≤ 0 → n ≡ 0 +n≤0⇒n≡0 z≤n = refl + pred-mono : pred Preserves _≤_ ⟶ _≤_ pred-mono z≤n = z≤n pred-mono (s≤s le) = le @@ -143,8 +185,6 @@ pred-mono (s≤s le) = le -- Properties of _<_ -- Relation theoretic properties of _<_ -_<?_ : Decidable _<_ -x <? y = suc x ≤? y <-irrefl : Irreflexive _≡_ _<_ <-irrefl refl (s≤s n<n) = <-irrefl refl n<n @@ -170,6 +210,30 @@ x <? y = suc x ≤? y ... | tri≈ ≰ ≡ ≱ = tri≈ (≰ ∘ ≤-pred) (cong suc ≡) (≱ ∘ ≤-pred) ... | tri> ≰ ≢ ≥ = tri> (≰ ∘ ≤-pred) (≢ ∘ suc-injective) (s≤s ≥) +infix 4 _<?_ _>?_ + +_<?_ : Decidable _<_ +x <? y = suc x ≤? y + +_>?_ : Decidable _>_ +_>?_ = flip _<?_ + +<-resp₂-≡ : _<_ Respects₂ _≡_ +<-resp₂-≡ = subst (_ <_) , subst (_< _) + +<-isStrictPartialOrder : IsStrictPartialOrder _≡_ _<_ +<-isStrictPartialOrder = record + { isEquivalence = isEquivalence + ; irrefl = <-irrefl + ; trans = <-trans + ; <-resp-≈ = <-resp₂-≡ + } + +<-strictPartialOrder : StrictPartialOrder 0ℓ 0ℓ 0ℓ +<-strictPartialOrder = record + { isStrictPartialOrder = <-isStrictPartialOrder + } + <-isStrictTotalOrder : IsStrictTotalOrder _≡_ _<_ <-isStrictTotalOrder = record { isEquivalence = isEquivalence @@ -177,12 +241,15 @@ x <? y = suc x ≤? y ; compare = <-cmp } -<-strictTotalOrder : StrictTotalOrder _ _ _ +<-strictTotalOrder : StrictTotalOrder 0ℓ 0ℓ 0ℓ <-strictTotalOrder = record { isStrictTotalOrder = <-isStrictTotalOrder } -- Other properties of _<_ +<-irrelevance : Irrelevant _<_ +<-irrelevance = ≤-irrelevance + <⇒≤pred : ∀ {m n} → m < n → m ≤ pred n <⇒≤pred (s≤s le) = le @@ -192,6 +259,10 @@ x <? y = suc x ≤? y <⇒≢ : _<_ ⇒ _≢_ <⇒≢ m<n refl = 1+n≰n m<n +≤⇒≯ : _≤_ ⇒ _≯_ +≤⇒≯ z≤n () +≤⇒≯ (s≤s m≤n) (s≤s n≤m) = ≤⇒≯ m≤n n≤m + <⇒≱ : _<_ ⇒ _≱_ <⇒≱ (s≤s m+1≤n) (s≤s n≤m) = <⇒≱ m+1≤n n≤m @@ -214,11 +285,17 @@ x <? y = suc x ≤? y ≮⇒≥ {zero} {suc j} 1≮j+1 = contradiction (s≤s z≤n) 1≮j+1 ≮⇒≥ {suc i} {suc j} i+1≮j+1 = s≤s (≮⇒≥ (i+1≮j+1 ∘ s≤s)) -≤+≢⇒< : ∀ {m n} → m ≤ n → m ≢ n → m < n -≤+≢⇒< {_} {zero} z≤n m≢n = contradiction refl m≢n -≤+≢⇒< {_} {suc n} z≤n m≢n = s≤s z≤n -≤+≢⇒< {_} {suc n} (s≤s m≤n) 1+m≢1+n = - s≤s (≤+≢⇒< m≤n (1+m≢1+n ∘ cong suc)) +≤∧≢⇒< : ∀ {m n} → m ≤ n → m ≢ n → m < n +≤∧≢⇒< {_} {zero} z≤n m≢n = contradiction refl m≢n +≤∧≢⇒< {_} {suc n} z≤n m≢n = s≤s z≤n +≤∧≢⇒< {_} {suc n} (s≤s m≤n) 1+m≢1+n = + s≤s (≤∧≢⇒< m≤n (1+m≢1+n ∘ cong suc)) + +n≮n : ∀ n → n ≮ n +n≮n n = <-irrefl (refl {x = n}) + +m<n⇒n≢0 : ∀ {m n} → m < n → n ≢ 0 +m<n⇒n≢0 (s≤s m≤n) () ------------------------------------------------------------------------ -- Properties of _≤′_ @@ -239,6 +316,25 @@ s≤′s (≤′-step m≤′n) = ≤′-step (s≤′s m≤′n) ≤⇒≤′ z≤n = z≤′n ≤⇒≤′ (s≤s m≤n) = s≤′s (≤⇒≤′ m≤n) +≤′-step-injective : ∀ {m n} {p q : m ≤′ n} → ≤′-step p ≡ ≤′-step q → p ≡ q +≤′-step-injective refl = refl + +-- Decidablity for _≤'_ + +infix 4 _≤′?_ _<′?_ _≥′?_ _>′?_ + +_≤′?_ : Decidable _≤′_ +x ≤′? y = map′ ≤⇒≤′ ≤′⇒≤ (x ≤? y) + +_<′?_ : Decidable _<′_ +x <′? y = suc x ≤′? y + +_≥′?_ : Decidable _≥′_ +_≥′?_ = flip _≤′?_ + +_>′?_ : Decidable _>′_ +_>′?_ = flip _<′?_ + ------------------------------------------------------------------------ -- Properties of _≤″_ @@ -259,6 +355,22 @@ s≤′s (≤′-step m≤′n) = ≤′-step (s≤′s m≤′n) proof z≤n = refl proof (s≤s m≤n) = cong suc (proof m≤n) +-- Decidablity for _≤″_ + +infix 4 _≤″?_ _<″?_ _≥″?_ _>″?_ + +_≤″?_ : Decidable _≤″_ +x ≤″? y = map′ ≤⇒≤″ ≤″⇒≤ (x ≤? y) + +_<″?_ : Decidable _<″_ +x <″? y = suc x ≤″? y + +_≥″?_ : Decidable _≥″_ +_≥″?_ = flip _≤″?_ + +_>″?_ : Decidable _>″_ +_>″?_ = flip _<″?_ + ------------------------------------------------------------------------ -- Properties of _+_ @@ -289,20 +401,41 @@ s≤′s (≤′-step m≤′n) = ≤′-step (s≤′s m≤′n) suc (n + m) ≡⟨ sym (+-suc n m) ⟩ n + suc m ∎ -+-isSemigroup : IsSemigroup _≡_ _+_ ++-isSemigroup : IsSemigroup _+_ +-isSemigroup = record { isEquivalence = isEquivalence ; assoc = +-assoc ; ∙-cong = cong₂ _+_ } -+-0-isCommutativeMonoid : IsCommutativeMonoid _≡_ _+_ 0 ++-semigroup : Semigroup 0ℓ 0ℓ ++-semigroup = record + { isSemigroup = +-isSemigroup + } + ++-0-isMonoid : IsMonoid _+_ 0 ++-0-isMonoid = record + { isSemigroup = +-isSemigroup + ; identity = +-identity + } + ++-0-monoid : Monoid 0ℓ 0ℓ ++-0-monoid = record + { isMonoid = +-0-isMonoid + } + ++-0-isCommutativeMonoid : IsCommutativeMonoid _+_ 0 +-0-isCommutativeMonoid = record { isSemigroup = +-isSemigroup ; identityˡ = +-identityˡ ; comm = +-comm } ++-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ ++-0-commutativeMonoid = record + { isCommutativeMonoid = +-0-isCommutativeMonoid + } + -- Other properties of _+_ and _≡_ +-cancelˡ-≡ : LeftCancellative _≡_ _+_ @@ -343,6 +476,13 @@ i+j≡0⇒j≡0 i {j} i+j≡0 = i+j≡0⇒i≡0 j (trans (+-comm j i) (i+j≡0)) +-cancel-≤ : Cancellative _≤_ _+_ +-cancel-≤ = +-cancelˡ-≤ , +-cancelʳ-≤ +≤-stepsˡ : ∀ {m n} o → m ≤ n → m ≤ o + n +≤-stepsˡ zero m≤n = m≤n +≤-stepsˡ (suc o) m≤n = ≤-step (≤-stepsˡ o m≤n) + +≤-stepsʳ : ∀ {m n} o → m ≤ n → m ≤ n + o +≤-stepsʳ {m} o m≤n = subst (m ≤_) (+-comm o _) (≤-stepsˡ o m≤n) + m≤m+n : ∀ m n → m ≤ m + n m≤m+n zero n = z≤n m≤m+n (suc m) n = s≤s (m≤m+n m n) @@ -351,10 +491,6 @@ n≤m+n : ∀ m n → n ≤ m + n n≤m+n m zero = z≤n n≤m+n m (suc n) = subst (suc n ≤_) (sym (+-suc m n)) (s≤s (n≤m+n m n)) -≤-steps : ∀ {m n} k → m ≤ n → m ≤ k + n -≤-steps zero m≤n = m≤n -≤-steps (suc k) m≤n = ≤-step (≤-steps k m≤n) - m+n≤o⇒m≤o : ∀ m {n o} → m + n ≤ o → m ≤ o m+n≤o⇒m≤o zero m+n≤o = z≤n m+n≤o⇒m≤o (suc m) (s≤s m+n≤o) = s≤s (m+n≤o⇒m≤o m m+n≤o) @@ -367,25 +503,41 @@ m+n≤o⇒n≤o (suc m) m+n<o = m+n≤o⇒n≤o m (<⇒≤ m+n<o) +-mono-≤ {_} {m} z≤n o≤p = ≤-trans o≤p (n≤m+n m _) +-mono-≤ {_} {_} (s≤s m≤n) o≤p = s≤s (+-mono-≤ m≤n o≤p) -+-monoˡ-< : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_ -+-monoˡ-< {_} {suc y} (s≤s z≤n) u≤v = s≤s (≤-steps y u≤v) -+-monoˡ-< {_} {_} (s≤s (s≤s x<y)) u≤v = s≤s (+-monoˡ-< (s≤s x<y) u≤v) ++-monoˡ-≤ : ∀ n → (_+ n) Preserves _≤_ ⟶ _≤_ ++-monoˡ-≤ n m≤o = +-mono-≤ m≤o (≤-refl {n}) + ++-monoʳ-≤ : ∀ n → (n +_) Preserves _≤_ ⟶ _≤_ ++-monoʳ-≤ n m≤o = +-mono-≤ (≤-refl {n}) m≤o -+-monoʳ-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_ -+-monoʳ-< {_} {y} z≤n u<v = ≤-trans u<v (n≤m+n y _) -+-monoʳ-< {_} {_} (s≤s x≤y) u<v = s≤s (+-monoʳ-< x≤y u<v) ++-mono-<-≤ : _+_ Preserves₂ _<_ ⟶ _≤_ ⟶ _<_ ++-mono-<-≤ {_} {suc y} (s≤s z≤n) u≤v = s≤s (≤-stepsˡ y u≤v) ++-mono-<-≤ {_} {_} (s≤s (s≤s x<y)) u≤v = s≤s (+-mono-<-≤ (s≤s x<y) u≤v) + ++-mono-≤-< : _+_ Preserves₂ _≤_ ⟶ _<_ ⟶ _<_ ++-mono-≤-< {_} {y} z≤n u<v = ≤-trans u<v (n≤m+n y _) ++-mono-≤-< {_} {_} (s≤s x≤y) u<v = s≤s (+-mono-≤-< x≤y u<v) +-mono-< : _+_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_ -+-mono-< x≤y = +-monoʳ-< (<⇒≤ x≤y) ++-mono-< x≤y = +-mono-≤-< (<⇒≤ x≤y) + ++-monoˡ-< : ∀ n → (_+ n) Preserves _<_ ⟶ _<_ ++-monoˡ-< n = +-monoˡ-≤ n -¬i+1+j≤i : ∀ i {j} → i + suc j ≰ i -¬i+1+j≤i zero () -¬i+1+j≤i (suc i) le = ¬i+1+j≤i i (≤-pred le) ++-monoʳ-< : ∀ n → (n +_) Preserves _<_ ⟶ _<_ ++-monoʳ-< zero m≤o = m≤o ++-monoʳ-< (suc n) m≤o = s≤s (+-monoʳ-< n m≤o) + +i+1+j≰i : ∀ i {j} → i + suc j ≰ i +i+1+j≰i zero () +i+1+j≰i (suc i) le = i+1+j≰i i (≤-pred le) m+n≮n : ∀ m n → m + n ≮ n -m+n≮n zero n = <-irrefl refl +m+n≮n zero n = n≮n n m+n≮n (suc m) (suc n) (s≤s m+n<n) = m+n≮n m (suc n) (≤-step m+n<n) +m+n≮m : ∀ m n → m + n ≮ m +m+n≮m m n = subst (_≮ m) (+-comm n m) (m+n≮n n m) + m≤′m+n : ∀ m n → m ≤′ m + n m≤′m+n m n = ≤⇒≤′ (m≤m+n m n) @@ -460,21 +612,56 @@ n≤′m+n (suc m) n = ≤′-step (n≤′m+n m n) n * o + m * (n * o) ≡⟨⟩ suc m * (n * o) ∎ -*-isSemigroup : IsSemigroup _≡_ _*_ +*-isSemigroup : IsSemigroup _*_ *-isSemigroup = record { isEquivalence = isEquivalence ; assoc = *-assoc ; ∙-cong = cong₂ _*_ } -*-1-isCommutativeMonoid : IsCommutativeMonoid _≡_ _*_ 1 +*-semigroup : Semigroup 0ℓ 0ℓ +*-semigroup = record + { isSemigroup = *-isSemigroup + } + +*-1-isMonoid : IsMonoid _*_ 1 +*-1-isMonoid = record + { isSemigroup = *-isSemigroup + ; identity = *-identity + } + +*-1-monoid : Monoid 0ℓ 0ℓ +*-1-monoid = record + { isMonoid = *-1-isMonoid + } + +*-1-isCommutativeMonoid : IsCommutativeMonoid _*_ 1 *-1-isCommutativeMonoid = record { isSemigroup = *-isSemigroup ; identityˡ = *-identityˡ ; comm = *-comm } -*-+-isCommutativeSemiring : IsCommutativeSemiring _≡_ _+_ _*_ 0 1 +*-1-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ +*-1-commutativeMonoid = record + { isCommutativeMonoid = *-1-isCommutativeMonoid + } + +*-+-isSemiring : IsSemiring _+_ _*_ 0 1 +*-+-isSemiring = record + { isSemiringWithoutAnnihilatingZero = record + { +-isCommutativeMonoid = +-0-isCommutativeMonoid + ; *-isMonoid = *-1-isMonoid + ; distrib = *-distrib-+ } + ; zero = *-zero + } + +*-+-semiring : Semiring 0ℓ 0ℓ +*-+-semiring = record + { isSemiring = *-+-isSemiring + } + +*-+-isCommutativeSemiring : IsCommutativeSemiring _+_ _*_ 0 1 *-+-isCommutativeSemiring = record { +-isCommutativeMonoid = +-0-isCommutativeMonoid ; *-isCommutativeMonoid = *-1-isCommutativeMonoid @@ -482,7 +669,7 @@ n≤′m+n (suc m) n = ≤′-step (n≤′m+n m n) ; zeroˡ = *-zeroˡ } -*-+-commutativeSemiring : CommutativeSemiring _ _ +*-+-commutativeSemiring : CommutativeSemiring 0ℓ 0ℓ *-+-commutativeSemiring = record { isCommutativeSemiring = *-+-isCommutativeSemiring } @@ -511,7 +698,7 @@ i*j≡1⇒i≡1 zero j () i*j≡1⇒i≡1 (suc (suc i)) (suc (suc j)) () i*j≡1⇒i≡1 (suc (suc i)) (suc zero) () i*j≡1⇒i≡1 (suc (suc i)) zero eq = - contradiction (trans (*-comm 0 i) eq) λ() + contradiction (trans (sym $ *-zeroʳ i) eq) λ() i*j≡1⇒j≡1 : ∀ i j → i * j ≡ 1 → j ≡ 1 i*j≡1⇒j≡1 i j eq = i*j≡1⇒i≡1 j i (trans (*-comm j i) eq) @@ -526,6 +713,12 @@ i*j≡1⇒j≡1 i j eq = i*j≡1⇒i≡1 j i (trans (*-comm j i) eq) *-mono-≤ z≤n _ = z≤n *-mono-≤ (s≤s m≤n) u≤v = +-mono-≤ u≤v (*-mono-≤ m≤n u≤v) +*-monoˡ-≤ : ∀ n → (_* n) Preserves _≤_ ⟶ _≤_ +*-monoˡ-≤ n m≤o = *-mono-≤ m≤o (≤-refl {n}) + +*-monoʳ-≤ : ∀ n → (n *_) Preserves _≤_ ⟶ _≤_ +*-monoʳ-≤ n m≤o = *-mono-≤ (≤-refl {n}) m≤o + *-mono-< : _*_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_ *-mono-< (s≤s z≤n) (s≤s u≤v) = s≤s z≤n *-mono-< (s≤s (s≤s m≤n)) (s≤s u≤v) = @@ -534,7 +727,7 @@ i*j≡1⇒j≡1 i j eq = i*j≡1⇒i≡1 j i (trans (*-comm j i) eq) *-monoˡ-< : ∀ n → (_* suc n) Preserves _<_ ⟶ _<_ *-monoˡ-< n (s≤s z≤n) = s≤s z≤n *-monoˡ-< n (s≤s (s≤s m≤o)) = - +-monoʳ-< (≤-refl {suc n}) (*-monoˡ-< n (s≤s m≤o)) + +-mono-≤-< (≤-refl {suc n}) (*-monoˡ-< n (s≤s m≤o)) *-monoʳ-< : ∀ n → (suc n *_) Preserves _<_ ⟶ _<_ *-monoʳ-< zero (s≤s m≤o) = +-mono-≤ (s≤s m≤o) z≤n @@ -544,6 +737,18 @@ i*j≡1⇒j≡1 i j eq = i*j≡1⇒i≡1 j i (trans (*-comm j i) eq) ------------------------------------------------------------------------ -- Properties of _^_ +^-identityʳ : RightIdentity 1 _^_ +^-identityʳ zero = refl +^-identityʳ (suc x) = cong suc (^-identityʳ x) + +^-zeroˡ : LeftZero 1 _^_ +^-zeroˡ zero = refl +^-zeroˡ (suc e) = begin + 1 ^ suc e ≡⟨⟩ + 1 * (1 ^ e) ≡⟨ *-identityˡ (1 ^ e) ⟩ + 1 ^ e ≡⟨ ^-zeroˡ e ⟩ + 1 ∎ + ^-distribˡ-+-* : ∀ m n p → m ^ (n + p) ≡ m ^ n * m ^ p ^-distribˡ-+-* m zero p = sym (+-identityʳ (m ^ p)) ^-distribˡ-+-* m (suc n) p = begin @@ -551,6 +756,29 @@ i*j≡1⇒j≡1 i j eq = i*j≡1⇒i≡1 j i (trans (*-comm j i) eq) m * ((m ^ n) * (m ^ p)) ≡⟨ sym (*-assoc m _ _) ⟩ (m * (m ^ n)) * (m ^ p) ∎ +^-semigroup-morphism : ∀ {n} → (n ^_) Is +-semigroup -Semigroup⟶ *-semigroup +^-semigroup-morphism = record + { ⟦⟧-cong = cong (_ ^_) + ; ∙-homo = ^-distribˡ-+-* _ + } + +^-monoid-morphism : ∀ {n} → (n ^_) Is +-0-monoid -Monoid⟶ *-1-monoid +^-monoid-morphism = record + { sm-homo = ^-semigroup-morphism + ; ε-homo = refl + } + +^-*-assoc : ∀ m n p → (m ^ n) ^ p ≡ m ^ (n * p) +^-*-assoc m n zero = begin + 1 ≡⟨⟩ + m ^ 0 ≡⟨ cong (m ^_) (sym $ *-zeroʳ n) ⟩ + m ^ (n * 0) ∎ +^-*-assoc m n (suc p) = begin + (m ^ n) * ((m ^ n) ^ p) ≡⟨ cong ((m ^ n) *_) (^-*-assoc m n p) ⟩ + (m ^ n) * (m ^ (n * p)) ≡⟨ sym (^-distribˡ-+-* m n (n * p)) ⟩ + m ^ (n + n * p) ≡⟨ cong (m ^_) (sym (+-*-suc n p)) ⟩ + m ^ (n * (suc p)) ∎ + i^j≡0⇒i≡0 : ∀ i j → i ^ j ≡ 0 → i ≡ 0 i^j≡0⇒i≡0 i zero () i^j≡0⇒i≡0 i (suc j) eq = [ id , i^j≡0⇒i≡0 i j ]′ (i*j≡0⇒i≡0∨j≡0 i eq) @@ -656,28 +884,43 @@ i^j≡1⇒j≡0∨i≡1 i (suc j) eq = inj₂ (i*j≡1⇒i≡1 i (i ^ j) eq) ⊓-⊔-absorptive : Absorptive _⊓_ _⊔_ ⊓-⊔-absorptive = ⊓-abs-⊔ , ⊔-abs-⊓ -⊔-isSemigroup : IsSemigroup _≡_ _⊔_ +⊔-isSemigroup : IsSemigroup _⊔_ ⊔-isSemigroup = record { isEquivalence = isEquivalence ; assoc = ⊔-assoc ; ∙-cong = cong₂ _⊔_ } -⊔-0-isCommutativeMonoid : IsCommutativeMonoid _≡_ _⊔_ 0 +⊔-semigroup : Semigroup 0ℓ 0ℓ +⊔-semigroup = record + { isSemigroup = ⊔-isSemigroup + } + +⊔-0-isCommutativeMonoid : IsCommutativeMonoid _⊔_ 0 ⊔-0-isCommutativeMonoid = record { isSemigroup = ⊔-isSemigroup - ; identityˡ = ⊔-identityˡ + ; identityˡ = ⊔-identityˡ ; comm = ⊔-comm } -⊓-isSemigroup : IsSemigroup _≡_ _⊓_ +⊔-0-commutativeMonoid : CommutativeMonoid 0ℓ 0ℓ +⊔-0-commutativeMonoid = record + { isCommutativeMonoid = ⊔-0-isCommutativeMonoid + } + +⊓-isSemigroup : IsSemigroup _⊓_ ⊓-isSemigroup = record { isEquivalence = isEquivalence ; assoc = ⊓-assoc ; ∙-cong = cong₂ _⊓_ } -⊔-⊓-isSemiringWithoutOne : IsSemiringWithoutOne _≡_ _⊔_ _⊓_ 0 +⊓-semigroup : Semigroup 0ℓ 0ℓ +⊓-semigroup = record + { isSemigroup = ⊔-isSemigroup + } + +⊔-⊓-isSemiringWithoutOne : IsSemiringWithoutOne _⊔_ _⊓_ 0 ⊔-⊓-isSemiringWithoutOne = record { +-isCommutativeMonoid = ⊔-0-isCommutativeMonoid ; *-isSemigroup = ⊓-isSemigroup @@ -686,19 +929,19 @@ i^j≡1⇒j≡0∨i≡1 i (suc j) eq = inj₂ (i*j≡1⇒i≡1 i (i ^ j) eq) } ⊔-⊓-isCommutativeSemiringWithoutOne - : IsCommutativeSemiringWithoutOne _≡_ _⊔_ _⊓_ 0 + : IsCommutativeSemiringWithoutOne _⊔_ _⊓_ 0 ⊔-⊓-isCommutativeSemiringWithoutOne = record { isSemiringWithoutOne = ⊔-⊓-isSemiringWithoutOne ; *-comm = ⊓-comm } -⊔-⊓-commutativeSemiringWithoutOne : CommutativeSemiringWithoutOne _ _ +⊔-⊓-commutativeSemiringWithoutOne : CommutativeSemiringWithoutOne 0ℓ 0ℓ ⊔-⊓-commutativeSemiringWithoutOne = record { isCommutativeSemiringWithoutOne = ⊔-⊓-isCommutativeSemiringWithoutOne } -⊓-⊔-isLattice : IsLattice _≡_ _⊓_ _⊔_ +⊓-⊔-isLattice : IsLattice _⊓_ _⊔_ ⊓-⊔-isLattice = record { isEquivalence = isEquivalence ; ∨-comm = ⊓-comm @@ -710,13 +953,18 @@ i^j≡1⇒j≡0∨i≡1 i (suc j) eq = inj₂ (i*j≡1⇒i≡1 i (i ^ j) eq) ; absorptive = ⊓-⊔-absorptive } -⊓-⊔-isDistributiveLattice : IsDistributiveLattice _≡_ _⊓_ _⊔_ +⊓-⊔-lattice : Lattice 0ℓ 0ℓ +⊓-⊔-lattice = record + { isLattice = ⊓-⊔-isLattice + } + +⊓-⊔-isDistributiveLattice : IsDistributiveLattice _⊓_ _⊔_ ⊓-⊔-isDistributiveLattice = record { isLattice = ⊓-⊔-isLattice ; ∨-∧-distribʳ = ⊓-distribʳ-⊔ } -⊓-⊔-distributiveLattice : DistributiveLattice _ _ +⊓-⊔-distributiveLattice : DistributiveLattice 0ℓ 0ℓ ⊓-⊔-distributiveLattice = record { isDistributiveLattice = ⊓-⊔-isDistributiveLattice } @@ -743,11 +991,43 @@ m⊓n≤m⊔n zero n = ≤-refl m⊓n≤m⊔n (suc m) zero = ≤-refl m⊓n≤m⊔n (suc m) (suc n) = s≤s (m⊓n≤m⊔n m n) +m≤n⇒m⊓n≡m : ∀ {m n} → m ≤ n → m ⊓ n ≡ m +m≤n⇒m⊓n≡m z≤n = refl +m≤n⇒m⊓n≡m (s≤s m≤n) = cong suc (m≤n⇒m⊓n≡m m≤n) + +m≤n⇒n⊓m≡m : ∀ {m n} → m ≤ n → n ⊓ m ≡ m +m≤n⇒n⊓m≡m {m} m≤n = trans (⊓-comm _ m) (m≤n⇒m⊓n≡m m≤n) + +m⊓n≡m⇒m≤n : ∀ {m n} → m ⊓ n ≡ m → m ≤ n +m⊓n≡m⇒m≤n m⊓n≡m = subst (_≤ _) m⊓n≡m (m⊓n≤n _ _) + +m⊓n≡n⇒n≤m : ∀ {m n} → m ⊓ n ≡ n → n ≤ m +m⊓n≡n⇒n≤m m⊓n≡n = subst (_≤ _) m⊓n≡n (m⊓n≤m _ _) + +m≤n⇒n⊔m≡n : ∀ {m n} → m ≤ n → n ⊔ m ≡ n +m≤n⇒n⊔m≡n z≤n = ⊔-identityʳ _ +m≤n⇒n⊔m≡n (s≤s m≤n) = cong suc (m≤n⇒n⊔m≡n m≤n) + +m≤n⇒m⊔n≡n : ∀ {m n} → m ≤ n → m ⊔ n ≡ n +m≤n⇒m⊔n≡n {m} m≤n = trans (⊔-comm m _) (m≤n⇒n⊔m≡n m≤n) + +n⊔m≡m⇒n≤m : ∀ {m n} → n ⊔ m ≡ m → n ≤ m +n⊔m≡m⇒n≤m n⊔m≡m = subst (_ ≤_) n⊔m≡m (m≤m⊔n _ _) + +n⊔m≡n⇒m≤n : ∀ {m n} → n ⊔ m ≡ n → m ≤ n +n⊔m≡n⇒m≤n n⊔m≡n = subst (_ ≤_) n⊔m≡n (n≤m⊔n _ _) + ⊔-mono-≤ : _⊔_ Preserves₂ _≤_ ⟶ _≤_ ⟶ _≤_ ⊔-mono-≤ {x} {y} {u} {v} x≤y u≤v with ⊔-sel x u ... | inj₁ x⊔u≡x rewrite x⊔u≡x = ≤-trans x≤y (m≤m⊔n y v) ... | inj₂ x⊔u≡u rewrite x⊔u≡u = ≤-trans u≤v (n≤m⊔n y v) +⊔-monoˡ-≤ : ∀ n → (_⊔ n) Preserves _≤_ ⟶ _≤_ +⊔-monoˡ-≤ n m≤o = ⊔-mono-≤ m≤o (≤-refl {n}) + +⊔-monoʳ-≤ : ∀ n → (n ⊔_) Preserves _≤_ ⟶ _≤_ +⊔-monoʳ-≤ n m≤o = ⊔-mono-≤ (≤-refl {n}) m≤o + ⊔-mono-< : _⊔_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_ ⊔-mono-< = ⊔-mono-≤ @@ -756,6 +1036,12 @@ m⊓n≤m⊔n (suc m) (suc n) = s≤s (m⊓n≤m⊔n m n) ... | inj₁ y⊓v≡y rewrite y⊓v≡y = ≤-trans (m⊓n≤m x u) x≤y ... | inj₂ y⊓v≡v rewrite y⊓v≡v = ≤-trans (m⊓n≤n x u) u≤v +⊓-monoˡ-≤ : ∀ n → (_⊓ n) Preserves _≤_ ⟶ _≤_ +⊓-monoˡ-≤ n m≤o = ⊓-mono-≤ m≤o (≤-refl {n}) + +⊓-monoʳ-≤ : ∀ n → (n ⊓_) Preserves _≤_ ⟶ _≤_ +⊓-monoʳ-≤ n m≤o = ⊓-mono-≤ (≤-refl {n}) m≤o + ⊓-mono-< : _⊓_ Preserves₂ _<_ ⟶ _<_ ⟶ _<_ ⊓-mono-< = ⊓-mono-≤ @@ -790,6 +1076,23 @@ m⊓n≤m+n m n with ⊓-sel m n +-distrib-⊓ : _+_ DistributesOver _⊓_ +-distrib-⊓ = +-distribˡ-⊓ , +-distribʳ-⊓ +-- Other properties +⊓-triangulate : ∀ x y z → x ⊓ y ⊓ z ≡ (x ⊓ y) ⊓ (y ⊓ z) +⊓-triangulate x y z = begin + x ⊓ y ⊓ z ≡⟨ cong (λ v → x ⊓ v ⊓ z) (sym (⊓-idem y)) ⟩ + x ⊓ (y ⊓ y) ⊓ z ≡⟨ ⊓-assoc x _ _ ⟩ + x ⊓ ((y ⊓ y) ⊓ z) ≡⟨ cong (x ⊓_) (⊓-assoc y _ _) ⟩ + x ⊓ (y ⊓ (y ⊓ z)) ≡⟨ sym (⊓-assoc x _ _) ⟩ + (x ⊓ y) ⊓ (y ⊓ z) ∎ + +⊔-triangulate : ∀ x y z → x ⊔ y ⊔ z ≡ (x ⊔ y) ⊔ (y ⊔ z) +⊔-triangulate x y z = begin + x ⊔ y ⊔ z ≡⟨ cong (λ v → x ⊔ v ⊔ z) (sym (⊔-idem y)) ⟩ + x ⊔ (y ⊔ y) ⊔ z ≡⟨ ⊔-assoc x _ _ ⟩ + x ⊔ ((y ⊔ y) ⊔ z) ≡⟨ cong (x ⊔_) (⊔-assoc y _ _) ⟩ + x ⊔ (y ⊔ (y ⊔ z)) ≡⟨ sym (⊔-assoc x _ _) ⟩ + (x ⊔ y) ⊔ (y ⊔ z) ∎ + ------------------------------------------------------------------------ -- Properties of _∸_ @@ -801,6 +1104,38 @@ n∸n≡0 : ∀ n → n ∸ n ≡ 0 n∸n≡0 zero = refl n∸n≡0 (suc n) = n∸n≡0 n +-- Ordering properties of _∸_ +n∸m≤n : ∀ m n → n ∸ m ≤ n +n∸m≤n zero n = ≤-refl +n∸m≤n (suc m) zero = ≤-refl +n∸m≤n (suc m) (suc n) = ≤-trans (n∸m≤n m n) (n≤1+n n) + +m≮m∸n : ∀ m n → m ≮ m ∸ n +m≮m∸n zero (suc n) () +m≮m∸n m zero = n≮n m +m≮m∸n (suc m) (suc n) = m≮m∸n m n ∘ ≤-trans (n≤1+n (suc m)) + +∸-mono : _∸_ Preserves₂ _≤_ ⟶ _≥_ ⟶ _≤_ +∸-mono z≤n (s≤s n₁≥n₂) = z≤n +∸-mono (s≤s m₁≤m₂) (s≤s n₁≥n₂) = ∸-mono m₁≤m₂ n₁≥n₂ +∸-mono m₁≤m₂ (z≤n {n = n₁}) = ≤-trans (n∸m≤n n₁ _) m₁≤m₂ + +∸-monoˡ-≤ : ∀ {m n} o → m ≤ n → m ∸ o ≤ n ∸ o +∸-monoˡ-≤ o m≤n = ∸-mono {u = o} m≤n ≤-refl + +∸-monoʳ-≤ : ∀ {m n} o → m ≤ n → o ∸ m ≥ o ∸ n +∸-monoʳ-≤ _ m≤n = ∸-mono ≤-refl m≤n + +m∸n≡0⇒m≤n : ∀ {m n} → m ∸ n ≡ 0 → m ≤ n +m∸n≡0⇒m≤n {zero} {_} _ = z≤n +m∸n≡0⇒m≤n {suc m} {zero} () +m∸n≡0⇒m≤n {suc m} {suc n} eq = s≤s (m∸n≡0⇒m≤n eq) + +m≤n⇒m∸n≡0 : ∀ {m n} → m ≤ n → m ∸ n ≡ 0 +m≤n⇒m∸n≡0 {n = n} z≤n = 0∸n≡0 n +m≤n⇒m∸n≡0 {_} (s≤s m≤n) = m≤n⇒m∸n≡0 m≤n + +-- Properties of _∸_ and _+_ +-∸-comm : ∀ {m} n {o} → o ≤ m → (m + n) ∸ o ≡ (m ∸ o) + n +-∸-comm {zero} _ {suc o} () +-∸-comm {zero} _ {zero} _ = refl @@ -822,11 +1157,6 @@ n∸n≡0 (suc n) = n∸n≡0 n (m + n) ∸ o ≡⟨ +-∸-assoc m o≤n ⟩ m + (n ∸ o) ∎ -n∸m≤n : ∀ m n → n ∸ m ≤ n -n∸m≤n zero n = ≤-refl -n∸m≤n (suc m) zero = ≤-refl -n∸m≤n (suc m) (suc n) = ≤-trans (n∸m≤n m n) (n≤1+n n) - n≤m+n∸m : ∀ m n → n ≤ m + (n ∸ m) n≤m+n∸m m zero = z≤n n≤m+n∸m zero (suc n) = ≤-refl @@ -846,6 +1176,41 @@ m+n∸m≡n {m} {n} m≤n = begin (n + m) ∸ m ≡⟨ m+n∸n≡m n m ⟩ n ∎ +m∸n+n≡m : ∀ {m n} → n ≤ m → (m ∸ n) + n ≡ m +m∸n+n≡m {m} {n} n≤m = begin + (m ∸ n) + n ≡⟨ sym (+-∸-comm n n≤m) ⟩ + (m + n) ∸ n ≡⟨ m+n∸n≡m m n ⟩ + m ∎ + +m∸[m∸n]≡n : ∀ {m n} → n ≤ m → m ∸ (m ∸ n) ≡ n +m∸[m∸n]≡n {m} {_} z≤n = n∸n≡0 m +m∸[m∸n]≡n {suc m} {suc n} (s≤s n≤m) = begin + suc m ∸ (m ∸ n) ≡⟨ +-∸-assoc 1 (n∸m≤n n m) ⟩ + suc (m ∸ (m ∸ n)) ≡⟨ cong suc (m∸[m∸n]≡n n≤m) ⟩ + suc n ∎ + +[i+j]∸[i+k]≡j∸k : ∀ i j k → (i + j) ∸ (i + k) ≡ j ∸ k +[i+j]∸[i+k]≡j∸k zero j k = refl +[i+j]∸[i+k]≡j∸k (suc i) j k = [i+j]∸[i+k]≡j∸k i j k + +-- Properties of _∸_ and _*_ +*-distribʳ-∸ : _*_ DistributesOverʳ _∸_ +*-distribʳ-∸ i zero zero = refl +*-distribʳ-∸ zero zero (suc k) = sym (0∸n≡0 (k * zero)) +*-distribʳ-∸ (suc i) zero (suc k) = refl +*-distribʳ-∸ i (suc j) zero = refl +*-distribʳ-∸ i (suc j) (suc k) = begin + (j ∸ k) * i ≡⟨ *-distribʳ-∸ i j k ⟩ + j * i ∸ k * i ≡⟨ sym $ [i+j]∸[i+k]≡j∸k i _ _ ⟩ + i + j * i ∸ (i + k * i) ∎ + +*-distribˡ-∸ : _*_ DistributesOverˡ _∸_ +*-distribˡ-∸ = comm+distrʳ⇒distrˡ (cong₂ _∸_) *-comm *-distribʳ-∸ + +*-distrib-∸ : _*_ DistributesOver _∸_ +*-distrib-∸ = *-distribˡ-∸ , *-distribʳ-∸ + +-- Properties of _∸_ and _⊓_ and _⊔_ m⊓n+n∸m≡n : ∀ m n → (m ⊓ n) + (n ∸ m) ≡ n m⊓n+n∸m≡n zero n = refl m⊓n+n∸m≡n (suc m) zero = refl @@ -857,40 +1222,14 @@ m⊓n+n∸m≡n (suc m) (suc n) = cong suc $ m⊓n+n∸m≡n m n [m∸n]⊓[n∸m]≡0 (suc m) zero = refl [m∸n]⊓[n∸m]≡0 (suc m) (suc n) = [m∸n]⊓[n∸m]≡0 m n -[i+j]∸[i+k]≡j∸k : ∀ i j k → (i + j) ∸ (i + k) ≡ j ∸ k -[i+j]∸[i+k]≡j∸k zero j k = refl -[i+j]∸[i+k]≡j∸k (suc i) j k = [i+j]∸[i+k]≡j∸k i j k - --- TODO: Can this proof be simplified? An automatic solver which can --- handle ∸ would be nice... -i∸k∸j+j∸k≡i+j∸k : ∀ i j k → i ∸ (k ∸ j) + (j ∸ k) ≡ i + j ∸ k -i∸k∸j+j∸k≡i+j∸k zero j k = begin - 0 ∸ (k ∸ j) + (j ∸ k) ≡⟨ cong (_+ (j ∸ k)) (0∸n≡0 (k ∸ j)) ⟩ - 0 + (j ∸ k) ≡⟨⟩ - j ∸ k ∎ -i∸k∸j+j∸k≡i+j∸k (suc i) j zero = begin - suc i ∸ (0 ∸ j) + j ≡⟨ cong (λ x → suc i ∸ x + j) (0∸n≡0 j) ⟩ - suc i ∸ 0 + j ≡⟨⟩ - suc (i + j) ∎ -i∸k∸j+j∸k≡i+j∸k (suc i) zero (suc k) = begin - i ∸ k + 0 ≡⟨ +-identityʳ _ ⟩ - i ∸ k ≡⟨ cong (_∸ k) (sym (+-identityʳ _)) ⟩ - i + 0 ∸ k ∎ -i∸k∸j+j∸k≡i+j∸k (suc i) (suc j) (suc k) = begin - suc i ∸ (k ∸ j) + (j ∸ k) ≡⟨ i∸k∸j+j∸k≡i+j∸k (suc i) j k ⟩ - suc i + j ∸ k ≡⟨ cong (_∸ k) (sym (+-suc i j)) ⟩ - i + suc j ∸ k ∎ - -*-distribʳ-∸ : _*_ DistributesOverʳ _∸_ -*-distribʳ-∸ i zero k = begin - (0 ∸ k) * i ≡⟨ cong (_* i) (0∸n≡0 k) ⟩ - 0 ≡⟨ sym $ 0∸n≡0 (k * i) ⟩ - 0 ∸ (k * i) ∎ -*-distribʳ-∸ i (suc j) zero = refl -*-distribʳ-∸ i (suc j) (suc k) = begin - (j ∸ k) * i ≡⟨ *-distribʳ-∸ i j k ⟩ - j * i ∸ k * i ≡⟨ sym $ [i+j]∸[i+k]≡j∸k i _ _ ⟩ - i + j * i ∸ (i + k * i) ∎ +∸-distribˡ-⊓-⊔ : ∀ x y z → x ∸ (y ⊓ z) ≡ (x ∸ y) ⊔ (x ∸ z) +∸-distribˡ-⊓-⊔ x zero zero = sym (⊔-idem x) +∸-distribˡ-⊓-⊔ zero zero (suc z) = refl +∸-distribˡ-⊓-⊔ zero (suc y) zero = refl +∸-distribˡ-⊓-⊔ zero (suc y) (suc z) = refl +∸-distribˡ-⊓-⊔ (suc x) (suc y) zero = sym (m≤n⇒m⊔n≡n (≤-step (n∸m≤n y x))) +∸-distribˡ-⊓-⊔ (suc x) zero (suc z) = sym (m≤n⇒n⊔m≡n (≤-step (n∸m≤n z x))) +∸-distribˡ-⊓-⊔ (suc x) (suc y) (suc z) = ∸-distribˡ-⊓-⊔ x y z ∸-distribʳ-⊓ : _∸_ DistributesOverʳ _⊓_ ∸-distribʳ-⊓ zero y z = refl @@ -898,24 +1237,102 @@ i∸k∸j+j∸k≡i+j∸k (suc i) (suc j) (suc k) = begin ∸-distribʳ-⊓ (suc x) (suc y) zero = sym (⊓-zeroʳ (y ∸ x)) ∸-distribʳ-⊓ (suc x) (suc y) (suc z) = ∸-distribʳ-⊓ x y z +∸-distribˡ-⊔-⊓ : ∀ x y z → x ∸ (y ⊔ z) ≡ (x ∸ y) ⊓ (x ∸ z) +∸-distribˡ-⊔-⊓ x zero zero = sym (⊓-idem x) +∸-distribˡ-⊔-⊓ zero zero z = 0∸n≡0 z +∸-distribˡ-⊔-⊓ zero (suc y) z = 0∸n≡0 (suc y ⊔ z) +∸-distribˡ-⊔-⊓ (suc x) (suc y) zero = sym (m≤n⇒m⊓n≡m (≤-step (n∸m≤n y x))) +∸-distribˡ-⊔-⊓ (suc x) zero (suc z) = sym (m≤n⇒n⊓m≡m (≤-step (n∸m≤n z x))) +∸-distribˡ-⊔-⊓ (suc x) (suc y) (suc z) = ∸-distribˡ-⊔-⊓ x y z + ∸-distribʳ-⊔ : _∸_ DistributesOverʳ _⊔_ ∸-distribʳ-⊔ zero y z = refl ∸-distribʳ-⊔ (suc x) zero z = refl ∸-distribʳ-⊔ (suc x) (suc y) zero = sym (⊔-identityʳ (y ∸ x)) ∸-distribʳ-⊔ (suc x) (suc y) (suc z) = ∸-distribʳ-⊔ x y z -im≡jm+n⇒[i∸j]m≡n : ∀ i j m n → i * m ≡ j * m + n → (i ∸ j) * m ≡ n -im≡jm+n⇒[i∸j]m≡n i j m n eq = begin - (i ∸ j) * m ≡⟨ *-distribʳ-∸ m i j ⟩ - (i * m) ∸ (j * m) ≡⟨ cong (_∸ j * m) eq ⟩ - (j * m + n) ∸ (j * m) ≡⟨ cong (_∸ j * m) (+-comm (j * m) n) ⟩ - (n + j * m) ∸ (j * m) ≡⟨ m+n∸n≡m n (j * m) ⟩ - n ∎ - -∸-mono : _∸_ Preserves₂ _≤_ ⟶ _≥_ ⟶ _≤_ -∸-mono z≤n (s≤s n₁≥n₂) = z≤n -∸-mono (s≤s m₁≤m₂) (s≤s n₁≥n₂) = ∸-mono m₁≤m₂ n₁≥n₂ -∸-mono m₁≤m₂ (z≤n {n = n₁}) = ≤-trans (n∸m≤n n₁ _) m₁≤m₂ +------------------------------------------------------------------------ +-- Properties of ∣_-_∣ + +n≡m⇒∣n-m∣≡0 : ∀ {n m} → n ≡ m → ∣ n - m ∣ ≡ 0 +n≡m⇒∣n-m∣≡0 {zero} refl = refl +n≡m⇒∣n-m∣≡0 {suc n} refl = n≡m⇒∣n-m∣≡0 {n} refl + +m≤n⇒∣n-m∣≡n∸m : ∀ {n m} → m ≤ n → ∣ n - m ∣ ≡ n ∸ m +m≤n⇒∣n-m∣≡n∸m {zero} z≤n = refl +m≤n⇒∣n-m∣≡n∸m {suc n} z≤n = refl +m≤n⇒∣n-m∣≡n∸m (s≤s m≤n) = m≤n⇒∣n-m∣≡n∸m m≤n + +∣n-m∣≡0⇒n≡m : ∀ {n m} → ∣ n - m ∣ ≡ 0 → n ≡ m +∣n-m∣≡0⇒n≡m {zero} {zero} eq = refl +∣n-m∣≡0⇒n≡m {zero} {suc m} () +∣n-m∣≡0⇒n≡m {suc n} {zero} () +∣n-m∣≡0⇒n≡m {suc n} {suc m} eq = cong suc (∣n-m∣≡0⇒n≡m eq) + +∣n-m∣≡n∸m⇒m≤n : ∀ {n m} → ∣ n - m ∣ ≡ n ∸ m → m ≤ n +∣n-m∣≡n∸m⇒m≤n {zero} {zero} eq = z≤n +∣n-m∣≡n∸m⇒m≤n {zero} {suc m} () +∣n-m∣≡n∸m⇒m≤n {suc n} {zero} eq = z≤n +∣n-m∣≡n∸m⇒m≤n {suc n} {suc m} eq = s≤s (∣n-m∣≡n∸m⇒m≤n eq) + +∣n-n∣≡0 : ∀ n → ∣ n - n ∣ ≡ 0 +∣n-n∣≡0 n = n≡m⇒∣n-m∣≡0 {n} refl + +∣n-n+m∣≡m : ∀ n m → ∣ n - n + m ∣ ≡ m +∣n-n+m∣≡m zero m = refl +∣n-n+m∣≡m (suc n) m = ∣n-n+m∣≡m n m + +∣n+m-n+o∣≡∣m-o| : ∀ n m o → ∣ n + m - n + o ∣ ≡ ∣ m - o ∣ +∣n+m-n+o∣≡∣m-o| zero m o = refl +∣n+m-n+o∣≡∣m-o| (suc n) m o = ∣n+m-n+o∣≡∣m-o| n m o + +n∸m≤∣n-m∣ : ∀ n m → n ∸ m ≤ ∣ n - m ∣ +n∸m≤∣n-m∣ n m with ≤-total m n +... | inj₁ m≤n = subst (n ∸ m ≤_) (sym (m≤n⇒∣n-m∣≡n∸m m≤n)) ≤-refl +... | inj₂ n≤m = subst (_≤ ∣ n - m ∣) (sym (m≤n⇒m∸n≡0 n≤m)) z≤n + +∣n-m∣≤n⊔m : ∀ n m → ∣ n - m ∣ ≤ n ⊔ m +∣n-m∣≤n⊔m zero m = ≤-refl +∣n-m∣≤n⊔m (suc n) zero = ≤-refl +∣n-m∣≤n⊔m (suc n) (suc m) = ≤-step (∣n-m∣≤n⊔m n m) + +∣-∣-comm : Commutative ∣_-_∣ +∣-∣-comm zero zero = refl +∣-∣-comm zero (suc m) = refl +∣-∣-comm (suc n) zero = refl +∣-∣-comm (suc n) (suc m) = ∣-∣-comm n m + +∣n-m∣≡[n∸m]∨[m∸n] : ∀ m n → (∣ n - m ∣ ≡ n ∸ m) ⊎ (∣ n - m ∣ ≡ m ∸ n) +∣n-m∣≡[n∸m]∨[m∸n] m n with ≤-total m n +... | inj₁ m≤n = inj₁ $ m≤n⇒∣n-m∣≡n∸m m≤n +... | inj₂ n≤m = inj₂ $ begin + ∣ n - m ∣ ≡⟨ ∣-∣-comm n m ⟩ + ∣ m - n ∣ ≡⟨ m≤n⇒∣n-m∣≡n∸m n≤m ⟩ + m ∸ n ∎ + +private + + *-distribˡ-∣-∣-aux : ∀ a m n → m ≤ n → a * ∣ n - m ∣ ≡ ∣ a * n - a * m ∣ + *-distribˡ-∣-∣-aux a m n m≤n = begin + a * ∣ n - m ∣ ≡⟨ cong (a *_) (m≤n⇒∣n-m∣≡n∸m m≤n) ⟩ + a * (n ∸ m) ≡⟨ *-distribˡ-∸ a n m ⟩ + a * n ∸ a * m ≡⟨ sym $′ m≤n⇒∣n-m∣≡n∸m (*-monoʳ-≤ a m≤n) ⟩ + ∣ a * n - a * m ∣ ∎ + +*-distribˡ-∣-∣ : _*_ DistributesOverˡ ∣_-_∣ +*-distribˡ-∣-∣ a m n with ≤-total m n +... | inj₁ m≤n = begin + a * ∣ m - n ∣ ≡⟨ cong (a *_) (∣-∣-comm m n) ⟩ + a * ∣ n - m ∣ ≡⟨ *-distribˡ-∣-∣-aux a m n m≤n ⟩ + ∣ a * n - a * m ∣ ≡⟨ ∣-∣-comm (a * n) (a * m) ⟩ + ∣ a * m - a * n ∣ ∎ +... | inj₂ n≤m = *-distribˡ-∣-∣-aux a n m n≤m + +*-distribʳ-∣-∣ : _*_ DistributesOverʳ ∣_-_∣ +*-distribʳ-∣-∣ = comm+distrˡ⇒distrʳ (cong₂ ∣_-_∣) *-comm *-distribˡ-∣-∣ + +*-distrib-∣-∣ : _*_ DistributesOver ∣_-_∣ +*-distrib-∣-∣ = *-distribˡ-∣-∣ , *-distribʳ-∣-∣ ------------------------------------------------------------------------ -- Properties of ⌊_/2⌋ @@ -938,17 +1355,22 @@ im≡jm+n⇒[i∸j]m≡n i j m n eq = begin ⌊n/2⌋≤′n (suc n) = ≤′-step (⌈n/2⌉≤′n n) ------------------------------------------------------------------------ --- Modules for reasoning about natural number relations +-- Other properties + +-- If there is an injection from a type to ℕ, then the type has +-- decidable equality. --- A module for automatically solving propositional equivalences -module SemiringSolver = - Solver (ACR.fromCommutativeSemiring *-+-commutativeSemiring) _≟_ +eq? : ∀ {a} {A : Set a} → A ↣ ℕ → Decidable {A = A} _≡_ +eq? inj = via-injection inj _≟_ + +------------------------------------------------------------------------ +-- Modules for reasoning about natural number relations -- A module for reasoning about the _≤_ relation module ≤-Reasoning where open import Relation.Binary.PartialOrderReasoning (DecTotalOrder.poset ≤-decTotalOrder) public - renaming (_≈⟨_⟩_ to _≡⟨_⟩_) + hiding (_≈⟨_⟩_) infixr 2 _<⟨_⟩_ @@ -961,23 +1383,140 @@ module ≤-Reasoning where -- Please use the new names as continuing support for the old names is -- not guaranteed. +-- Version 0.14 + _*-mono_ = *-mono-≤ +{-# WARNING_ON_USAGE _*-mono_ +"Warning: _*-mono_ was deprecated in v0.14. +Please use *-mono-≤ instead." +#-} _+-mono_ = +-mono-≤ - +{-# WARNING_ON_USAGE _+-mono_ +"Warning: _+-mono_ was deprecated in v0.14. +Please use +-mono-≤ instead." +#-} +-right-identity = +-identityʳ +{-# WARNING_ON_USAGE +-right-identity +"Warning: +-right-identity was deprecated in v0.14. +Please use +-identityʳ instead." +#-} *-right-zero = *-zeroʳ +{-# WARNING_ON_USAGE *-right-zero +"Warning: *-right-zero was deprecated in v0.14. +Please use *-zeroʳ instead." +#-} distribʳ-*-+ = *-distribʳ-+ +{-# WARNING_ON_USAGE distribʳ-*-+ +"Warning: distribʳ-*-+ was deprecated in v0.14. +Please use *-distribʳ-+ instead." +#-} *-distrib-∸ʳ = *-distribʳ-∸ +{-# WARNING_ON_USAGE *-distrib-∸ʳ +"Warning: *-distrib-∸ʳ was deprecated in v0.14. +Please use *-distribʳ-∸ instead." +#-} cancel-+-left = +-cancelˡ-≡ +{-# WARNING_ON_USAGE cancel-+-left +"Warning: cancel-+-left was deprecated in v0.14. +Please use +-cancelˡ-≡ instead." +#-} cancel-+-left-≤ = +-cancelˡ-≤ +{-# WARNING_ON_USAGE cancel-+-left-≤ +"Warning: cancel-+-left-≤ was deprecated in v0.14. +Please use +-cancelˡ-≤ instead." +#-} cancel-*-right = *-cancelʳ-≡ +{-# WARNING_ON_USAGE cancel-*-right +"Warning: cancel-*-right was deprecated in v0.14. +Please use *-cancelʳ-≡ instead." +#-} cancel-*-right-≤ = *-cancelʳ-≤ - +{-# WARNING_ON_USAGE cancel-*-right-≤ +"Warning: cancel-*-right-≤ was deprecated in v0.14. +Please use *-cancelʳ-≤ instead." +#-} strictTotalOrder = <-strictTotalOrder +{-# WARNING_ON_USAGE strictTotalOrder +"Warning: strictTotalOrder was deprecated in v0.14. +Please use <-strictTotalOrder instead." +#-} isCommutativeSemiring = *-+-isCommutativeSemiring +{-# WARNING_ON_USAGE isCommutativeSemiring +"Warning: isCommutativeSemiring was deprecated in v0.14. +Please use *-+-isCommutativeSemiring instead." +#-} commutativeSemiring = *-+-commutativeSemiring +{-# WARNING_ON_USAGE commutativeSemiring +"Warning: commutativeSemiring was deprecated in v0.14. +Please use *-+-commutativeSemiring instead." +#-} isDistributiveLattice = ⊓-⊔-isDistributiveLattice +{-# WARNING_ON_USAGE isDistributiveLattice +"Warning: isDistributiveLattice was deprecated in v0.14. +Please use ⊓-⊔-isDistributiveLattice instead." +#-} distributiveLattice = ⊓-⊔-distributiveLattice +{-# WARNING_ON_USAGE distributiveLattice +"Warning: distributiveLattice was deprecated in v0.14. +Please use ⊓-⊔-distributiveLattice instead." +#-} ⊔-⊓-0-isSemiringWithoutOne = ⊔-⊓-isSemiringWithoutOne +{-# WARNING_ON_USAGE ⊔-⊓-0-isSemiringWithoutOne +"Warning: ⊔-⊓-0-isSemiringWithoutOne was deprecated in v0.14. +Please use ⊔-⊓-isSemiringWithoutOne instead." +#-} ⊔-⊓-0-isCommutativeSemiringWithoutOne = ⊔-⊓-isCommutativeSemiringWithoutOne +{-# WARNING_ON_USAGE ⊔-⊓-0-isCommutativeSemiringWithoutOne +"Warning: ⊔-⊓-0-isCommutativeSemiringWithoutOne was deprecated in v0.14. +Please use ⊔-⊓-isCommutativeSemiringWithoutOne instead." +#-} ⊔-⊓-0-commutativeSemiringWithoutOne = ⊔-⊓-commutativeSemiringWithoutOne +{-# WARNING_ON_USAGE ⊔-⊓-0-commutativeSemiringWithoutOne +"Warning: ⊔-⊓-0-commutativeSemiringWithoutOne was deprecated in v0.14. +Please use ⊔-⊓-commutativeSemiringWithoutOne instead." +#-} + +-- Version 0.15 + +¬i+1+j≤i = i+1+j≰i +{-# WARNING_ON_USAGE ¬i+1+j≤i +"Warning: ¬i+1+j≤i was deprecated in v0.15. +Please use i+1+j≰i instead." +#-} +≤-steps = ≤-stepsˡ +{-# WARNING_ON_USAGE ≤-steps +"Warning: ≤-steps was deprecated in v0.15. +Please use ≤-stepsˡ instead." +#-} + +-- Version 0.17 + +i∸k∸j+j∸k≡i+j∸k : ∀ i j k → i ∸ (k ∸ j) + (j ∸ k) ≡ i + j ∸ k +i∸k∸j+j∸k≡i+j∸k zero j k = cong (_+ (j ∸ k)) (0∸n≡0 (k ∸ j)) +i∸k∸j+j∸k≡i+j∸k (suc i) j zero = cong (λ x → suc i ∸ x + j) (0∸n≡0 j) +i∸k∸j+j∸k≡i+j∸k (suc i) zero (suc k) = begin + i ∸ k + 0 ≡⟨ +-identityʳ _ ⟩ + i ∸ k ≡⟨ cong (_∸ k) (sym (+-identityʳ _)) ⟩ + i + 0 ∸ k ∎ +i∸k∸j+j∸k≡i+j∸k (suc i) (suc j) (suc k) = begin + suc i ∸ (k ∸ j) + (j ∸ k) ≡⟨ i∸k∸j+j∸k≡i+j∸k (suc i) j k ⟩ + suc i + j ∸ k ≡⟨ cong (_∸ k) (sym (+-suc i j)) ⟩ + i + suc j ∸ k ∎ +{-# WARNING_ON_USAGE i∸k∸j+j∸k≡i+j∸k +"Warning: i∸k∸j+j∸k≡i+j∸k was deprecated in v0.17." +#-} +im≡jm+n⇒[i∸j]m≡n : ∀ i j m n → i * m ≡ j * m + n → (i ∸ j) * m ≡ n +im≡jm+n⇒[i∸j]m≡n i j m n eq = begin + (i ∸ j) * m ≡⟨ *-distribʳ-∸ m i j ⟩ + (i * m) ∸ (j * m) ≡⟨ cong (_∸ j * m) eq ⟩ + (j * m + n) ∸ (j * m) ≡⟨ cong (_∸ j * m) (+-comm (j * m) n) ⟩ + (n + j * m) ∸ (j * m) ≡⟨ m+n∸n≡m n (j * m) ⟩ + n ∎ +{-# WARNING_ON_USAGE im≡jm+n⇒[i∸j]m≡n +"Warning: im≡jm+n⇒[i∸j]m≡n was deprecated in v0.17." +#-} +≤+≢⇒< = ≤∧≢⇒< +{-# WARNING_ON_USAGE ≤+≢⇒< +"Warning: ≤+≢⇒< was deprecated in v0.17. +Please use ≤∧≢⇒< instead." +#-} diff --git a/src/Data/Nat/Solver.agda b/src/Data/Nat/Solver.agda new file mode 100644 index 0000000..21a8e33 --- /dev/null +++ b/src/Data/Nat/Solver.agda @@ -0,0 +1,21 @@ +------------------------------------------------------------------------ +-- The Agda standard library +-- +-- Automatic solvers for equations over naturals +------------------------------------------------------------------------ + +-- See README.Nat for examples of how to use this solver + +module Data.Nat.Solver where + +import Algebra.Solver.Ring.Simple as Solver +import Algebra.Solver.Ring.AlmostCommutativeRing as ACR +open import Data.Nat using (_≟_) +open import Data.Nat.Properties + +------------------------------------------------------------------------ +-- A module for automatically solving propositional equivalences +-- containing _+_ and _*_ + +module +-*-Solver = + Solver (ACR.fromCommutativeSemiring *-+-commutativeSemiring) _≟_ diff --git a/src/Data/Nat/Unsafe.agda b/src/Data/Nat/Unsafe.agda new file mode 100644 index 0000000..34839cf --- /dev/null +++ b/src/Data/Nat/Unsafe.agda @@ -0,0 +1,13 @@ +------------------------------------------------------------------------ +-- The Agda standard library +-- +-- Unsafe natural number types and operations +------------------------------------------------------------------------ + +module Data.Nat.Unsafe where + +open import Data.Nat.Base +import Relation.Binary.PropositionalEquality.TrustMe as TrustMe + +erase : ∀ {m n} → m ≤″ n → m ≤″ n +erase (less-than-or-equal eq) = less-than-or-equal (TrustMe.erase eq) |