Program Instance Linker_composite_defs : Linker (list composite_definition) := {
link := link_composite_defs;
linkorder := @List.incl composite_definition
}.
Next Obligation.
apply incl_refl.
Defined.
Next Obligation.
red; intros; eauto.
Defined.
Next Obligation.
apply link_composite_def_inv in H; destruct H as (A & B & C).
split; red; intros; apply C; auto.
Defined.
(** Connections with [build_composite_env]. *)

(* Specifications: *)
Lemma add_composite_definitions_append:
forall l1 l2 env env'',
add_composite_definitions env (l1 ++ l2) = OK env'' <->
exists env', add_composite_definitions env l1 = OK env' /\ add_composite_definitions env' l2 = OK env''.
Lemma composite_eq:
forall su1 m1 a1 sz1 al1 r1 pos1 al2p1 szal1
su2 m2 a2 sz2 al2 r2 pos2 al2p2 szal2,
su1 = su2 -> m1 = m2 -> a1 = a2 -> sz1 = sz2 -> al1 = al2 -> r1 = r2 ->
Build_composite su1 m1 a1 sz1 al1 r1 pos1 al2p1 szal1 = Build_composite su2 m2 a2 sz2 al2 r2 pos2 al2p2 szal2.
Lemma composite_of_def_eq:
forall env id co,
composite_consistent env co ->
env!id = None ->
composite_of_def env id (co_su co) (co_members co) (co_attr co) = OK co.
Lemma composite_consistent_unique:
forall env co1 co2,
composite_consistent env co1 ->
composite_consistent env co2 ->
co_su co1 = co_su co2 ->
co_members co1 = co_members co2 ->
co_attr co1 = co_attr co2 ->
co1 = co2.
Lemma composite_of_def_stable:
forall (env env': composite_env)
(EXTENDS: forall id co, env!id = Some co -> env'!id = Some co)
id su m a co,
env'!id = None ->
composite_of_def env id su m a = OK co ->
composite_of_def env' id su m a = OK co.
Lemma link_add_composite_definitions:
forall l0 env0,
build_composite_env l0 = OK env0 ->
forall l env1 env1' env2,
add_composite_definitions env1 l = OK env1' ->
(forall id co, env1!id = Some co -> env2!id = Some co) ->
(forall id co, env0!id = Some co -> env2!id = Some co) ->
(forall id, env2!id = if In_dec ident_eq id (map name_composite_def l0) then env0!id else env1!id) ->
((forall cd1 cd2, In cd1 l0 -> In cd2 l -> name_composite_def cd2 = name_composite_def cd1 -> cd2 = cd1)) ->
{ env2' |
add_composite_definitions env2 (filter_redefs l0 l) = OK env2'
/\ (forall id co, env1'!id = Some co -> env2'!id = Some co)
/\ (forall id co, env0!id = Some co -> env2'!id = Some co) }.
Theorem link_build_composite_env:
forall l1 l2 l env1 env2,
build_composite_env l1 = OK env1 ->
build_composite_env l2 = OK env2 ->
link l1 l2 = Some l ->
{ env |
build_composite_env l = OK env
/\ (forall id co, env1!id = Some co -> env!id = Some co)
/\ (forall id co, env2!id = Some co -> env!id = Some co) }.