Section cs_preserve.
Context (cs_from cs_to: compspecs).
Definition test_aux (b: bool) (i: ident): bool :=
b && match (@cenv_cs cs_from) ! i, (@cenv_cs cs_to) ! i with
| Some co_from, Some co_to => eqb_list eqb_member (co_members co_from) (co_members co_to) && eqb_su (co_su co_from) (co_su co_to) && eqb_attr (co_attr co_from) (co_attr co_to)
| _, _ => false
end.
Fixpoint cs_preserve_type (coeq: PTree.t bool) (t: type): bool :=
match t with
| Tarray t0 _ _ => cs_preserve_type coeq t0
| Tstruct id _ => match coeq ! id with | Some b => test_aux b id | _ => false end
| Tunion id _ => match coeq ! id with | Some b => test_aux b id | _ => false end
| _ => true
end.
Fixpoint cs_preserve_members (coeq: PTree.t bool) (m: members): bool :=
match m with
| nil => true
| ((_, t) :: m) => andb (cs_preserve_type coeq t) (cs_preserve_members coeq m)
end.
Class change_composite_env: Type := {
coeq: PTree.t bool;
coeq_consistent:
forall i co b,
(@cenv_cs cs_to) ! i = Some co ->
coeq ! i = Some b ->
b = cs_preserve_members coeq (co_members co);
coeq_complete:
forall i,
(exists co, (@cenv_cs cs_to) ! i = Some co) <->
(exists b, coeq ! i = Some b)
}.
Definition cs_preserve_env: PTree.t bool :=
let l := composite_reorder.rebuild_composite_elements (@cenv_cs cs_to) in
fold_right (fun (ic: positive * composite) (T0: PTree.t bool) => let (i, co) := ic in let T := T0 in PTree.set i (cs_preserve_members T (co_members co)) T) (PTree.empty _) l.

(* Specifications: *)
Lemma aux1: forall T co,
(fix fm (l : list (ident * type * bool)) : bool :=
match l with
| nil => true
| (_, _, b) :: l' => b && fm l'
end)
(map
(fun it0 : positive * type =>
let (i0, t0) := it0 in
(i0, t0,
type_func.F (fun t : type => match t with | Tstruct _ _ | Tunion _ _ => false | _ => true end) (fun (b : bool) (_ : type) (_ : Z) (_ : attr) => b)
(fun (b : bool) (id : ident) (_ : attr) => test_aux b id)
(fun (b : bool) (id : ident) (_ : attr) => test_aux b id) T t0)) (co_members co)) =
cs_preserve_members T (co_members co).
Lemma aux2:
type_func.Env (fun t : type => match t with | Tstruct _ _ | Tunion _ _ => false | _ => true end) (fun (b : bool) (_ : type) (_ : Z) (_ : attr) => b)
(fun (b : bool) (id : ident) (_ : attr) => test_aux b id)
(fun (b : bool) (id : ident) (_ : attr) => test_aux b id)
(fun _ : struct_or_union =>
fix fm (l : list (ident * type * bool)) : bool :=
match l with
| nil => true
| (_, _, b) :: l' => b && fm l'
end) (composite_reorder.rebuild_composite_elements cenv_cs) =
cs_preserve_env.
Lemma cs_preserve_env_consisent: forall (coeq: PTree.t bool),
coeq = cs_preserve_env ->
forall i co b,
(@cenv_cs cs_to) ! i = Some co ->
coeq ! i = Some b ->
b = cs_preserve_members coeq (co_members co).
Lemma cs_preserve_completeness: forall (coeq: PTree.t bool),
coeq = cs_preserve_env ->
forall i,
(exists co, (@cenv_cs cs_to) ! i = Some co) <->
(exists b, coeq ! i = Some b).