Definition hist_incl (h : hist_part) l := forall t e, h t = Some e -> nth_error l t = Some e.
Definition hist_list (h : hist_part) l := forall t e, h t = Some e <-> nth_error l t = Some e.

(* Specifications: *)
Lemma hist_list_inj : forall h l1 l2 (Hl1 : hist_list h l1) (Hl2 : hist_list h l2), l1 = l2.
Lemma hist_list_nil_inv1 : forall l, hist_list empty_map l -> l = [].
Lemma hist_list_nil_inv2 : forall h, hist_list h [] -> h = empty_map.
Definition ghost_ref l g := EX hr : hist_part, !!(hist_list hr l) &&
own(RA := ref_PCM map_disj_PCM) g (None, Some hr) NoneP.
Lemma hist_next : forall h l (Hlist : hist_list h l), h (length l) = None.
Definition ghost_hist_ref sh (h r : hist_part) g :=
own(RA := ref_PCM map_disj_PCM) g (Some (sh, h), Some r) NoneP.
Lemma hist_add : forall (sh : share) (h h' : hist_part) e p t' (Hfresh : h' t' = None),
ghost_hist_ref sh h h' p |-- |==> ghost_hist_ref sh (map_upd h t' e) (map_upd h' t' e) p.
Lemma hist_incl_nil : forall h, hist_incl empty_map h.
Lemma hist_list_nil : hist_list empty_map [].
Lemma hist_list_snoc : forall h l e, hist_list h l ->
hist_list (map_upd h (length l) e) (l ++ [e]).
Lemma hist_sub_list_incl : forall sh h h' l (Hsub : hist_sub sh h h') (Hlist : hist_list h' l),
hist_incl h l.
Lemma hist_sub_Tsh : forall h h', hist_sub Tsh h h' <-> (h = h').
Lemma hist_ref_join : forall sh h l p, sh <> Share.bot ->
ghost_hist sh h p * ghost_ref l p =
EX h' : hist_part, !!(hist_list h' l /\ hist_sub sh h h') && ghost_hist_ref sh h h' p.
Corollary hist_ref_join_nil : forall sh p, sh <> Share.bot ->
ghost_hist sh empty_map p * ghost_ref [] p = ghost_hist_ref sh empty_map empty_map p.
Lemma hist_ref_incl : forall sh h h' p, sh <> Share.bot ->
ghost_hist sh h p * ghost_ref h' p |-- !!hist_incl h h'.
Lemma hist_add' : forall sh h h' e p, sh <> Share.bot ->
ghost_hist sh h p * ghost_ref h' p |-- |==>
ghost_hist sh (map_upd h (length h') e) p * ghost_ref (h' ++ [e]) p.