(* PERSONAL MEM: Is the contents of the global memory,
       with the juice of a single thread and the Cur that corresponds to that juice.*)
    Definition acc_coh:= fun m phi pr => @max_acc_coh_acc_coh m phi (max_coh pr).Definition personal_mem {m phi} (pr : mem_cohere' m phi) : juicy_mem:=
      mkJuicyMem
        (@juicyRestrict phi m (acc_coh pr))
        phi
        (juicyRestrictContentCoh (acc_coh pr) (cont_coh pr))
        (juicyRestrictAccCoh (acc_coh pr))
        (juicyRestrictMaxCoh (acc_coh pr) (max_coh pr))
        (juicyRestrictAllocCoh (acc_coh pr) (all_coh pr)).Definition juicy_sem := (FSem.F _ _ JuicyFSem.t) _ the_sem.(* Definition juicy_step := (FSem.step _ _ JuicyFSem.t) _ _ the_sem. *)

    Program Definition first_phi (tp : thread_pool) : rmap := (@getThreadR _ _ _ 0%nat tp _).Program Definition level_tp (tp : thread_pool) := level (first_phi tp).Definition tp_level_is_above n tp :=
      (forall i (cnti : containsThread tp i), le n (level (getThreadR cnti))) /\
      (forall i phi, lockRes(resources:=LocksAndResources) tp i = Some (Some phi) -> le n (level phi)).Definition tp_level_is n tp :=
      (forall i (cnti : containsThread tp i), level (getThreadR cnti) = n) /\
      (forall i phi, lockRes(resources:=LocksAndResources) tp i = Some (Some phi) -> level phi = n).(*
    Lemma mem_compatible_same_level tp m :
      mem_compatible tp m -> tp_level_is (level_tp tp) tp.
    Proof.
      intros M.
      pose proof disjoint_threads_compat M as DT.
      pose proof disjoint_locks_t_hread_compat M as DLT.
      destruct M as [Phi M].
      unfold level_tp, first_phi.
      split.
      - intros i cnti.
        destruct (eq_dec i 0%nat).
        + subst.
          repeat f_equal.
          now apply cnt_irr.
        + apply rmap_join_eq_level.
          apply DT.
          auto.
      - intros i phi E.
        apply rmap_join_eq_level.
        rewrite joins_sym.
        eapply (DLT _); eauto.
    Qed. *)

    Definition cnt_from_ordinal tp : forall i : ordinal (pos.n (num_threads tp)), containsThread tp i.Definition age_tp_to (k : nat) (tp : thread_pool) : thread_pool :=
      match tp with
        mk n pool maps lset =>
        mk n pool
           ((age_to k) oo maps)
           (AMap.map (option_map (age_to k)) lset)
      end.

(* Specifications: *)
Lemma level_age_tp_to tp k : tp_level_is_above k tp -> tp_level_is k (age_tp_to k tp).
Lemma map_compose {A B C} (g : A -> B) (f : B -> C) l : map (f oo g) l = map f (map g l).
Lemma join_list_age_to k l Phi : le k (level Phi) -> join_list l Phi -> join_list (map (age_to k) l) (age_to k Phi).
Lemma join_list'_age_to k (l : list (option res)) (Phi : option res) : (match Phi with None => Logic.True | Some phi => le k (level phi) end) -> join_list' l Phi -> join_list' (map (option_map (age_to k)) l) (option_map (age_to k) Phi).
Lemma join_all_age_to k tp Phi : le k (level Phi) -> join_all tp Phi -> join_all (age_tp_to k tp) (age_to k Phi).
Lemma cnt_age {js i age} : containsThread (age_tp_to age js) i -> containsThread js i.
Lemma cnt_age' {js i age} : containsThread js i -> containsThread (age_tp_to age js) i.
Lemma age_getThreadCode: forall i tp age cnt cnt', @getThreadC _ _ _ i tp cnt = @getThreadC _ _ _ i (age_tp_to age tp) cnt'.