Instance list_PCM (P : Ghost) : Ghost := { valid a := True; Join_G := list_join }.Definition ghost_list {P : Ghost} g l := own(RA := list_PCM P) g l NoneP.Definition list_incl {A} (l1 l2 : list (option A)) := (length l1 <= length l2)%nat /\
  forall n a, nth n l1 None = Some a -> nth n l2 None = Some a.

(* Specifications: *)
Lemma app_nth : forall {A} n l1 l2 (d : A), nth n (l1 ++ l2) d = if lt_dec n (length l1) then nth n l1 d else nth (n - length l1) l2 d.
Lemma replace_nth_length : forall {A} n l (a : A), length (replace_nth n l a) = length l.
Lemma replace_nth_app : forall {A} n l1 l2 (a : A), replace_nth n (l1 ++ l2) a = if lt_dec n (length l1) then replace_nth n l1 a ++ l2 else l1 ++ replace_nth (n - length l1) l2 a.
Lemma list_join_app : forall {P : Ghost} l1 l2 m1 m2 n1 n2, length l1 = length m1 -> length l1 = length n1 -> list_join l1 m1 n1 -> list_join l2 m2 n2 -> list_join (l1 ++ l2) (m1 ++ m2) (n1 ++ n2).
Lemma list_join_None : forall {P : Ghost} n l, (n <= length l)%nat -> list_join (repeat None n) l l.
Lemma list_join_over : forall {P : Ghost} l l1 l2 l1', (length l <= length l1)%nat -> list_join l l1 l1' -> list_join l (l1 ++ l2) (l1' ++ l2).
Lemma singleton_length : forall {A} n (a : A), length (list_singleton n a) = S n.
Lemma list_join_singleton : forall {P : Ghost} n a c l (Hn : (n < length l)%nat) (Hjoin: join (Some a) (nth n l None) (Some c)), list_join (list_singleton n a) l (replace_nth n l (Some c)).
Lemma replace_nth_same : forall {A} n l (d : A), replace_nth n l (nth n l d) = l.
Lemma nth_replace_nth : forall {A} n l a (d : A), (n < length l)%nat -> nth n (replace_nth n l a) d = a.
Lemma nth_replace_nth' : forall {A} n m l a (d : A), m <> n -> nth m (replace_nth n l a) d = nth m l d.
Lemma Znth_replace_nth : forall {A} {d : Inhabitant A} n l (a : A), (n < length l)%nat -> Znth (Z.of_nat n) (replace_nth n l a) = a.
Lemma Znth_replace_nth' : forall {A} {d : Inhabitant A} n m l (a : A), m <> Z.of_nat n -> Znth m (replace_nth n l a) = Znth m l.
Lemma ghost_list_nth : forall {P : Ghost} g n l (a : G) (Ha : nth n l None = Some a), ghost_list g l = ghost_list g (list_singleton n a) * ghost_list g (replace_nth n l None).
Lemma list_join_length : forall {P : Ghost} l1 l2 l3, list_join l1 l2 l3 -> (length l1 <= length l3)%nat.
Lemma list_join_filler : forall {P : Ghost} l1 l2 l3 n, list_join l1 l2 l3 -> (n <= length l3 - length l1)%nat -> list_join (l1 ++ repeat None n) l2 l3.
Lemma list_join_nth : forall {P : Ghost} l1 l2 l3 n, list_join l1 l2 l3 -> join (nth n l1 None) (nth n l2 None) (nth n l3 None).
Lemma list_join_max : forall {P : Ghost} l1 l2 l3, list_join l1 l2 l3 -> length l3 = Max.max (length l1) (length l2).
Lemma list_join_nth_error : forall {P : Ghost} l1 l2 l3 n, list_join l1 l2 l3 -> join (nth_error l1 n) (nth_error l2 n) (nth_error l3 n).
Lemma list_join_alt : forall {P : Ghost} l1 l2 l3, list_join l1 l2 l3 <-> forall n, join (nth_error l1 n) (nth_error l2 n) (nth_error l3 n).
Lemma nth_error_replace_nth : forall {A} n l (a : A), (n < length l)%nat -> nth_error (replace_nth n l a) n = Some a.
Lemma nth_error_replace_nth' : forall {A} n m l (a : A), m <> n -> nth_error (replace_nth n l a) m = nth_error l m.