-
Notifications
You must be signed in to change notification settings - Fork 248
Proved sorted permutations are equal #2748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
injective⇒nonStrictlyContractive : ∀ (f : Fin n → Fin m) → Injective _≡_ _≡_ f → | ||
∀ i → ¬ (∀ j → j ≤ i → f j < i) | ||
injective⇒nonStrictlyContractive f f-injective i j≤i⇒fj<i = | ||
ℕ.n≮n (toℕ i) (injective⇒≤ h-injective) | ||
where | ||
h : Fin′ (suc i) → Fin′ i | ||
h k = lower (f (inject! k)) (j≤i⇒fj<i _ (ℕ.s≤s⁻¹ (inject!-< k))) | ||
|
||
h-injective : Injective _≡_ _≡_ h | ||
h-injective = inject!-injective ∘ f-injective ∘ lower-injective _ _ | ||
|
||
injective⇒existsPivot : ∀ (f : Fin n → Fin m) → Injective _≡_ _≡_ f → | ||
∀ (i : Fin n) → ∃ λ (j : Fin n) → j ≤ i × i ≤ f j | ||
injective⇒existsPivot {n = suc n} f f-injective i with any? (λ j → j ≤? i ×-dec i ≤? f j) | ||
... | yes result = result | ||
... | no ¬result = contradiction | ||
strictlyContractive | ||
(injective⇒nonStrictlyContractive f f-injective i) | ||
where | ||
strictlyContractive : ∀ j → j ≤ i → f j < i | ||
strictlyContractive j j≤i with i ≤? f j | ||
... | yes i≤fj = contradiction (j , j≤i , i≤fj) ¬result | ||
... | no i≰fj = ℕ.≰⇒> i≰fj | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Downstream, after resolving the issues around #2744, I'd hope that these could be read off from a single appeal to min?
to construct a suitable minimal counterexample (for existsPivot
) or else rule out the Universal
case branch by contradiction with nonStrictlyContractive
. See also #2746 for the use of pigeonhole
to prove injective⇒≤
, so some simplification in the proof of nonStrictlyContractive
might also be possible?
inject!-< : (k : Fin′ i) → inject! k < i | ||
lower-injective : lower i i<n ≡ lower j j<n → i ≡ j | ||
injective⇒nonStrictlyContractive : ∀ (f : Fin n → Fin m) → Injective _≡_ _≡_ f → ∀ i → ¬ (∀ j → j ≤ i → f j < i) | ||
injective⇒existsPivot : ∀ (f : Fin n → Fin m) → Injective _≡_ _≡_ f → ∀ (i : Fin n) → ∃ λ (j : Fin n) → j ≤ i × i ≤ f j |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any particular reason (beyond 'redundant' documentation for the sake of the reader) to include the types of i
and j
here? They're inferrable form the declared type of f
, or not?
@@ -121,6 +121,10 @@ lower₁ {zero} zero ne = contradiction refl ne | |||
lower₁ {suc n} zero _ = zero | |||
lower₁ {suc n} (suc i) ne = suc (lower₁ i (ne ∘ cong suc)) | |||
|
|||
lower : ∀ (i : Fin m) → .(toℕ i ℕ.< n) → Fin n |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As on previous iterations: suggest deprecating/redefining lower₁
in terms of this new definition, to avoid redundant duplication?
UPDATED: oh, I see... it would involve importing Data.Nat.Properties
in order to fix up the precondition, and that might be considered A Bad Thing...
∀ {i j} → toℕ i ≡ toℕ j → | ||
lookup ys j ≤ lookup xs i | ||
↗↭↗⇒≤ {xs} {ys} xs↭ys xs↗ ys↗ {i} {j} i≡j | ||
with Fin.injective⇒existsPivot _ (inverseʳ⇒injective _ (Inverse.inverseʳ (toFin xs↭ys))) i |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with Fin.injective⇒existsPivot _ (inverseʳ⇒injective _ (Inverse.inverseʳ (toFin xs↭ys))) i | |
with Fin.injective⇒existsPivot _ (inverseʳ⇒injective _ (Inverse.inverseʳ (onIndices xs↭ys))) i |
???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, there's no need for with
here: the pattern is irrefutable, and computable with a pattern-matching let
, so...
with Fin.injective⇒existsPivot _ (inverseʳ⇒injective _ (Inverse.inverseʳ (toFin xs↭ys))) i | ||
... | (k , k≤i , i≤π[k]) = begin | ||
lookup ys j ≤⟨ lookup-mono-≤ O ys↗ (P.subst (ℕ._≤ _) i≡j i≤π[k]) ⟩ | ||
lookup ys (toFin xs↭ys ⟨$⟩ʳ k) ≈⟨ toFin-lookup xs↭ys k ⟨ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
lookup ys (toFin xs↭ys ⟨$⟩ʳ k) ≈⟨ toFin-lookup xs↭ys k ⟨ | |
lookup ys (onIndices xs↭ys ⟨$⟩ʳ k) ≈⟨ onIndices-lookup xs↭ys k ⟨ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Various nitpicks and bugfixes suggested, but otherwise: good to go!
lower {suc _} {suc n} zero leq = zero | ||
lower {suc _} {suc n} (suc i) leq = suc (lower i (ℕ.s≤s⁻¹ leq)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lower {suc _} {suc n} zero leq = zero | |
lower {suc _} {suc n} (suc i) leq = suc (lower i (ℕ.s≤s⁻¹ leq)) | |
lower {n = suc _} zero leq = zero | |
lower {n = suc _} (suc i) leq = suc (lower i (ℕ.s≤s⁻¹ leq)) |
I don't think there's any need to involve the m
binding in the definition, and named telescopes are (typically) more robust in the face of modifications to variable
declarations etc.
lower-injective {suc _} {suc n} zero zero eq = refl | ||
lower-injective {suc _} {suc n} (suc i) (suc j) eq = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto re: avoiding the m
binding
lower-injective {suc _} {suc n} zero zero eq = refl | |
lower-injective {suc _} {suc n} (suc i) (suc j) eq = | |
lower-injective {n = suc n} zero zero eq = refl | |
lower-injective {n = suc n} (suc i) (suc j) eq = |
``` | ||
|
||
* In `Data.Fin.Permutation`: | ||
```agda | ||
cast-id : .(m ≡ n) → Permutation m n | ||
swap : Permutation m n → Permutation (suc (suc m)) (suc (suc n)) | ||
inject!-injective : swap : Permutation m n → Permutation (suc (suc m)) (suc (suc n)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happened here?
The main result. Would like to try and sneak this into v2.3 for @onestruggler.
Have also added an explanation of the choice of propositional permutation in
SortingAlgorithm
and a lemma that proves the setoid version.