Definition gupd_reptype_array t1 n a (i: Z) (t0: type) (v: list (reptype t1)) (v0: reptype t0) : reptype_structlist (ArrayField t1 n a i t0) :=
  if Z.eqb i 0 as b
    return reptype_structlist
             (if b
              then Fcons 1002%positive t0
                     (Fcons 1003%positive (Tarray t1 (n - 1) a) Fnil)
              else
                if (Z.eqb i (n - 1))
                then Fcons 1001%positive (Tarray t1 (n - 1) a)
                       (Fcons 1002%positive t0 Fnil)
                else Fcons 1001%positive (Tarray t1 i a)
                       (Fcons 1002%positive t0
                          (Fcons 1003%positive (Tarray t1 (n - i - 1) a) Fnil)))
  then (v0, skipn 1%nat v)
  else
    if Z.eqb i (n - 1) as b0
      return reptype_structlist
               (if b0
                then Fcons 1001%positive (Tarray t1 (n - 1) a)
                       (Fcons 1002%positive t0 Fnil)
                else Fcons 1001%positive (Tarray t1 i a)
                       (Fcons 1002%positive t0
                          (Fcons 1003%positive (Tarray t1 (n - i - 1) a) Fnil)))
    then (v, v0)
    else (v, (v0, skipn (nat_of_Z (i + 1)) v)).Fixpoint gupd_reptype_structlist f (i0: ident) (t0: type) (v: reptype_structlist f) (v0: reptype t0) : reptype_structlist (all_fields_replace_one2 f i0 t0) :=
  let res :=
  match f as f'
    return reptype_structlist f' ->
           reptype_structlist (match f' with
                               | Fnil => Fnil
                               | Fcons i1 t1 flds0 =>
                                 if ident_eq i0 i1
                                 then Fcons i1 t0 flds0
                                 else Fcons i1 t1 (all_fields_replace_one2 flds0 i0 t0)
                               end)
  with
  | Fnil => fun _ => struct_default_val _
  | Fcons i1 t1 flds0 => fun v =>
   (if ident_eq i0 i1 as b
      return reptype_structlist (if b
                                 then Fcons i1 t0 flds0
                                 else Fcons i1 t1 (all_fields_replace_one2 flds0 i0 t0))
    then
     (if is_Fnil flds0 as b0
        return (if b0 then reptype t1 else reptype t1 * reptype_structlist flds0) ->
               (if b0 then reptype t0 else reptype t0 * reptype_structlist flds0)
      then fun _ => v0
      else fun v => (v0, snd v)
     ) v
    else
     (if is_Fnil flds0 as b0
        return (if b0 then reptype t1 else reptype t1 * reptype_structlist flds0) ->
               (if is_Fnil (all_fields_replace_one2 flds0 i0 t0) then reptype t1 else reptype t1 *
                   reptype_structlist (all_fields_replace_one2 flds0 i0 t0))
      then
        if is_Fnil (all_fields_replace_one2 flds0 i0 t0) as b1
          return reptype t1 ->
                 (if b1 then reptype t1 else reptype t1 *
                     reptype_structlist (all_fields_replace_one2 flds0 i0 t0))
        then fun v => v
        else fun _ => (default_val _, struct_default_val _) (* impossible situation *)
      else
        if is_Fnil (all_fields_replace_one2 flds0 i0 t0) as b1
          return reptype t1 * reptype_structlist flds0 ->
                 (if b1 then reptype t1 else reptype t1 *
                     reptype_structlist (all_fields_replace_one2 flds0 i0 t0))
        then fun _ => default_val _
        else fun v => (fst v, gupd_reptype_structlist flds0 i0 t0 (snd v) v0)
      ) v
   )
  end v
  in
  eq_rect_r reptype_structlist res (gupd_reptype_structlist_aux f i0 t0).Definition gupd_reptype_unionlist (i0: ident) (t0: type) (v0: reptype t0) : reptype_unionlist (Fcons i0 t0 Fnil) := v0.Fixpoint gupd_reptype (t: type) (gfs: list gfield) (t0: type) (v: reptype t) (v0: reptype t0): reptype (nf_replace2 t gfs t0) :=
  match gfs as gfs' return reptype (nf_replace2 t gfs' t0) with
  | nil => v0
  | ArraySubsc i :: gfs0 =>
      match nested_field_type2 t gfs0 as T
        return reptype T ->
               reptype (match T with
                        | Tarray t1 n a =>
                          nf_replace2 t gfs0
                            (Tstruct 1000%positive (ArrayField t1 n a i t0) noattr)
                        | _ => t
                        end)
      with
      | Tarray t1 n a =>
        fun v1 => gupd_reptype t gfs0 (Tstruct 1000%positive (ArrayField t1 n a i t0) noattr) v
                    (gupd_reptype_array t1 n a i t0 v1 v0)
      | _ => fun _ => default_val _
      end (proj_reptype t gfs0 v)
  | StructField i :: gfs0 =>
    match nested_field_type2 t gfs0 as T
      return reptype T -> reptype (match T with
                                   | Tstruct i0 f a => nf_replace2 t gfs0
                                     (Tstruct i0 (all_fields_replace_one2 f i t0) a)
                                   | _ => t
                                   end)
    with
    | Tstruct i0 f a => fun v1 => gupd_reptype t gfs0 (Tstruct i0 (all_fields_replace_one2 f i t0) a) v
                                 (gupd_reptype_structlist f i t0 v1 v0)
    | _ => fun _ => default_val _
    end (proj_reptype t gfs0 v)
  | UnionField i :: gfs0 =>
    match nested_field_type2 t gfs0 as T
      return reptype T -> reptype (match T with
                                   | Tunion i0 f a => nf_replace2 t gfs0
                                     (Tunion i0 (Fcons i t0 Fnil) a)
                                   | _ => t
                                   end)
    with
    | Tunion i0 f a => fun _ => gupd_reptype t gfs0 (Tunion i0 (Fcons i t0 Fnil)a) v
                                 (gupd_reptype_unionlist i t0 v0)
    | _ => fun _ => default_val _
    end (proj_reptype t gfs0 v)
  end.Definition proj_except_reptype_array t1 n a (i: Z) (v: list (reptype t1)) : reptype_structlist (all_fields_except_one2 (ArrayField t1 n a i Tvoid) 1002%positive):=
  if Z.eqb i 0 as b
    return reptype_structlist (all_fields_except_one2
             (if b
              then Fcons 1002%positive Tvoid
                     (Fcons 1003%positive (Tarray t1 (n - 1) a) Fnil)
              else
                if (Z.eqb i (n - 1))
                then Fcons 1001%positive (Tarray t1 (n - 1) a)
                       (Fcons 1002%positive Tvoid Fnil)
                else Fcons 1001%positive (Tarray t1 i a)
                       (Fcons 1002%positive Tvoid
                          (Fcons 1003%positive (Tarray t1 (n - i - 1) a) Fnil)))
             1002%positive)
  then skipn 1%nat v
  else
    if Z.eqb i (n - 1) as b0
      return reptype_structlist (all_fields_except_one2
               (if b0
                then Fcons 1001%positive (Tarray t1 (n - 1) a)
                       (Fcons 1002%positive Tvoid Fnil)
                else Fcons 1001%positive (Tarray t1 i a)
                       (Fcons 1002%positive Tvoid
                          (Fcons 1003%positive (Tarray t1 (n - i - 1) a) Fnil)))
               1002%positive)
    then v
    else (v, skipn (nat_of_Z (i + 1)) v).Fixpoint proj_except_reptype_structlist (f: fieldlist) (id: ident) (v: reptype_structlist f): reptype_structlist (all_fields_except_one2 f id) :=
  let res :=
  match f as f'
    return reptype_structlist f' ->
           reptype_structlist (match f' with
                               | Fnil => Fnil
                               | Fcons i t f0 =>
                                   if ident_eq id i
                                   then f0
                                   else Fcons i t (all_fields_except_one2 f0 id)
                               end)
  with
  | Fnil => fun v => v
  | Fcons i t f0 => fun v =>
     if ident_eq id i as b
       return reptype_structlist (if b
                                  then f0
                                  else Fcons i t (all_fields_except_one2 f0 id))
     then
      (if (is_Fnil f0) as b0
         return (if b0 then reptype t else reptype t * reptype_structlist f0) -> reptype_structlist f0
       then fun _ => struct_default_val _
       else fun v => snd v) v
     else
      (if (is_Fnil f0) as b0
         return (if b0 then reptype t else reptype t * reptype_structlist f0) ->
                (if is_Fnil (all_fields_except_one2 f0 id) then reptype t else
                 reptype t * reptype_structlist (all_fields_except_one2 f0 id))
       then fun v =>
         if is_Fnil (all_fields_except_one2 f0 id) as b1
           return if b1 then reptype t else
                  reptype t * reptype_structlist (all_fields_except_one2 f0 id)
         then v
         else (v, struct_default_val _)
       else fun v =>
         if is_Fnil (all_fields_except_one2 f0 id) as b1
           return if b1 then reptype t else
                  reptype t * reptype_structlist (all_fields_except_one2 f0 id)
         then fst v
         else (fst v, proj_except_reptype_structlist f0 id (snd v))
      ) v
  end v
  in
  match f as f'
    return reptype_structlist (match f' with
                               | Fnil => Fnil
                               | Fcons i t f0 =>
                                   if ident_eq id i
                                   then f0
                                   else Fcons i t (all_fields_except_one2 f0 id)
                               end) ->
           reptype_structlist (all_fields_except_one2 f' id)
  with
  | Fnil => fun v => v
  | _ => fun v => v
  end res.Definition proj_except_reptype_unionlist: reptype_unionlist Fnil := union_default_val _.Definition proj_except_reptype (t: type) (gf: gfield) (gfs: list gfield) (v: reptype t) : reptype (nf_sub2 t gf gfs) :=
  match gf as GF
    return reptype (nested_field_type2 t gfs) ->
           reptype match GF, nested_field_type2 t gfs with
                   | ArraySubsc i, Tarray t0 n a =>
                     nf_replace2 t gfs (Tstruct 1000%positive
                       (all_fields_except_one2 (ArrayField t0 n a i Tvoid) 1002%positive) noattr)
                   | StructField i, Tstruct i0 f a =>
                     nf_replace2 t gfs (Tstruct i0 (all_fields_except_one2 f i) a)
                   | UnionField i, Tunion i0 f a =>
                     nf_replace2 t gfs (Tunion i0 Fnil a)
                   | _, _ => t
                   end
  with
  | ArraySubsc i =>
    match nested_field_type2 t gfs as T
      return reptype T ->
             reptype match T with
                     | Tarray t0 n a =>
                       nf_replace2 t gfs (Tstruct 1000%positive
                         (all_fields_except_one2 (ArrayField t0 n a i Tvoid) 1002%positive) noattr)
                     | _ => t
                     end
    with
    | Tarray t0 n a =>
      fun v0 => gupd_reptype t gfs
            (Tstruct 1000%positive
              (all_fields_except_one2 (ArrayField t0 n a i Tvoid) 1002%positive) noattr) v
                             (proj_except_reptype_array t0 n a i v0)
    | _ => fun _ => default_val _
    end
  | StructField i  =>
    match nested_field_type2 t gfs as T
      return reptype T ->
             reptype match T with
                     | Tstruct i0 f a =>
                         nf_replace2 t gfs (Tstruct i0 (all_fields_except_one2 f i) a)
                     | _ => t
                     end
    with
    | Tstruct i0 f a => fun v0 => gupd_reptype t gfs (Tstruct i0 (all_fields_except_one2 f i) a) v
                          (proj_except_reptype_structlist f i v0)
    | _ => fun _ => default_val _
    end
  | UnionField i =>
    match nested_field_type2 t gfs as T
      return reptype T ->
             reptype match T with
                     | Tunion i0 f a =>
                         nf_replace2 t gfs (Tunion i0 Fnil a)
                     | _ => t
                     end
    with
    | Tunion i0 f a => fun v0 => gupd_reptype t gfs (Tunion i0 Fnil a) v proj_except_reptype_unionlist
    | _ => fun _ => default_val _
    end
  end (proj_reptype t gfs v).Definition upd_reptype_array t0 (i: Z) (v: list (reptype t0)) (v0: reptype t0) : list (reptype t0) :=
  (force_lengthn (nat_of_Z i) v (default_val _)) ++ (v0 :: skipn (nat_of_Z (i + 1)) v).Fixpoint upd_reptype_structlist f (i0: ident) (ofs: Z) (v: reptype_structlist f)
  (v0: reptype match field_offset_rec i0 f ofs, field_type i0 f with
               | Errors.OK _, Errors.OK t0 => t0
               | _, _ => Tvoid
               end) : reptype_structlist f :=
  match f as f'
    return reptype_structlist f' ->
           reptype match field_offset_rec i0 f' ofs, field_type i0 f' with
                   | Errors.OK _, Errors.OK t0 => t0
                   | _, _ => Tvoid
                   end ->
           reptype_structlist f'
  with
  | Fnil => fun _ _ => struct_default_val _
  | Fcons i1 t1 flds0 =>
    if ident_eq i0 i1 as b
      return reptype_structlist (Fcons i1 t1 flds0) ->
             reptype match (if b
                            then Errors.OK (align ofs (alignof t1))
                            else field_offset_rec i0 flds0 (align ofs (alignof t1) + sizeof t1)),
                           (if b then Errors.OK t1 else field_type i0 flds0) with
                     | Errors.OK _, Errors.OK t0 => t0
                     | _, _ => Tvoid
                     end ->
             reptype_structlist (Fcons i1 t1 flds0)
    then if (is_Fnil flds0) as b0
           return (if b0 then reptype t1 else (reptype t1 * reptype_structlist flds0)%type) ->
                  reptype match Errors.OK (align ofs (alignof t1)), Errors.OK t1 with
                          | Errors.OK _, Errors.OK t0 => t0
                          | _, _ => Tvoid
                          end ->
                  if b0 then reptype t1 else (reptype t1 * reptype_structlist flds0)%type
         then fun _ v2 => v2
         else fun v1 v2 => (v2, snd v1)
    else if (is_Fnil flds0) as b0
           return (if b0 then reptype t1 else (reptype t1 * reptype_structlist flds0)%type) ->
                  reptype match field_offset_rec i0 flds0 (align ofs (alignof t1) + sizeof t1),
                                field_type i0 flds0 with
                          | Errors.OK _, Errors.OK t0 => t0
                          | _, _ => Tvoid
                          end ->
                  if b0 then reptype t1 else (reptype t1 * reptype_structlist flds0)%type
         then fun _ _ => default_val _
         else fun v1 v2 => (fst v1, upd_reptype_structlist flds0 i0 _ (snd v1) v2)
  end v v0.Fixpoint upd_reptype_unionlist f (i0: ident)
  (v0: reptype match field_type i0 f with
               | Errors.OK t0 => t0
               | _ => Tvoid
               end) : reptype_unionlist f :=
  match f as f'
    return reptype match field_type i0 f' with
                   | Errors.OK t0 => t0
                   | _ => Tvoid
                   end ->
           reptype_unionlist f'
  with
  | Fnil => fun _ => union_default_val _
  | Fcons i1 t1 flds0 =>
    if ident_eq i0 i1 as b
      return reptype match (if b then Errors.OK t1 else field_type i0 flds0) with
                     | Errors.OK t0 => t0
                     | _ => Tvoid
                     end ->
             reptype_unionlist (Fcons i1 t1 flds0)
    then if (is_Fnil flds0) as b0
           return reptype match Errors.OK t1 with
                          | Errors.OK t0 => t0
                          | _ => Tvoid
                          end ->
                  if b0 then reptype t1 else (reptype t1 + reptype_unionlist flds0)%type
         then fun v2 => v2
         else fun v2 => inl v2
    else if (is_Fnil flds0) as b0
           return reptype match field_type i0 flds0 with
                          | Errors.OK t0 => t0
                          | _ => Tvoid
                          end ->
                  if b0 then reptype t1 else (reptype t1 + reptype_unionlist flds0)%type
         then fun _ => default_val _
         else fun v2 => inr (upd_reptype_unionlist flds0 i0 v2)
  end v0.Fixpoint upd_reptype (t: type) (gfs: list gfield) (v: reptype t) (v0: reptype (nested_field_type2 t gfs)): reptype t :=
  match gfs as gfs'
    return reptype (nested_field_type2 t gfs') -> reptype t
  with
  | nil => fun v1 => v1
  | gf :: gfs0 => fun v1 =>
    let res :=
    match gf as GF
      return reptype (nested_field_type2 t gfs0) ->
             reptype match GF with
                     | ArraySubsc i =>
                       match nested_field_type2 t gfs0 with
                       | Tarray t0 n _ => t0
                       | _ => Tvoid
                       end
                     | StructField i =>
                       match nested_field_type2 t gfs0 with
                       | Tstruct i0 f a =>
                         match field_offset i f, field_type i f with
                         | Errors.OK _, Errors.OK t0 => t0
                         | _, _ => Tvoid
                         end
                       | _ => Tvoid
                       end
                     | UnionField i =>
                       match nested_field_type2 t gfs0 with
                       | Tunion i0 f a =>
                         match field_type i f with
                         | Errors.OK t0 => t0
                         | _ => Tvoid
                         end
                       | _ => Tvoid
                       end
                     end ->
             reptype (nested_field_type2 t gfs0)
    with
    | ArraySubsc i =>
      match nested_field_type2 t gfs0 as T
        return reptype T ->
               reptype (match T with
                        | Tarray t0 n a => t0
                        | _ => Tvoid
                        end) ->
               reptype T
      with
      | Tarray t0 n a => fun v2 v3 => upd_reptype_array t0 i v2 v3
      | _ => fun _ _=> default_val _
      end
    | StructField i =>
      match nested_field_type2 t gfs0 as T
        return reptype T ->
               reptype (match T with
                        | Tstruct i0 f a =>
                          match field_offset i f, field_type i f with
                          | Errors.OK _, Errors.OK t0 => t0
                          | _, _ => Tvoid
                          end
                        | _ => Tvoid
                        end) ->
               reptype T
      with
      | Tstruct i0 f a => fun v2 v3 => upd_reptype_structlist f i 0 v2 v3
      | _ => fun _ _ => default_val _
      end
    | UnionField i =>
      match nested_field_type2 t gfs0 as T
        return reptype T ->
               reptype (match T with
                        | Tunion i0 f a =>
                          match field_type i f with
                          | Errors.OK t0 => t0
                          | _ => Tvoid
                          end
                        | _ => Tvoid
                        end) ->
               reptype T
      with
      | Tunion i0 f a => fun _ v3 => upd_reptype_unionlist f i v3
      | _ => fun _ _ => default_val _
      end
    end (proj_reptype t gfs0 v) (eq_rect_r reptype v1 (eq_sym (nested_field_type2_cons _ _ _)))
    in upd_reptype t gfs0 v res
  end v0.

(* Specifications: *)
Lemma proj_reptype_nil: forall t v, nested_legal_fieldlist t = true -> JMeq (proj_reptype t nil v) v.
Lemma proj_reptype_cons_Tstruct: forall t id gfs i f a v v0, nested_legal_fieldlist t = true -> nested_field_type2 t gfs = Tstruct i f a -> JMeq (proj_reptype t gfs v) v0 -> JMeq (proj_reptype t (StructField id :: gfs) v) (proj_reptype_structlist id f 0 v0).
Lemma upd_reptype_nil: forall t v v0, upd_reptype t nil v v0 = v0.
Lemma upd_reptype_cons: forall t gf gfs v v0 v0', legal_nested_field t (gf :: gfs) -> JMeq v0 v0' -> upd_reptype t (gf :: gfs) v v0 = upd_reptype t gfs v (upd_reptype _ (gf :: nil) (proj_reptype t gfs v) v0').