Skip to content

Commit 6d5af55

Browse files
authored
Add prove of injectivity to Data.Fin.combine (#1679)
1 parent 2b2c4fe commit 6d5af55

File tree

2 files changed

+108
-4
lines changed

2 files changed

+108
-4
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,17 @@ Other minor changes
912912
finTofun-funToFin : funToFin ∘ finToFun ≗ id
913913
funTofin-funToFun : finToFun (funToFin f) ≗ f
914914
^↔→ : Extensionality _ _ → Fin (n ^ m) ↔ (Fin m → Fin n)
915+
916+
toℕ-mono-< : i < j → toℕ i ℕ.< toℕ j
917+
toℕ-mono-≤ : i ≤ j → toℕ i ℕ.≤ toℕ j
918+
toℕ-cancel-≤ : toℕ i ℕ.≤ toℕ j → i ≤ j
919+
toℕ-cancel-< : toℕ i ℕ.< toℕ j → i < j
920+
921+
toℕ-combine : toℕ (combine x y) ≡ k ℕ.* toℕ x ℕ.+ toℕ y
922+
combine-injectiveˡ : combine x z ≡ combine y z → x ≡ y
923+
combine-injectiveʳ : combine x y ≡ combine x z → y ≡ z
924+
combine-injective : combine x y ≡ combine w z → x ≡ w × y ≡ z
925+
combine-surjective : ∀ x → ∃₂ λ y z → combine y z ≡ x
915926
```
916927

917928
* Added new functions in `Data.Integer.Base`:

src/Data/Fin/Properties.agda

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,18 @@ open import Data.Fin.Base
1919
open import Data.Fin.Patterns
2020
open import Data.Nat.Base as ℕ using (ℕ; zero; suc; s≤s; z≤n; _∸_; _^_)
2121
import Data.Nat.Properties as ℕₚ
22+
open import Data.Nat.Solver
2223
open import Data.Unit using (⊤; tt)
2324
open import Data.Product using (Σ-syntax; ∃; ∃₂; ∄; _×_; _,_; map; proj₁; proj₂; uncurry; <_,_>)
25+
open import Data.Product.Properties using (,-injective)
2426
open import Data.Sum.Base as Sum using (_⊎_; inj₁; inj₂; [_,_]; [_,_]′)
2527
open import Data.Sum.Properties using ([,]-map-commute; [,]-∘-distr)
2628
open import Function.Base using (_∘_; id; _$_; flip)
2729
open import Function.Bundles using (_↣_; _⇔_; _↔_; mk⇔; mk↔′)
2830
open import Function.Definitions.Core2 using (Surjective)
2931
open import Relation.Binary as B hiding (Decidable; _⇔_)
3032
open import Relation.Binary.PropositionalEquality as P
31-
using (_≡_; _≢_; refl; sym; trans; cong; subst; _≗_; module ≡-Reasoning)
33+
using (_≡_; _≢_; refl; sym; trans; cong; cong₂; subst; _≗_; module ≡-Reasoning)
3234
open import Relation.Nullary.Decidable as Dec using (map′)
3335
open import Relation.Nullary.Reflects
3436
open import Relation.Nullary.Negation using (contradiction)
@@ -151,6 +153,22 @@ toℕ≤pred[n] (suc {n = suc n} i) = s≤s (toℕ≤pred[n] i)
151153
toℕ≤pred[n]′ : {n} (i : Fin n) toℕ i ℕ.≤ ℕ.pred n
152154
toℕ≤pred[n]′ i = ℕₚ.<⇒≤pred (toℕ<n i)
153155

156+
toℕ-mono-< : {n} {i j : Fin n} i < j toℕ i ℕ.< toℕ j
157+
toℕ-mono-< {i = 0F} {suc j} (s≤s z≤n) = s≤s z≤n
158+
toℕ-mono-< {i = suc i} {suc (suc j)} (s≤s (s≤s i<j)) = s≤s (toℕ-mono-< (s≤s i<j))
159+
160+
toℕ-mono-≤ : {n} {i j : Fin n} i ≤ j toℕ i ℕ.≤ toℕ j
161+
toℕ-mono-≤ {i = 0F} {j} z≤n = z≤n
162+
toℕ-mono-≤ {i = suc i} {suc j} (s≤s i≤j) = s≤s (toℕ-mono-≤ i≤j)
163+
164+
toℕ-cancel-≤ : {n} {i j : Fin n} toℕ i ℕ.≤ toℕ j i ≤ j
165+
toℕ-cancel-≤ {i = 0F} {j} z≤n = z≤n
166+
toℕ-cancel-≤ {i = suc i} {suc j} (s≤s i≤j) = s≤s (toℕ-cancel-≤ i≤j)
167+
168+
toℕ-cancel-< : {n} {i j : Fin n} toℕ i ℕ.< toℕ j i < j
169+
toℕ-cancel-< {i = 0F} {suc j} (s≤s z≤n) = s≤s z≤n
170+
toℕ-cancel-< {i = suc i} {suc (suc j)} (s≤s (s≤s i<j)) = s≤s (toℕ-cancel-< (s≤s i<j))
171+
154172
------------------------------------------------------------------------
155173
-- fromℕ
156174
------------------------------------------------------------------------
@@ -552,9 +570,9 @@ splitAt-≥ (suc m) (suc i) (s≤s i≥m) = cong (Sum.map suc id) (splitAt-≥ m
552570

553571
-- Fin (m * n) ↔ Fin m × Fin n
554572

555-
remQuot-combine : {n k} (x : Fin n) y remQuot k (combine x y) ≡ (x , y)
556-
remQuot-combine {suc n} {k} 0F y rewrite splitAt-↑ˡ k y (n ℕ.* k) = refl
557-
remQuot-combine {suc n} {k} (suc x) y rewrite splitAt-↑ʳ k (n ℕ.* k) (combine x y) = cong (Data.Product.map₁ suc) (remQuot-combine x y)
573+
remQuot-combine : {n k} (i : Fin n) j remQuot k (combine i j) ≡ (i , j)
574+
remQuot-combine {suc n} {k} 0F j rewrite splitAt-↑ˡ k j (n ℕ.* k) = refl
575+
remQuot-combine {suc n} {k} (suc i) j rewrite splitAt-↑ʳ k (n ℕ.* k) (combine i j) = cong (Data.Product.map₁ suc) (remQuot-combine i j)
558576

559577
combine-remQuot : {n} k (i : Fin (n ℕ.* k)) uncurry combine (remQuot {n} k i) ≡ i
560578
combine-remQuot {suc n} k i with splitAt k i | P.inspect (splitAt k) i
@@ -570,6 +588,81 @@ combine-remQuot {suc n} k i with splitAt k i | P.inspect (splitAt k) i
570588
i ∎
571589
where open ≡-Reasoning
572590

591+
toℕ-combine : {n m} (i : Fin n) (j : Fin m) toℕ (combine i j) ≡ m ℕ.* toℕ i ℕ.+ toℕ j
592+
toℕ-combine {n = suc n} {m} i@0F j = begin
593+
toℕ (combine i j) ≡⟨⟩
594+
toℕ (j ↑ˡ (n ℕ.* m)) ≡⟨ toℕ-↑ˡ j (n ℕ.* m) ⟩
595+
toℕ j ≡⟨⟩
596+
0 ℕ.+ toℕ j ≡˘⟨ cong (ℕ._+ toℕ j) (ℕₚ.*-zeroʳ m) ⟩
597+
m ℕ.* toℕ i ℕ.+ toℕ j ∎
598+
where open ≡-Reasoning
599+
toℕ-combine {n = suc n} {m} (suc i) j = begin
600+
toℕ (combine (suc i) j) ≡⟨⟩
601+
toℕ (m ↑ʳ combine i j) ≡⟨ toℕ-↑ʳ m (combine i j) ⟩
602+
m ℕ.+ toℕ (combine i j) ≡⟨ cong (m ℕ.+_) (toℕ-combine i j) ⟩
603+
m ℕ.+ (m ℕ.* toℕ i ℕ.+ toℕ j) ≡⟨ solve 3 (λ m i j m :+ (m :* i :+ j) := m :* (con 1 :+ i) :+ j) refl m (toℕ i) (toℕ j) ⟩
604+
m ℕ.* toℕ (suc i) ℕ.+ toℕ j ∎
605+
where
606+
open ≡-Reasoning
607+
open +-*-Solver
608+
609+
combine-injectiveˡ : {n m} (i j : Fin n) (k : Fin m) combine i k ≡ combine j k i ≡ j
610+
combine-injectiveˡ {n} {m@(suc _)} i j k combine[i,k]≡combine[j,k] =
611+
toℕ-injective (ℕₚ.*-cancelˡ-≡ m (ℕₚ.+-cancelʳ-≡ (m ℕ.* toℕ i) (m ℕ.* toℕ j) (begin
612+
m ℕ.* toℕ i ℕ.+ toℕ k ≡˘⟨ toℕ-combine i k ⟩
613+
toℕ (combine i k) ≡⟨ cong toℕ combine[i,k]≡combine[j,k] ⟩
614+
toℕ (combine j k) ≡⟨ toℕ-combine j k ⟩
615+
m ℕ.* toℕ j ℕ.+ toℕ k ∎)))
616+
where open ≡-Reasoning
617+
618+
combine-injectiveʳ : {n m} (i : Fin n) (j k : Fin m) combine i j ≡ combine i k j ≡ k
619+
combine-injectiveʳ {n} {m} i j k combine[i,k]≡combine[j,k] = toℕ-injective (ℕₚ.+-cancelˡ-≡ (m ℕ.* toℕ i) (begin
620+
m ℕ.* toℕ i ℕ.+ toℕ j ≡˘⟨ toℕ-combine i j ⟩
621+
toℕ (combine i j) ≡⟨ cong toℕ combine[i,k]≡combine[j,k] ⟩
622+
toℕ (combine i k) ≡⟨ toℕ-combine i k ⟩
623+
m ℕ.* toℕ i ℕ.+ toℕ k ∎))
624+
where open ≡-Reasoning
625+
626+
combine-injective : {n m} (i : Fin n) (j : Fin m) (k : Fin n) (l : Fin m) combine i j ≡ combine k l i ≡ k × j ≡ l
627+
combine-injective i j k l combine[i,j]≡combine[k,l] =
628+
lemma₂ i j k l combine[i,j]≡combine[k,l] , lemma₃ i j k l combine[i,j]≡combine[k,l]
629+
where
630+
lemma₁ : {n m} (i : Fin n) (j : Fin m) (k : Fin n) (l : Fin m) i < k combine i j < combine k l
631+
lemma₁ {n} {m} i j k l i<k = toℕ-cancel-< (begin-strict
632+
toℕ (combine i j) ≡⟨ toℕ-combine i j ⟩
633+
m ℕ.* toℕ i ℕ.+ toℕ j <⟨ ℕₚ.+-monoʳ-< (m ℕ.* toℕ i) (toℕ<n j) ⟩
634+
m ℕ.* toℕ i ℕ.+ m ≡⟨ ℕₚ.+-comm _ m ⟩
635+
m ℕ.+ m ℕ.* toℕ i ≡⟨ cong (m ℕ.+_) (ℕₚ.*-comm m _) ⟩
636+
m ℕ.+ toℕ i ℕ.* m ≡⟨ ℕₚ.*-comm (suc (toℕ i)) m ⟩
637+
m ℕ.* suc (toℕ i) ≤⟨ ℕₚ.*-monoʳ-≤ m (toℕ-mono-< i<k) ⟩
638+
m ℕ.* toℕ k ≤⟨ ℕₚ.m≤m+n (m ℕ.* toℕ k) (toℕ l) ⟩
639+
m ℕ.* toℕ k ℕ.+ toℕ l ≡˘⟨ toℕ-combine k l ⟩
640+
toℕ (combine k l) ∎)
641+
where
642+
open ℕₚ.≤-Reasoning
643+
open +-*-Solver
644+
645+
lemma₂ : {n m} (i : Fin n) (j : Fin m) (k : Fin n) (l : Fin m) combine i j ≡ combine k l i ≡ k
646+
lemma₂ i j k l combine[i,j]≡combine[k,l] with <-cmp i k
647+
... | tri< i<k _ _ = contradiction combine[i,j]≡combine[k,l] (<⇒≢ (lemma₁ i j k l i<k))
648+
... | tri≈ _ i≡k _ = i≡k
649+
... | tri> _ _ i>k = contradiction (sym combine[i,j]≡combine[k,l]) (<⇒≢ (lemma₁ k l i j i>k))
650+
651+
lemma₃ : {n m} (i : Fin n) (j : Fin m) (k : Fin n) (l : Fin m) combine i j ≡ combine k l j ≡ l
652+
lemma₃ i j k l combine[i,j]≡combine[k,l] = combine-injectiveʳ i j l (begin
653+
combine i j ≡⟨ combine[i,j]≡combine[k,l] ⟩
654+
combine k l ≡˘⟨ cong (λ h combine h l) (lemma₂ i j k l combine[i,j]≡combine[k,l]) ⟩
655+
combine i l ∎)
656+
where open ≡-Reasoning
657+
658+
combine-surjective : {n m} (i : Fin (n ℕ.* m)) Σ[ j ∈ Fin n ] Σ[ k ∈ Fin m ] combine j k ≡ i
659+
combine-surjective {n} {m} i with remQuot {n} m i | P.inspect (remQuot {n} m) i
660+
... | j , k | P.[ eq ] = j , k , (begin
661+
combine j k ≡˘⟨ uncurry (cong₂ combine) (,-injective eq) ⟩
662+
uncurry combine (remQuot {n} m i) ≡⟨ combine-remQuot {n} m i ⟩
663+
i ∎)
664+
where open ≡-Reasoning
665+
573666
------------------------------------------------------------------------
574667
-- Bundles
575668

0 commit comments

Comments
 (0)