Definition field_address t gfs p :=
if (field_compatible_dec t gfs p)
then offset_val (nested_field_offset t gfs) p
else Vundef.
Definition field_address0 t gfs p :=
if (field_compatible0_dec t gfs p)
then offset_val (nested_field_offset t gfs) p
else Vundef.

(* Specifications: *)
Lemma field_address_isptr:
forall t path c, field_compatible t path c -> isptr (field_address t path c).
Lemma field_address0_isptr:
forall t path c, field_compatible0 t path c -> isptr (field_address0 t path c).
Lemma field_address_clarify:
forall t path c,
is_pointer_or_null (field_address t path c) ->
field_address t path c = offset_val (nested_field_offset t path) c.
Lemma field_address0_clarify:
forall t path c,
is_pointer_or_null (field_address0 t path c) ->
field_address0 t path c = offset_val (nested_field_offset t path) c.
Lemma field_compatible_field_compatible0:
forall (t : type) (gfs : list gfield) (p : val),
field_compatible t gfs p -> field_compatible0 t gfs p.
Lemma field_compatible_field_compatible0':
forall (t : type) (i : Z) (gfs : list gfield) (p : val),
field_compatible t (ArraySubsc i :: gfs) p <->
field_compatible0 t (ArraySubsc i :: gfs) p /\
field_compatible0 t (ArraySubsc (i + 1) :: gfs) p.
Lemma field_compatible0_range:
forall i lo hi t gfs p,
lo <= i <= hi ->
field_compatible0 t (ArraySubsc lo :: gfs) p ->
field_compatible0 t (ArraySubsc hi :: gfs) p ->
field_compatible0 t (ArraySubsc i :: gfs) p.
Lemma field_compatible_range:
forall i lo hi t gfs p,
lo <= i < hi ->
field_compatible0 t (ArraySubsc lo :: gfs) p ->
field_compatible0 t (ArraySubsc hi :: gfs) p ->
field_compatible t (ArraySubsc i :: gfs) p.
Lemma is_pointer_or_null_field_compatible:
forall t path c,
is_pointer_or_null (field_address t path c) ->
field_compatible t path c.
Lemma nested_field_type_ArraySubsc: forall t i gfs,
nested_field_type t (ArraySubsc i :: gfs) = nested_field_type t (ArraySubsc 0 :: gfs).
(* TODO: not useful any longer *)
(* Lemma gfield_type_complete_type: forall t gf, legal_field t gf -> complete_type cenv_cs t = true -> complete_type cenv_cs (gfield_type t gf) = true.  Lemma gfield_array_type_complete_type: forall t lo hi, legal_field0 t (ArraySubsc lo) -> complete_type cenv_cs t = true -> complete_type cenv_cs (gfield_array_type t lo hi) = true.  Lemma nested_field_type_complete_type: forall t gfs, legal_nested_field t gfs -> complete_type cenv_cs t = true -> complete_type cenv_cs (nested_field_type t gfs) = true.  Lemma nested_field_array_type_complete_type: forall t gfs lo hi, legal_nested_field0 t (ArraySubsc lo :: gfs) -> complete_type cenv_cs t = true -> complete_type cenv_cs (nested_field_array_type t gfs lo hi) = true. *)
Lemma gfield_type_nested_pred: forall {atom_pred: type -> bool}, atom_pred Tvoid = true -> forall (t: type) (gf: gfield),
nested_pred atom_pred t = true -> nested_pred atom_pred (gfield_type t gf) = true.
Lemma gfield_array_type_nested_pred: forall {atom_pred: type -> bool},
(forall t n m a,
0 <= m ->
atom_pred (Tarray t n a) = true ->
atom_pred (Tarray t m (no_alignas_attr a)) = true) ->
forall (t: type) lo hi,
lo <= hi ->
legal_field0 t (ArraySubsc lo) ->
nested_pred atom_pred t = true -> nested_pred atom_pred (gfield_array_type t lo hi) = true.
Lemma gfield_type_complete_legal_cosu_type: forall (t: type) (gf: gfield),
legal_field t gf ->
complete_legal_cosu_type t = true -> complete_legal_cosu_type (gfield_type t gf) = true.
Lemma gfield_array_type_complete_legal_cosu_type: forall (t: type) lo hi,
legal_field0 t (ArraySubsc lo) ->
complete_legal_cosu_type t = true ->
complete_legal_cosu_type (gfield_array_type t lo hi) = true.
Lemma nested_field_type_complete_legal_cosu_type: forall (t: type) (gfs: list gfield), complete_legal_cosu_type t = true -> legal_nested_field t gfs -> complete_legal_cosu_type (nested_field_type t gfs) = true.
Lemma nested_field_array_type_complete_legal_cosu_type: forall (t: type) (gfs: list gfield) lo hi, complete_legal_cosu_type t = true -> legal_nested_field0 t (ArraySubsc lo :: gfs) -> complete_legal_cosu_type (nested_field_array_type t gfs lo hi) = true.
Lemma nested_field_type_nest_pred: forall {atom_pred: type -> bool}, atom_pred Tvoid = true -> forall (t: type) (gfs: list gfield),
nested_pred atom_pred t = true -> nested_pred atom_pred (nested_field_type t gfs) = true.
Lemma nested_field_array_type_nest_pred: forall {atom_pred: type -> bool},
atom_pred Tvoid = true ->
(forall t n m a,
0 <= m ->
atom_pred (Tarray t n a) = true ->
atom_pred (Tarray t m (no_alignas_attr a)) = true) ->
forall (t: type) gfs lo hi,
lo <= hi ->
legal_nested_field0 t (ArraySubsc lo :: gfs) ->
nested_pred atom_pred t = true ->
nested_pred atom_pred (nested_field_array_type t gfs lo hi) = true.
(* Lemma alignof_gfield_type_divide_alignof: forall t gf, legal_alignas_type t = true -> (alignof (gfield_type t gf) | alignof t).  Lemma alignof_gfield_array_type_eq: forall t lo hi i, legal_alignas_type t = true -> legal_field0 t (ArraySubsc lo) -> alignof (gfield_array_type t lo hi) = alignof (gfield_type t (ArraySubsc i)).  Lemma alignof_nested_field_type_divide_alignof: forall t gfs, legal_alignas_type t = true -> legal_nested_field t gfs -> (alignof (nested_field_type t gfs) | alignof t).  Lemma alignof_nested_field_type_divide_alignof': forall t gfs, legal_alignas_type t = true -> legal_nested_field0 t gfs -> (alignof (nested_field_type t gfs) | alignof t).  Lemma alignof_nested_field_array_type_eq: forall t gfs lo hi i, legal_alignas_type t = true -> legal_nested_field0 t (ArraySubsc lo :: gfs) -> alignof (nested_field_array_type t gfs lo hi) = alignof (nested_field_type t (ArraySubsc i :: gfs)).  Lemma alignof_nested_field_array_type_divide_alignof: forall t gfs lo hi, legal_alignas_type t = true -> legal_nested_field0 t (ArraySubsc lo :: gfs) -> (alignof (nested_field_array_type t gfs lo hi) | alignof t).  Lemma gfield_offset_type_divide: forall gf t, legal_alignas_type t = true -> (alignof (gfield_type t gf) | gfield_offset t gf). *)
Lemma legal_nested_field0_field:
forall t gfs, legal_nested_field t gfs -> legal_nested_field0 t gfs.