(** Pointers cannot be forged. *)
Definition quantity_chunk (chunk: memory_chunk) :=
match chunk with
| Mint64 | Mfloat64 | Many64 => Q64
| _ => Q32
end.
Inductive shape_encoding (chunk: memory_chunk) (v: val): list memval -> Prop :=
| shape_encoding_f: forall q i mvl,
(chunk = Mint32 \/ chunk = Many32 \/ chunk = Mint64 \/ chunk = Many64) ->
q = quantity_chunk chunk ->
S i = size_quantity_nat q ->
(forall mv, In mv mvl -> exists j, mv = Fragment v q j /\ S j <> size_quantity_nat q) ->
shape_encoding chunk v (Fragment v q i :: mvl)
| shape_encoding_b: forall b mvl,
match v with Vint _ => True | Vlong _ => True | Vfloat _ => True | Vsingle _ => True | _ => False end ->
(forall mv, In mv mvl -> exists b', mv = Byte b') ->
shape_encoding chunk v (Byte b :: mvl)
| shape_encoding_u: forall mvl,
(forall mv, In mv mvl -> mv = Undef) ->
shape_encoding chunk v (Undef :: mvl).

(* Specifications: *)
Lemma encode_val_shape: forall chunk v, shape_encoding chunk v (encode_val chunk v).
Inductive shape_decoding (chunk: memory_chunk): list memval -> val -> Prop :=
| shape_decoding_f: forall v q i mvl,
(chunk = Mint32 \/ chunk = Many32 \/ chunk = Mint64 \/ chunk = Many64) ->
q = quantity_chunk chunk ->
S i = size_quantity_nat q ->
(forall mv, In mv mvl -> exists j, mv = Fragment v q j /\ S j <> size_quantity_nat q) ->
shape_decoding chunk (Fragment v q i :: mvl) (Val.load_result chunk v)
| shape_decoding_b: forall b mvl v,
match v with Vint _ => True | Vlong _ => True | Vfloat _ => True | Vsingle _ => True |  _ => False end ->
(forall mv, In mv mvl -> exists b', mv = Byte b') ->
shape_decoding chunk (Byte b :: mvl) v
| shape_decoding_u: forall mvl,
shape_decoding chunk mvl Vundef.
Lemma decode_val_shape: forall chunk mv1 mvl,
shape_decoding chunk (mv1 :: mvl) (decode_val chunk (mv1 :: mvl)).
Lemma encode_val_shape: forall chunk v, shape_encoding chunk v (encode_val chunk v).
Inductive shape_decoding (chunk: memory_chunk): list memval -> val -> Prop :=
| shape_decoding_f: forall v q i mvl,
(chunk = Mint32 \/ chunk = Many32 \/ chunk = Mint64 \/ chunk = Many64) ->
q = quantity_chunk chunk ->
S i = size_quantity_nat q ->
(forall mv, In mv mvl -> exists j, mv = Fragment v q j /\ S j <> size_quantity_nat q) ->
shape_decoding chunk (Fragment v q i :: mvl) (Val.load_result chunk v)
| shape_decoding_b: forall b mvl v,
match v with Vint _ => True | Vlong _ => True | Vfloat _ => True | Vsingle _ => True |  _ => False end ->
(forall mv, In mv mvl -> exists b', mv = Byte b') ->
shape_decoding chunk (Byte b :: mvl) v
| shape_decoding_u: forall mvl,
shape_decoding chunk mvl Vundef.
Lemma decode_val_shape: forall chunk mv1 mvl,
shape_decoding chunk (mv1 :: mvl) (decode_val chunk (mv1 :: mvl)).