@@ -5,7 +5,7 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M
5
5
6
6
Basic properties of lists.
7
7
-/
8
- import logic.basic data.nat.basic data.option data.bool
8
+ import logic.basic data.nat.basic data.option data.bool data.prod
9
9
tactic.interactive algebra.group
10
10
open function nat
11
11
@@ -923,6 +923,15 @@ by induction l; simp [list.join, *] at *
923
923
924
924
end monoid
925
925
926
+ @[simp] theorem sum_const_nat (m n : ℕ) : sum (list.repeat m n) = m * n :=
927
+ by induction n; simp [*, nat.mul_succ]
928
+
929
+ @[simp] theorem length_join (L : list (list α)) : length (join L) = sum (map length L) :=
930
+ by induction L; simp *
931
+
932
+ @[simp] theorem length_bind (l : list α) (f : α → list β) : length (bind l f) = sum (map (length ∘ f) l) :=
933
+ by rw [bind, length_join, map_map]
934
+
926
935
/- all & any, bounded quantifiers over lists -/
927
936
928
937
theorem forall_mem_nil (p : α → Prop ) : ∀ x ∈ @nil α, p x :=
@@ -1517,36 +1526,47 @@ def transpose : list (list α) → list (list α)
1517
1526
1518
1527
/- permutations -/
1519
1528
1520
- def permutations_aux2 (t : α) (ts : list α) : list α → (list α → β) → list β → list α × list β
1521
- | [] f r := (ts, r)
1522
- | (y::ys) f r := let (us, zs) := permutations_aux2 ys (λx : list α, f (y::x)) r in
1523
- (y :: us, f (t :: y :: us) :: zs)
1529
+ section permutations
1524
1530
1525
- private def meas : list α × list α → ℕ × ℕ | (l, i) := (length l + length i, length l)
1531
+ def permutations_aux2 (t : α) (ts : list α) (r : list β) : list α → (list α → β) → list α × list β
1532
+ | [] f := (ts, r)
1533
+ | (y::ys) f := let (us, zs) := permutations_aux2 ys (λx : list α, f (y::x)) in
1534
+ (y :: us, f (t :: y :: us) :: zs)
1526
1535
1527
- local infix ` ≺ `: 50 := inv_image (prod.lex (<) (<)) meas
1536
+ private def meas : (Σ'_:list α, list α) → ℕ × ℕ | ⟨l, i⟩ := (length l + length i, length l)
1528
1537
1529
- def permutations_aux.F : Π (x : list α × list α), (Π (y : list α × list α), y ≺ x → list (list α)) → list (list α)
1530
- | ([], is) IH := []
1531
- | (t::ts, is) IH :=
1532
- have h1 : (ts, t :: is) ≺ (t :: ts, is), from
1533
- show prod.lex _ _ (succ (length ts + length is), length ts) (succ (length ts) + length is, length (t :: ts)),
1534
- by rw nat.succ_add; exact prod.lex.right _ _ (lt_succ_self _),
1535
- have h2 : (is, []) ≺ (t :: ts, is), from prod.lex.left _ _ _ (lt_add_of_pos_left _ (succ_pos _)),
1536
- foldr (λy r, (permutations_aux2 t ts y id r).2 ) (IH (ts, t::is) h1) (is :: IH (is, []) h2)
1538
+ local infix ` ≺ `:50 := inv_image (prod.lex (<) (<)) meas
1537
1539
1538
- def permutations_aux : list α × list α → list (list α) :=
1539
- well_founded.fix (inv_image.wf meas (prod.lex_wf lt_wf lt_wf)) permutations_aux.F
1540
+ @[elab_as_eliminator] def permutations_aux.rec {C : list α → list α → Sort v}
1541
+ (H0 : ∀ is, C [] is)
1542
+ (H1 : ∀ t ts is, C ts (t::is) → C is [] → C (t::ts) is) : ∀ l₁ l₂, C l₁ l₂
1543
+ | [] is := H0 is
1544
+ | (t::ts) is :=
1545
+ have h1 : ⟨ts, t :: is⟩ ≺ ⟨t :: ts, is⟩, from
1546
+ show prod.lex _ _ (succ (length ts + length is), length ts) (succ (length ts) + length is, length (t :: ts)),
1547
+ by rw nat.succ_add; exact prod.lex.right _ _ (lt_succ_self _),
1548
+ have h2 : ⟨is, []⟩ ≺ ⟨t :: ts, is⟩, from prod.lex.left _ _ _ (lt_add_of_pos_left _ (succ_pos _)),
1549
+ H1 t ts is (permutations_aux.rec ts (t::is)) (permutations_aux.rec is [])
1550
+ using_well_founded {
1551
+ dec_tac := tactic.assumption,
1552
+ rel_tac := λ _ _, `[exact ⟨(≺), @inv_image.wf _ _ _ meas (prod.lex_wf lt_wf lt_wf)⟩] }
1553
+
1554
+ def permutations_aux : list α → list α → list (list α) :=
1555
+ @@permutations_aux.rec (λ _ _, list (list α)) (λ is, [])
1556
+ (λ t ts is IH1 IH2, foldr (λy r, (permutations_aux2 t ts r y id).2 ) IH1 (is :: IH2))
1540
1557
1541
1558
def permutations (l : list α) : list (list α) :=
1542
- l :: permutations_aux (l, [])
1559
+ l :: permutations_aux l []
1560
+
1561
+ @[simp] theorem permutations_aux_nil (is : list α) : permutations_aux [] is = [] :=
1562
+ by simp [permutations_aux, permutations_aux.rec]
1543
1563
1544
- def permutations_aux.eqn_1 (is : list α) : permutations_aux ([], is) = [] :=
1545
- well_founded.fix_eq _ _ _
1564
+ @[simp] theorem permutations_aux_cons (t : α) (ts is : list α) :
1565
+ permutations_aux (t :: ts) is = foldr (λy r, (permutations_aux2 t ts r y id).2 )
1566
+ (permutations_aux ts (t::is)) (permutations is) :=
1567
+ by simp [permutations_aux, permutations_aux.rec, permutations]
1546
1568
1547
- def permutations_aux.eqn_2 (t : α) (ts is) : permutations_aux (t::ts, is) =
1548
- foldr (λy r, (permutations_aux2 t ts y id r).2 ) (permutations_aux (ts, t::is)) (permutations is) :=
1549
- well_founded.fix_eq _ _ _
1569
+ end permutations
1550
1570
1551
1571
/- insert -/
1552
1572
section insert
@@ -1652,15 +1672,16 @@ theorem erase_sublist_erase (a : α) : ∀ {l₁ l₂ : list α}, l₁ <+ l₂
1652
1672
then by rw [h, erase_cons_head, erase_cons_head]; exact s
1653
1673
else by rw [erase_cons_tail _ h, erase_cons_tail _ h]; exact (erase_sublist_erase s).cons2 _ _ _
1654
1674
1655
- theorem mem_erase_of_ne_of_mem {a b : α} {l : list α} (ab : a ≠ b) (al : a ∈ l) : a ∈ l.erase b :=
1656
- if h : b ∈ l then match l, l.erase b, exists_erase_eq h, al with
1657
- | ._, ._, ⟨l₁, l₂, _, rfl, rfl⟩, al :=
1658
- by simp at *; exact or.resolve_left al ab
1659
- end else by simp [h, al]
1660
-
1661
1675
theorem mem_of_mem_erase {a b : α} {l : list α} : a ∈ l.erase b → a ∈ l :=
1662
1676
@erase_subset _ _ _ _ _
1663
1677
1678
+ @[simp] theorem mem_erase_of_ne {a b : α} {l : list α} (ab : a ≠ b) : a ∈ l.erase b ↔ a ∈ l :=
1679
+ ⟨mem_of_mem_erase, λ al,
1680
+ if h : b ∈ l then match l, l.erase b, exists_erase_eq h, al with
1681
+ | ._, ._, ⟨l₁, l₂, _, rfl, rfl⟩, al :=
1682
+ by simp at *; exact or.resolve_left al ab
1683
+ end else by simp [h, al]⟩
1684
+
1664
1685
theorem erase_comm (a b : α) (l : list α) : (l.erase a).erase b = (l.erase b).erase a :=
1665
1686
if ab : a = b then by simp [ab] else
1666
1687
if ha : a ∈ l then
@@ -1932,6 +1953,40 @@ ball.imp_left (λ x, mem_of_mem_inter_right) h
1932
1953
1933
1954
end inter
1934
1955
1956
+ /- bag_inter -/
1957
+ section bag_inter
1958
+ variable [decidable_eq α]
1959
+
1960
+ @[simp] theorem nil_bag_inter (l : list α) : [].bag_inter l = [] :=
1961
+ by cases l; refl
1962
+
1963
+ @[simp] theorem bag_inter_nil (l : list α) : l.bag_inter [] = [] :=
1964
+ by cases l; refl
1965
+
1966
+ @[simp] theorem cons_bag_inter_of_pos {a} (l₁ : list α) {l₂} (h : a ∈ l₂) :
1967
+ (a :: l₁).bag_inter l₂ = a :: l₁.bag_inter (l₂.erase a) :=
1968
+ by cases l₂; exact if_pos h
1969
+
1970
+ @[simp] theorem cons_bag_inter_of_neg {a} (l₁ : list α) {l₂} (h : a ∉ l₂) :
1971
+ (a :: l₁).bag_inter l₂ = l₁.bag_inter l₂ :=
1972
+ by cases l₂; simp [h, list.bag_inter]
1973
+
1974
+ theorem mem_bag_inter {a : α} : ∀ {l₁ l₂ : list α}, a ∈ l₁.bag_inter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
1975
+ | [] l₂ := by simp
1976
+ | (b::l₁) l₂ := by
1977
+ by_cases b ∈ l₂; simp [*, and_or_distrib_left];
1978
+ by_cases a = b with ba; simp *
1979
+
1980
+ theorem bag_inter_sublist_left : ∀ l₁ l₂ : list α, l₁.bag_inter l₂ <+ l₁
1981
+ | [] l₂ := by simp [nil_sublist]
1982
+ | (b::l₁) l₂ := begin
1983
+ by_cases b ∈ l₂; simp [h],
1984
+ { apply cons_sublist_cons, apply bag_inter_sublist_left },
1985
+ { apply sublist_cons_of_sublist, apply bag_inter_sublist_left }
1986
+ end
1987
+
1988
+ end bag_inter
1989
+
1935
1990
/- pairwise relation (generalized no duplicate) -/
1936
1991
1937
1992
section pairwise
@@ -2483,6 +2538,10 @@ theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤
2483
2538
(mem_range'.1 $ h $ mem_range'.2 ⟨le_add_right _ _, nat.add_lt_add_left hn s⟩).2 ,
2484
2539
λ h, subset_of_sublist (range'_sublist_right.2 h)⟩
2485
2540
2541
+ theorem nth_range' : ∀ s {m n : ℕ}, m < n → nth (range' s n) m = some (s + m)
2542
+ | s 0 (n+1 ) _ := by simp
2543
+ | s (m+1 ) (n+1 ) h := by simp [nth_range' (s+1 ) (lt_of_add_lt_add_right h)]
2544
+
2486
2545
theorem range'_concat (s n : ℕ) : range' s (n + 1 ) = range' s n ++ [s+n] :=
2487
2546
by rw add_comm n 1 ; exact (range'_append s n 1 ).symm
2488
2547
@@ -2514,6 +2573,9 @@ by simp [range_eq_range', zero_le]
2514
2573
@[simp] theorem not_mem_range_self {n : ℕ} : n ∉ range n :=
2515
2574
mt mem_range.1 $ lt_irrefl _
2516
2575
2576
+ theorem nth_range {m n : ℕ} (h : m < n) : nth (range n) m = some m :=
2577
+ by simp [range_eq_range', nth_range' _ h]
2578
+
2517
2579
theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
2518
2580
| 0 := rfl
2519
2581
| (n+1 ) := by simp [iota, range'_concat, iota_eq_reverse_range' n]
0 commit comments