Skip to content

Commit 38288ae

Browse files
authored
feat: upstream List.Perm (#5069)
1 parent b939fef commit 38288ae

File tree

11 files changed

+500
-132
lines changed

11 files changed

+500
-132
lines changed

src/Init/Data/List.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ import Init.Data.List.Pairwise
2121
import Init.Data.List.Sublist
2222
import Init.Data.List.TakeDrop
2323
import Init.Data.List.Zip
24+
import Init.Data.List.Perm

src/Init/Data/List/Basic.lean

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,36 @@ theorem lookup_cons [BEq α] {k : α} :
12231223
((k,b)::es).lookup a = match a == k with | true => some b | false => es.lookup a :=
12241224
rfl
12251225

1226+
/-! ## Permutations -/
1227+
1228+
/-! ### Perm -/
1229+
1230+
/--
1231+
`Perm l₁ l₂` or `l₁ ~ l₂` asserts that `l₁` and `l₂` are permutations
1232+
of each other. This is defined by induction using pairwise swaps.
1233+
-/
1234+
inductive Perm : List α → List α → Prop
1235+
/-- `[] ~ []` -/
1236+
| nil : Perm [] []
1237+
/-- `l₁ ~ l₂ → x::l₁ ~ x::l₂` -/
1238+
| cons (x : α) {l₁ l₂ : List α} : Perm l₁ l₂ → Perm (x :: l₁) (x :: l₂)
1239+
/-- `x::y::l ~ y::x::l` -/
1240+
| swap (x y : α) (l : List α) : Perm (y :: x :: l) (x :: y :: l)
1241+
/-- `Perm` is transitive. -/
1242+
| trans {l₁ l₂ l₃ : List α} : Perm l₁ l₂ → Perm l₂ l₃ → Perm l₁ l₃
1243+
1244+
@[inherit_doc] scoped infixl:50 " ~ " => Perm
1245+
1246+
/-! ### isPerm -/
1247+
1248+
/--
1249+
`O(|l₁| * |l₂|)`. Computes whether `l₁` is a permutation of `l₂`. See `isPerm_iff` for a
1250+
characterization in terms of `List.Perm`.
1251+
-/
1252+
def isPerm [BEq α] : List α → List α → Bool
1253+
| [], l₂ => l₂.isEmpty
1254+
| a :: l₁, l₂ => l₂.contains a && l₁.isPerm (l₂.erase a)
1255+
12261256
/-! ## Logical operations -/
12271257

12281258
/-! ### any -/

0 commit comments

Comments
 (0)