(** Properties of [List.map] (mapping a function over a list). *)

(* Specifications: *)
Lemma list_map_exten:
forall (A B: Type) (f f': A -> B) (l: list A),
(forall x, In x l -> f x = f' x) ->
List.map f' l = List.map f l.
Lemma list_map_compose:
forall (A B C: Type) (f: A -> B) (g: B -> C) (l: list A),
List.map g (List.map f l) = List.map (fun x => g(f x)) l.
Lemma list_map_identity:
forall (A: Type) (l: list A),
List.map (fun (x:A) => x) l = l.
Lemma list_map_nth:
forall (A B: Type) (f: A -> B) (l: list A) (n: nat),
nth_error (List.map f l) n = option_map f (nth_error l n).
Lemma list_length_map:
forall (A B: Type) (f: A -> B) (l: list A),
List.length (List.map f l) = List.length l.
Lemma list_in_map_inv:
forall (A B: Type) (f: A -> B) (l: list A) (y: B),
In y (List.map f l) -> exists x:A, y = f x /\ In x l.
Lemma list_append_map:
forall (A B: Type) (f: A -> B) (l1 l2: list A),
List.map f (l1 ++ l2) = List.map f l1 ++ List.map f l2.
Lemma list_append_map_inv:
forall (A B: Type) (f: A -> B) (m1 m2: list B) (l: list A),
List.map f l = m1 ++ m2 ->
exists l1, exists l2, List.map f l1 = m1 /\ List.map f l2 = m2 /\ l = l1 ++ l2.
Lemma list_map_exten:
forall (A B: Type) (f f': A -> B) (l: list A),
(forall x, In x l -> f x = f' x) ->
List.map f' l = List.map f l.
Lemma list_map_compose:
forall (A B C: Type) (f: A -> B) (g: B -> C) (l: list A),
List.map g (List.map f l) = List.map (fun x => g(f x)) l.
Lemma list_map_identity:
forall (A: Type) (l: list A),
List.map (fun (x:A) => x) l = l.
Lemma list_map_nth:
forall (A B: Type) (f: A -> B) (l: list A) (n: nat),
nth_error (List.map f l) n = option_map f (nth_error l n).
Lemma list_length_map:
forall (A B: Type) (f: A -> B) (l: list A),
List.length (List.map f l) = List.length l.
Lemma list_in_map_inv:
forall (A B: Type) (f: A -> B) (l: list A) (y: B),
In y (List.map f l) -> exists x:A, y = f x /\ In x l.
Lemma list_append_map:
forall (A B: Type) (f: A -> B) (l1 l2: list A),
List.map f (l1 ++ l2) = List.map f l1 ++ List.map f l2.
Lemma list_append_map_inv:
forall (A B: Type) (f: A -> B) (m1 m2: list B) (l: list A),
List.map f l = m1 ++ m2 ->
exists l1, exists l2, List.map f l1 = m1 /\ List.map f l2 = m2 /\ l = l1 ++ l2.