lean4-htt/src/Init/Data/Vector/Perm.lean
Sebastian Ullrich 09a5b34931
feat: make private the default in module (#9044)
This PR adjusts the experimental module system to make `private` the
default visibility modifier in `module`s, introducing `public` as a new
modifier instead. `public section` can be used to revert the default for
an entire section, though this is more intended to ease gradual adoption
of the new semantics such as in `Init` (and soon `Std`) where they
should be replaced by a future decl-by-decl re-review of visibilities.
2025-06-28 16:30:53 +00:00

132 lines
4.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2024 Lean FRO. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kim Morrison
-/
module
prelude
public import all Init.Data.Array.Basic
public import Init.Data.Array.Perm
public import all Init.Data.Vector.Basic
public import Init.Data.Vector.Lemmas
public section
set_option linter.listVariables true -- Enforce naming conventions for `List`/`Array`/`Vector` variables.
set_option linter.indexVariables true -- Enforce naming conventions for index variables.
namespace Vector
open List Array
/--
`Perm as bs` asserts that `as` and `bs` are permutations of each other.
This is a wrapper around `List.Perm`, and for now has much less API.
For more complicated verification, use `perm_iff_toList_perm` and the `List` API.
-/
structure Perm (as bs : Vector α n) : Prop where
of_toArray_perm ::
toArray : as.toArray ~ bs.toArray
@[inherit_doc] scoped infixl:50 " ~ " => Perm
theorem perm_iff_toArray_perm {as bs : Vector α n} : as ~ bs ↔ as.toArray ~ bs.toArray :=
⟨Perm.toArray, Perm.of_toArray_perm⟩
theorem perm_iff_toList_perm {as bs : Vector α n} : as ~ bs ↔ as.toList ~ bs.toList :=
perm_iff_toArray_perm.trans Array.perm_iff_toList_perm
theorem Perm.of_toList_perm {as bs : Vector α n} : as.toList ~ bs.toList → as ~ bs :=
perm_iff_toList_perm.mpr
theorem Perm.toList {as bs : Vector α n} : as ~ bs → as.toList ~ bs.toList :=
perm_iff_toList_perm.mp
@[simp] theorem perm_mk (as bs : Array α) (ha : as.size = n) (hb : bs.size = n) :
mk as ha ~ mk bs hb ↔ as ~ bs := by
simp [perm_iff_toArray_perm]
theorem toArray_perm_iff (xs : Vector α n) (ys : Array α) : xs.toArray ~ ys ↔ ∃ h, xs ~ Vector.mk ys h := by
constructor
· intro h
refine ⟨by simp [← h.size_eq], .of_toArray_perm h⟩
· intro ⟨h, p⟩
exact p.toArray
theorem perm_toArray_iff (xs : Array α) (ys : Vector α n) : xs ~ ys.toArray ↔ ∃ h, Vector.mk xs h ~ ys := by
constructor
· intro h
refine ⟨by simp [h.size_eq], .of_toArray_perm h⟩
· intro ⟨h, p⟩
exact p.toArray
@[simp, refl] protected theorem Perm.refl (xs : Vector α n) : xs ~ xs := by
cases xs
simp
protected theorem Perm.rfl {xs : Vector α n} : xs ~ xs := .refl _
theorem Perm.of_eq {xs ys : Vector α n} (h : xs = ys) : xs ~ ys := h ▸ .rfl
@[symm]
protected theorem Perm.symm {xs ys : Vector α n} (h : xs ~ ys) : ys ~ xs := by
cases xs; cases ys
simp only [perm_mk] at h
simpa using h.symm
protected theorem Perm.trans {xs ys zs : Vector α n} (h₁ : xs ~ ys) (h₂ : ys ~ zs) : xs ~ zs := by
cases xs; cases ys; cases zs
simp only [perm_mk] at h₁ h₂
simpa using h₁.trans h₂
instance : Trans (Perm (α := α) (n := n)) (Perm (α := α) (n := n)) (Perm (α := α) (n := n)) where
trans h₁ h₂ := Perm.trans h₁ h₂
theorem perm_comm {xs ys : Vector α n} : xs ~ ys ↔ ys ~ xs := ⟨Perm.symm, Perm.symm⟩
theorem Perm.mem_iff {a : α} {xs ys : Vector α n} (p : xs ~ ys) : a ∈ xs ↔ a ∈ ys := by
rcases xs with ⟨xs⟩
rcases ys with ⟨ys⟩
simp at p
simpa using p.mem_iff
theorem Perm.append {xs ys : Vector α m} {as bs : Vector α n}
(p₁ : xs ~ ys) (p₂ : as ~ bs) : xs ++ as ~ ys ++ bs := by
cases xs; cases ys; cases as; cases bs
simp only [perm_mk, mk_append_mk] at p₁ p₂ ⊢
exact p₁.append p₂
theorem Perm.push (x : α) {xs ys : Vector α n} (p : xs ~ ys) :
xs.push x ~ ys.push x := by
cases xs; cases ys
simp only [perm_mk, push_mk] at p ⊢
exact p.push x
theorem Perm.push_comm (x y : α) {xs ys : Vector α n} (p : xs ~ ys) :
(xs.push x).push y ~ (ys.push y).push x := by
rcases xs with ⟨xs, rfl⟩
rcases ys with ⟨ys, h⟩
simp only [perm_mk, push_mk] at p ⊢
simpa using p.push_comm x y
theorem swap_perm {xs : Vector α n} {i j : Nat} (h₁ : i < n) (h₂ : j < n) :
xs.swap i j ~ xs := by
rcases xs with ⟨xs, rfl⟩
simp only [swap, perm_iff_toList_perm]
apply set_set_perm
namespace Perm
set_option linter.indexVariables false in
theorem extract {xs ys : Vector α n} (h : xs ~ ys) {lo hi : Nat}
(wlo : ∀ i, i < lo → xs[i]? = ys[i]?) (whi : ∀ i, hi ≤ i → xs[i]? = ys[i]?) :
xs.extract lo hi ~ ys.extract lo hi := by
rcases xs with ⟨xs, rfl⟩
rcases ys with ⟨ys, h⟩
exact ⟨Array.Perm.extract h.toArray (by simpa using wlo) (by simpa using whi)⟩
end Perm
end Vector