Definition mkII
            (NB2':block)
            (Hyp1: (Mem.nextblock m2 <= NB2')%positive)
            (Hyp2: forall (b1 b2 : block) (delta : Z),
                       j12' b1 = Some (b2, delta) -> (b2 < NB2')%positive)
           : Mem.mem'.Definition minmax_at (m:mem) (j:meminj) (b2 b1: block) : option(Z * Z) :=
  match j b1
  with Some (b,delta) =>
            if peq b b2
            then match (zmap_finite_c _ (PMap.get b1 m.(Mem.mem_contents)))
                 with (mn,mx) => Some(mn+delta,mx+delta)
                 end
            else None
     | None => None
  end.Definition minmaxN (n:block) (m:mem) (j:meminj) (b2:block) : option (Z * Z):=
Pos.peano_rect
            (fun p => option(Z * Z))
            (minmax_at m j b2 (1%positive))
            (fun p Hp =>
               match minmax_at m j b2 (Pos.succ p)
               with Some(min1,max1) =>
                       match Hp with
                         Some(min2, max2) => Some (Zmin min1 min2, Zmax max1 max2)
                       | None => Some(min1,max1)
                       end
                  | None => Hp
               end)
            n.Definition minmax m j (b2:block): option(Z * Z) :=
   if plt 1%positive (Mem.nextblock m)
   then minmaxN (Pos.pred (Mem.nextblock m)) m j b2
   else None.Definition MINMAX_Offset (b2:block) : option (Z * Z) :=
  if plt b2 (Mem.nextblock m2)
  then match (zmap_finite_c _ (PMap.get b2 m2.(Mem.mem_contents)))
       with (min2, max2) =>
          match minmax m1' j12 b2 with
             Some(min1, max1) =>
                  Some(Z.min min1 min2, Z.max max1 max2)
           | None => Some(min2,max2)
          end
       end
  else minmax m1' j12' b2.

(* Specifications: *)
Lemma interpolate_II_strongHeqMKI: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ (forall b1 b2 d1, j12' b1 = Some(b2,d1) -> j12 b1 = Some(b2,d1) \/ exists b3 d, j' b1 = Some(b3,d)) /\ (forall b2 b3 d2, j23' b2 = Some(b3,d2) -> j23 b2 = Some(b3,d2) \/ exists b1 d, j' b1 = Some(b3,d)) /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3' /\ (forall b1 b2 ofs2, j12' b1 = Some(b2,ofs2) -> (j12 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)) /\ (forall b2 b3 ofs3, j23' b2 = Some(b3,ofs3) -> (j23 b2 = Some (b3,ofs3)) \/ (b2 = Mem.nextblock m2 /\ j' (Mem.nextblock m1) = Some(b3,ofs3)) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ j' ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3))).
Lemma interpolate_II_HeqMKI: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3' /\ (forall b1 b2 ofs2, j12' b1 = Some(b2,ofs2) -> (j12 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)) /\ (forall b2 b3 ofs3, j23' b2 = Some(b3,ofs3) -> (j23 b2 = Some (b3,ofs3)) \/ (b2 = Mem.nextblock m2 /\ j' (Mem.nextblock m1) = Some(b3,ofs3)) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ j' ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3))).
Lemma interpolate_II: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3'.
Lemma interpolate_II_strong: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ (forall b1 b2 d1, j12' b1 = Some(b2,d1) -> j12 b1 = Some(b2,d1) \/ exists b3 d, j' b1 = Some(b3,d)) /\ (forall b2 b3 d2, j23' b2 = Some(b3,d2) -> j23 b2 = Some(b3,d2) \/ exists b1 d, j' b1 = Some(b3,d)) /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3'.
Lemma interpolate_II_HeqMKI: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3' /\ (forall b1 b2 ofs2, j12' b1 = Some(b2,ofs2) -> (j12 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)) /\ (forall b2 b3 ofs3, j23' b2 = Some(b3,ofs3) -> (j23 b2 = Some (b3,ofs3)) \/ (b2 = Mem.nextblock m2 /\ j' (Mem.nextblock m1) = Some(b3,ofs3)) \/ (exists m, (b2 = Mem.nextblock m2 + m)%positive /\ j' ((Mem.nextblock m1+m)%positive) = Some(b3,ofs3))).
Lemma interpolate_II: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3'.
Lemma interpolate_II_strong: forall m1 m2 j12 (MInj12 : Mem.inject j12 m1 m2) m1' (Fwd1: mem_forward m1 m1') j23 m3 (MInj23 : Mem.inject j23 m2 m3) m3' (Fwd3: mem_forward m3 m3') j' (MInj13': Mem.inject j' m1' m3') (InjIncr: inject_incr (compose_meminj j12 j23) j') (InjSep: inject_separated (compose_meminj j12 j23) j' m1 m3) (Unch11': Mem.unchanged_on (loc_unmapped (compose_meminj j12 j23)) m1 m1') (Unch33': Mem.unchanged_on (loc_out_of_reach (compose_meminj j12 j23) m1) m3 m3'), exists m2', exists j12', exists j23', j'=compose_meminj j12' j23' /\ (forall b1 b2 d1, j12' b1 = Some(b2,d1) -> j12 b1 = Some(b2,d1) \/ exists b3 d, j' b1 = Some(b3,d)) /\ (forall b2 b3 d2, j23' b2 = Some(b3,d2) -> j23 b2 = Some(b3,d2) \/ exists b1 d, j' b1 = Some(b3,d)) /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ Mem.inject j12' m1' m2' /\ mem_forward m2 m2' /\ Mem.inject j23' m2' m3' /\ Mem.unchanged_on (loc_out_of_reach j12 m1) m2 m2' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3 /\ Mem.unchanged_on (loc_unmapped j23) m2 m2' /\ Mem.unchanged_on (loc_out_of_reach j23 m2) m3 m3'.