Definition mkInjections (m1 m1' m2:mem) (j k l: meminj)
                     :  meminj * meminj * block * block :=
  if plt (Mem.nextblock m1) (Mem.nextblock m1')
  then mkInjectionsN (Pos.to_nat (Mem.nextblock m1') - Pos.to_nat(Mem.nextblock m1))
                (Mem.nextblock m1)
                (Mem.nextblock m2) j k l
  else (j,k,Mem.nextblock m1,Mem.nextblock m2).

(* Specifications: *)
Lemma mkInjections_0: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')), ( Pos.le (Mem.nextblock m1') (Mem.nextblock m1) /\ Mem.nextblock m1 = n1' /\ Mem.nextblock m2 = n2' /\ j' = j /\ k' = k) \/ (exists N, (N > 0)%nat /\ (Mem.nextblock m1 + (Pos.of_nat N) = n1')%positive /\ (n1' = Mem.nextblock m1') /\ (Mem.nextblock m2 + (Pos.of_nat N) = n2')%positive).
Lemma mkInjections_1_injinc: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VB: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1), inject_incr j j'.
Lemma mkInjections_1_injsep: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')), inject_separated j j' m1 m2.
Lemma mkInjections_2_injinc: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VB: forall b1 b2 ofs2, k b1 = Some(b2,ofs2) -> Mem.valid_block m2 b1), inject_incr k k'.
Lemma mkInjections_2_injsep: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VB: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1) m3 (Sep:inject_separated (compose_meminj j k) l m1 m3), inject_separated k k' m2 m3.
Lemma mkInjections_3: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b1 b2 ofs2, j' b1 = Some(b2,ofs2) -> (j b1 = Some (b2,ofs2)) \/ (b1 = Mem.nextblock m1 /\ b2 = Mem.nextblock m2 /\ ofs2 = 0) \/ (exists m, (b1 = Mem.nextblock m1 + m /\ b2=Mem.nextblock m2 + m)%positive /\ ofs2=0).
Lemma mkInjections_3V: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (HJ: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> (b1 < Mem.nextblock m1 /\ b2 < Mem.nextblock m2)%positive) (HK: forall b2 b3 ofs3, k b2 = Some(b3,ofs3) -> (b2 < Mem.nextblock m2)%positive) b1 b2 ofs2, j' b1 = Some(b2,ofs2) -> (j b1 = Some (b2,ofs2) /\ (b1 < Mem.nextblock m1 /\ b2 < Mem.nextblock m2)%positive) \/ (b1 = Mem.nextblock m1 /\ b2=Mem.nextblock m2 /\ ofs2=0 /\ (b1 < n1' /\ b2<n2')%positive) \/ (exists m, (b1 = Mem.nextblock m1 + m)%positive /\ (b2=Mem.nextblock m2 + m)%positive /\ ofs2=0 /\ (b1 < n1' /\ b2<n2')%positive).
Lemma mkInjections_4: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b2 b3 ofs3, k' b2 = Some(b3,ofs3) -> k b2 = Some (b3,ofs3) \/ (b2 = Mem.nextblock m2 /\ l (Mem.nextblock m1) = Some(b3,ofs3)) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ l ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3)).
Lemma mkInjections_4Val: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (HK: forall b2 b3 ofs3, k b2 = Some(b3,ofs3) -> (b2 < Mem.nextblock m2)%positive) b2 b3 ofs3, k' b2 = Some(b3,ofs3) -> (k b2 = Some (b3,ofs3) /\ (b2 < Mem.nextblock m2)%positive) \/ (b2 = Mem.nextblock m2 /\ l (Mem.nextblock m1) = Some(b3, ofs3) /\ (b2 < n2')%positive) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ l ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3) /\ (b2 < n2')%positive).
Lemma mkInjections_7: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b (HB: (b < n1')%positive), ((Mem.nextblock m1 <= b)%positive -> j' b <> None) /\ ((b < Mem.nextblock m1)%positive -> j' b = j b).
Lemma mkInjections_6: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b (J': j' b = None), j b = None.
Lemma mkInjections_5: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VBj1: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1) (VBj2: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m2 b2) (VBk2: forall b1 b2 ofs2, k b1 = Some(b2,ofs2) -> Mem.valid_block m2 b1) (VBl1: forall b1 b2 ofs2, l b1 = Some(b2,ofs2) -> (b1 < n1')%positive) b2 (HB: (b2 < n2')%positive), k' b2 = None -> (Mem.valid_block m2 b2 /\ k b2 = None) \/ (b2 = Mem.nextblock m2 /\ l (Mem.nextblock m1) = None) \/ (exists m, b2 = ((Mem.nextblock m2) + m)%positive /\ l ((Mem.nextblock m1+m)%positive) = None).
Lemma J12'_no_overlap: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) j' j12' j23' n1' n2' (HeqMKI: mkInjections m1 m1' m2 j12 j23 j' = (j12', j23',n1',n2')), Mem.meminj_no_overlap j12' m1'.
Lemma mkInjections_composememinj: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (InjIncr: inject_incr (compose_meminj j k) l) m3 (InjSep: inject_separated (compose_meminj j k) l m1 m3) (VBj1: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1) (VBj2: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m2 b2) (VBk2: forall b1 b2 ofs2, k b1 = Some(b2,ofs2) -> Mem.valid_block m2 b1) (VBL1': forall b1 b3 ofs3, l b1 = Some (b3, ofs3) -> (b1 < n1')%positive), l = compose_meminj j' k'.
Lemma mkInjections_0: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')), ( Pos.le (Mem.nextblock m1') (Mem.nextblock m1) /\ Mem.nextblock m1 = n1' /\ Mem.nextblock m2 = n2' /\ j' = j /\ k' = k) \/ (exists N, (N > 0)%nat /\ (Mem.nextblock m1 + (Pos.of_nat N) = n1')%positive /\ (n1' = Mem.nextblock m1') /\ (Mem.nextblock m2 + (Pos.of_nat N) = n2')%positive).
Lemma mkInjections_1_injinc: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VB: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1), inject_incr j j'.
Lemma mkInjections_1_injsep: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')), inject_separated j j' m1 m2.
Lemma mkInjections_2_injinc: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VB: forall b1 b2 ofs2, k b1 = Some(b2,ofs2) -> Mem.valid_block m2 b1), inject_incr k k'.
Lemma mkInjections_2_injsep: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VB: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1) m3 (Sep:inject_separated (compose_meminj j k) l m1 m3), inject_separated k k' m2 m3.
Lemma mkInjections_3: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b1 b2 ofs2, j' b1 = Some(b2,ofs2) -> (j b1 = Some (b2,ofs2)) \/ (b1 = Mem.nextblock m1 /\ b2 = Mem.nextblock m2 /\ ofs2 = 0) \/ (exists m, (b1 = Mem.nextblock m1 + m /\ b2=Mem.nextblock m2 + m)%positive /\ ofs2=0).
Lemma mkInjections_3V: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (HJ: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> (b1 < Mem.nextblock m1 /\ b2 < Mem.nextblock m2)%positive) (HK: forall b2 b3 ofs3, k b2 = Some(b3,ofs3) -> (b2 < Mem.nextblock m2)%positive) b1 b2 ofs2, j' b1 = Some(b2,ofs2) -> (j b1 = Some (b2,ofs2) /\ (b1 < Mem.nextblock m1 /\ b2 < Mem.nextblock m2)%positive) \/ (b1 = Mem.nextblock m1 /\ b2=Mem.nextblock m2 /\ ofs2=0 /\ (b1 < n1' /\ b2<n2')%positive) \/ (exists m, (b1 = Mem.nextblock m1 + m)%positive /\ (b2=Mem.nextblock m2 + m)%positive /\ ofs2=0 /\ (b1 < n1' /\ b2<n2')%positive).
Lemma mkInjections_4: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b2 b3 ofs3, k' b2 = Some(b3,ofs3) -> k b2 = Some (b3,ofs3) \/ (b2 = Mem.nextblock m2 /\ l (Mem.nextblock m1) = Some(b3,ofs3)) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ l ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3)).
Lemma mkInjections_4Val: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (HK: forall b2 b3 ofs3, k b2 = Some(b3,ofs3) -> (b2 < Mem.nextblock m2)%positive) b2 b3 ofs3, k' b2 = Some(b3,ofs3) -> (k b2 = Some (b3,ofs3) /\ (b2 < Mem.nextblock m2)%positive) \/ (b2 = Mem.nextblock m2 /\ l (Mem.nextblock m1) = Some(b3, ofs3) /\ (b2 < n2')%positive) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ l ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3) /\ (b2 < n2')%positive).
Lemma mkInjections_7: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b (HB: (b < n1')%positive), ((Mem.nextblock m1 <= b)%positive -> j' b <> None) /\ ((b < Mem.nextblock m1)%positive -> j' b = j b).
Lemma mkInjections_6: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) b (J': j' b = None), j b = None.
Lemma mkInjections_5: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (VBj1: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1) (VBj2: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m2 b2) (VBk2: forall b1 b2 ofs2, k b1 = Some(b2,ofs2) -> Mem.valid_block m2 b1) (VBl1: forall b1 b2 ofs2, l b1 = Some(b2,ofs2) -> (b1 < n1')%positive) b2 (HB: (b2 < n2')%positive), k' b2 = None -> (Mem.valid_block m2 b2 /\ k b2 = None) \/ (b2 = Mem.nextblock m2 /\ l (Mem.nextblock m1) = None) \/ (exists m, b2 = ((Mem.nextblock m2) + m)%positive /\ l ((Mem.nextblock m1+m)%positive) = None).
Lemma J12'_no_overlap: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) j' j12' j23' n1' n2' (HeqMKI: mkInjections m1 m1' m2 j12 j23 j' = (j12', j23',n1',n2')), Mem.meminj_no_overlap j12' m1'.
Lemma mkInjections_composememinj: forall m1 m1' m2 j k l j' k' n1' n2' (HI: mkInjections m1 m1' m2 j k l = (j',k',n1',n2')) (InjIncr: inject_incr (compose_meminj j k) l) m3 (InjSep: inject_separated (compose_meminj j k) l m1 m3) (VBj1: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m1 b1) (VBj2: forall b1 b2 ofs2, j b1 = Some(b2,ofs2) -> Mem.valid_block m2 b2) (VBk2: forall b1 b2 ofs2, k b1 = Some(b2,ofs2) -> Mem.valid_block m2 b1) (VBL1': forall b1 b3 ofs3, l b1 = Some (b3, ofs3) -> (b1 < n1')%positive), l = compose_meminj j' k'.