module MatrixNormalization.Props where open import Level using (Level; _⊔_) renaming (zero to lzero) open import Function open import Data.Empty open import Data.Unit.Polymorphic open import Data.Product open import Data.Sum open import Data.Sum.Relation.Binary.LeftOrder hiding (⊎-<-strictTotalOrder) open import Data.Sum.Relation.Binary.Pointwise open import Relation.Unary.Consequences open import Data.Bool open import Data.Nat as ℕ hiding (_⊔_; _^_) open import Data.Nat.Properties as ℕ hiding (<⇒≢) open import Data.Fin as F open import Data.Fin.Properties as F open import Data.Vec open import Data.Vec.Recursive using (_^_) open import Relation.Binary open import Relation.Binary.PropositionalEquality as PE open import Relation.Binary.Definitions open import Relation.Binary.Construct.Never open import Relation.Binary.Construct.Always as Aw using (Always) open import Relation.Nullary.Decidable import Never as N open import LeftOrder open import MatrixNormalization.FinProps open import lbry open FinProps private variable m n : ℕ ℓ′ ℓ′′ ℓ′′′ : Level C : Set ℓ′ getTupleVec : (xs : Vec C n) (i j : Fin n) → C ^ 2 getTupleVec xs i j = lookup xs i , lookup xs j module PropNorm {c ℓ₁ ℓ₂} (rel : StrictTotalOrder c ℓ₁ ℓ₂) where open module A' = StrictTotalOrder rel renaming (Carrier to A') A-strictTotalOrder : StrictTotalOrder _ _ _ A-strictTotalOrder = ⊎-<-strictTotalOrder {e = ℓ₂} {f = ℓ₂} rel (N.strictTotalOrder _ _) open module A = StrictTotalOrder A-strictTotalOrder renaming (Carrier to A; _<_ to _A<_) public _A>_ = flip _A<_ _⊎<_ : Rel A _ _⊎<_ = A'._<_ ⊎-< (Always {ℓ = ℓ₂}) _⊎>_ = flip _⊎<_ Never→Always : ∀ {p q} → p A< q → p ⊎< q Never→Always ₁∼₂ = ₁∼₂ Never→Always (₁∼₁ x∼y) = ₁∼₁ x∼y _≈≡_ : (p q : A) → _ _≈≡_ = Pointwise A'._≈_ _≡_ _⊎≤_ : Rel A _ p ⊎≤ q = (p A< q) ⊎ (p ≈≡ q) _⊎≥_ = flip _⊎≤_ trans<< : ∀ {p q r} → p ⊎< q → q ⊎< r → p ⊎< r trans<< {p} {q} {r} = ⊎-<-transitive A'.trans (Aw.trans _ _ {p} {q} {r}) trans≈≡< : ∀ {p q r} → p ≈≡ q → q ⊎< r → p ⊎< r trans≈≡< (inj₁ p≈q) ₁∼₂ = ₁∼₂ trans≈≡< (inj₁ p≈q) (₁∼₁ q∼r) = ₁∼₁ (A'.<-respˡ-≈ (IsEquivalence.sym A'.isEquivalence p≈q) q∼r) trans≈≡< (inj₂ refl) q<r = q<r TriSet : (p q : A) → Set _ TriSet p q = Tri (p A< q) (p ≈≡ q) (p A> q) normTwoVectors' : {p q : A} → TriSet p q → A ^ 2 → Set (c ⊔ ℓ₂) normTwoVectors' {p} {q} (tri< _ _ _) (r , s) = r ≡ p × s ≡ q normTwoVectors' {p} {q} (tri≈ _ _ _) (r , s) = r ≡ p × s ⊎> q normTwoVectors' {p} {q} (tri> _ _ _) (r , s) = r ≡ q × s ≡ p trichotmous-⊎-< : Trichotomous (Pointwise A'._≈_ _≡_) (A'._<_ ⊎-< (Never {ℓ′} {ℓ′′})) trichotmous-⊎-< = ⊎-<-trichotomous A'.compare (N.trichotomous _ _) normTwoVectors : Rel (A ^ 2) (c ⊔ ℓ₂) normTwoVectors (p , q) = normTwoVectors' (trichotmous-⊎-< p q) normalizeTwoLines : ∀ (i j : Fin n) → .(i ≢ j) → Rel (Vec A n) _ normalizeTwoLines {n} i j i≢j xs ys = sameDifferent × normTwoVectors (getTupleVec xs i j) (getTupleVec ys i j) where sameDifferent : Set _ sameDifferent = ∀ k → k ≢ i → k ≢ j → lookup xs k ≡ lookup ys k linesBeforeINormalized : (i : Fin n) → Vec A n → Set (c ⊔ ℓ₂) linesBeforeINormalized i xs = ∀ j → j F.≤ i → ∀ k → k F.> j → lookup xs j ⊎< lookup xs k allLinesNormalized : Vec A n → Set _ allLinesNormalized xs = ∀ i j → i F.< j → lookup xs i ⊎< lookup xs j allLinesNonZero : Vec A n → Set _ allLinesNonZero xs = ∀ i → IsInj₁ (lookup xs i) allLinesNonZeroAndNorm : Vec A n → Set _ allLinesNonZeroAndNorm xs = allLinesNonZero xs × allLinesNormalized xs linesBeforeMaximum→allLinesNorm : ∀ xs → linesBeforeINormalized {suc n} (fromℕ n) xs → allLinesNormalized xs linesBeforeMaximum→allLinesNorm xs p i j i<j = p i (≤fromℕ _) j i<j linesNormalizedBeforeIJ : (i j : Fin n) .(i≤j : i F.≤ j) → Vec A n → Set _ linesNormalizedBeforeIJ i j i<j xs = (∀ h → h F.< i → ∀ k → h F.< k → lookup xs h ⊎< lookup xs k) × (∀ k → i F.< k → k F.≤ j → lookup xs i ⊎< lookup xs k) linesNormalizedBeforeIJ++ : ∀ i j .(i≤j : i F.≤ j) (xs : Vec A (suc n)) ys → linesNormalizedBeforeIJ i (inject₁ j) (cong≤ʳ (sym (toℕ-inject₁ _)) i≤j) xs → normalizeTwoLines i (suc j) (<⇒≢ (s≤s i≤j)) xs ys → linesNormalizedBeforeIJ i (suc j) (m≤n⇒m≤1+n i≤j) ys proj₁ (linesNormalizedBeforeIJ++ i j i≤j xs ys (bef , after) (sameDiff , cases)) h h<i k h<k rewrite sym (sameDiff h (<⇒≢ h<i) (<⇒≢ (<-≤-trans h<i (m≤n⇒m≤1+n (dec⇒recomputable (F._≤?_ _) i≤j))))) with A.compare (lookup xs i) (lookup xs (suc j)) | k F.≟ i | k F.≟ suc j ... | tri< a ¬b ¬c | yes refl | _ rewrite cases .proj₁ = bef _ h<i _ h<i ... | tri< a ¬b ¬c | no k≢i | yes refl rewrite cases .proj₂ = bef _ h<i _ h<k ... | tri< a ¬b ¬c | no k≢i | no k≢sj rewrite sym (sameDiff _ k≢i k≢sj) = bef h h<i k h<k ... | tri≈ ¬a b ¬c | yes refl | _ rewrite cases .proj₁ = bef _ h<i _ h<i ... | tri≈ ¬a b ¬c | no k≢i | yes refl = trans<< (bef _ h<i _ h<k) (cases .proj₂) ... | tri≈ ¬a b ¬c | no k≢i | no k≢sj rewrite sym (sameDiff _ k≢i k≢sj) = bef _ h<i _ h<k ... | tri> ¬a ¬b c | p | yes refl rewrite cases .proj₂ = bef _ h<i _ h<i ... | tri> ¬a ¬b c | yes refl | no k≢sj rewrite cases .proj₁ = bef _ h<k _ (s≤s (<⇒≤ (<-≤-trans h<k (dec⇒recomputable (F._≤?_ _) i≤j)))) ... | tri> ¬a ¬b c | no k≢i | no k≢sj rewrite sym (sameDiff _ k≢i k≢sj) = bef _ h<i _ h<k proj₂ (linesNormalizedBeforeIJ++ i j i≤j xs ys (bef , after) (sameDiff , cases)) k i<k k≤sj with A.compare (lookup xs i) (lookup xs (suc j)) | k F.≟ suc j ... | tri< a ¬b ¬c | yes refl rewrite cases .proj₁ | cases .proj₂ = Never→Always a ... | tri< a ¬b ¬c | no k≢sj rewrite cases .proj₁ | sym (sameDiff _ (<⇒≢ i<k ∘ sym) k≢sj) = after _ i<k (cong≤ʳ (sym (toℕ-inject₁ _)) (≤∧s≢⇒≤ k≤sj λ p → k≢sj (toℕ-injective p))) ... | tri≈ ¬a b ¬c | yes refl rewrite cases .proj₁ = trans≈≡< b (cases .proj₂) ... | tri≈ ¬a b ¬c | no k≢sj rewrite cases .proj₁ | sym (sameDiff _ (<⇒≢ i<k ∘ sym) k≢sj) = after _ i<k (cong≤ʳ (sym (toℕ-inject₁ _)) (≤∧s≢⇒≤ k≤sj λ p → k≢sj (toℕ-injective p))) ... | tri> ¬a ¬b c | yes refl rewrite cases .proj₁ | cases .proj₂ = Never→Always c ... | tri> ¬a ¬b c | no k≢sj rewrite cases .proj₁ | sym (sameDiff _ (<⇒≢ i<k ∘ sym) k≢sj) = trans<< (Never→Always c) (after _ i<k (cong≤ʳ (sym (toℕ-inject₁ _)) (≤∧s≢⇒≤ k≤sj λ p → k≢sj (toℕ-injective p)))) linesIJ→I : ∀ i (xs : Vec A (suc n)) → linesNormalizedBeforeIJ i (fromℕ _) (≤fromℕ i) xs → linesBeforeINormalized i xs linesIJ→I i xs (normBef , normAfter) j j≤i k k>j with j F.≟ i ... | yes refl = normAfter _ k>j (≤fromℕ _) ... | no j≢i = normBef j (F.≤∧≢⇒< j≤i j≢i) k k>j norm00 : (xs : Vec A (suc n)) → linesNormalizedBeforeIJ zero zero z≤n xs proj₁ (norm00 xs) _ () _ _ proj₂ (norm00 xs) zero () z≤n proj₂ (norm00 xs) (suc k) (s≤s _) () normII : ∀ i (xs : Vec A (suc n)) → linesBeforeINormalized (inject₁ i) xs → linesNormalizedBeforeIJ (suc i) (suc i) F.≤-refl xs proj₁ (normII i xs p) h (s≤s h<si) k h<k = p _ (cong≤ʳ (sym (toℕ-inject₁ _)) h<si) _ h<k proj₂ (normII i xs p) k i<k k≤i = ⊥-elim (F.<-asym i<k (F.≤∧≢⇒< k≤i (<⇒≢ i<k ∘ sym))) finProps : FinProps (Vec A (suc n)) n Pij finProps = linesNormalizedBeforeIJ Pi finProps = linesBeforeINormalized P finProps = allLinesNormalized Pab finProps = normalizeTwoLines Pij→Pi finProps = linesIJ→I Pi→P finProps = linesBeforeMaximum→allLinesNorm Pi→Pii finProps = normII Ps finProps = linesNormalizedBeforeIJ++ P00 finProps = norm00