Utils
Iterators for aggregation operations
- ∑ (i ∈ l), f i : list-based summation
- ∑ (i = b, e), f i : summation over integer ranges
Definition iter_list {A B} (l : list B) f (d : A) := List.fold_left f l d.
Definition iter_seq {T} b e f (d : T) := iter_list (List.seq b (S e - b)) f d.
Arguments iter_seq : simpl never.
Arguments iter_list : simpl never.
Theorem fold_iter_list : ∀ {A B} (f : A → B → A) l d,
List.fold_left f l d = iter_list l f d.
Theorem fold_iter_seq' : ∀ A b len f (d : A),
iter_list (List.seq b len) f d =
if b + len =? 0 then d
else iter_seq b (b + len - 1) f d.
Theorem fold_left_op_fun_from_d : ∀ {T A} d op a l (f : A → _)
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
List.fold_left (λ (c : T) i, op c (f i)) l a =
op a (List.fold_left (λ (c : T) i, op c (f i)) l d).
Theorem iter_list_op_fun_from_d : ∀ T A d op a l (f : A → _)
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
iter_list l (λ (c : T) (i : A), op c (f i)) a =
op a (iter_list l (λ (c : T) (i : A), op c (f i)) d).
Theorem iter_list_all_d : ∀ T A d op (l : list A) f
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
(∀ i, i ∈ l → f i = d)
→ iter_list l (λ (c : T) i, op c (f i)) d = d.
Theorem iter_seq_all_d : ∀ T d op b e f
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
(∀ i : nat, b ≤ i ≤ e → f i = d)
→ iter_seq b e (λ (c : T) (i : nat), op c (f i)) d = d.
Theorem iter_list_split_first : ∀ T A d op l z f
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
l ≠ []
→ iter_list l (λ (c : T) (i : A), op c (f i)) d =
op (f (List.hd z l))
(iter_list (List.tl l) (λ (c : T) (i : A), op c (f i)) d).
Theorem iter_list_split_last : ∀ T A d (op : T → T → T) l (g : A → T) z,
l ≠ []
→ iter_list l (λ c i, op c (g i)) d =
op (iter_list (List.removelast l) (λ c i, op c (g i)) d)
(g (List.last l z)).
Theorem iter_seq_split_first : ∀ T d op b k g
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
b ≤ k
→ iter_seq b k (λ (c : T) (i : nat), op c (g i)) d =
op (g b) (iter_seq (S b) k (λ (c : T) (i : nat), op c (g i)) d).
Theorem iter_seq_split_last : ∀ T d (op : T → T → T) b k g,
b ≤ k
→ iter_seq b k (λ (c : T) (i : nat), op c (g i)) d =
op (iter_seq (S b) k (λ (c : T) (i : nat), op c (g (i - 1)%nat)) d) (g k).
Theorem iter_seq_split : ∀ T d op j g b k
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
b ≤ S j ≤ S k
→ iter_seq b k (λ (c : T) (i : nat), op c (g i)) d =
op (iter_seq b j (λ (c : T) (i : nat), op c (g i)) d)
(iter_seq (j + 1) k (λ (c : T) (i : nat), op c (g i)) d).
Theorem iter_seq_split3 : ∀ T d op j g b k
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
b ≤ j ≤ k
→ iter_seq b k (λ (c : T) (i : nat), op c (g i)) d =
op (op (iter_seq (S b) j (λ (c : T) (i : nat), op c (g (i - 1))) d) (g j))
(iter_seq (j + 1) k (λ (c : T) (i : nat), op c (g i)) d).
Theorem iter_list_eq_compat : ∀ A B d (op : A → A → A) (l : list B) g h,
(∀ i, i ∈ l → g i = h i)
→ iter_list l (λ c i, op c (g i)) d =
iter_list l (λ c i, op c (h i)) d.
Theorem iter_seq_eq_compat : ∀ T d (op : T → T → T) b k g h,
(∀ i, b ≤ i ≤ k → g i = h i)
→ iter_seq b k (λ c i, op c (g i)) d =
iter_seq b k (λ c i, op c (h i)) d.
Theorem iter_seq_succ_succ : ∀ {T} (d : T) b k f,
iter_seq (S b) (S k) f d =
iter_seq b k (λ c i, f c (S i)) d.
Theorem iter_seq_succ_succ' : ∀ {T} (d : T) b k f,
iter_seq (S b) (S k) (λ c i, f c (i - 1)) d =
iter_seq b k (λ c i, f c i) d.
Theorem iter_list_empty : ∀ T A d (op : T → T → T) (l : list A) g,
l = []
→ iter_list l (λ c i, op c (g i)) d = d.
Theorem iter_seq_empty : ∀ T d (op : T → T → T) b k g,
k < b
→ iter_seq b k (λ (c : T) (i : nat), op c (g i)) d = d.
Theorem iter_list_distr : ∀ T A d op g h (l : list A)
(op_d_l : ∀ x, op d x = x)
(op_comm : ∀ a b, op a b = op b a)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
iter_list l (λ (c : T) (i : A), op c (op (g i) (h i))) d =
op (iter_list l (λ (c : T) (i : A), op c (g i)) d)
(iter_list l (λ (c : T) (i : A), op c (h i)) d).
Theorem iter_seq_distr : ∀ T d op g h b k
(op_d_l : ∀ x, op d x = x)
(op_comm : ∀ a b, op a b = op b a)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
iter_seq b k (λ (c : T) (i : nat), (op c (op (g i) (h i)))) d =
op
(iter_seq b k (λ (c : T) (i : nat), op c (g i)) d)
(iter_seq b k (λ (c : T) (i : nat), op c (h i)) d).
Theorem iter_list_inv : ∀ T A d op inv (f : A → T) l
(inv_op_distr : ∀ a b, inv (op a b) = op (inv a) (inv b)),
inv (iter_list l (λ (c : T) i, op c (f i)) d) =
iter_list l (λ (c : T) i, op c (inv (f i))) (inv d).
Theorem iter_shift : ∀ {T} s b k f (d : T),
s ≤ b ≤ k
→ iter_seq b k f d =
iter_seq (b - s) (k - s) (λ c i, f c (s + i)) d.
Theorem iter_rshift : ∀ {T} s b k f (d : T),
iter_seq b k f d =
iter_seq (s + b) (s + k) (λ c i, f c (i - s)) d.
Theorem iter_seq_inv : ∀ T d op inv b e f
(inv_op_distr : ∀ a b, inv (op a b) = op (inv a) (inv b)),
inv (iter_seq b e (λ (c : T) (i : nat), op c (f i)) d) =
iter_seq b e (λ (c : T) (i : nat), op c (inv (f i))) (inv d).
Theorem iter_seq_rtl : ∀ T d op b k f
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_comm : ∀ a b, op a b = op b a)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
iter_seq b k (λ (c : T) (i : nat), op c (f i)) d =
iter_seq b k (λ (c : T) (i : nat), op c (f (k + b - i))) d.
Theorem iter_list_only_one : ∀ T A d (op : T → T → T) (g : A → T) a,
op d (g a) = g a
→ iter_list [a] (λ c i, op c (g i)) d = g a.
Theorem iter_seq_only_one : ∀ T d (op : T → T → T) g n,
op d (g n) = g n
→ iter_seq n n (λ c i, op c (g i)) d = g n.
Theorem iter_list_cons : ∀ A B d op (a : B) la f
(op_d_l : ∀ x, op d x = x)
(op_d_r : ∀ x, op x d = x)
(op_assoc : ∀ a b c, op a (op b c) = op (op a b) c),
iter_list (a :: la) (λ (c : A) i, op c (f i)) d =
op (f a) (iter_list la (λ (c : A) i, op c (f i)) d).
Theorem iter_list_app : ∀ A B (d : A) (f : A → B → A) la lb,
iter_list (la ++ lb) f d = iter_list lb f (iter_list la f d).
Theorem iter_list_seq : ∀ T d (op : T → T → T) b len f,
len ≠ 0
→ iter_list (List.seq b len) (λ c i, op c (f i)) d =
iter_seq b (b + len - 1) (λ c i, op c (f i)) d.
Theorem List_flat_length_map : ∀ A B (f : A → list B) l,
length (List.flat_map f l) = iter_list l (fun c a ⇒ c + length (f a)) 0.
List_cart_prod
List.list_prod [1; 2] [3; 4; 5] = [(1,3); (1,4); (1,5); (2,3); (2,4); (2,5)] List_cart_prod [[1; 2]; [3; 4; 5]] = [[1;3]; [1;4]; [1;5]; [2;3]; [2;4]; [2;5]]
- List_cart_prod [] returns []
- List_cart_prod [[1; 2]; [3; 4]] returns all pairs as 2-lists
- List_cart_prod [[a1; a2]; [b1]; [c1; c2]] returns 4 3-lists: a1; b1; c1, a1; b1; c2, a2; b1; c1, a2; b1; c2
Fixpoint List_cart_prod {A} (ll : list (list A)) :=
match ll with
| [] ⇒ [[]]
| l :: ll' ⇒ List.flat_map (λ a, List.map (cons a) (List_cart_prod ll')) l
end.
Theorem List_cart_prod_length : ∀ A (ll : list (list A)),
ll ≠ []
→ length (List_cart_prod ll) = iter_list ll (fun c l ⇒ c × length l) 1.
Theorem List_in_cart_prod_length : ∀ A (ll : list (list A)) l,
l ∈ List_cart_prod ll → length l = length ll.
Theorem List_in_nth_cart_prod : ∀ A (d : A) ll l i,
i < length ll
→ l ∈ List_cart_prod ll
→ List.nth i l d ∈ List.nth i ll [].
Theorem List_in_cart_prod_iff : ∀ {A} (d : A) ll la,
la ∈ List_cart_prod ll
↔ length la = length ll ∧
∀ i, i < length la → List.nth i la d ∈ List.nth i ll [].
List_extract
- the list segment before the match
- the matching element
- the segment after the match
Fixpoint List_extract {A} (f : A → bool) l :=
match l with
| [] ⇒ None
| a :: la ⇒
if f a then Some ([], a, la)
else
match List_extract f la with
| None ⇒ None
| Some (bef, b, aft) ⇒ Some (a :: bef, b, aft)
end
end.
Theorem List_extract_Some_iff : ∀ A (f : A → _) l a bef aft,
List_extract f l = Some (bef, a, aft)
↔ (∀ x, x ∈ bef → f x = false) ∧ f a = true ∧ l = bef ++ a :: aft.
Theorem List_extract_None_iff : ∀ {A} (f : A → _) l,
List_extract f l = None ↔ ∀ a, a ∈ l → f a = false.
match l with
| [] ⇒ None
| a :: la ⇒
if f a then Some ([], a, la)
else
match List_extract f la with
| None ⇒ None
| Some (bef, b, aft) ⇒ Some (a :: bef, b, aft)
end
end.
Theorem List_extract_Some_iff : ∀ A (f : A → _) l a bef aft,
List_extract f l = Some (bef, a, aft)
↔ (∀ x, x ∈ bef → f x = false) ∧ f a = true ∧ l = bef ++ a :: aft.
Theorem List_extract_None_iff : ∀ {A} (f : A → _) l,
List_extract f l = None ↔ ∀ a, a ∈ l → f a = false.
List_rank
Fixpoint List_rank_loop i [A] (f : A → bool) (l : list A) : nat :=
match l with
| [] ⇒ i
| x :: tl ⇒ if f x then i else List_rank_loop (S i) f tl
end.
Definition List_rank [A] := @List_rank_loop 0 A.
Theorem List_rank_loop_interv : ∀ {A} f (l : list A) i,
i ≤ List_rank_loop i f l ≤ i + length l.
Theorem List_rank_loop_if : ∀ A d f (l : list A) i j,
List_rank_loop i f l = j
→ (∀ k, i ≤ k < j → f (List.nth (k - i) l d) = false) ∧
(j < i + length l ∧ f (List.nth (j - i) l d) = true ∨
j = i + length l).
Theorem List_rank_if : ∀ {A} d f (l : list A) {i},
List_rank f l = i
→ (∀ j, j < i → f (List.nth j l d) = false) ∧
(i < length l ∧ f (List.nth i l d) = true ∨ i = length l).
match l with
| [] ⇒ i
| x :: tl ⇒ if f x then i else List_rank_loop (S i) f tl
end.
Definition List_rank [A] := @List_rank_loop 0 A.
Theorem List_rank_loop_interv : ∀ {A} f (l : list A) i,
i ≤ List_rank_loop i f l ≤ i + length l.
Theorem List_rank_loop_if : ∀ A d f (l : list A) i j,
List_rank_loop i f l = j
→ (∀ k, i ≤ k < j → f (List.nth (k - i) l d) = false) ∧
(j < i + length l ∧ f (List.nth (j - i) l d) = true ∨
j = i + length l).
Theorem List_rank_if : ∀ {A} d f (l : list A) {i},
List_rank f l = i
→ (∀ j, j < i → f (List.nth j l d) = false) ∧
(i < length l ∧ f (List.nth i l d) = true ∨ i = length l).
List_map2
Fixpoint List_map2 {A B C} (f : A → B → C) la lb :=
match la with
| [] ⇒ []
| a :: la' ⇒
match lb with
| [] ⇒ []
| b :: lb' ⇒ f a b :: List_map2 f la' lb'
end
end.
Theorem List_map2_nil_l : ∀ A B C (f : A → B → C) la, List_map2 f [] la = [].
Theorem List_map2_nil_r : ∀ A B C (f : A → B → C) la, List_map2 f la [] = [].
Theorem List_map2_nth : ∀ {A B C} a b c (f : A → B → C) la lb n,
n < length la
→ n < length lb
→ List.nth n (List_map2 f la lb) c = f (List.nth n la a) (List.nth n lb b).
Theorem List_map2_map_l :
∀ A B C D (f : C → B → D) g (la : list A) (lb : list B),
List_map2 f (List.map g la) lb = List_map2 (λ a b, f (g a) b) la lb.
Theorem List_map2_map_r :
∀ A B C D (f : A → C → D) g (la : list A) (lb : list B),
List_map2 f la (List.map g lb) = List_map2 (λ a b, f a (g b)) la lb.
Theorem List_map_map2 : ∀ A B C D (f : A → B) (g : C → D → A) la lb,
List.map f (List_map2 g la lb) = List_map2 (λ a b, f (g a b)) la lb.
Theorem List_fold_left_map2 :
∀ A B C D (f : A → B → A) (g : C → D → B) lc ld (a : A),
List.fold_left f (List_map2 g lc ld) a =
List.fold_left (λ b c, f b (g (fst c) (snd c))) (List.combine lc ld) a.
Theorem List_length_map2 : ∀ A B C (f : A → B → C) la lb,
length (List_map2 f la lb) = min (length la) (length lb).
Theorem List_in_map2_iff : ∀ A B C (f : A → B → C) la lb c,
c ∈ List_map2 f la lb ↔
∃ i,
i < min (length la) (length lb) ∧
∃ a b, f (List.nth i la a) (List.nth i lb b) = c.
Theorem List_map2_ext_in : ∀ A B C (f g : A → B → C) la lb,
(∀ ab, ab ∈ List.combine la lb → f (fst ab) (snd ab) = g (fst ab) (snd ab))
→ List_map2 f la lb = List_map2 g la lb.
Theorem List_map2_diag : ∀ A B (f : A → A → B) la,
List_map2 f la la = List.map (λ i, f i i) la.
Theorem List_map2_map2_seq_l : ∀ {A B C} d (f : A → B → C) la lb,
List_map2 f la lb =
List_map2 (λ i b, f (List.nth i la d) b) (List.seq 0 (length la)) lb.
Theorem List_map2_map2_seq_r : ∀ {A B C} d (f : A → B → C) la lb,
List_map2 f la lb =
List_map2 (λ a i, f a (List.nth i lb d)) la (List.seq 0 (length lb)).
Theorem List_map2_app_l : ∀ A B C l1 l2 l (f : A → B → C),
List_map2 f (l1 ++ l2) l =
List_map2 f l1 (List.firstn (length l1) l) ++
List_map2 f l2 (List.skipn (length l1) l).
Theorem List_map2_swap : ∀ A B C (f : A → B → C) la lb,
List_map2 f la lb = List_map2 (λ a b, f b a) lb la.
Theorem List_map2_rev_seq_r : ∀ A B (f : A → _ → B) la sta len,
List_map2 f la (List.rev (List.seq sta len)) =
List_map2 (λ a i, f a (2 × sta + len - 1 - i)) la (List.seq sta len).
Theorem List_map2_map_min :
∀ {A B C} ad bd la lb (f : A → B → C),
List_map2 f la lb =
List.map (λ i, f (List.nth i la ad) (List.nth i lb bd))
(List.seq 0 (min (length la) (length lb))).
Theorem List_map2_app_app :
∀ A B C la lb lc ld (f : A → B → C),
length la = length lb
→ List_map2 f (la ++ lc) (lb ++ ld) =
List_map2 f la lb ++ List_map2 f lc ld.
Theorem List_rev_map2 : ∀ A B C (f : A → B → C) la lb,
length la = length lb
→ List.rev (List_map2 f la lb) = List_map2 f (List.rev la) (List.rev lb).
Theorem List_eq_map2_nil : ∀ A B C (f : A → B → C) la lb,
List_map2 f la lb = [] → la = [] ∨ lb = [].
binomial
Fixpoint binomial n k :=
match k with
| 0 ⇒ 1
| S k' ⇒
match n with
| 0 ⇒ 0
| S n' ⇒ binomial n' k' + binomial n' k
end
end.
Theorem binomial_succ_succ : ∀ n k,
binomial (S n) (S k) = binomial n k + binomial n (S k).
Theorem binomial_lt : ∀ n k, n < k → binomial n k = 0.
Theorem binomial_succ_diag_r : ∀ n, binomial n (S n) = 0.
This page has been generated by coqdoc