(*  Lemma threadStep_not_unhalts:
    forall g i tp m cnt cmpt tp' m' tr,
      @threadStep g i tp m cnt cmpt tp' m' tr ->
      forall j cnt cnt',
        (@threadHalted j tp cnt) ->
        (@threadHalted j tp' cnt') .
  Proof.
    intros; inversion H; inversion H0; subst.
    destruct (NatTID.eq_tid_dec i j).
    - subst j.
      eapply corestep_not_halted in Hcorestep.
      unfold halted, j_halted in Hcorestep; simpl in Hcorestep.
      unfold j_halted in Hcorestep.
      replace cnt1 with cnt in Hthread0 by apply cnt_irr.
      rewrite Hthread0 in Hthread; inversion Hthread;
      subst c0.
      rewrite Hcorestep in Hcant; inversion Hcant.
    - econstructor; eauto.
      Set Printing Implicit.
      rewrite gsoThreadCode; auto;
      erewrite <- age_getThreadCode; eauto.
  Qed.*)

    (* The initial machine has to be redefined.
       Right now its build by default with empty maps,
       but it should be built with the correct juice,
       corresponding to global variables, arguments
       and function specs. *)

    (*Lemma onePos: (0<1)%coq_nat. auto. Qed.*)
    Definition initial_machine rmap c:=
      mk
        (mkPos (le_n 1))
        (fun _ => (Krun c))
        (fun _ => rmap)
        (AMap.empty _).Definition init_mach rmap (m: mem) (tp:thread_pool) (v:val) (args:list val) : Prop :=
      exists c, initial_core the_sem 0 m c v args /\
        match rmap with Some rmap => tp = initial_machine rmap c | None => False end.

(* Specifications: *)
Lemma access_cohere_sub': forall phi1 phi2 m, access_cohere' m phi1 -> join_sub phi2 phi1 -> access_cohere' m phi2.
Lemma mem_cohere'_juicy_mem jm : mem_cohere' (m_dry jm) (m_phi jm).
Lemma compatible_threadRes_join: forall js m, mem_compatible js m -> forall i (cnti: containsThread js i) j (cntj: containsThread js j), i <> j -> sepalg.joins (getThreadR cnti) (getThreadR cntj).
Lemma compatible_threadRes_lockRes_join: forall js m, mem_compatible js m -> forall i (cnti: containsThread js i) l R phi, ThreadPool.lockRes js l = Some (R, Some phi) -> sepalg.joins (getThreadR cnti) phi.
Lemma compatible_lockRes_cohere: forall js m l R phi, lockRes js l = Some (R, Some phi) -> mem_compatible js m -> mem_cohere' m phi .
Lemma compatible_threadRes_cohere: forall js m i (cnt:containsThread js i), mem_compatible js m -> mem_cohere' m (getThreadR cnt) .
Lemma cnt_age_iff {js i n} : containsThread js i <-> containsThread (age_tp_to n js) i.
Lemma gtc_age : forall js i n, forall (cnt: containsThread js i) (cnt': containsThread (age_tp_to n js) i), getThreadC cnt = getThreadC cnt'.
Lemma getThreadR_age: forall js i age, forall (cnt: containsThread js i) (cnt': containsThread (age_tp_to age js) i), age_to age (getThreadR cnt) = getThreadR cnt'.
Lemma LockRes_age: forall js age a, isSome (lockRes (age_tp_to age js) a) = isSome(lockRes js a).
Lemma LockRes_age_content1: forall js age a R, lockRes (age_tp_to age js) a = Some (R, None) -> lockRes js a = Some (R, None).
Lemma LockRes_age_content2: forall js age a R rm, lockRes (age_tp_to age js) a = Some (R, Some rm) -> exists r, lockRes js a = Some (R, Some r) /\ rm = age_to age r.
Lemma access_cohere'_age m : hereditary age (access_cohere' m).
Lemma access_cohere'_unage m : hereditary unage (access_cohere' m).
Lemma mem_cohere'_age m : hereditary age (mem_cohere' m).
Lemma mem_cohere'_unage m : hereditary unage (mem_cohere' m).
Lemma mem_cohere_age_to n m phi : mem_cohere' m phi -> mem_cohere' m (age_to n phi).
Lemma mem_cohere_age_to_opp n m phi : mem_cohere' m (age_to n phi) -> mem_cohere' m phi.