Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
  | val_content_inject_8_signed:
      forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
      val_content_inject f Mint8signed (Vint n1) (Vint n2)
  | val_content_inject_8_unsigned:
      forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
      val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
  | val_content_inject_16_signed:
      forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
      val_content_inject f Mint16signed (Vint n1) (Vint n2)
  | val_content_inject_16_unsigned:
      forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
      val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
  | val_content_inject_single:
      forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
      val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
  | val_content_inject_base:
      forall chunk v1 v2, val_inject f v1 v2 ->
      val_content_inject f chunk v1 v2.

Lemma make_store_correct: forall f sp te tm addr tvaddr rhs tvrhs chunk m vaddr vrhs m' fn k, eval_expr tge sp te tm addr tvaddr -> eval_expr tge sp te tm rhs tvrhs -> Mem.storev chunk m vaddr vrhs = Some m' -> Mem.inject f m tm -> val_inject f vaddr tvaddr -> val_inject f vrhs tvrhs -> exists tm', exists tvrhs', step tge (State fn (make_store chunk addr rhs) k sp te tm) E0 (State fn Sskip k sp te tm') /\ Mem.storev chunk tm tvaddr tvrhs' = Some tm' /\ Mem.inject f m' tm'.