@@ -8,7 +8,7 @@ Basic properties of lists.
8
8
import
9
9
tactic.interactive tactic.mk_iff_of_inductive_prop tactic.split_ifs
10
10
logic.basic logic.function logic.relation
11
- algebra.group
11
+ algebra.group order.basic
12
12
data.nat.basic data.option data.bool data.prod data.sigma data.fin
13
13
open function nat
14
14
@@ -352,12 +352,12 @@ by induction l₂ with b l₂ ih; simp
352
352
353
353
local attribute [simp] reverse_core
354
354
355
- @[simp] theorem reverse_cons (a : α) (l : list α) : reverse (a::l) = concat ( reverse l) a :=
356
- have aux : ∀ l₁ l₂, reverse_core l₁ (concat l₂ a) = concat ( reverse_core l₁ l₂) a ,
357
- by intros l₁; induction l₁; intros; rsimp ,
358
- aux l nil
355
+ @[simp] theorem reverse_cons (a : α) (l : list α) : reverse (a::l) = reverse l ++ [a] :=
356
+ have aux : ∀ l₁ l₂, reverse_core l₁ l₂ ++ [a] = reverse_core l₁ (l₂ ++ [a]) ,
357
+ by intro l₁; induction l₁; simp * ,
358
+ ( aux l nil).symm
359
359
360
- theorem reverse_cons' (a : α) (l : list α) : reverse (a::l) = reverse l ++ [a] :=
360
+ theorem reverse_cons' (a : α) (l : list α) : reverse (a::l) = concat ( reverse l) a :=
361
361
by simp
362
362
363
363
@[simp] theorem reverse_singleton (a : α) : reverse [a] = [a] := rfl
@@ -1085,6 +1085,133 @@ by induction L; simp *
1085
1085
@[simp] theorem length_bind (l : list α) (f : α → list β) : length (list.bind l f) = sum (map (length ∘ f) l) :=
1086
1086
by rw [list.bind, length_join, map_map]
1087
1087
1088
+ /- lexicographic ordering -/
1089
+
1090
+ inductive lex (r : α → α → Prop ) : list α → list α → Prop
1091
+ | nil {} {a l} : lex [] (a :: l)
1092
+ | cons {a l₁ l₂} (h : lex l₁ l₂) : lex (a :: l₁) (a :: l₂)
1093
+ | rel {a₁ l₁ a₂ l₂} (h : r a₁ a₂) : lex (a₁ :: l₁) (a₂ :: l₂)
1094
+
1095
+ namespace lex
1096
+ theorem cons_iff {r : α → α → Prop } [is_irrefl α r] {a l₁ l₂} :
1097
+ lex r (a :: l₁) (a :: l₂) ↔ lex r l₁ l₂ :=
1098
+ ⟨λ h, by cases h with _ _ _ _ _ h _ _ _ _ h;
1099
+ [exact h, exact (irrefl_of r a h).elim], lex.cons⟩
1100
+
1101
+ instance is_order_connected (r : α → α → Prop )
1102
+ [is_order_connected α r] [is_trichotomous α r] :
1103
+ is_order_connected (list α) (lex r) :=
1104
+ ⟨λ l₁, match l₁ with
1105
+ | _, [], c::l₃, nil := or.inr nil
1106
+ | _, [], c::l₃, rel _ := or.inr nil
1107
+ | _, [], c::l₃, cons _ := or.inr nil
1108
+ | _, b::l₂, c::l₃, nil := or.inl nil
1109
+ | a::l₁, b::l₂, c::l₃, rel h :=
1110
+ (is_order_connected.conn _ b _ h).imp rel rel
1111
+ | a::l₁, b::l₂, _::l₃, cons h := begin
1112
+ rcases trichotomous_of r a b with ab | rfl | ab,
1113
+ { exact or.inl (rel ab) },
1114
+ { exact (_match _ l₂ _ h).imp cons cons },
1115
+ { exact or.inr (rel ab) }
1116
+ end
1117
+ end ⟩
1118
+
1119
+ instance is_trichotomous (r : α → α → Prop ) [is_trichotomous α r] :
1120
+ is_trichotomous (list α) (lex r) :=
1121
+ ⟨λ l₁, match l₁ with
1122
+ | [], [] := or.inr (or.inl rfl)
1123
+ | [], b::l₂ := or.inl nil
1124
+ | a::l₁, [] := or.inr (or.inr nil)
1125
+ | a::l₁, b::l₂ := begin
1126
+ rcases trichotomous_of r a b with ab | rfl | ab,
1127
+ { exact or.inl (rel ab) },
1128
+ { exact (_match l₁ l₂).imp cons
1129
+ (or.imp (congr_arg _) cons) },
1130
+ { exact or.inr (or.inr (rel ab)) }
1131
+ end
1132
+ end ⟩
1133
+
1134
+ instance is_asymm (r : α → α → Prop )
1135
+ [is_asymm α r] : is_asymm (list α) (lex r) :=
1136
+ ⟨λ l₁, match l₁ with
1137
+ | a::l₁, b::l₂, lex.rel h₁, lex.rel h₂ := asymm h₁ h₂
1138
+ | a::l₁, b::l₂, lex.rel h₁, lex.cons h₂ := asymm h₁ h₁
1139
+ | a::l₁, b::l₂, lex.cons h₁, lex.rel h₂ := asymm h₂ h₂
1140
+ | a::l₁, b::l₂, lex.cons h₁, lex.cons h₂ :=
1141
+ by exact _match _ _ h₁ h₂
1142
+ end ⟩
1143
+
1144
+ instance is_strict_total_order (r : α → α → Prop )
1145
+ [is_strict_total_order' α r] : is_strict_total_order' (list α) (lex r) :=
1146
+ {..is_strict_weak_order_of_is_order_connected}
1147
+
1148
+ instance decidable_rel [decidable_eq α] (r : α → α → Prop )
1149
+ [decidable_rel r] : decidable_rel (lex r)
1150
+ | l₁ [] := is_false $ λ h, by cases h
1151
+ | [] (b::l₂) := is_true lex.nil
1152
+ | (a::l₁) (b::l₂) := begin
1153
+ haveI := decidable_rel l₁ l₂,
1154
+ refine decidable_of_iff (r a b ∨ a = b ∧ lex r l₁ l₂) ⟨λ h, _, λ h, _⟩,
1155
+ { rcases h with h | ⟨rfl, h⟩,
1156
+ { exact lex.rel h },
1157
+ { exact lex.cons h } },
1158
+ { rcases h with _|⟨_,_,_,h⟩|⟨_,_,_,_,h⟩,
1159
+ { exact or.inr ⟨rfl, h⟩ },
1160
+ { exact or.inl h } }
1161
+ end
1162
+
1163
+ theorem append_right (r : α → α → Prop ) :
1164
+ ∀ {s₁ s₂} t, lex r s₁ s₂ → lex r s₁ (s₂ ++ t)
1165
+ | _ _ t nil := nil
1166
+ | _ _ t (cons h) := cons (append_right _ h)
1167
+ | _ _ t (rel r) := rel r
1168
+
1169
+ theorem append_left (R : α → α → Prop ) {t₁ t₂} (h : lex R t₁ t₂) :
1170
+ ∀ s, lex R (s ++ t₁) (s ++ t₂)
1171
+ | [] := h
1172
+ | (a::l) := cons (append_left l)
1173
+
1174
+ theorem imp {r s : α → α → Prop } (H : ∀ a b, r a b → s a b) :
1175
+ ∀ l₁ l₂, lex r l₁ l₂ → lex s l₁ l₂
1176
+ | _ _ nil := nil
1177
+ | _ _ (cons h) := cons (imp _ _ h)
1178
+ | _ _ (rel r) := rel (H _ _ r)
1179
+
1180
+ theorem to_ne : ∀ {l₁ l₂ : list α}, lex (≠) l₁ l₂ → l₁ ≠ l₂
1181
+ | _ _ (cons h) e := to_ne h (list.cons.inj e).2
1182
+ | _ _ (rel r) e := r (list.cons.inj e).1
1183
+
1184
+ theorem ne_iff {l₁ l₂ : list α} (H : length l₁ ≤ length l₂) :
1185
+ lex (≠) l₁ l₂ ↔ l₁ ≠ l₂ :=
1186
+ ⟨to_ne, λ h, begin
1187
+ induction l₁ with a l₁ IH generalizing l₂; cases l₂ with b l₂,
1188
+ { contradiction },
1189
+ { apply nil },
1190
+ { exact (not_lt_of_ge H).elim (succ_pos _) },
1191
+ { cases classical.em (a = b) with ab ab,
1192
+ { subst b, apply cons,
1193
+ exact IH (le_of_succ_le_succ H) (mt (congr_arg _) h) },
1194
+ { exact rel ab } }
1195
+ end ⟩
1196
+
1197
+ end lex
1198
+
1199
+ -- Note: this overrides an instance in core lean
1200
+ instance has_lt' [has_lt α] : has_lt (list α) := ⟨lex (<)⟩
1201
+
1202
+ theorem nil_lt_cons [has_lt α] (a : α) (l : list α) : [] < a :: l :=
1203
+ lex.nil
1204
+
1205
+ instance [linear_order α] : linear_order (list α) :=
1206
+ linear_order_of_STO' (lex (<))
1207
+
1208
+ -- Note: this overrides an instance in core lean
1209
+ instance has_le' [linear_order α] : has_le (list α) :=
1210
+ preorder.to_has_le _
1211
+
1212
+ instance [decidable_linear_order α] : decidable_linear_order (list α) :=
1213
+ decidable_linear_order_of_STO' (lex (<))
1214
+
1088
1215
/- all & any, bounded quantifiers over lists -/
1089
1216
1090
1217
theorem forall_mem_nil (p : α → Prop ) : ∀ x ∈ @nil α, p x :=
@@ -2892,56 +3019,17 @@ theorem pairwise_iff_nth_le {R} : ∀ {l : list α},
2892
3019
exact H _ _ (succ_lt_succ h) (succ_pos _) }
2893
3020
end
2894
3021
2895
- inductive lex (R : α → α → Prop ) : list α → list α → Prop
2896
- | nil {} (a l) : lex [] (a::l)
2897
- | cons {} (a) {l l'} : lex l l' → lex (a::l) (a::l')
2898
- | rel {a a'} (l l') : R a a' → lex (a::l) (a'::l')
2899
-
2900
- theorem lex_append_right (R : α → α → Prop ) :
2901
- ∀ {s₁ s₂} t, lex R s₁ s₂ → lex R s₁ (s₂ ++ t)
2902
- | _ _ t (lex.nil a l) := lex.nil _ _
2903
- | _ _ t (lex.cons a h) := lex.cons _ (lex_append_right _ h)
2904
- | _ _ t (lex.rel _ _ r) := lex.rel _ _ r
2905
-
2906
- theorem lex_append_left (R : α → α → Prop ) {t₁ t₂} (h : lex R t₁ t₂) :
2907
- ∀ s, lex R (s ++ t₁) (s ++ t₂)
2908
- | [] := h
2909
- | (a::l) := lex.cons _ (lex_append_left l)
2910
-
2911
- theorem lex.imp {R S : α → α → Prop } (H : ∀ a b, R a b → S a b) :
2912
- ∀ l₁ l₂, lex R l₁ l₂ → lex S l₁ l₂
2913
- | _ _ (lex.nil a l) := lex.nil _ _
2914
- | _ _ (lex.cons a h) := lex.cons _ (lex.imp _ _ h)
2915
- | _ _ (lex.rel _ _ r) := lex.rel _ _ (H _ _ r)
2916
-
2917
- theorem ne_of_lex_ne : ∀ {l₁ l₂ : list α}, lex (≠) l₁ l₂ → l₁ ≠ l₂
2918
- | _ _ (lex.cons a h) e := ne_of_lex_ne h (list.cons.inj e).2
2919
- | _ _ (lex.rel _ _ r) e := r (list.cons.inj e).1
2920
-
2921
- theorem lex_ne_iff {l₁ l₂ : list α} (H : length l₁ ≤ length l₂) :
2922
- lex (≠) l₁ l₂ ↔ l₁ ≠ l₂ :=
2923
- ⟨ne_of_lex_ne, λ h, begin
2924
- induction l₁ with a l₁ IH generalizing l₂; cases l₂ with b l₂,
2925
- { contradiction },
2926
- { apply lex.nil },
2927
- { exact (not_lt_of_ge H).elim (succ_pos _) },
2928
- { cases classical.em (a = b) with ab ab,
2929
- { subst b, apply lex.cons,
2930
- exact IH (le_of_succ_le_succ H) (mt (congr_arg _) h) },
2931
- { exact lex.rel _ _ ab } }
2932
- end ⟩
2933
-
2934
3022
theorem pairwise_sublists' {R} : ∀ {l : list α}, pairwise R l →
2935
3023
pairwise (lex (swap R)) (sublists' l)
2936
3024
| _ (pairwise.nil _) := pairwise_singleton _ _
2937
3025
| _ (@pairwise.cons _ _ a l H₁ H₂) :=
2938
3026
begin
2939
3027
simp [pairwise_append, pairwise_map],
2940
3028
have IH := pairwise_sublists' H₂,
2941
- refine ⟨IH, IH.imp (λ l₁ l₂, lex.cons _ ), _⟩,
3029
+ refine ⟨IH, IH.imp (λ l₁ l₂, lex.cons), _⟩,
2942
3030
intros l₁ sl₁ x l₂ sl₂ e, subst e,
2943
3031
cases l₁ with b l₁, {constructor},
2944
- exact lex.rel _ _ (H₁ _ $ subset_of_sublist sl₁ $ mem_cons_self _ _)
3032
+ exact lex.rel (H₁ _ $ subset_of_sublist sl₁ $ mem_cons_self _ _)
2945
3033
end
2946
3034
2947
3035
theorem pairwise_sublists {R} {l : list α} (H : pairwise R l) :
@@ -3305,7 +3393,7 @@ nodup_filter _
3305
3393
3306
3394
@[simp] theorem nodup_sublists {l : list α} : nodup (sublists l) ↔ nodup l :=
3307
3395
⟨λ h, nodup_of_nodup_map _ (nodup_of_sublist (map_ret_sublist_sublists _) h),
3308
- λ h, (pairwise_sublists h).imp (λ _ _ h, mt reverse_inj.2 (ne_of_lex_ne h) )⟩
3396
+ λ h, (pairwise_sublists h).imp (λ _ _ h, mt reverse_inj.2 h.to_ne )⟩
3309
3397
3310
3398
@[simp] theorem nodup_sublists' {l : list α} : nodup (sublists' l) ↔ nodup l :=
3311
3399
by rw [sublists'_eq_sublists, nodup_map_iff reverse_injective,
0 commit comments