Require Import Arith. Require Import Bool. Require Import List. Require Import Natmap. Require Import FMaps. Require Import EqNat. Require Import lj_definitions. Require Import lj_infrastructure. Require Import lj_soundness. Require Import lj_constraint_definitions. Require Import lj_constraint_infrastructure. Require Import lj_constraint_soundness. Require Import LFJ_definitions. Require Import base2. Section Composition. Definition sat_meth_constr_p (dcl' : dcl) (ms' : ms) (p : P) : bool := match head (path p (cl_dcl dcl')) with Some (cld_def _ _ _ mds') => meth_in_mds mds' ms' | None => false end. Fixpoint sat_comp_constr_p (c_list : list comp_constraint) (p : P) : bool := match c_list with (introduced_method_constr ms' dcl' _) :: c_list' => sat_meth_constr_p dcl' ms' p && (sat_comp_constr_p c_list' p) | (introduced_class_constr dcl' _) :: c_list' => in_clds dcl' p && (sat_comp_constr_p c_list' p) | nil => true end. Lemma eq_vd_list_eq : forall (vd_list1 vd_list2 : list vd), vd_list_eq vd_list1 vd_list2 = true <-> vd_list1 = vd_list2. induction vd_list1; destruct vd_list2; pa; intros; auto. simpl in H; discriminate. discriminate. simpl in H; destruct a; destruct t; discriminate. discriminate. simpl in H; destruct a; destruct v; destruct t; destruct t0. generalize H; clear H; case (eq_nat_dec v0 v); intros. destruct (andb_prop _ _ H). rewrite ((proj1 (eq_cl_eq _ _)) H0). rewrite ((proj1 (IHvd_list1 _)) H1). congruence. discriminate. inversion H; subst. simpl; destruct v; destruct t; case (eq_nat_dec v v); intros. apply andb_true_intro; pa. destruct c; simpl. case (eq_nat_dec d d); intros; auto. auto. applyI IHvd_list1. congruence. Qed. Lemma eq_ms_eq : forall (ms1 ms2 : ms), ms_eq ms1 ms2 = true <-> ms1 = ms2. destruct ms1; destruct ms2; destruct t; destruct t0; simpl; case (eq_nat_dec m m0); pa; intros. destruct (andb_prop _ _ H). rewrite ((proj1 (eq_cl_eq _ _)) H0). rewrite ((proj1 (eq_vd_list_eq _ _)) H1); congruence. inversion H; subst; apply andb_true_intro; pa. applyI eq_cl_eq; auto. applyI eq_vd_list_eq; auto. discriminate. congruence. Qed. Lemma sat_comp_constr_app_ps : forall (c_list1 c_list2 : list comp_constraint) (ft : FT) (ps : PSpec), (sat_comp_constr_ps ft ps (c_list1 ++ c_list2) = true) <-> (sat_comp_constr_ps ft ps c_list1 = true /\ sat_comp_constr_ps ft ps c_list2 = true). induction c_list1; simpl; pa; intros. pa; simpl; auto. bd H. destruct a; pa. destruct (andb_prop _ _ H); apply andb_true_intro; pa. exact (proj1 ((proj1 (IHc_list1 _ _ _)) H1)). destruct (andb_prop _ _ H); exact (proj2 ((proj1 (IHc_list1 _ _ _)) H1)). destruct (andb_prop _ _ H); apply andb_true_intro; pa. exact (proj1 ((proj1 (IHc_list1 _ _ _)) H1)). destruct (andb_prop _ _ H); exact (proj2 ((proj1 (IHc_list1 _ _ _)) H1)). destruct a; bd H. destruct (andb_prop _ _ H2); apply andb_true_intro; pa. applyI IHc_list1; pa. destruct (andb_prop _ _ H2); apply andb_true_intro; pa. applyI IHc_list1; pa. Qed. Lemma sat_comp_constr_app_p : forall (c_list1 c_list2 : list comp_constraint) (p : P), (sat_comp_constr_p (c_list1 ++ c_list2) p = true) <-> (sat_comp_constr_p c_list1 p = true /\ sat_comp_constr_p c_list2 p = true). induction c_list1; simpl; pa; intros. pa; simpl; auto. bd H. destruct a; pa. destruct (andb_prop _ _ H); apply andb_true_intro; pa. exact (proj1 ((proj1 (IHc_list1 _ _)) H1)). destruct (andb_prop _ _ H); exact (proj2 ((proj1 (IHc_list1 _ _)) H1)). destruct (andb_prop _ _ H); apply andb_true_intro; pa. exact (proj1 ((proj1 (IHc_list1 _ _)) H1)). destruct (andb_prop _ _ H); exact (proj2 ((proj1 (IHc_list1 _ _)) H1)). destruct a; bd H. destruct (andb_prop _ _ H2); apply andb_true_intro; pa. applyI IHc_list1; pa. destruct (andb_prop _ _ H2); apply andb_true_intro; pa. applyI IHc_list1; pa. Qed. Lemma cons_option_Some : forall (A : Type) (a : A) (l : option (list A)) (la : list A), cons_option a l = Some la -> exists la', l = Some la'. intros A a l; case l; intros. exists l0; reflexivity. simpl in H; discriminate. Qed. Lemma In_mds_In_compose : forall (mds mds' : list md) (rmb' : rmb) (ms' ms'': ms) (mb' : mb), compose_refined_md mds (rmd_def ms' rmb') = Some mds' -> In (md_def ms'' mb') mds -> exists mb'', In (md_def ms'' mb'') mds'. induction mds; simpl; intros. discriminate. bd H0. subst; destruct mb'; destruct rmb'. caseEq (ms_eq ms'' ms'); intros H0; rewrite H0 in H. inversion H. exists (mb_def (l0 ++ l ++ l1) x0); simpl; po1; rewrite ((proj1 (eq_ms_eq ms'' ms')) H0); reflexivity. destruct (cons_option_Some _ _ _ _ H); unfold cons_option in H; rewrite H1 in H; inversion H. exists (mb_def l x); simpl; po1. destruct a; destruct m0; destruct rmb'. caseEq (ms_eq m ms'); intros H1; rewrite H1 in H. inversion H; subst. exists mb'; simpl; po2. destruct (cons_option_Some _ _ _ _ H); unfold cons_option in H; rewrite H2 in H; inversion H. destruct (IHmds _ _ _ _ _ H2 H0). exists x2; simpl; po2. Qed. Lemma In_compose_In_mds : forall (mds mds' : list md) (rmb' : rmb) (ms' ms'': ms) (mb': mb), compose_refined_md mds (rmd_def ms' rmb') = Some mds' -> In (md_def ms'' mb') mds' -> exists mb'', In (md_def ms'' mb'') mds. induction mds; simpl; intros. discriminate. bd H0. destruct a; destruct m0; destruct rmb'. caseEq (ms_eq m ms'); intros H1; rewrite H1 in H. inversion H; rewrite <- H3 in H0. simpl in H0; bd H0. inversion H0. exists (mb_def l x); po1. exists mb'; po2. destruct (cons_option_Some _ _ _ _ H); rewrite H2 in H; simpl in H; inversion H. rewrite <- H4 in H0; simpl in H0; bd H0. inversion H0. exists (mb_def l x); po1. destruct (IHmds _ _ _ _ _ H2 H0). exists x2; po2. Qed. Lemma in_mds_In_mds : forall (mds : list md) (ms' : ms), meth_in_mds mds ms' = true -> exists mb', In (md_def ms' mb') mds. induction mds; simpl. intros; discriminate. intro; destruct a; caseEq (ms_eq ms' m); intros. exists m0; po1; rewrite ((proj1 (eq_ms_eq _ _ )) H); reflexivity. destruct (IHmds _ H0). exists x; po2. Qed. Lemma In_mds_in_mds : forall (mds : list md) (ms' : ms) (mb' : mb), In (md_def ms' mb') mds -> meth_in_mds mds ms' = true. induction mds; simpl. intros; contradiction. intros; bd H. rewrite H; caseEq (ms_eq ms' ms'); intros; try reflexivity. rewrite (((proj2 (eq_ms_eq _ _ )) (refl_equal ms'))) in H0; discriminate. destruct a. rewrite (IHmds _ _ H); case (ms_eq ms' m); reflexivity. Qed. Lemma in_rclds_in_p : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds : list md) (rmds : list rmd) (p p' : P), compose_refines_class p (refines_cld_def dcl' cl' fds' mds rmds) = Some p' -> exists fds'', exists mds'', In (cld_def dcl' cl' fds'' mds'') p'. induction p; intros. simpl in H; discriminate. destruct a; simpl in H. generalize H; clear H; case (eq_nat_dec d dcl'); intros. caseEq (compose_refined_mds l0 rmds); intros; rewrite H0 in H. inversion H. exists (introduce_fields l fds'); exists (introduce_methods l1 mds); simpl; rewrite e; po1. discriminate. unfold cons_option in H; caseEq (compose_refines_class p (refines_cld_def dcl' cl' fds' mds rmds)); intros; rewrite H0 in H. inversion H. import (IHp _ H0). bd H1. exists x; exists x0; po2. discriminate. Qed. Lemma in_rclds_mds_in_p : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (ms' : ms) (mds : list md) (mb' : mb) (rmds : list rmd) (p p' : P), compose_refines_class p (refines_cld_def dcl' cl' fds' mds rmds) = Some p' -> In (md_def ms' mb') mds -> exists fds'', exists mds'', In (cld_def dcl' cl' fds'' mds'') p' /\ (exists mb'', In (md_def ms' mb'') mds''). induction p; intros. simpl in H; discriminate. destruct a; simpl in H. generalize H; clear H; case (eq_nat_dec d dcl'); intros. caseEq (compose_refined_mds l0 rmds); intros; rewrite H1 in H. inversion H. exists (introduce_fields l fds'); exists (introduce_methods l1 mds); simpl; rewrite e; pa. po1. generalize H0; clear; induction mds. simpl; intros; contradiction. destruct a; simpl. intros; bd H0. inversion H0; subst. exists mb'. clear; induction (introduce_methods l1 mds). simpl; po1. destruct a; simpl. simpl; caseEq (ms_eq m ms'); intros. simpl; po1. simpl; po2. destruct (IHmds H0). cs (m = ms'); subst. exists m0. clear; induction (introduce_methods l1 mds). simpl; po1. destruct a; simpl. simpl; caseEq (ms_eq m ms'); intros. simpl; po1. simpl; po2. simpl; exists x. generalize H H1; clear; induction (introduce_methods l1 mds). simpl; intros; contradiction. destruct a; simpl; intros. bd H. inversion H; subst. simpl; caseEq (ms_eq ms' m); intros. rewrite ((proj1 (eq_ms_eq _ _)) H0) in H1. congruence. simpl; po1. case (ms_eq m1 m). simpl; po2. simpl; po2; auto. discriminate. destruct (cons_option_Some _ _ _ _ H). import (IHp _ H1 H0); bd H2. rewrite H1 in H; simpl in H; inversion H. exists x0; exists x1; pa. simpl; po2. exists x2; exact H2. Qed. Lemma in_p_in_compose_rcld : forall (dcl' dcl'': dcl) (cl' cl'' : cl) (fds' fds'': list fd) (mds' mds'': list md) (rmds : list rmd) (p p' : P), dcl' <> dcl'' -> In (cld_def dcl' cl' fds' mds') p -> compose_refines_class p (refines_cld_def dcl'' cl'' fds'' mds'' rmds) = Some p' -> In (cld_def dcl' cl' fds' mds') p'. induction p. simpl; contradiction. destruct a; simpl; case (eq_nat_dec d dcl''); intros. bd H0. congruence. destruct (compose_refined_mds l0 rmds). inversion H1. simpl; po2. discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1. bd H0. inversion H0; subst. inversion H1; po1. import (IHp _ H H0 H2). inversion H1; po2. Qed. Lemma in_p_in_compose_rcld' : forall (dcl': dcl) (cl' cl'' : cl) (fds' fds'': list fd) (mds' mds'': list md) (rmds : list rmd) (p p' : P), In (cld_def dcl' cl' fds' mds') p -> distinct _ (names p) -> compose_refines_class p (refines_cld_def dcl' cl'' fds'' mds'' rmds) = Some p' -> exists mds''', compose_refined_mds mds' rmds = Some mds''' /\ In (cld_def dcl' cl'' (introduce_fields fds' fds'') (introduce_methods mds''' mds'')) p'. induction p. simpl; contradiction. destruct a; simpl; case (eq_nat_dec d dcl'); intros. bd H. inversion H; subst. destruct (compose_refined_mds mds' rmds). exists l; pa. inversion H1; simpl; po1. discriminate. caseEq (compose_refined_mds l0 rmds); intros; rewrite H2 in H1; inversion H1. bd H0; subst. elimtype False; apply H6; generalize H; clear; induction p. simpl; auto. simpl; destruct a; intros. bd H. inversion H; subst; po1. simpl; po2; auto. bd H. congruence. bd H0; destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1; inversion H1. import (IHp _ H H0 H2). bd H3. exists x0; pa. simpl; po2. Qed. Lemma in_compose_rcld_in_p : forall (dcl' dcl'': dcl) (cl' cl'' : cl) (fds' fds'': list fd) (mds' mds'': list md) (rmds : list rmd) (p p' : P), dcl' <> dcl'' -> In (cld_def dcl' cl' fds' mds') p' -> compose_refines_class p (refines_cld_def dcl'' cl'' fds'' mds'' rmds) = Some p' -> In (cld_def dcl' cl' fds' mds') p. induction p. simpl; intros; discriminate. destruct a; simpl; case (eq_nat_dec d dcl''); intros. subst. destruct (compose_refined_mds l0 rmds). inversion H1; subst. simpl in H0; bd H0. inversion H0. congruence. simpl; po2. discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1. inversion H1; subst; clear H1. simpl in H0; bd H0. po1. import (IHp _ H H0 H2). po2. Qed. Lemma in_compose_rcld_in_p' : forall (dcl': dcl) (cl' cl'' : cl) (fds1 fds2: list fd) (mds1 mds2: list md) (rmds : list rmd) (p p' : P), In (cld_def dcl' cl' fds1 mds1) p' -> distinct _ (names p) -> compose_refines_class p (refines_cld_def dcl' cl'' fds2 mds2 rmds) = Some p' -> exists mds', exists mds'', compose_refined_mds mds' rmds = Some mds'' /\ mds1 = (introduce_methods mds'' mds2) /\ exists fds', fds1 = introduce_fields fds' fds2 /\ exists cl'', In (cld_def dcl' cl'' fds' mds') p. induction p. simpl; intros; discriminate. destruct a; simpl; case (eq_nat_dec d dcl'); intros. bd H0. caseEq (compose_refined_mds l0 rmds); intros; rewrite H2 in H1. inversion H1; subst; clear H1. simpl in H; bd H. inversion H; subst. exists l0; exists l1; repeat pa. exists l; pa. exists c; po1. elimtype False; apply H4. apply (In_names _ _ _ _ _ H). discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1; inversion H1; subst; clear H1. simpl in H; bd H. congruence. bd H0. import (IHp _ H H0 H2); bd H1; subst. exists x0; exists x1; repeat pa; exists x2; pa; exists x3; po2. Qed. Lemma in_mds_in_compose : forall (ms' : ms) (rmds' : list rmd) (mds' mds'' : list md), meth_in_mds mds' ms' = true -> compose_refined_mds mds' rmds' = Some mds'' -> meth_in_mds mds'' ms' = true. induction rmds'. simpl; congruence. destruct a; simpl. intros mds' mds''; caseEq (compose_refined_mds mds' rmds'); intros. import (IHrmds' _ _ H0 H); clear IHrmds' H0 H. generalize mds'' mds' H1 H2; clear. induction l; intros; simpl in H2. discriminate. destruct a. simpl in H1; destruct m1; destruct r. caseEq (ms_eq ms' m0); caseEq (ms_eq m0 m); intros; rewrite H0 in H2; rewrite H in H1. inversion H1; simpl. rewrite H0; auto. destruct (cons_option_Some _ _ _ _ H1); rewrite H3 in H1; simpl in H1; inversion H1. simpl; rewrite H0; auto. inversion H1; simpl; rewrite H0; exact H2. destruct (cons_option_Some _ _ _ _ H1); rewrite H3 in H1; simpl in H1; inversion H1. simpl; rewrite H0; auto. discriminate. Qed. Lemma in_compose_in_mds : forall (ms' : ms) (rmds' : list rmd) (mds' mds'' : list md), meth_in_mds mds'' ms' = true -> compose_refined_mds mds' rmds' = Some mds'' -> meth_in_mds mds' ms' = true. induction rmds'. simpl; congruence. destruct a; simpl. intros mds' mds''; caseEq (compose_refined_mds mds' rmds'); intros. apply (IHrmds' mds' l); auto. generalize mds'' H0 H1; clear; induction l. simpl; intros; discriminate. destruct a; simpl; destruct m1; destruct r; caseEq (ms_eq ms' m0); auto; caseEq (ms_eq m0 m). intros; inversion H2; subst. simpl in H1; rewrite H0 in H1; auto. intros; destruct (cons_option_Some _ _ _ _ H2); rewrite H3 in H2; simpl in H2; inversion H2; subst; simpl in H1; rewrite H0 in H1. apply (IHl _ H1 H3). discriminate. Qed. Lemma in_mds_in_introduce : forall (ms' : ms) (mds' mds'' : list md), meth_in_mds mds' ms' = true -> meth_in_mds (introduce_methods mds' mds'') ms' = true. induction mds''; simpl. auto. intros; generalize (IHmds'' H); clear. destruct a; induction (introduce_methods mds' mds''). simpl; intros; discriminate. destruct a; simpl. caseEq (ms_eq ms' m1). caseEq (ms_eq m1 m). intros H H0 H1; simpl; rewrite ((proj1 (eq_ms_eq _ _ )) H0 ); rewrite ((proj1 (eq_ms_eq _ _ )) H); rewrite ((proj2 (eq_ms_eq m _ )) (refl_equal _)); reflexivity. intros H H0 H1; simpl; rewrite H0; reflexivity. caseEq (ms_eq m1 m). simpl. intros H H0 H1; simpl; rewrite <- ((proj1 (eq_ms_eq _ _ )) H); rewrite H0; exact H1. intros; simpl; rewrite H0; auto. Qed. Lemma in_mds_in_introduce' : forall (ms' : ms) (mds' mds'' : list md), meth_in_mds mds'' ms' = true -> meth_in_mds (introduce_methods mds' mds'') ms' = true. induction mds''; simpl. intros; discriminate. destruct a; caseEq (ms_eq ms' m); intros. rewrite ((proj1 (eq_ms_eq _ _ )) H); clear; induction (introduce_methods mds' mds''). simpl; rewrite ((proj2 (eq_ms_eq m _ )) (refl_equal _)); reflexivity. destruct a; simpl. caseEq (ms_eq m1 m); intros. simpl; rewrite ((proj2 (eq_ms_eq m _ )) (refl_equal _)); reflexivity. simpl; case (ms_eq m m1); auto. generalize (IHmds'' H0) H; clear. induction (introduce_methods mds' mds''). simpl; intros; discriminate. destruct a; simpl. caseEq (ms_eq ms' m1); intros. caseEq (ms_eq m1 m); intros. rewrite ((proj1 (eq_ms_eq _ _ )) H) in H1; rewrite H2 in H1; discriminate. simpl; rewrite H; auto. caseEq (ms_eq m1 m); intros. simpl; rewrite H1; exact H0. simpl; rewrite H; auto. Qed. Lemma in_introduce_in_mds : forall (ms' : ms) (mds' mds'' : list md), meth_in_mds (introduce_methods mds' mds'') ms' = true -> meth_in_mds mds'' ms' = false -> meth_in_mds mds' ms' = true. induction mds''; simpl. intros; congruence. destruct a; caseEq (ms_eq ms' m); intros. discriminate. apply IHmds''; auto. rewrite <- H0; generalize H; clear; induction (introduce_methods mds' mds''). simpl. intros; rewrite H; auto. destruct a; simpl; caseEq (ms_eq m1 m). intros H H0; simpl; rewrite ((proj1 (eq_ms_eq _ _ )) H); rewrite H0; auto. simpl; caseEq (ms_eq ms' m1); auto. Qed. Lemma sat_p_sat_compose : forall (n : nat) (rcld' : rcld) (dcl' : dcl) (ms' : ms) (p p' : P), sat_comp_constr_p (introduced_method_constr ms' dcl' n :: nil) p = true -> compose_refines_class p rcld' = Some p' -> sat_comp_constr_p (introduced_method_constr ms' dcl' n :: nil) p' = true. induction p; simpl. intros; discriminate. destruct a; destruct rcld'; case (eq_nat_dec d0 dcl'); caseEq (compose_refined_mds l0 l3). unfold sat_meth_constr_p at 1; simpl; case (eq_nat_dec d d0); simpl; intros; subst. generalize H0; clear H0; inversion H1; unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' dcl'); simpl; intros. destruct (andb_prop _ _ H0); apply andb_true_intro; pa. import (in_mds_in_compose _ _ _ _ H3 H). apply in_mds_in_introduce; auto. congruence. generalize H0; clear H0; unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); simpl. congruence. fold (sat_meth_constr_p dcl' ms' p); fold (sat_meth_constr_p dcl' ms' p'); intros. intros; destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; inversion H1. simpl in IHp. import (IHp _ H0 H2). unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d). congruence. fold (sat_meth_constr_p dcl' ms' x). auto. case (eq_nat_dec d d0). intros; discriminate. unfold sat_meth_constr_p at 1; simpl; case (eq_nat_dec dcl' d). congruence. fold (sat_meth_constr_p dcl' ms' p); intros. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; inversion H1. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d). congruence. fold (sat_meth_constr_p dcl' ms' x). intros; apply (IHp _ H0 H2). case (eq_nat_dec d d0). unfold sat_meth_constr_p at 1; simpl; case (eq_nat_dec dcl' d). congruence. fold (sat_meth_constr_p dcl' ms' p); intros. inversion H1; subst; clear H1. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d0). congruence. fold (sat_meth_constr_p dcl' ms' p); auto. unfold sat_meth_constr_p at 1; simpl; case (eq_nat_dec dcl' d); simpl; intros. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; inversion H1. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); simpl. intros; destruct (andb_prop _ _ H0); apply andb_true_intro; pa. fold (sat_meth_constr_p dcl' ms' x). intros; destruct (andb_prop _ _ H0); apply andb_true_intro; pa. congruence. fold (sat_meth_constr_p dcl' ms' p) in H0. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; inversion H1. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); intros. congruence. fold (sat_meth_constr_p dcl' ms' x). simpl in IHp; auto. case (eq_nat_dec d d0). intros; discriminate. unfold sat_meth_constr_p at 1; simpl; case (eq_nat_dec dcl' d); simpl; intros. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; inversion H1. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); simpl. intros; destruct (andb_prop _ _ H0); apply andb_true_intro; pa. fold (sat_meth_constr_p dcl' ms' x). intros; destruct (andb_prop _ _ H0); apply andb_true_intro; pa. congruence. fold (sat_meth_constr_p dcl' ms' p) in H0. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; inversion H1. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); intros. congruence. fold (sat_meth_constr_p dcl' ms' x). simpl in IHp; auto. Qed. Lemma sat_rmds_sat_compose : forall (n : nat) (ty' : ty) (rmds : list rmd) (tyc_list : list ty_constraint) (cc_list : list comp_constraint) (rcld' : rcld) (p p' : P), wf_refined_meth_list_constr n ty' rmds cc_list tyc_list -> sat_comp_constr_p cc_list p = true -> compose_refines_class p rcld' = Some p' -> sat_comp_constr_p cc_list p' = true. induction rmds. simpl; intros; inversion H; subst; auto. destruct a; intros; inversion H; subst; simpl. inversion H4; subst; simpl in H0; destruct (andb_prop _ _ H0). rewrite (IHrmds _ _ _ _ _ H7 H3 H1). apply (sat_p_sat_compose n rcld' _ _ p p'); auto. simpl; rewrite H2; simpl; auto. Qed. Lemma distinct_introduced_names : forall (cld_list1 cld_list2: list cld), distinct _ (names cld_list1) -> distinct _ (names (introduce_classes cld_list1 cld_list2)). induction cld_list2. simpl; auto. simpl. intros H; import (IHcld_list2 H); clear H IHcld_list2. destruct a. induction (introduce_classes cld_list1 cld_list2). simpl; pa. unfold not; intros H; bd H. discriminate. destruct a; simpl in H0; bd H0; import (IHl1 H0). simpl; case (eq_nat_dec d d0); intros. simpl in H. exact H. simpl; pa. unfold not; intros. bd H1. congruence. simpl in H; bd H; auto. pa. unfold not; intro H1; apply H2; generalize n H1; clear; induction l1. simpl; auto. simpl; destruct a; case (eq_nat_dec d d1); intros. simpl; po2. auto. simpl in *|-*. bd H1. po1. po2; auto. simpl in H; bd H. Qed. Lemma In_rm_dcl_split : forall (cld1 cld2 : cld) (cld_list : list cld) , In cld1 (rm_dcl cld_list cld2) <-> (names (cld1 :: nil) <> names (cld2 :: nil) /\ In cld1 cld_list). induction cld_list; repeat pa; intros. simpl in H; contradiction. destruct cld1; destruct cld2; simpl in H; bd H; congruence. destruct a; destruct cld2; simpl in H; bd H. generalize H; clear H; case (eq_nat_dec d0 d); intros. tauto. simpl in H; bd H. destruct cld1; simpl; congruence. tauto. destruct a; destruct cld2; simpl in H; bd H. generalize H; clear H; case (eq_nat_dec d0 d); intros. simpl; po2. tauto. simpl; simpl in H; bd H. po1. po2; tauto. destruct cld1; destruct cld2; destruct a; simpl in H; bd H. simpl; case (eq_nat_dec d0 d1); intros. congruence. simpl; po1. simpl. simpl; case (eq_nat_dec d0 d1); intros. applyI IHcld_list; pa. simpl; po2. applyI IHcld_list; pa. Qed. Lemma In_introduce_classes : forall (cld_list1 cld_list2 : list cld) (cld' : cld), In cld' (introduce_classes cld_list1 cld_list2) -> In cld' cld_list1 \/ In cld' (introduce_classes nil cld_list2). induction cld_list2; simpl; intros. simpl; po1. bd H. po2; po1. cs (names (cld' :: nil) = names (a :: nil)). destruct cld'; destruct a; simpl in H0; inversion H0; subst; clear H0. elimtype False; generalize H; clear; induction (introduce_classes cld_list1 cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d0 d); intros. auto. simpl in H; bd H; auto. congruence. assert (In cld' (introduce_classes cld_list1 cld_list2)). destruct cld'; destruct a; simpl in H0. assert (d <> d0). congruence. clear H0. generalize H H1; clear; induction (introduce_classes cld_list1 cld_list2). simpl; intros; exact H. destruct a; simpl; case (eq_nat_dec d0 d1); simpl; intros. po2; auto. bd H. po1. po2; auto. import (IHcld_list2 _ H1). bd H2. po1. repeat po2. destruct cld'; destruct a. assert (d <> d0). simpl in H0; congruence. generalize H2 H3; clear. induction (introduce_classes nil cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d0 d1); intros. bd H2. congruence. auto. simpl; bd H2. po1. po2; auto. Qed. Lemma In_rm_dcl : forall (cld' cld'': cld) (cld_list : list cld), In cld' (rm_dcl cld_list cld'') -> In cld' cld_list. induction cld_list. simpl; intros; contradiction. destruct a; destruct cld''; simpl; case (eq_nat_dec d0 d); intros. po2; auto. simpl in H; bd H. po1. po2; auto. Qed. Lemma In_introduce_classes' : forall (cld_list1 cld_list2 : list cld) (cld' : cld), In cld' (introduce_classes nil cld_list2) -> In cld' (introduce_classes cld_list1 cld_list2). induction cld_list2; simpl; intros; bd H. po1. po2. import (IHcld_list2 _ (In_rm_dcl _ _ _ H)); clear IHcld_list2. cs (names (cld' :: nil) = names (a :: nil)). destruct cld'; destruct a; simpl in H1; inversion H1; subst; clear H0. elimtype False; generalize H; clear; induction (introduce_classes nil cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d0 d); intros. auto. simpl in H; bd H; auto. congruence. clear H. induction (introduce_classes cld_list1 cld_list2). simpl in H0; contradiction. simpl in H0; bd H0. subst. simpl in *|-*; destruct cld'; destruct a; simpl. case (eq_nat_dec d0 d); intros; subst. congruence. simpl; po1. simpl in *|-*; destruct a0; destruct a; simpl. case (eq_nat_dec d0 d); intros; subst; auto. simpl; po2; auto. Qed. Lemma not_In_introduce_classes : forall (cld_list1 cld_list2 : list cld) (cld' : cld), In cld' (introduce_classes cld_list1 cld_list2) -> ~ In cld' (introduce_classes nil cld_list2) -> In cld' cld_list1. induction cld_list2; simpl; intros. exact H. bd H0. bd H. apply IHcld_list2. apply (In_rm_dcl _ _ _ H). unfold not; intros H3; apply H2. destruct a; destruct cld'. assert (d <> d0). import ((proj1 (In_rm_dcl_split _ _ _)) H); bd H1; simpl in H6. congruence. generalize H3 H1; clear; induction (introduce_classes nil cld_list2). simpl; contradiction. simpl; destruct a; case (eq_nat_dec d d1); intros. bd H3. congruence. auto. simpl; bd H3; auto. Qed. Lemma not_In_introduce_classes' : forall (cld_list1 cld_list2 : list cld) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), In (cld_def dcl' cl' fds' mds') (introduce_classes cld_list1 cld_list2) -> ~ In (cl_dcl dcl') (names (introduce_classes nil cld_list2)) -> In (cld_def dcl' cl' fds' mds') cld_list1. induction cld_list2; simpl; intros. exact H. destruct a; bd H0. bd H. apply IHcld_list2. simpl in H0; bd H0. congruence. simpl in H0; bd H0. congruence. simpl in H0; bd H0. import (In_rm_dcl _ _ _ H). apply IHcld_list2; auto. unfold not; intros; apply H2. generalize H0 H3; clear; induction (introduce_classes nil cld_list2). simpl; intros; congruence. simpl; destruct a; case (eq_nat_dec d d0); simpl; intros. bd H3. congruence. auto. bd H3. po1. po2; auto. Qed. Lemma In_head_introduce_classes : forall (cld_list1 cld_list2 : list cld) (cld1 cld2 : cld), In cld1 (introduce_classes (cld2 :: cld_list1) cld_list2) -> In cld1 (introduce_classes (cld2 :: nil) cld_list2) \/ In cld1 (introduce_classes cld_list1 cld_list2). intros. cs (In cld1 (introduce_classes nil cld_list2)). clear H. po2. induction cld_list2. simpl in H0; contradiction. simpl in H0; bd H0; subst. simpl; po1. simpl in H0; destruct ((proj1 (In_rm_dcl_split _ _ _ )) H0). destruct cld1; destruct a; simpl in H. assert (d <> d0). congruence. po2. generalize d d0 c0 l0 l1 l2 H0 H2; clear. induction cld_list2. simpl; contradiction. intros d d0; simpl; destruct a; case (eq_nat_dec d0 d1); simpl. intros; auto; rewrite e in H2. import (In_rm_dcl _ _ _ H0). import (IHcld_list2 _ _ _ _ _ _ H H2); subst. generalize H1; clear; induction (introduce_classes cld_list1 cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d1 d0); simpl; intros. auto. case (eq_nat_dec d1 d0); intros; try congruence. simpl; bd H1. po1. po2; auto. intros. bd H0. po1. po2. assert (d <> d1). import ((proj1 (In_rm_dcl_split _ _ _)) H0); bd H. import ((proj1 (In_rm_dcl_split _ _ _)) H); bd H1. simpl in H6; congruence. import ((proj1 (In_rm_dcl_split _ _ _)) H0); bd H1. import (IHcld_list2 _ _ _ _ _ _ H1 H). applyI In_rm_dcl_split. pa. destruct cld1. cs (In (cl_dcl d) (names (introduce_classes nil cld_list2))). import (not_In_introduce_classes _ _ _ H H0). simpl in H2; bd H2; subst. induction cld_list2. simpl in H1; bd H1; discriminate. destruct a; simpl in *. bd H0; bd H; bd H1. elimtype False; inversion H1; subst. generalize H; clear; induction (introduce_classes (cld_def d c l l0 :: cld_list1) cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d d0); intros. auto. simpl in H; bd H; congruence. cs (d = d0); subst. elimtype False; generalize H1; clear. induction (introduce_classes nil cld_list2). simpl; intros H; bd H; discriminate. destruct a; simpl; case (eq_nat_dec d0 d); simpl; intros; auto. bd H1; congruence. cs (In (cld_def d c l l0) (introduce_classes nil cld_list2)). po1; po2; generalize H2 H4; clear. induction cld_list2. simpl; contradiction. destruct a; simpl; case (eq_nat_dec d0 d1); intros. bd H4. inversion H4; subst. applyI In_rm_dcl_split. applyI In_rm_dcl_split. simpl; pa. congruence. subst. applyI In_rm_dcl_split; simpl; pa. congruence. import ((proj1 (In_rm_dcl_split _ _ _)) H4); bd H. import (IHcld_list2 H2 H). import ((proj1 (In_rm_dcl_split _ _ _)) H0); bd H1. bd H4. simpl; po1. import ((proj1 (In_rm_dcl_split _ _ _)) H4); bd H. import (IHcld_list2 H2 H). simpl; po2. applyI In_rm_dcl_split; simpl; pa. congruence. applyI In_rm_dcl_split; simpl; pa. import ((proj1 (In_rm_dcl_split _ _ _)) H0); bd H1. import ((proj1 (In_rm_dcl_split _ _ _)) H); bd H5. assert (In (cl_dcl d) (names (introduce_classes nil cld_list2))). generalize H1; clear; induction (introduce_classes nil cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d0 d1); intros. simpl; po2; auto. simpl in *|-*; bd H1; auto. destruct (IHcld_list2 H4 H6 H5). po1; po2. applyI In_rm_dcl_split; pa. repeat po2; applyI In_rm_dcl_split; pa. induction cld_list2. simpl in H1; bd H1; discriminate. destruct a; simpl in *. bd H0; bd H; bd H1. elimtype False; inversion H1; subst. generalize H; clear; induction (introduce_classes (cld2 :: cld_list1) cld_list2). simpl; auto. simpl; destruct a; case (eq_nat_dec d d0); intros. auto. simpl in H; bd H; congruence. cs (d = d0); subst. elimtype False; generalize H1; clear. induction (introduce_classes nil cld_list2). simpl; intros H; bd H; discriminate. destruct a; simpl; case (eq_nat_dec d0 d); simpl; intros; auto. bd H1; congruence. cs (In (cld_def d c l l0) (introduce_classes nil cld_list2)). po2; po2; generalize H3 H2 H5; clear. induction cld_list2. simpl; contradiction. destruct a; simpl; case (eq_nat_dec d0 d1); intros. bd H5. inversion H5; congruence. applyI In_rm_dcl_split; simpl; pa. congruence. auto. applyI In_rm_dcl_split; simpl; pa. congruence. import ((proj1 (In_rm_dcl_split _ _ _)) H5); bd H. import (IHcld_list2 H3 H2 H). import ((proj1 (In_rm_dcl_split _ _ _)) H0); bd H1. bd H5. po1. import ((proj1 (In_rm_dcl_split _ _ _)) H5); bd H. import (IHcld_list2 H3 H2 H). simpl; po2. import ((proj1 (In_rm_dcl_split _ _ _)) H0); bd H1. applyI In_rm_dcl_split; pa. applyI In_rm_dcl_split; pa. import ((proj1 (In_rm_dcl_split _ _ _)) H); bd H6. assert (In (cl_dcl d) (names (introduce_classes nil cld_list2))). generalize H3 H1; clear; induction (introduce_classes nil cld_list2). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); simpl; intros. po2; auto. bd H1. po1. po2; auto. destruct (IHcld_list2 H6 H5 H7). po1; po2; applyI In_rm_dcl_split; pa. repeat po2; applyI In_rm_dcl_split; pa. import (not_In_introduce_classes' _ _ _ _ _ _ H H1). simpl in H2; bd H2; subst. po1. generalize H1; clear; induction cld_list2. simpl; intros; po1. destruct a; simpl; case (eq_nat_dec d d0); intros. bd H1. congruence. bd H1. po2; applyI In_rm_dcl_split; pa. simpl; congruence. apply IHcld_list2. unfold not; intros H; apply H0; generalize n H; clear; induction (introduce_classes nil cld_list2). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); intros. bd H. congruence. auto. bd H. simpl; po1. simpl; po2; auto. po2. generalize H1 H2; clear; induction cld_list2. simpl; intros; auto. destruct a; simpl; case (eq_nat_dec d d0); intros. bd H1. congruence. bd H1. po2; applyI In_rm_dcl_split; pa. simpl; congruence. apply IHcld_list2. unfold not; intros H; apply H0; generalize n H; clear; induction (introduce_classes nil cld_list2). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); intros. bd H. congruence. auto. bd H. simpl; po1. simpl; po2; auto. exact H2. Qed. Lemma distinct_refines_class : forall (rcld' : rcld) (cld_list cld_list': list cld), distinct _ (names cld_list) -> compose_refines_class cld_list rcld' = Some cld_list' -> distinct _ (names cld_list'). induction cld_list. simpl; intros; discriminate. destruct rcld'; destruct a; simpl; case (eq_nat_dec d0 d); intros. caseEq (compose_refined_mds l3 l1); intros; rewrite H1 in H0. inversion H0. simpl; bd H; pa. discriminate. bd H; destruct (cons_option_Some _ _ _ _ H0). import (IHcld_list _ H H1). rewrite H1 in H0; simpl in H0. inversion H0. simpl; pa. generalize x n H3 H1; clear; induction cld_list. simpl; intros; discriminate. simpl; destruct a; case (eq_nat_dec d1 d); case ( compose_refined_mds l3 l1 ); intros. inversion H1. simpl; unfold not; intros H; bd H. discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H in H1; simpl in H1; inversion H1. simpl; apply and_not_or; pa. simpl in H3; bd H3. simpl in H3; bd H3; apply (IHcld_list); auto. destruct (cons_option_Some _ _ _ _ H1); rewrite H in H1; simpl in H1; inversion H1. simpl; apply and_not_or; pa; simpl in H3; bd H3. apply (IHcld_list); auto. Qed. Lemma distinct_compose_names : forall (ps : PSel) (p : P), compose ps = Some p -> distinct _ (names p). induction ps; simpl; intros. inversion H; simpl; tauto. caseEq (compose ps); intros; rewrite H0 in H. import (IHps _ H0); clear IHps H0. destruct a. generalize l l0 p p0 H H1; clear; simpl. induction l; simpl. induction l0; simpl; intros. congruence. inversion H; subst; clear H. generalize (IHl0 _ _ (refl_equal _) H1); clear; induction (introduce_classes p0 l0); intros. destruct a; simpl; pa. unfold not; intros. bd H0; congruence. destruct a0; simpl in H; bd H. destruct a; simpl; case (eq_nat_dec d0 d); intros. subst; simpl; pa. clear; induction l. simpl; unfold not; intros H; bd H. discriminate. destruct a; simpl; case (eq_nat_dec d d0); unfold not; intros. auto. simpl in H; bd H; auto. congruence. simpl in IHl; destruct (IHl H); auto. pa. simpl; unfold not; intros. bd H0. congruence. simpl in IHl; destruct (IHl H); auto. simpl; pa. simpl in IHl; destruct (IHl H); auto. generalize n H2; clear; induction l. simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); unfold not; intros. cs (d0 = d). auto. cs (In (cl_dcl d) (names l)). auto. apply IHl; auto. simpl in H; bd H. auto. cs (d0 = d). auto. cs (In (cl_dcl d) (names l)). auto. apply IHl; auto. import (IHl H). simpl in H0; bd H0. intros; caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p0) l); intros; rewrite H0 in H. caseEq (compose_refines_class p1 a); intros; rewrite H2 in H. inversion H. import (IHl l0 (introduce_classes p1 l0) p0); clear IHl; rewrite H0 in H3. import (H3 (refl_equal _) H1). assert (distinct _ (names p1)). generalize p0 p1 H1 H0; clear. induction l; simpl. congruence. intros. caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p0) l); intros; rewrite H in H0. import (IHl _ _ H1 H). apply (distinct_refines_class _ _ _ H2 H0). discriminate. import (distinct_refines_class _ _ _ H6 H2). apply (distinct_introduced_names _ l0 H7). discriminate. discriminate. discriminate. Qed. Lemma sat_rmd_valid_compoe : forall (dcl' : dcl) (cl' : cl) (rmds : list rmd) (mds : list md) (fds' : list fd) (p : P) (n : nat) (tyc_list : list ty_constraint) (cc_list : list comp_constraint), wf_refined_meth_list_constr n dcl' rmds cc_list tyc_list -> sat_comp_constr_p cc_list (cld_def dcl' cl' fds' mds :: p) = true -> exists mds', compose_refined_mds mds rmds = Some mds'. induction rmds; simpl; intros. exists mds; reflexivity. destruct a. inversion H; subst; inversion H3; subst. simpl in H0; destruct (andb_prop _ _ H0). destruct (IHrmds _ _ _ _ _ _ H6 H2) as [mds' G1]; rewrite G1. unfold sat_meth_constr_p in H1. caseEq (path (cld_def dcl' cl' fds' mds :: p) dcl'); intros; rewrite H4 in H1; simpl in H1. discriminate. destruct c. rewrite (path_eq_self _ _ _ _ _ _ _ H4) in H4. generalize H4; clear H4; simpl; case (eq_nat_dec d d); intros; inversion H4; subst. assert (meth_in_mds mds' (ms_def ty' m' vd_list) = true). generalize l1 mds' H1 G1; clear; induction rmds; simpl; intros. congruence. caseEq (compose_refined_mds l1 rmds); intros; rewrite H in G1. import (IHrmds _ _ H1 H). destruct a. destruct (in_mds_In_mds _ _ H0). destruct (In_mds_In_compose _ _ _ _ _ _ G1 H2). apply (In_mds_in_mds _ _ _ H3). discriminate. generalize H5; clear; induction mds'; intros H1. simpl in H1; discriminate. destruct a; unfold meth_in_mds in H1; fold meth_in_mds in H1. simpl; destruct m0. caseEq (ms_eq m (ms_def ty' m' vd_list)); intros. exists (md_def m (mb_def (s_list1 ++ l ++ s_list2) y) :: mds'); reflexivity. caseEq (ms_eq (ms_def ty' m' vd_list) m); intros; rewrite H0 in H1. rewrite ((proj1 (eq_ms_eq _ _ )) H0) in H. rewrite ((proj2 (eq_ms_eq _ _ )) (refl_equal m)) in H; discriminate. unfold cons_option. destruct (IHmds' H1). rewrite H2. exists (md_def m (mb_def l x) :: x0); reflexivity. congruence. Qed. Lemma in_clds_compose' : forall (dcl' : dcl) (cl': cl) (rmds : list rmd) (mds : list md) (fds' : list fd) (p p': P), in_clds dcl' p = true -> compose_refines_class p (refines_cld_def dcl' cl' fds' mds rmds) = Some p' -> in_clds dcl' p' = true. induction p. simpl; intros; discriminate. simpl; destruct a; case (eq_nat_dec d dcl'); caseEq (compose_refined_mds l0 rmds); intros. inversion H1; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. reflexivity. congruence. discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1; inversion H1. generalize H0; clear H0; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl. congruence. fold (in_clds dcl' p); fold (in_clds dcl' x); intros. apply IHp; auto. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1; inversion H1. generalize H0; clear H0; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl. congruence. fold (in_clds dcl' p); fold (in_clds dcl' x); intros. apply IHp; auto. Qed. Lemma compose_in_clds : forall (dcl' : dcl) (cl': cl) (rmds : list rmd) (mds : list md) (fds' : list fd) (p p': P), compose_refines_class p (refines_cld_def dcl' cl' fds' mds rmds) = Some p' -> in_clds dcl' p = true. induction p. simpl; intros; discriminate. simpl; destruct a; case (eq_nat_dec d dcl'); caseEq (compose_refined_mds l0 rmds); intros. subst; unfold in_clds; simpl; case (eq_nat_dec dcl' dcl'); simpl; intros. reflexivity. congruence. discriminate. destruct (cons_option_Some _ _ _ _ H0); import (IHp _ H1). unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. congruence. auto. destruct (cons_option_Some _ _ _ _ H0); import (IHp _ H1). unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. congruence. auto. Qed. Lemma compose_in_clds' : forall (dcl' dcl'': dcl) (cl': cl) (rmds : list rmd) (mds : list md) (fds' : list fd) (p p': P), in_clds dcl' p' = true -> compose_refines_class p (refines_cld_def dcl'' cl' fds' mds rmds) = Some p' -> dcl' <> dcl'' -> in_clds dcl' p = true. induction p. simpl; intros; discriminate. simpl; destruct a; case (eq_nat_dec d dcl''); caseEq (compose_refined_mds l0 rmds); intros. generalize H0; clear H0; inversion H1; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. congruence. exact H0. discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H3 in H1; simpl in H1; inversion H1; subst. generalize H0; clear H0; inversion H1; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. reflexivity. fold (in_clds dcl' x) in H0; apply (IHp _ H0 H3). auto. destruct (cons_option_Some _ _ _ _ H1); rewrite H3 in H1; simpl in H1; inversion H1; subst. generalize H0; clear H0; inversion H1; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. reflexivity. fold (in_clds dcl' x) in H0; apply (IHp _ H0 H3). auto. Qed. Lemma in_clds_compose : forall (dcl' dcl'': dcl) (cl': cl) (rmds : list rmd) (mds : list md) (fds' : list fd) (p p': P), in_clds dcl' p = true -> compose_refines_class p (refines_cld_def dcl'' cl' fds' mds rmds) = Some p' -> dcl' <> dcl'' -> in_clds dcl' p' = true. induction p. simpl; intros; discriminate. simpl; destruct a; case (eq_nat_dec d dcl''); caseEq (compose_refined_mds l0 rmds); intros. generalize H0; clear H0; inversion H1; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl; intros. congruence. exact H0. discriminate. destruct (cons_option_Some _ _ _ _ H1); rewrite H3 in H1; simpl in H1; inversion H1. generalize H0; clear H0; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl. auto. fold (in_clds dcl' p); fold (in_clds dcl' x); intros. apply IHp; auto. destruct (cons_option_Some _ _ _ _ H1); rewrite H3 in H1; simpl in H1; inversion H1. generalize H0; clear H0; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl. congruence. fold (in_clds dcl' p); fold (in_clds dcl' x); intros. apply IHp; auto. Qed. Lemma sat_not_introduced : forall (dcl' : dcl) (p p' : P) (m : ms), in_path p' dcl' = false -> sat_meth_constr_p dcl' m p = true -> sat_meth_constr_p dcl' m (introduce_classes p p') = true. induction p'; simpl. auto. destruct a; simpl; case (eq_nat_dec dcl' d). intros; discriminate. unfold sat_meth_constr_p at 2; simpl; case (eq_nat_dec dcl' d); simpl. congruence. intros _ n m. fold (sat_meth_constr_p dcl' m (rm_dcl (introduce_classes p p') (cld_def d c l l0))). intros H H0; generalize n (IHp' _ H H0); clear. induction (introduce_classes p p'); simpl; auto. unfold sat_meth_constr_p; destruct a; case (eq_nat_dec d d0); simpl; case (eq_nat_dec dcl' d0). congruence. intros; auto. simpl; auto. auto. Qed. Lemma sat_not_introduced' : forall (dcl' : dcl) (p p' : P) (m : ms), in_path p' dcl' = false -> sat_meth_constr_p dcl' m (introduce_classes p p') = true -> sat_meth_constr_p dcl' m p = true. induction p'; simpl; auto. destruct a; simpl; case (eq_nat_dec dcl' d). intros; discriminate. unfold sat_meth_constr_p at 1; simpl; case (eq_nat_dec dcl' d); simpl. congruence. intros _ n m. fold (sat_meth_constr_p dcl' m (rm_dcl (introduce_classes p p') (cld_def d c l l0))). intros H H0; apply IHp'; auto. generalize H0 n; clear; induction (introduce_classes p p'); simpl; auto. unfold sat_meth_constr_p; destruct a; case (eq_nat_dec d d0); simpl; case (eq_nat_dec dcl' d0). congruence. intros; auto. simpl; auto. auto. Qed. Lemma sat_rclds_fold' : forall (rclds : list rcld) (p p0: P) (dcl' : dcl) (ms' : ms), fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p'0 => compose_refines_class p'0 rcld' | None => None (A:=P) end) (Some p) rclds = Some p0 -> sat_meth_constr_rclds rclds dcl' ms' = true -> sat_meth_constr_p dcl' ms' p0 = true. induction rclds; simpl; intros. discriminate. destruct a; simpl in H0. caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p'0 => compose_refines_class p'0 rcld' | None => None end) (Some p) rclds); intros; rewrite H1 in H. revert H0; destruct (eq_nat_dec dcl' d); intros. caseEq (meth_in_mds l0 ms'); intros; rewrite H2 in H0. subst; generalize p0 H H2; clear; induction p1. simpl; intros; discriminate. intro p0; simpl; destruct a; case (eq_nat_dec d0 d); intros. destruct (compose_refined_mds l3 l1); inversion H; subst; clear H. unfold sat_meth_constr_p; simpl; case (eq_nat_dec d d); simpl. intros; generalize H2; clear. apply in_mds_in_introduce'. congruence. destruct (cons_option_Some _ _ _ _ H). rewrite H0 in H; inversion H; subst. unfold sat_meth_constr_p; simpl; case (eq_nat_dec d d0); simpl. congruence. intros; eapply IHp1; eauto. import (IHrclds _ _ _ _ H1 H0). subst; generalize p0 H3 H; clear; induction p1. simpl; intros; discriminate. intro p0; simpl; destruct a; case (eq_nat_dec d0 d); intros. caseEq (compose_refined_mds l3 l1); intros; rewrite H0 in H; inversion H; subst; clear H. revert H3; unfold sat_meth_constr_p; simpl; case (eq_nat_dec d d); simpl. intros. eapply in_mds_in_introduce; eapply in_mds_in_compose; eauto. congruence. destruct (cons_option_Some _ _ _ _ H). rewrite H0 in H; inversion H; subst. revert H3; unfold sat_meth_constr_p; simpl; case (eq_nat_dec d d0); simpl; auto. intros. eapply IHp1; eauto. import (IHrclds _ _ _ _ H1 H0). revert p0 n H H2; clear; induction p1. simpl; intros; discriminate. intro p0; simpl; destruct a; case (eq_nat_dec d0 d). destruct (compose_refined_mds l3 l1). intros e n H; inversion H; subst. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); intros; congruence. intros; discriminate. intros n n0 H; destruct (cons_option_Some _ _ _ _ H) as [x H0]; rewrite H0 in H; inversion H. unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d0); simpl; auto. intros. apply (IHp1 x); auto. discriminate. Qed. Lemma sat_comp_valid_compose : forall (clds : list cld) (rclds : list rcld) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint) (n : nat) (p : P), wf_rcld_constr_list n rclds cc_list uc_list tyc_list -> sat_comp_constr_p cc_list p = true -> exists p', compose_fd (feature_def rclds clds) p = Some p'. induction rclds. simpl; intros; exists (introduce_classes p clds); reflexivity. simpl; destruct a; intros. inversion H; subst. destruct ((proj1 (sat_comp_constr_app_p _ _ _)) H0). destruct (IHrclds _ _ _ _ _ H7 H2) as [p' Compose_p']. unfold compose_fd in Compose_p'. caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) rclds); intros; rewrite H4 in Compose_p'. assert (sat_comp_constr_p cc_list1 p0 = true). generalize p0 H4 H1; clear. induction rclds; intros. simpl in H4; congruence. destruct a; simpl in H4. destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None end) (Some p) rclds). import (IHrclds _ (refl_equal _) H1). generalize H4 H; clear; induction cc_list1. simpl; auto. destruct a; simpl; intros. destruct (andb_prop _ _ H); rewrite H1 in H; rewrite IHcc_list1; auto. apply (sat_p_sat_compose n (refines_cld_def d c l l0 l1) _ m p1); simpl; auto. destruct (andb_prop _ _ H); rewrite H1 in H; rewrite IHcc_list1; auto. case (eq_nat_dec d0 d); intros. subst; rewrite (in_clds_compose' _ _ _ _ _ _ _ H0 H4); simpl; reflexivity. rewrite (in_clds_compose _ _ _ _ _ _ _ _ H0 H4); simpl; auto. discriminate. generalize H3 H5; clear; induction p0. intros; inversion H3; subst; simpl in H5; discriminate. intros; destruct a; simpl; case (eq_nat_dec d0 d). inversion H3; subst. simpl in H5; destruct (andb_prop _ _ H5). intros; subst; destruct (sat_rmd_valid_compoe _ _ _ _ _ _ _ _ _ H12 H0) as [mds' H4]; rewrite H4. exists _; reflexivity. simpl in H5; destruct (andb_prop _ _ H5). intros; subst; destruct (sat_rmd_valid_compoe _ _ _ _ _ _ _ _ _ H11 H0) as [mds' H4]; rewrite H4. exists _; reflexivity. intros; destruct (IHp0 H3). clear IHp0; inversion H3; subst. simpl in *|-*; destruct (andb_prop _ _ H5). apply andb_true_intro; split. unfold in_clds in H; simpl in H; generalize H; case (eq_nat_dec d d0); intros; auto; congruence. generalize tyc_list2 cc_list n0 H12 H0; clear; induction l1; intros; inversion H12; subst. simpl; reflexivity. destruct a; inversion H2; subst; simpl in *|-*. destruct (andb_prop _ _ H0); apply andb_true_intro; split. unfold sat_meth_constr_p in H; simpl in H; generalize H; case (eq_nat_dec d d0); intros; auto. eauto. simpl in *|-*. destruct (andb_prop _ _ H5); apply andb_true_intro; split. unfold in_clds in H; simpl in H; generalize H; case (eq_nat_dec d d0); intros; auto; congruence. generalize tyc_list2 cc_list n0 H11 H0; clear; induction l1; intros; inversion H11; subst. simpl; reflexivity. destruct cc; inversion H2; subst; simpl in *|-*. destruct (andb_prop _ _ H0); apply andb_true_intro; split. unfold sat_meth_constr_p in H; simpl in H; generalize H; case (eq_nat_dec d1 d0); intros; auto. eauto. destruct (compose_refines_class p0 (refines_cld_def d c l l0 l1)); simpl. exists _; reflexivity. discriminate. discriminate. Qed. Lemma sat_meth_rm_dcl : forall (dcl' dcl'' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (ms' : ms) (p : P), dcl'' <> dcl' -> (sat_meth_constr_p dcl'' ms' (rm_dcl p (cld_def dcl' cl' fds' mds')) = true <-> (sat_meth_constr_p dcl'' ms' p = true)). induction p; simpl. tauto. destruct a; unfold sat_meth_constr_p; simpl; case (eq_nat_dec dcl' d); case (eq_nat_dec dcl'' d); simpl. congruence. intros _ _ n; pa; intros; applyI (IHp n); auto. case (eq_nat_dec dcl'' d); simpl; tauto. case (eq_nat_dec dcl'' d); simpl; tauto. Qed. Fixpoint sat_comp_constr_psel (c_list : list comp_constraint) (ps: PSel) : bool := match c_list with (introduced_method_constr ms' dcl' _) :: c_list' => sat_meth_constr_PSel dcl' ms' ps && (sat_comp_constr_psel c_list' ps) | (introduced_class_constr dcl' _) :: c_list' => sat_cld_constr_PSel dcl' ps && (sat_comp_constr_psel c_list' ps) | nil => true end. Lemma in_clds_in_p : forall (dcl' : dcl) (p : P), in_clds dcl' p = true -> exists cl, exists fds, exists mds, In (cld_def dcl' cl fds mds) p. induction p. simpl; intros; discriminate. destruct a; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl. intros; subst; exists c; exists l; exists l0; po1. fold (in_clds dcl' p); intros n H; import (IHp H); bd H0. exists x; exists x0; exists x1; po2. Qed. Lemma in_p_in_clds : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (p : P), In (cld_def dcl' cl' fds' mds') p -> in_clds dcl' p = true. induction p; simpl. contradiction. intros H; bd H; subst. unfold in_clds; simpl; case (eq_nat_dec dcl' dcl'); simpl. reflexivity. congruence. destruct a; unfold in_clds; simpl; case (eq_nat_dec dcl' d); simpl. reflexivity. auto. Qed. Lemma wf_PSpec_In : forall (ft : FT) (ps : PSpec) (n : nat), wf_PSpec ft ps -> In n ps -> exists fd, nth_error ft n = Some fd. induction ps; intros. simpl in H0; contradiction. simpl in H0; destruct H0 as [eq_n | In_n]. subst. inversion H; subst. generalize n H2; clear; induction ft; simpl; intros; inversion H2. subst; clear H2 IHft. induction ft; simpl. exists a; reflexivity. destruct (length ft); simpl. exists a0; reflexivity. simpl in IHft; auto. destruct n; simpl. exists a; reflexivity. apply IHft; omega. eapply IHps; eauto. inversion H; auto. Qed. Lemma wf_PSpec_build_p : forall (ft : FT) (ps : PSpec), wf_PSpec ft ps -> exists ps', build_PSel ft ps = Some ps' /\ (forall fd', In fd' ps' -> In fd' ft). induction ps; intros; unfold build_p. simpl; exists nil; split; auto. intros; contradiction. inversion H; subst. simpl. destruct (wf_PSpec_In _ _ a H). simpl; auto. rewrite H0. destruct (IHps H4) as [ps' [H5 H6]]. rewrite H5; exists (x :: ps'); split; auto. simpl; intros. destruct H1 as [eq_x | In_fd']. subst; generalize ft H0; clear; induction a. simpl; intros; destruct ft; inversion H0; simpl; auto. simpl; destruct ft; intros. discriminate. simpl; right; auto. auto. Qed. Lemma wf_PSpec_build_p' : forall (ft : FT) (ps : PSpec), wf_PSpec ft ps -> exists ps', build_PSel ft ps = Some ps' /\ (forall fd', In fd' ps' -> exists n, nth_error ft n = Some fd'). induction ps; intros; unfold build_p. simpl; exists nil; split; auto. intros; contradiction. inversion H; subst. simpl. destruct (wf_PSpec_In _ _ a H). simpl; auto. rewrite H0. destruct (IHps H4) as [ps' [H5 H6]]. rewrite H5; exists (x :: ps'); split; auto. simpl; intros. destruct H1 as [eq_x | In_fd']. subst; generalize ft H0; clear; induction a. simpl; intros; destruct ft; inversion H0; simpl; auto. simpl; destruct ft; intros. exists 0; simpl; reflexivity. exists 0; simpl; reflexivity. intros. exists (S a); assumption. apply H6; auto. Qed. Lemma wf_FT_wf_fd : forall (ft : FT) (fd : FD) (c_list : list feature_constraint) (m n : nat), wf_FT m ft c_list -> nth_error ft n = Some fd -> exists fc, In fc c_list /\ wf_feature (n + m) fd fc. induction ft; intros. destruct n; simpl in H0; discriminate. destruct n. simpl in H0; inversion H0; inversion H; subst. exists fc; inversion H6; subst; simpl; auto. simpl in H0; inversion H; subst. destruct (IHft _ _ _ _ H7 H0) as [fc' [In_fd WF_fd]]. exists fc'; split. simpl; right; auto. rewrite plus_Snm_nSm; exact WF_fd. Qed. Lemma wf_FT_wf_fd' : forall (ft : FT) (fd : FD) (c_list : list feature_constraint) (m : nat), wf_FT m ft c_list -> In fd ft -> exists fc, In fc c_list /\ exists n, wf_feature n fd fc. induction ft; intros. simpl in H0; contradiction. simpl in H0; destruct H0 as [Eq_a | In_a]. inversion H; subst. exists fc; split; simpl; auto. exists m; assumption. simpl in H; inversion H; subst. destruct (IHft _ _ _ H6 In_a) as [fc' [In_fc' [n WF_fd]]]. exists fc'; simpl; split; auto. exists n; auto. Qed. Lemma sat_comp_wf_FT : forall (ft : FT) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint) (fc_list : list feature_constraint) (n : nat) (ps : PSpec), In (feature_constr n cc_list uc_list tyc_list) fc_list -> sat_feature_comp_constr ft ps fc_list -> In n ps -> sat_comp_constr_ps ft ps cc_list = true. induction fc_list; intros until ps; intros H H0 H1. simpl in H; contradiction. inversion H0; subst. simpl in H; destruct H as [eq_fc | In_fc]; subst. inversion eq_fc; subst; simpl in H0; inversion H0; subst; auto. eapply IHfc_list; eauto. simpl in H; destruct H; subst. inversion H; subst. contradiction. eapply IHfc_list; eauto. Qed. Lemma distinct_nth_error : forall (A : Type) (list_A : list A) (a : A) (m n : nat), distinct _ list_A -> nth_error list_A m = Some a -> nth_error list_A n = Some a -> m = n. induction list_A. destruct m; simpl; intros; discriminate. destruct m; destruct n; simpl; intros; auto. inversion H0; subst; destruct H; elimtype False; apply H. generalize n H1; clear; induction list_A. destruct n; simpl; intros; discriminate. intros; destruct n; simpl in *|-*. inversion H1; auto. right; eauto. inversion H1; subst; destruct H; elimtype False; apply H. generalize m H0; clear; induction list_A. destruct m; simpl; intros; discriminate. intros; destruct m; simpl in *|-*. inversion H0; auto. right; eauto. destruct H; rewrite (IHlist_A a0 m n); auto. Qed. Lemma distinct_WF_FT : forall (ft : FT) (c_list : list feature_constraint) (m : nat), wf_FT m ft c_list -> distinct _ ft. induction ft; intros. simpl; auto. simpl in *|-*; inversion H; subst; split; auto. eauto. Qed. Lemma distinct_WF_PSpec : forall (ft : FT) (ps : PSpec), wf_PSpec ft ps -> distinct _ ps. induction ps; intros. simpl; auto. simpl in *|-*; inversion H; subst; split; auto. Qed. Lemma In_PSpec : forall (ps' : PSel) (ft : FT) (ps : PSpec) (fd' : FD), In fd' ps' -> build_PSel ft ps = Some ps' -> exists n, In n ps /\ nth_error ft n = Some fd'. induction ps'. simpl; intros; contradiction. simpl; intros; destruct H; subst. destruct ps; simpl in *|-*. discriminate. caseEq (nth_error ft n); intros; rewrite H in H0. caseEq (build_PSel ft ps); intros; rewrite H1 in H0; inversion H0; subst. exists n; auto. discriminate. destruct ps; simpl in H0. discriminate. caseEq (nth_error ft n); intros; rewrite H1 in H0. caseEq (build_PSel ft ps); intros; rewrite H2 in H0; inversion H0; subst. destruct (IHps' _ _ _ H H2) as [n' [In_n' find_n']]; exists n'; simpl; auto. discriminate. Qed. Lemma distinct_WF_PSel : forall (ft : FT) (c_list : list feature_constraint) (ps : PSpec) (ps' : PSel), wf_PSpec ft ps -> wf_FT 0 ft c_list -> build_PSel ft ps = Some ps'-> distinct _ ps'. intros. import (distinct_WF_FT _ _ _ H0); import (distinct_WF_PSpec _ _ H). generalize ft ps' H1 H2 H3; clear; induction ps; simpl; intros. inversion H1; simpl; auto. destruct H3; caseEq (nth_error ft a); intros; rewrite H3 in H1. caseEq (build_PSel ft ps); intros; rewrite H4 in H1; simpl in H1; inversion H1; subst. simpl. split; auto. unfold not; intros; apply H; generalize a f p H4 H5 H3 H2; clear; intros. destruct (In_PSpec _ _ _ _ H5 H4) as [n' [In_n' find_n']]. rewrite (distinct_nth_error _ _ _ _ _ H2 find_n' H3) in In_n'; auto. eauto. discriminate. Qed. Lemma wf_FT_wf_fd'' : forall (ft : FT) (c_list : list feature_constraint) (ps : PSpec), wf_PSpec ft ps -> wf_FT 0 ft c_list -> sat_feature_comp_constr ft ps c_list -> exists ps', build_PSel ft ps = Some ps' /\ (forall fd' : FD, In fd' ps' -> exists n, nth_error ft n = Some fd' /\ In n ps /\ exists cc_list, exists uc_list, exists tyc_list, In (feature_constr n cc_list uc_list tyc_list) c_list /\ wf_feature n fd' (feature_constr n cc_list uc_list tyc_list) /\ sat_comp_constr_ps ft ps cc_list = true). intros. destruct (wf_PSpec_build_p' _ _ H) as [ps' [Bld_p In_ps']]. exists ps'; repeat split; auto. intros; destruct (In_ps' _ H2) as [n' In_n']. exists n'; repeat split; auto. destruct (In_PSpec _ _ _ _ H2 Bld_p) as [n'' [In_n'' find_n'']]. rewrite <- (distinct_nth_error _ _ _ _ _ (distinct_WF_FT _ _ _ H0) find_n'' In_n'); auto. destruct (wf_FT_wf_fd _ _ _ _ _ H0 In_n') as [fc' [In_fc WF_fd']]. rewrite (plus_0_r _) in WF_fd'; inversion WF_fd'; subst. exists _; exists _; exists _; repeat split; eauto. apply (sat_comp_wf_FT _ _ _ _ _ _ _ In_fc H1). destruct (In_PSpec _ _ _ _ H2 Bld_p) as [n'' [In_n'' find_n'']]. rewrite <- (distinct_nth_error _ _ _ _ _ (distinct_WF_FT _ _ _ H0) find_n'' In_n'); auto. Qed. Inductive safe_comp_ps : PSel -> Prop := | safe_comp_cons : forall (fd : FD) (ps : PSel) (n : nat) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), wf_feature n fd (feature_constr n cc_list uc_list tyc_list) -> sat_comp_constr_psel cc_list ps = true -> safe_comp_ps ps -> safe_comp_ps (fd :: ps) | safe_comp_nil : safe_comp_ps nil. Lemma param_cc_list : forall ft m c_list, wf_FT m ft c_list -> forall n uc_list tyc_list cc_list, In (feature_constr n cc_list uc_list tyc_list) c_list -> forall cc : comp_constraint, In cc cc_list -> (exists ms' : ms, exists dcl' : dcl, cc = introduced_method_constr ms' dcl' n) \/ (exists dcl' : dcl, cc = introduced_class_constr dcl' n). induction ft; intros; inversion H; subst. simpl in H0; contradiction. simpl in H0; destruct H0 as [eq_fc | In_fc]. subst. inversion H6; subst; generalize cc_list uc_list2 tyc_list2 H10 H1; clear. induction rclds; intros; inversion H10; subst. simpl in H1; contradiction. destruct (in_app_or _ _ _ H1). inversion H2; subst. simpl in H; destruct H; subst. right; exists _; reflexivity. left. generalize cc_list tyc_list3 dcl' H H5; clear; induction rmds; simpl; intros; inversion H5; subst. simpl in H; contradiction. destruct a; inversion H5; subst. simpl in H; destruct H. inversion H4; subst. rewrite <- H15; exists _; exists _; reflexivity. eapply IHrmds; eauto. simpl in H; destruct H; subst. right; exists _; reflexivity. left. generalize cc_list tyc_list3 dcl' H H4; clear; induction rmds; simpl; intros; inversion H4; subst. simpl in H; contradiction. destruct a; inversion H4; subst. simpl in H; destruct H. inversion H5; subst. rewrite <- H15; exists _; exists _; reflexivity. eapply IHrmds; eauto. eapply IHrclds; eauto. eapply IHft; eauto. Qed. Lemma sat_ps_safe_comp : forall (ft : FT) (ps : PSpec) (c_list : list feature_constraint), wf_FT 0 ft c_list -> sat_feature_comp_constr ft ps c_list -> wf_PSpec ft ps -> exists ps', build_PSel ft ps = Some ps' /\ safe_comp_ps ps'. intros ft ps fc_list WF_ft Sat_cl WF_ps. generalize (distinct_WF_FT _ _ _ WF_ft); intros Dis_ft. generalize (distinct_WF_PSpec _ _ WF_ps); intros Dis_ps. destruct (wf_FT_wf_fd'' _ _ _ WF_ps WF_ft Sat_cl) as [ps' [Bld_ps In_ps']]. exists ps'; split; auto. generalize ps Bld_ps In_ps' Dis_ft Dis_ps (param_cc_list _ _ _ WF_ft); clear; induction ps'. intros; constructor. intros ps Bld_ps In_ps' Dis_ft Dis_ps Par_cc; destruct ps; simpl in Bld_ps; try (inversion Bld_ps; fail). case_eq (nth_error ft n); intros; rewrite H in Bld_ps. caseEq (build_PSel ft ps); intros; rewrite H0 in Bld_ps; simpl in Bld_ps; inversion Bld_ps; subst; clear Bld_ps. simpl in In_ps'; destruct (In_ps' a (or_introl _ (refl_equal _))) as [n' [In_n' [_ [cc_list [uc_list [tyc_list [In_f [WF_a Sat_cc]]]]]]]]. rewrite (distinct_nth_error _ _ _ _ _ Dis_ft H In_n') in *|-*; clear H. eapply safe_comp_cons. apply WF_a. generalize (Par_cc _ _ _ _ In_f); clear Par_cc; intros Par_cc. generalize ps ps' Par_cc H0 Sat_cc; clear; induction cc_list; simpl. intros; simpl; reflexivity. destruct a; simpl; intros; revert Sat_cc; case (eq_nat_dec n' n); intros. rewrite H0 in Sat_cc. destruct (andb_prop _ _ Sat_cc); apply andb_true_intro; split; auto. eapply IHcc_list; eauto. destruct (Par_cc _ (or_introl _ (refl_equal _))) as [[ms' [dcl' Eq_cc]] | [dcl' Fal]]. congruence. discriminate. rewrite H0 in Sat_cc. destruct (andb_prop _ _ Sat_cc); apply andb_true_intro; split; auto. eapply IHcc_list; eauto. destruct (Par_cc _ (or_introl _ (refl_equal _))) as [[ms' [dcl' Eq_cc]] | [dcl' Fal]]. discriminate. congruence. eapply IHps'; eauto. intros. destruct (In_ps' _ (or_intror _ H)) as [n'' [In_n'' [_ [cc_list' [uc_list' [tyc_list' [In_f' [WF_a' Sat_cc']]]]]]]]. case (eq_nat_dec n' n''); intros; subst. elimtype False. simpl in Dis_ps; destruct Dis_ps as [NIn_n'' _]; apply NIn_n''. generalize ps' n'' fd' In_n'' H Dis_ft H0; clear; induction ps. simpl; intros; inversion H0; subst; simpl in H; contradiction. simpl; intros. caseEq (nth_error ft a); intros; rewrite H1 in H0. caseEq ((build_PSel ft ps)); intros; rewrite H2 in H0; simpl in H0; inversion H0; subst. simpl in H; destruct H; subst. left; eapply distinct_nth_error; eauto. right; eapply IHps; eauto. discriminate. exists n''; split; repeat (exists _); repeat split; auto. destruct (In_PSpec _ _ _ _ H H0) as [n''' [In_n''' find_n''']]. rewrite <- (distinct_nth_error _ _ _ _ _ Dis_ft find_n''' In_n''); auto. repeat (exists _); repeat split; auto. apply In_f'. apply WF_a'. generalize (Par_cc _ _ _ _ In_f'); clear Par_cc; intros Par_cc. generalize ps ps' n0 Par_cc H0 Sat_cc'; clear; induction cc_list'; simpl. intros; simpl; reflexivity. destruct a; simpl; intros; revert Sat_cc'; case (eq_nat_dec n'' n); intros; subst. rewrite H0 in Sat_cc'. destruct (andb_prop _ _ Sat_cc'); apply andb_true_intro; split; auto. generalize H; case (eq_nat_dec n' n); intros; congruence. eapply IHcc_list'; eauto. destruct (Par_cc _ (or_introl _ (refl_equal _))) as [[ms' [dcl' Eq_cc]] | [dcl' Fal]]. congruence. discriminate. rewrite H0 in Sat_cc'. destruct (andb_prop _ _ Sat_cc'); apply andb_true_intro; split; auto. generalize H; case (eq_nat_dec n' n); intros; congruence. eapply IHcc_list'; eauto. destruct (Par_cc _ (or_introl _ (refl_equal _))) as [[ms' [dcl' Eq_cc]] | [dcl' Fal]]. discriminate. congruence. simpl in Dis_ps; destruct Dis_ps; auto. discriminate. Qed. End Composition. Section Uniqueness. Fixpoint cld_gen_unique_constraint (cld_list : list cld) : list unique_constraint := match cld_list with cld_def dcl' _ fds' mds' :: cld_list' => fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) (nil : list unique_constraint) fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) (nil : list unique_constraint) mds' ++ cld_gen_unique_constraint cld_list' | nil => nil end. Fixpoint rcld_gen_unique_constraint (rcld_list : list rcld) : list unique_constraint := match rcld_list with refines_cld_def dcl' _ fds' mds' _ :: rcld_list' => fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) (nil : list unique_constraint) fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) (nil : list unique_constraint) mds' ++ rcld_gen_unique_constraint rcld_list' | nil => nil end. Definition f_gen_unique_constraint (fd : FD) : list unique_constraint := match fd with feature_def rclds clds => rcld_gen_unique_constraint rclds ++ cld_gen_unique_constraint clds end. Fixpoint ps_gen_unique_constraint (ps : PSel) {struct ps} : list unique_constraint := match ps with fd' :: ps' => f_gen_unique_constraint fd' ++ ps_gen_unique_constraint ps' | nil => nil end. Lemma in_fd_gen_unique_constraint : forall (cld_list : list cld) (dcl' : dcl) (fd' : fd), In (unique_fields_constraint dcl' fd') (cld_gen_unique_constraint cld_list) <-> (exists cl', exists fds', exists mds', In (cld_def dcl' cl' fds' mds') cld_list /\ (In fd' fds')). induction cld_list. simpl; pa; intros. contradiction. bd H. destruct a; simpl; pa; intros. destruct (in_app_or _ _ _ H). exists c; exists l; exists l0; pa. po1. assert (d = dcl'). generalize H0; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. apply (IHl H0). congruence. generalize H0; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. po2; apply (IHl H0). destruct (in_app_or _ _ _ H0). elimtype False; generalize H1; clear; induction l0. simpl; auto. destruct a; simpl; intros; bd H1. discriminate. auto. import ((proj1 (IHcld_list _ _) ) H1). bd H2. exists x; exists x0; exists x1; pa. po2. apply (in_or_app (fold_right (fun (fd'0 : fd) (m : list unique_constraint) => unique_fields_constraint d fd'0 :: m) nil l) (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint d ms' :: m end) nil l0 ++ cld_gen_unique_constraint cld_list) (unique_fields_constraint dcl' fd')). bd H. inversion H2; subst; clear H2. po1. generalize H; clear; induction x0; simpl; intros. exact H. bd H. subst; po1. po2; auto. po2. apply in_or_app; po2. applyI IHcld_list. exists x; exists x0; exists x1; pa. Qed. Lemma in_ms_gen_unique_constraint : forall (cld_list : list cld) (dcl' : dcl) (ms' : ms), In (unique_methods_constraint dcl' ms') (cld_gen_unique_constraint cld_list) <-> (exists cl', exists fds', exists mds', In (cld_def dcl' cl' fds' mds') cld_list /\ (meth_in_mds mds' ms' = true)). induction cld_list. simpl; pa; intros. contradiction. bd H. destruct a; simpl; pa; intros. destruct (in_app_or _ _ _ H). elimtype False; generalize H0; clear; induction l. simpl; auto. destruct a; simpl; intros; bd H0. discriminate. auto. destruct (in_app_or _ _ _ H0). exists c; exists l; exists l0; pa. po1. assert (d = dcl'). generalize H1; clear; induction l0. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. inversion H1; auto. apply (IHl0 H1). congruence. generalize H1; clear; induction l0. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. inversion H1; subst. rewrite ((proj2 (eq_ms_eq _ ms') )(refl_equal _)); reflexivity. destruct (ms_eq ms' m); auto. import ((proj1 (IHcld_list _ _) ) H1). bd H2. exists x; exists x0; exists x1; pa. po2. apply (in_or_app (fold_right (fun (fd'0 : fd) (m : list unique_constraint) => unique_fields_constraint d fd'0 :: m) nil l) (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint d ms' :: m end) nil l0 ++ cld_gen_unique_constraint cld_list) (unique_methods_constraint dcl' ms')). bd H. inversion H2; subst; clear H2. po2; apply in_or_app; po1. generalize H; clear; induction x1. simpl; intros; discriminate. destruct a; simpl. caseEq (ms_eq ms' m). intros; po1. rewrite ((proj1 (eq_ms_eq _ _)) H); reflexivity. intros; po2; auto. po2; apply in_or_app; po2. applyI IHcld_list. exists x; exists x0; exists x1; pa. Qed. Lemma in_fd_gen_unique_constraint_rcld : forall (rcld_list : list rcld) (dcl' : dcl) (fd' : fd), In (unique_fields_constraint dcl' fd') (rcld_gen_unique_constraint rcld_list) <-> (exists cl', exists fds', exists mds', exists rmds', In (refines_cld_def dcl' cl' fds' mds' rmds') rcld_list /\ (In fd' fds')). induction rcld_list. simpl; pa; intros. contradiction. bd H. destruct a; simpl; pa; intros. destruct (in_app_or _ _ _ H). exists c; exists l; exists l0; exists l1; pa. po1. assert (d = dcl'). generalize H0; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. apply (IHl H0). congruence. generalize H0; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. po2; apply (IHl H0). destruct (in_app_or _ _ _ H0). elimtype False; generalize H1; clear; induction l0. simpl; auto. destruct a; simpl; intros; bd H1. discriminate. auto. import ((proj1 (IHrcld_list _ _) ) H1). bd H2. exists x; exists x0; exists x1; exists x2; pa. po2. apply (in_or_app (fold_right (fun (fd'0 : fd) (m : list unique_constraint) => unique_fields_constraint d fd'0 :: m) nil l) (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint d ms' :: m end) nil l0 ++ rcld_gen_unique_constraint rcld_list) (unique_fields_constraint dcl' fd')). bd H. inversion H2; subst; clear H2. po1. generalize H; clear; induction x0; simpl; intros. exact H. bd H. subst; po1. po2; auto. po2. apply in_or_app; po2. applyI IHrcld_list. exists x; exists x0; exists x1; exists x2; pa. Qed. Lemma in_ms_gen_unique_constraint_rcld : forall (rcld_list : list rcld) (dcl' : dcl) (ms' : ms), In (unique_methods_constraint dcl' ms') (rcld_gen_unique_constraint rcld_list) <-> (exists cl', exists fds', exists mds', exists rmds', In (refines_cld_def dcl' cl' fds' mds' rmds') rcld_list /\ (meth_in_mds mds' ms' = true)). induction rcld_list. simpl; pa; intros. contradiction. bd H. destruct a; simpl; pa; intros. destruct (in_app_or _ _ _ H). elimtype False; generalize H0; clear; induction l. simpl; auto. destruct a; simpl; intros; bd H0. discriminate. auto. destruct (in_app_or _ _ _ H0). exists c; exists l; exists l0; exists l1; pa. po1. assert (d = dcl'). generalize H1; clear; induction l0. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. inversion H1; auto. apply (IHl0 H1). congruence. generalize H1; clear; induction l0. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. inversion H1; subst. rewrite ((proj2 (eq_ms_eq _ ms') )(refl_equal _)); reflexivity. destruct (ms_eq ms' m); auto. import ((proj1 (IHrcld_list _ _) ) H1). bd H2. exists x; exists x0; exists x1; exists x2; pa. po2. apply (in_or_app (fold_right (fun (fd'0 : fd) (m : list unique_constraint) => unique_fields_constraint d fd'0 :: m) nil l) (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint d ms' :: m end) nil l0 ++ rcld_gen_unique_constraint rcld_list) (unique_methods_constraint dcl' ms')). bd H. inversion H2; subst; clear H2. po2; apply in_or_app; po1. generalize H; clear; induction x1. simpl; intros; discriminate. destruct a; simpl. caseEq (ms_eq ms' m). intros; po1. rewrite ((proj1 (eq_ms_eq _ _)) H); reflexivity. intros; po2; auto. po2; apply in_or_app; po2. applyI IHrcld_list. exists x; exists x0; exists x1; exists x2; pa. Qed. Lemma ex_composed_prog : forall (p : P) (ps : PSel) (fd' : FD), compose (fd' :: ps) = Some p -> exists p'', compose ps = Some p''. simpl. intros; destruct (compose ps). exists p0; reflexivity. discriminate. Qed. Lemma ex_composed_prog' : forall (p p': P) (cld_list : list cld) (rcld_list : list rcld) (rcld' : rcld), compose_fd (feature_def (rcld' :: rcld_list) cld_list) p' = Some p -> exists p'', compose_fd (feature_def rcld_list nil) p'= Some p'' /\ exists p''', compose_refines_class p'' rcld' = Some p'''/\ p = introduce_classes p''' cld_list /\ compose_fd (feature_def rcld_list cld_list) p' = Some (introduce_classes p'' cld_list). simpl. intros. destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p') rcld_list). exists p0; pa. reflexivity. destruct (compose_refines_class p0 rcld'). exists p1; repeat pa. congruence. discriminate. discriminate. Qed. Lemma in_compose_fd : forall (fd' : fd) (cld_list cld_list' : list cld) (rcld_list : list rcld) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (p : P), In (cld_def dcl' cl' fds' mds') p -> In fd' fds' -> compose_fd (feature_def rcld_list cld_list') cld_list = Some p -> distinct _ (names cld_list) -> (exists cl'', exists fds'', exists mds'', In (cld_def dcl' cl'' fds'' mds'') cld_list /\ In fd' fds'') \/ (exists cl'', exists fds'', exists mds'', In (cld_def dcl' cl'' fds'' mds'') cld_list' /\ In fd' fds'') \/ (exists cl'', exists fds'', exists mds'', exists rmds'', In (refines_cld_def dcl' cl'' fds'' mds'' rmds'') rcld_list /\ In fd' fds''). induction rcld_list. simpl; intros; inversion H1; subst; clear H1. induction cld_list'. simpl in *|-*; po1. exists cl'; exists fds'; exists mds'; pa. simpl in H; bd H; subst. po2; po1; exists cl'; exists fds'; exists mds'; pa. simpl; po1. import (IHcld_list' (In_rm_dcl _ _ _ H)). bd H1. po1; exists x; exists x0; exists x1; pa. po2; po1; exists x; exists x0; exists x1; pa. simpl; po2. intros; import (ex_composed_prog' _ _ _ _ _ H1); bd H3; subst. destruct a. cs (In (cl_dcl dcl') (names (introduce_classes nil cld_list'))). assert (In (cld_def dcl' cl' fds' mds') (introduce_classes nil cld_list')). generalize H H4; clear; induction cld_list'. simpl; intros H H0; bd H0. discriminate. destruct a; simpl; intros; bd H. po1. bd H4. inversion H4; subst; elimtype False; generalize H; clear; induction (introduce_classes x0 cld_list'). simpl; auto. destruct a; simpl. case (eq_nat_dec dcl' d); subst. intros; auto. simpl; intros n H; bd H. congruence. auto. po2; auto. import (IHcld_list' (In_rm_dcl _ _ _ H)). assert (In (cl_dcl dcl') (names (introduce_classes nil cld_list')) /\ dcl' <> d). generalize H4; clear; induction (introduce_classes nil cld_list'). simpl; intros H; bd H; discriminate. destruct a; simpl; case (eq_nat_dec d d0); simpl; intros; subst. import (IHl1 H4); bd H; pa. po2. bd H4. pa. po1. congruence. import (IHl1 H4); bd H; pa. po2. bd H1. generalize H1 (H0 H5); clear; induction (introduce_classes nil cld_list'). simpl; auto. destruct a; simpl; intros H H0; bd H0. case (eq_nat_dec d d0); intros; subst. congruence. simpl; po1. case (eq_nat_dec d d0); subst. intros; apply (IHl1 H H0). simpl; intros; po2; apply (IHl1 H H0). import ((IHrcld_list dcl' cl' fds' mds' (introduce_classes x cld_list')) (In_introduce_classes' x _ _ H5) H0 H3 H2). bd H8. po1; exists x1; exists x2; exists x3; pa. po2; po1; exists x1; exists x2; exists x3; pa. po2; po2; exists x1; exists x2; exists x3; exists x4; pa; simpl; po2. import (not_In_introduce_classes' _ _ _ _ _ _ H H4). assert (distinct _ (names x)). generalize x H2 H6; clear; induction rcld_list. simpl; congruence. intros; import (ex_composed_prog' _ _ _ _ _ H6); bd H; subst. apply (distinct_refines_class _ _ _ (IHrcld_list _ H2 H3) H4). cs (dcl' = d); subst. import (in_compose_rcld_in_p' _ _ _ _ _ _ _ _ _ _ H5 H8 H7). bd H9; subst. assert (In fd' x3 \/ In fd' l). generalize H0; clear; induction l; simpl. po1. induction (introduce_fields x3 l). simpl. intros; bd H0. po2; po1. destruct a0; destruct a; destruct t; destruct t0; simpl. case (eq_nat_dec f f0); intros; subst. caseEq (cl_eq c c0); intros; rewrite H in H0. destruct (IHl H0). po1. repeat po2. simpl in H0; bd H0. simpl in IHl; destruct (IHl (or_introl _ H0)). po1. repeat po2. apply IHl0. intros; apply IHl; po2. exact H0. simpl in H0; bd H0. simpl in IHl; destruct (IHl (or_introl _ H0)). po1. repeat po2. apply IHl0. intros; apply IHl; po2. exact H0. bd H10. assert (In (cld_def d x4 x3 x1) (introduce_classes x cld_list')). generalize H9 H4; clear; induction cld_list'. simpl; auto. destruct a; simpl; intros. bd H4. po2. assert (~ In (cl_dcl d) (names (introduce_classes nil cld_list'))). generalize H0 H4; clear; induction (introduce_classes nil cld_list'). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); intros H H0. unfold not; intros H1 H2; bd H2. congruence. apply IHl1; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl1; auto. generalize H4 (IHcld_list' H9 H); clear; induction (introduce_classes x cld_list'); simpl. auto. intros H H0; bd H0. subst. case (eq_nat_dec d0 d). congruence. simpl; intros; po1. destruct a; case (eq_nat_dec d0 d1). intros; auto. intros; simpl; po2; auto. import (IHrcld_list _ _ _ _ _ H11 H10 H3 H2). bd H13. po1; exists x5; exists x6; exists x7; pa. po2; po1; exists x5; exists x6; exists x7; pa. repeat po2; exists x5; exists x6; exists x7; exists x8; pa. simpl; po2. repeat po2; exists c; exists l; exists l0; exists l1; pa. simpl; po1. import (in_compose_rcld_in_p _ _ _ _ _ _ _ _ _ _ _ H9 H5 H7). bd H9; subst. assert (In (cld_def dcl' cl' fds' mds') (introduce_classes x cld_list')). generalize H10 H4; clear; induction cld_list'. simpl; auto. destruct a; simpl; intros. bd H4. po2. assert (~ In (cl_dcl dcl') (names (introduce_classes nil cld_list'))). generalize H0 H4; clear; induction (introduce_classes nil cld_list'). simpl; auto. destruct a; simpl; case (eq_nat_dec d d0); intros H H0. unfold not; intros H1 H2; bd H2. congruence. apply IHl1; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl1; auto. generalize H4 (IHcld_list' H10 H); clear; induction (introduce_classes x cld_list'); simpl. auto. intros H H0; bd H0. subst. case (eq_nat_dec d dcl'). congruence. simpl; intros; po1. destruct a; case (eq_nat_dec d d0). intros; auto. intros; simpl; po2; auto. import (IHrcld_list _ _ _ _ _ H11 H0 H3 H2). bd H12. po1; exists x1; exists x2; exists x3; pa. po2; po1; exists x1; exists x2; exists x3; pa. repeat po2; exists x1; exists x2; exists x3; exists x4; pa. simpl; po2. Qed. Lemma in_compose_ms : forall (ms' : ms) (cld_list cld_list' : list cld) (rcld_list : list rcld) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (p : P), In (cld_def dcl' cl' fds' mds') p -> meth_in_mds mds' ms'= true-> compose_fd (feature_def rcld_list cld_list') cld_list = Some p -> distinct _ (names cld_list) -> (exists cl'', exists fds'', exists mds'', In (cld_def dcl' cl'' fds'' mds'') cld_list /\ meth_in_mds mds'' ms' = true) \/ (exists cl'', exists fds'', exists mds'', In (cld_def dcl' cl'' fds'' mds'') cld_list' /\ meth_in_mds mds'' ms' = true) \/ (exists cl'', exists fds'', exists mds'', exists rmds'', In (refines_cld_def dcl' cl'' fds'' mds'' rmds'') rcld_list /\ meth_in_mds mds'' ms' = true). induction rcld_list. simpl; intros; inversion H1; subst; clear H1. induction cld_list'. simpl in *|-*; po1. exists cl'; exists fds'; exists mds'; pa. simpl in H; bd H; subst. po2; po1; exists cl'; exists fds'; exists mds'; pa. simpl; po1. import (IHcld_list' (In_rm_dcl _ _ _ H)). bd H1. po1; exists x; exists x0; exists x1; pa. po2; po1; exists x; exists x0; exists x1; pa. simpl; po2. intros; import (ex_composed_prog' _ _ _ _ _ H1); bd H3; subst. destruct a. cs (In (cl_dcl dcl') (names (introduce_classes nil cld_list'))). assert (In (cld_def dcl' cl' fds' mds') (introduce_classes nil cld_list')). generalize H H4; clear; induction cld_list'. simpl; intros H H0; bd H0. discriminate. destruct a; simpl; intros; bd H. po1. bd H4. inversion H4; subst; elimtype False; generalize H; clear; induction (introduce_classes x0 cld_list'). simpl; auto. destruct a; simpl. case (eq_nat_dec dcl' d); subst. intros; auto. simpl; intros n H; bd H. congruence. auto. po2; auto. import (IHcld_list' (In_rm_dcl _ _ _ H)). assert (In (cl_dcl dcl') (names (introduce_classes nil cld_list')) /\ dcl' <> d). generalize H4; clear; induction (introduce_classes nil cld_list'). simpl; intros H; bd H; discriminate. destruct a; simpl; case (eq_nat_dec d d0); simpl; intros; subst. import (IHl1 H4); bd H; pa. po2. bd H4. pa. po1. congruence. import (IHl1 H4); bd H; pa. po2. bd H1. generalize H1 (H0 H5); clear; induction (introduce_classes nil cld_list'). simpl; auto. destruct a; simpl; intros H H0; bd H0. case (eq_nat_dec d d0); intros; subst. congruence. simpl; po1. case (eq_nat_dec d d0); subst. intros; apply (IHl1 H H0). simpl; intros; po2; apply (IHl1 H H0). import ((IHrcld_list dcl' cl' fds' mds' (introduce_classes x cld_list')) (In_introduce_classes' x _ _ H5) H0 H3 H2). bd H8. po1; exists x1; exists x2; exists x3; pa. po2; po1; exists x1; exists x2; exists x3; pa. po2; po2; exists x1; exists x2; exists x3; exists x4; pa; simpl; po2. import (not_In_introduce_classes' _ _ _ _ _ _ H H4). assert (distinct _ (names x)). generalize x H2 H6; clear; induction rcld_list. simpl; congruence. intros; import (ex_composed_prog' _ _ _ _ _ H6); bd H; subst. apply (distinct_refines_class _ _ _ (IHrcld_list _ H2 H3) H4). cs (dcl' = d); subst. import (in_compose_rcld_in_p' _ _ _ _ _ _ _ _ _ _ H5 H8 H7). bd H9; subst. caseEq (meth_in_mds l0 ms'); intros. repeat po2; exists c; exists l; exists l0; exists l1; pa. simpl; po1. import (in_introduce_in_mds _ _ _ H0 H10). import (in_compose_in_mds _ _ _ _ H11 H12). assert (In (cld_def d x4 x3 x1) (introduce_classes x cld_list')). generalize H9 H4; clear; induction cld_list'. simpl; auto. destruct a; simpl; intros. bd H4. po2. assert (~ In (cl_dcl d) (names (introduce_classes nil cld_list'))). generalize H0 H4; clear; induction (introduce_classes nil cld_list'). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); intros H H0. unfold not; intros H1 H2; bd H2. congruence. apply IHl1; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl1; auto. generalize H4 (IHcld_list' H9 H); clear; induction (introduce_classes x cld_list'); simpl. auto. intros H H0; bd H0. subst. case (eq_nat_dec d0 d). congruence. simpl; intros; po1. destruct a; case (eq_nat_dec d0 d1). intros; auto. intros; simpl; po2; auto. import (IHrcld_list _ _ _ _ _ H14 H13 H3 H2). bd H15. po1; exists x5; exists x6; exists x7; pa. po2; po1; exists x5; exists x6; exists x7; pa. repeat po2; exists x5; exists x6; exists x7; exists x8; pa. simpl; po2. import (in_compose_rcld_in_p _ _ _ _ _ _ _ _ _ _ _ H9 H5 H7). bd H9; subst. assert (In (cld_def dcl' cl' fds' mds') (introduce_classes x cld_list')). generalize H10 H4; clear; induction cld_list'. simpl; auto. destruct a; simpl; intros. bd H4. po2. assert (~ In (cl_dcl dcl') (names (introduce_classes nil cld_list'))). generalize H0 H4; clear; induction (introduce_classes nil cld_list'). simpl; auto. destruct a; simpl; case (eq_nat_dec d d0); intros H H0. unfold not; intros H1 H2; bd H2. congruence. apply IHl1; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl1; auto. generalize H4 (IHcld_list' H10 H); clear; induction (introduce_classes x cld_list'); simpl. auto. intros H H0; bd H0. subst. case (eq_nat_dec d dcl'). congruence. simpl; intros; po1. destruct a; case (eq_nat_dec d d0). intros; auto. intros; simpl; po2; auto. import (IHrcld_list _ _ _ _ _ H11 H0 H3 H2). bd H12. po1; exists x1; exists x2; exists x3; pa. po2; po1; exists x1; exists x2; exists x3; pa. repeat po2; exists x1; exists x2; exists x3; exists x4; pa. simpl; po2. Qed. Lemma gen_unique_constraint : forall (ps : PSel) (p : P) (dc : unique_constraint), compose ps = Some p -> In dc (cld_gen_unique_constraint p) -> In dc (ps_gen_unique_constraint ps). induction ps; simpl. intros; inversion H; subst; simpl in H0; exact H0. caseEq (compose ps); intros. destruct dc. import ((proj1 (in_fd_gen_unique_constraint _ _ _ )) H1); clear H1. bd H2. destruct a. import (in_compose_fd _ _ _ _ _ _ _ _ _ H4 H2 H0 (distinct_compose_names _ _ H)). bd H1. apply in_or_app; po2; apply (IHps _ (unique_fields_constraint d f) H). applyI in_fd_gen_unique_constraint. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po2. applyI in_fd_gen_unique_constraint. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po1. applyI in_fd_gen_unique_constraint_rcld. exists x2; exists x3; exists x4; exists x5; pa. import ((proj1 (in_ms_gen_unique_constraint _ _ _ )) H1); clear H1. bd H2. destruct a. import (in_compose_ms _ _ _ _ _ _ _ _ _ H4 H2 H0 (distinct_compose_names _ _ H)). bd H1. apply in_or_app; po2; apply (IHps _ (unique_methods_constraint d m) H). applyI in_ms_gen_unique_constraint. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po2. applyI in_ms_gen_unique_constraint. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po1. applyI in_ms_gen_unique_constraint_rcld. exists x2; exists x3; exists x4; exists x5; pa. discriminate. Qed. Lemma In_dc_list_repeated : forall (dcl' : dcl) (cl' cl'' : cl) (f' : f) (dc_list: list unique_constraint), cl_eq cl'' cl' = false -> In (unique_fields_constraint dcl' (fd_def (ty_def cl') f')) dc_list -> f_repeated dcl' cl'' f' dc_list = true. induction dc_list. simpl; contradiction. destruct a; simpl; intros H. destruct f; destruct t; case (eq_nat_dec dcl' d). case (eq_nat_dec f' f). caseEq (cl_eq cl'' c); intros. bd H1. rewrite ((proj1 (eq_cl_eq _ _)) H0) in H. subst; inversion H1. rewrite ((proj2 (eq_cl_eq _ _)) H3) in H; discriminate. auto. auto. intros; bd H0. subst; inversion H0; congruence. auto. intros; bd H0. subst; inversion H0; congruence. auto. intros; bd H0. subst; inversion H0; auto. auto. Qed. Lemma In_dc_list_repeated_ms : forall (dcl' : dcl) (ty' ty'' : ty) (m' : m) (vd_list vd_list' : list vd) (dc_list: list unique_constraint), ms_eq (ms_def ty' m' vd_list) (ms_def ty'' m' vd_list') = false -> In (unique_methods_constraint dcl' (ms_def ty' m' vd_list)) dc_list -> ms_repeated dcl' ty'' m' vd_list' dc_list = true. induction dc_list. simpl; contradiction. destruct a; simpl. destruct ty'; destruct ty''; case (eq_nat_dec m' m'). caseEq (cl_eq c c0). caseEq (vd_list_eq vd_list vd_list'); simpl; intros. discriminate. bd H2. inversion H2; subst. apply IHdc_list; auto. simpl; case (eq_nat_dec m' m'). rewrite H0; rewrite H; auto. congruence. intros; bd H1. inversion H1; subst. apply IHdc_list; auto. simpl; case (eq_nat_dec m' m'). rewrite H; auto. congruence. congruence. destruct m; destruct ty'; destruct ty''; case (eq_nat_dec m' m'); intros. bd H0. inversion H0; subst. case (eq_nat_dec dcl' dcl'). case (eq_nat_dec m' m'). destruct (cl_eq c c0). destruct (vd_list_eq vd_list vd_list'). simpl in H; discriminate. simpl; auto. simpl; auto. congruence. congruence. case (eq_nat_dec dcl' d). case (eq_nat_dec m' m). destruct t. case (eq_nat_dec m m'). destruct (cl_eq c1 c0). destruct (vd_list_eq l vd_list'). simpl. intros; apply IHdc_list; auto. simpl; case (eq_nat_dec m' m'). destruct (cl_eq c c0). destruct (vd_list_eq vd_list vd_list'). simpl in H; discriminate. auto. auto. auto. simpl; auto. auto. auto. intros; apply IHdc_list; auto. simpl; case (eq_nat_dec m' m'). destruct (cl_eq c c0). destruct (vd_list_eq vd_list vd_list'). simpl in H; discriminate. auto. auto. auto. intros; apply IHdc_list; auto. simpl; case (eq_nat_dec m' m'). destruct (cl_eq c c0). destruct (vd_list_eq vd_list vd_list'). simpl in H; discriminate. auto. auto. auto. congruence. Qed. Lemma sat_subset_fd_constr : forall (dcl' : dcl) (dc_list dc_list': list unique_constraint), (forall (d : unique_constraint), In d dc_list -> In d dc_list') -> sat_f_unique_constraint dcl' dc_list' = true -> sat_f_unique_constraint dcl' dc_list = true. induction dc_list. simpl; auto. destruct a; simpl. destruct f; destruct t; case (eq_nat_dec dcl' d). caseEq (f_repeated dcl' c f dc_list); intros. assert (f_repeated d c f dc_list' = true). clear IHdc_list H1; induction dc_list. simpl in H; discriminate. destruct a; simpl in H. destruct f0; destruct t; simpl in H. generalize H; clear H; case (eq_nat_dec dcl' d0); subst. case (eq_nat_dec f f0). caseEq (cl_eq c c0); intros. apply IHdc_list; auto. intros; apply H0; bd H2. po1. simpl; repeat po2. subst. simpl in H0. apply (In_dc_list_repeated _ _ _ _ _ H (H0 _ (or_intror _ (or_introl _ (refl_equal _))))). intros. apply IHdc_list; auto. intros; apply H0; bd H1. po1. simpl; repeat po2. intros. apply IHdc_list; auto. intros; apply H0; bd H1. po1. simpl; repeat po2. apply IHdc_list; auto. intros; apply H0; bd H1. po1. simpl; repeat po2. subst; elimtype False; generalize (H0 _ (or_introl _ (refl_equal _))) H1 H2; clear; induction dc_list'. simpl; auto. destruct a; simpl; intros; bd H. inversion H; subst. cs (In (unique_fields_constraint d (fd_def (ty_def c) f)) dc_list'). generalize H1 H2; clear H1 H2; case (eq_nat_dec d d); intros e H1; subst. case (eq_nat_dec f f). rewrite ((proj2 (eq_cl_eq _ c)) (refl_equal _)). intros _ H3; rewrite H3 in H1; discriminate. congruence. congruence. generalize H1 H2; clear H1 H2; case (eq_nat_dec d d); intros e H1; subst. case (eq_nat_dec f f). rewrite ((proj2 (eq_cl_eq _ c)) (refl_equal _)). intros _ H3; rewrite H3 in H1; discriminate. auto. auto. destruct f0; destruct t. generalize H1 H2; clear H1 H2; case (eq_nat_dec d d0); intros e H1; subst. case (eq_nat_dec f f0). caseEq (cl_eq c c0); intros. rewrite ((proj1 (eq_cl_eq _ _)) H0) in *; subst. rewrite H2 in H1; auto. discriminate. subst. caseEq (f_repeated d0 c0 f0 dc_list'); intros H3; rewrite H3 in H1. discriminate. caseEq (cl_eq c0 c); intros. rewrite (proj2 (eq_cl_eq _ _) (sym_equal ((proj1 (eq_cl_eq _ _)) H4))) in H0; discriminate. rewrite (In_dc_list_repeated _ _ _ _ _ H4 H) in H3; discriminate. destruct (f_repeated d0 c0 f0 dc_list'); intros; auto. discriminate. auto. discriminate. auto. apply (IHdc_list dc_list'); auto. intros; auto. apply (IHdc_list dc_list'); auto. intros; apply (IHdc_list dc_list'); auto. Qed. Lemma sat_subset_ms_constr : forall (dcl' : dcl) (dc_list dc_list': list unique_constraint), (forall (d : unique_constraint), In d dc_list -> In d dc_list') -> sat_ms_unique_constraint dcl' dc_list' = true -> sat_ms_unique_constraint dcl' dc_list = true. induction dc_list. simpl; auto. destruct a; simpl. intros; apply (IHdc_list dc_list'); auto. destruct m; case (eq_nat_dec dcl' d). caseEq (ms_repeated dcl' t m l dc_list); intros. assert (ms_repeated d t m l dc_list' = true). clear IHdc_list H1; induction dc_list. simpl in H; discriminate. destruct a; simpl in H. apply IHdc_list; auto. intros. apply H0; auto. bd H1. po1. simpl; po2. po2. destruct m0. generalize H; clear H; case (eq_nat_dec dcl' d0); subst. case (eq_nat_dec m m0). destruct t0; destruct t. case (eq_nat_dec m0 m). caseEq (cl_eq c c0); intros. simpl in H1. caseEq (vd_list_eq l0 l); intros; rewrite H2 in H1. apply IHdc_list; auto. intros; apply H0; bd H3. po1. simpl; repeat po2. apply (In_dc_list_repeated_ms d (ty_def c) (ty_def c0) m l0 l dc_list'). simpl; clear e; subst. case (eq_nat_dec m0 m0). rewrite H; rewrite H2; auto. auto. apply H0; simpl; po2; po1; congruence. simpl in H1. apply (In_dc_list_repeated_ms d (ty_def c) (ty_def c0) m l0 l dc_list'). simpl; clear e; subst. case (eq_nat_dec m0 m0). rewrite H; auto. auto. apply H0; simpl; po2; po1; congruence. congruence. intros; apply IHdc_list; auto. intros; apply H0; bd H1. po1. simpl; repeat po2. intros. apply IHdc_list; auto. intros; apply H0; bd H1. po1. simpl; repeat po2. subst; elimtype False; generalize (H0 _ (or_introl _ (refl_equal _))) H1 H2; clear; induction dc_list'. simpl; auto. destruct a; simpl; intros; bd H. discriminate. auto. inversion H; subst; clear H. generalize H2; clear H2; case (eq_nat_dec d d). case (eq_nat_dec m m). destruct t; caseEq (cl_eq c c). caseEq (vd_list_eq l l); simpl; intros. clear e. generalize H1; clear H1; case (eq_nat_dec d d); intros; subst. rewrite H2 in H1; discriminate. congruence. rewrite ((proj2 (eq_vd_list_eq _ l)) (refl_equal _)) in *; discriminate. rewrite ((proj2 (eq_cl_eq _ c)) (refl_equal _)) in *; intros; discriminate. congruence. congruence. destruct m0. generalize H1 H2; clear H2 H1; case (eq_nat_dec d d0); intros e H1. case (eq_nat_dec m m0). destruct t; destruct t0; caseEq (cl_eq c0 c). caseEq (vd_list_eq l0 l); simpl; case (eq_nat_dec m0 m); intros. rewrite ((proj1 (eq_cl_eq _ _)) H2) in H1. rewrite ((proj1 (eq_vd_list_eq _ _)) H0) in H1. rewrite e0 in H1; rewrite H3 in H1; discriminate. congruence. rewrite e0 in H1. rewrite (In_dc_list_repeated_ms d (ty_def c) (ty_def c0) m l l0 dc_list') in H1. discriminate. simpl; case (eq_nat_dec m m). rewrite (proj2 (eq_cl_eq _ _) (sym_equal ((proj1 (eq_cl_eq _ _)) H2))). caseEq (vd_list_eq l l0); intros; auto. rewrite (proj2 (eq_vd_list_eq _ _) (sym_equal ((proj1 (eq_vd_list_eq _ _)) H4))) in H0; discriminate. auto. auto. congruence. intros. rewrite <- e0 in H1. rewrite (In_dc_list_repeated_ms d (ty_def c) (ty_def c0) m l l0 dc_list') in H1. discriminate. simpl; case (eq_nat_dec m m). caseEq (cl_eq c c0); auto. intros; rewrite (proj2 (eq_cl_eq _ _) (sym_equal ((proj1 (eq_cl_eq _ _)) H3))) in H0; discriminate. auto. generalize H2; clear H2; subst; case (eq_nat_dec m0 m0). simpl; intros. auto. congruence. intros; apply IHdc_list'; auto. destruct (ms_repeated d t0 m0 l0 dc_list'). discriminate. auto. intros; auto. apply (IHdc_list dc_list'). intros; apply H0; po2. exact H1. intros; apply (IHdc_list dc_list'). intros; apply H; po2. exact H0. Qed. Lemma sat_fd_unique_constraint : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_f_unique_constraint dcl' (cld_gen_unique_constraint (cld_def dcl' cl' fds' mds' :: nil) ) = true -> distinct _ fds' -> distinct _ (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds'). simpl; intros. assert (sat_f_unique_constraint dcl' (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds') = true). clear H0. induction fds'. simpl; auto. generalize H; clear H; destruct a; simpl; destruct t; case (eq_nat_dec dcl' dcl'). caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)); intros. discriminate. caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds')); intros. elimtype False; generalize H H1; clear; induction fds'. simpl; intros; discriminate. destruct a; simpl; destruct t; case (eq_nat_dec dcl' dcl'). case (eq_nat_dec f f0). caseEq (cl_eq c c0); intros. auto. discriminate. intros; auto. congruence. auto. congruence. clear H. induction fds'. simpl; auto. generalize H1; clear H1; destruct a; simpl; destruct t; case (eq_nat_dec dcl' dcl'). caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds')). intros; discriminate. intros; pa; auto. generalize H H0; clear; induction fds'. simpl; auto. destruct a; simpl. case (eq_nat_dec dcl' dcl'). destruct t; case (eq_nat_dec f f0). caseEq (cl_eq c c0). unfold not; intros. bd H1. apply H5; po1. subst; rewrite ((proj1 (eq_cl_eq _ c0)) H); reflexivity. intros; bd H1. discriminate. unfold not; intros; bd H1. apply n; auto. apply (IHfds' H). simpl; pa; bd H0. unfold not; intros; apply H4; auto. exact H1. congruence. simpl in H0; bd H0; apply (IHfds' H0 H1). congruence. Qed. Lemma sat_unique_constraint_ms : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_ms_unique_constraint dcl' (cld_gen_unique_constraint (cld_def dcl' cl' fds' mds' :: nil) ) = true -> distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds') -> distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _ => m' end) mds'). simpl; intros. assert (sat_ms_unique_constraint dcl' (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds') = true). clear H0. induction fds'. simpl in*|-*; auto. induction mds'. simpl; auto. generalize H; clear H; destruct a; simpl; destruct m; case (eq_nat_dec dcl' dcl'). caseEq (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m1 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m1 end) nil mds')). caseEq (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m1 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m1 end) nil mds' ++ nil)); intros. exact H1. elimtype False; generalize H H0; clear; induction mds'. simpl; intros; discriminate. destruct a; simpl; destruct t; case (eq_nat_dec dcl' dcl'). destruct m0; destruct t; case (eq_nat_dec m m0). case (eq_nat_dec m0 m). caseEq (cl_eq c0 c). caseEq (vd_list_eq l0 l); simpl; intros. auto. discriminate. simpl; intros; discriminate. congruence. intros; auto. congruence. caseEq (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m1 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m1 end) nil mds' ++ nil)); intros. discriminate. auto. congruence. simpl in H; apply (IHfds' H). clear H. induction mds'. simpl; auto. generalize H1; clear H1; destruct a; simpl; destruct m; case (eq_nat_dec dcl' dcl'). caseEq (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m1 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m1 end) nil mds')); intros. intros; discriminate. bd H0; intros; pa; auto. generalize H H0; clear; induction mds'. simpl; auto. destruct a; simpl. case (eq_nat_dec dcl' dcl'). destruct m1; destruct t0; destruct t; case (eq_nat_dec m m1). case (eq_nat_dec m1 m). caseEq (cl_eq c c0). caseEq (vd_list_eq l0 l). simpl. unfold not; intros. bd H2. apply H6; po1. clear e; subst; rewrite ((proj1 (eq_cl_eq _ c0)) H0); rewrite ((proj1 (eq_vd_list_eq _ _ )) H); reflexivity. intros; simpl in H1; discriminate. intros; simpl in H1; discriminate. intros; discriminate. unfold not; intros; bd H1. apply n; auto. apply (IHmds' H). simpl; pa; bd H0. unfold not; intros; apply H4; auto. exact H1. congruence. simpl in H0; bd H0; apply (IHmds' H0 H1). congruence. Qed. Lemma sat_ms_unique_constraint_none : forall (dc_list : list unique_constraint) (dcl' : dcl), (forall ms', ~ In (unique_methods_constraint dcl' ms') dc_list) -> sat_ms_unique_constraint dcl' dc_list = true. induction dc_list. simpl; auto. destruct a; simpl; intros. apply IHdc_list; intros; import (H ms'); bd H0. destruct m. case (eq_nat_dec dcl' d). import (H (ms_def t m l)); bd H0. congruence. intros; apply IHdc_list; intros; import (H ms'); bd H0. Qed. Lemma sat_fd_unique_constraint_none : forall (dc_list : list unique_constraint) (dcl' : dcl), (forall fd', ~ In (unique_fields_constraint dcl' fd') dc_list) -> sat_f_unique_constraint dcl' dc_list = true. induction dc_list. simpl; auto. destruct a; simpl; intros. destruct f; destruct t. case (eq_nat_dec dcl' d). import (H (fd_def (ty_def c) f)); bd H0. congruence. intros; apply IHdc_list; intros; import (H fd'); bd H0. apply IHdc_list; intros; import (H fd'); bd H0. Qed. Lemma sat_unique_constraint_all : forall (dc_list : list unique_constraint) (ms' : ms) (fd' : fd) (dcl' : dcl), In (unique_fields_constraint dcl' fd') dc_list \/ In (unique_methods_constraint dcl' ms') dc_list -> sat_unique_constraint dc_list = true -> sat_f_unique_constraint dcl' dc_list = true /\ sat_ms_unique_constraint dcl' dc_list = true. induction dc_list. simpl; auto. intros ms' fd' dcl' H; simpl in H; bd H. subst; simpl. destruct fd'; destruct t; case (eq_nat_dec dcl' dcl'). caseEq (f_repeated dcl' c f dc_list); simpl. intros; discriminate. intros; destruct (andb_prop _ _ H0); pa. cs (exists ms', In (unique_methods_constraint dcl' ms') dc_list). bd H3. apply (proj2 (IHdc_list _ (fd_def (ty_def c) f) _ (or_intror _ H3) H2)). bd H3. apply sat_ms_unique_constraint_none; auto. congruence. destruct a; simpl. destruct f; destruct t; case (eq_nat_dec d d). caseEq (f_repeated d c f dc_list); simpl. intros; discriminate. intros; destruct (andb_prop _ _ H1); pa. case (eq_nat_dec dcl' d); intros; subst. rewrite H0; exact H2. apply (proj1 (IHdc_list ms' _ _ (or_introl _ H) H3)). cs (exists ms', In (unique_methods_constraint dcl' ms') dc_list). bd H4. apply (proj2 (IHdc_list _ (fd_def (ty_def c) f) _ (or_intror _ H4) H3)). bd H4. apply sat_ms_unique_constraint_none; auto. congruence. destruct m; case (eq_nat_dec d d). case (eq_nat_dec dcl' d); intros; subst. destruct (ms_repeated d t m l dc_list). simpl in H0; discriminate. destruct (andb_prop _ _ H0). pa. apply (proj1 (IHdc_list ms' _ _ (or_introl _ H) H2)). destruct (ms_repeated d t m l dc_list). simpl in H0; discriminate. destruct (andb_prop _ _ H0). apply ((IHdc_list ms' _ _ (or_introl _ H) H2)). congruence. subst. destruct ms'; simpl. case (eq_nat_dec dcl' dcl'). destruct (ms_repeated dcl' t m l dc_list). simpl; intros; discriminate. intros; destruct (andb_prop _ _ H); clear H. pa. cs (exists fd', In (unique_fields_constraint dcl' fd') dc_list). bd H. apply (proj1 (IHdc_list (ms_def t m l) _ _ (or_introl _ H) H1)). bd H. apply sat_fd_unique_constraint_none; auto. congruence. destruct a; simpl. destruct f; destruct t; case (eq_nat_dec d d). caseEq (f_repeated d c f dc_list); simpl. intros; discriminate. intros; destruct (andb_prop _ _ H1); pa. case (eq_nat_dec dcl' d); intros; subst. rewrite H0; exact H2. apply (proj1 (IHdc_list ms' fd' _ (or_intror _ H) H3)). apply (proj2 (IHdc_list ms' fd' _ (or_intror _ H) H3)). congruence. destruct m; case (eq_nat_dec d d). case (eq_nat_dec dcl' d); intros; subst. destruct (ms_repeated d t m l dc_list). simpl in H0; discriminate. destruct (andb_prop _ _ H0). pa. apply (proj1 (IHdc_list ms' fd' _ (or_intror _ H) H2)). destruct (ms_repeated d t m l dc_list). simpl in H0; discriminate. destruct (andb_prop _ _ H0). apply ((IHdc_list ms' fd' _ (or_intror _ H) H2)). congruence. Qed. Lemma sat_subset_constr : forall (dc_list dc_list': list unique_constraint), (forall (d : unique_constraint), In d dc_list -> In d dc_list') -> sat_unique_constraint dc_list' = true -> sat_unique_constraint dc_list = true. induction dc_list. simpl; auto. destruct a. intros; import (H _ (or_introl _ (refl_equal _))). intros; import (sat_unique_constraint_all dc_list' (ms_def (ty_def cl_object) 0 nil) f d (or_introl _ H1) H0). bd H2. simpl; apply andb_true_intro; pa. import (sat_subset_fd_constr d (unique_fields_constraint d f :: dc_list) dc_list' H H5). simpl in H3; exact H3. apply (IHdc_list dc_list'); intros; auto. apply H; simpl; po2. intros. intros; import (H _ (or_introl _ (refl_equal _))). intros; import (sat_unique_constraint_all dc_list' m (fd_def (ty_def cl_object) 0) d (or_intror _ H1) H0). bd H2. simpl; apply andb_true_intro; pa. import (sat_subset_ms_constr d (unique_methods_constraint d m :: dc_list) dc_list' H H2). simpl in H3; exact H3. apply (IHdc_list dc_list'); intros; auto. apply H; simpl; po2. Qed. Lemma distinct_introduce_fields : forall (fds' fds'' : list fd), distinct fd fds' -> distinct fd (introduce_fields fds' fds''). induction fds''. simpl; auto. destruct a; simpl. intros; generalize (IHfds'' H); clear. induction (introduce_fields fds' fds''). simpl; tauto. destruct a; simpl; intros; bd H. destruct t0; destruct t; case (eq_nat_dec f0 f). caseEq (cl_eq c c0); intros. simpl; pa; auto. simpl; pa. unfold not; intros; apply H2. subst; generalize H1 H0; clear; induction l. simpl; intros. bd H1. inversion H1; subst. rewrite ((proj2 (eq_cl_eq _ c)) (refl_equal _)) in H0; discriminate. destruct a; simpl. destruct t; case (eq_nat_dec f0 f). caseEq (cl_eq c1 c0); simpl; intros. subst; bd H1. subst; bd H1. inversion H1; subst. po1. po2; auto. simpl; intros. bd H1. inversion H1; subst. congruence. po2; auto. subst. auto. simpl; intros. pa; auto. unfold not; intros; apply H2; generalize n H0; clear; induction l. simpl; intros. bd H0. congruence. destruct a; simpl. destruct t; case (eq_nat_dec f1 f). caseEq (cl_eq c1 c0); simpl; intros; bd H0. congruence. auto. simpl; intros. bd H0. po1. po2; auto. Qed. Lemma distinct_introduce_mds : forall (mds' mds'' : list md), distinct ms (map (fun md' : md => match md' with | md_def ms' _ => ms' end) mds') -> distinct ms (map (fun md' : md => match md' with | md_def ms' _ => ms' end) (introduce_methods mds' mds'')). induction mds''. simpl; auto. simpl. intros; generalize (IHmds'' H); clear. induction (introduce_methods mds' mds''). simpl; tauto. destruct a; simpl; intros; bd H. destruct a0. caseEq (ms_eq m1 m); intros; simpl; pa. rewrite <- ((proj1 (eq_ms_eq _ _) ) H0); exact H2. unfold not; intros; apply H2; generalize H0 H1; clear. induction l; simpl. intros. bd H1; subst. rewrite ((proj2 (eq_ms_eq m1 _) ) (refl_equal _ )) in H0; discriminate. destruct a; simpl. caseEq (ms_eq m2 m); intros. po2. apply IHl; auto. simpl in H1; bd H1. subst. rewrite ((proj2 (eq_ms_eq m1 _) ) (refl_equal _ )) in H0; discriminate. generalize H0 H1; clear; induction l; simpl. intros. contradiction. destruct a; simpl. caseEq (ms_eq m2 m); intros. bd H1; subst. rewrite H in H0; discriminate. simpl; po2. simpl; bd H1. po1. po2. generalize H0 H1; clear; induction l; simpl. intros. contradiction. destruct a; simpl. caseEq (ms_eq m2 m); intros. bd H1; subst. rewrite H in H0; discriminate. simpl; po2. simpl; bd H1. po1. po2; auto. simpl in H1; bd H1. po1. po2; auto. auto. Qed. Lemma distinct_compose_mds : forall (rmds' : list rmd) (mds' mds'' : list md), distinct ms (map (fun md' : md => match md' with md_def ms' _ => ms' end) mds') -> compose_refined_mds mds' rmds' = Some mds'' -> distinct ms (map (fun md' : md => match md' with md_def ms' _ => ms' end) mds''). induction rmds'. simpl; congruence. simpl. intros mds'; caseEq (compose_refined_mds mds' rmds'); intros. generalize mds'' H1 (IHrmds' _ _ H0 H); clear; destruct a; induction l. simpl; intros; discriminate. destruct a; destruct m1; destruct r; simpl. caseEq (ms_eq m0 m); intros; bd H0. inversion H1; subst. simpl; pa. destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl; inversion H1; subst; clear H1. simpl; pa. unfold not; intros; apply H4; generalize x1 H2 H1; clear; induction l. simpl; intros; discriminate. destruct a; simpl. destruct m2; caseEq (ms_eq m1 m). intros; inversion H2; subst; simpl in H1; bd H1. intros. destruct (cons_option_Some _ _ _ _ H2); rewrite H0 in H2; simpl; inversion H2; subst; clear H2. simpl in H1; bd H1. po1. import (IHl _ H0 H1). po2. apply (IHl _ H2 H0). discriminate. Qed. Theorem compose_distinct_fields : forall (ps : PSel) (p : P) (dcl': dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose ps = Some p -> In (cld_def dcl' cl' fds' mds') p -> (forall (rclds' : list rcld) (clds' : list cld) (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (feature_def rclds' clds') ps -> In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ fds'') -> distinct _ fds'. induction ps. simpl; intros; inversion H; subst. simpl in H0; contradiction. simpl; caseEq (compose ps); intros. assert (forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), In (cld_def dcl' cl' fds' mds') p -> distinct fd fds'). intros; apply (IHps p dcl'0 cl'0 fds'0 mds'0 H H3). intros; apply (H2 rclds' clds' dcl'' cl'' fds'' mds''). po2. auto. clear IHps. destruct a. assert (forall (dcl'' : dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (cld_def dcl'' cl'' fds'' mds'' ) l0 -> distinct fd fds''). intros; apply (H2 l l0 dcl'' cl'' fds'' mds''); auto. generalize p p0 dcl' cl' fds' mds' (distinct_compose_names _ _ H) H0 H1 H4 H3; clear. induction l. simpl. intros p p0 dcl' cl' fds' mds'; intros. inversion H0; subst; clear H0. induction l0. simpl in H1. apply (H3 _ _ _ _ H1); auto. simpl in H1; bd H1. rewrite H1 in H4. simpl in H4; apply (H4 _ _ _ _ (or_introl _ (refl_equal _))). apply IHl0. intros. simpl in H4; apply (H4 _ _ _ _ (or_intror _ H0)). apply (In_rm_dcl _ _ _ H1). destruct a; intros p p0 dcl' cl' fds' mds' H H1. import (ex_composed_prog' _ _ _ _ _ H1); bd H0. case (eq_nat_dec dcl' d); intro e; subst. cs ( In (cld_def d cl' fds' mds') (introduce_classes nil l0)). intros; apply (IHl _ _ _ _ _ _ H H0 (In_introduce_classes' x _ _ H2)); intros. apply (H6 _ _ _ _ H8). simpl in H7; apply (H7 _ _ _ _ H8). intros H3. import (not_In_introduce_classes _ _ _ H3 H2). assert (distinct _ (names x)). generalize x H H4; clear; induction l. simpl; congruence. simpl in *|-*. destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l). caseEq (compose_refines_class p0 a). intros p1 H x H5 H4; import (IHl _ H5 (refl_equal _)). inversion H4; subst; apply (distinct_refines_class _ _ _ H0 H). intros; discriminate. intros; discriminate. import (in_compose_rcld_in_p' _ _ _ _ _ _ _ _ _ _ (not_In_introduce_classes _ _ _ H3 H2) H7 H5). bd H8; subst. assert (In (cld_def d x4 x3 x1) (introduce_classes x l0)). assert (~ In (cl_dcl d) (names l0)). generalize H3 H2 H6; clear; induction l0. simpl. unfold not; intros; bd H. discriminate. simpl; intros. unfold not; intros; bd H2; bd H3. destruct a; simpl in H. cs (d0 = d). subst. generalize H3; clear; induction (introduce_classes x0 l0). simpl; auto. simpl. destruct a; case (eq_nat_dec d d0). auto. simpl; intros; bd H3. congruence. auto. bd H. congruence. apply IHl0; auto. apply (In_rm_dcl _ _ _ H3). unfold not; intros; apply H1; generalize H0 H4; clear. induction (introduce_classes nil l0). simpl; auto. destruct a; simpl. intros; bd H4. inversion H4; subst. case (eq_nat_dec d0 d). congruence. simpl; po1. case (eq_nat_dec d0 d1). auto. simpl; po2; auto. generalize H8 H9; clear; induction l0. simpl; auto. destruct a; simpl. intros H9 H10; bd H10. po2; generalize H10 (IHl0 H9 H0); clear; induction (introduce_classes x l0). simpl; auto. destruct a; simpl. intros; bd H. inversion H; subst; clear H. case (eq_nat_dec d0 d). congruence. simpl; po1. case (eq_nat_dec d0 d1). auto. simpl; po2; auto. intros. intros; generalize (IHl _ _ _ _ _ _ H H0 H9 H10 H12). apply (distinct_introduce_fields x3 l1). cs ( In (cld_def dcl' cl' fds' mds') (introduce_classes nil l0)). intros; apply (IHl _ _ _ _ _ _ H H0 (In_introduce_classes' x _ _ H2)); intros. apply (H6 _ _ _ _ H8). apply (H7 _ _ _ _ H8). intros H3. import (not_In_introduce_classes _ _ _ H3 H2). assert (distinct _ (names x)). generalize x H H4; clear; induction l. simpl; congruence. simpl in *|-*. destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l). caseEq (compose_refines_class p0 a). intros p1 H x H5 H4; import (IHl _ H5 (refl_equal _)). inversion H4; subst; apply (distinct_refines_class _ _ _ H0 H). intros; discriminate. intros; discriminate. import (in_compose_rcld_in_p _ _ _ _ _ _ _ _ _ _ _ e H6 H5). assert (In (cld_def dcl' cl' fds' mds') (introduce_classes x l0)). assert (~ In (cl_dcl dcl') (names l0)). generalize H3 H2 H6; clear; induction l0. simpl. unfold not; intros; bd H. discriminate. simpl; intros. unfold not; intros; bd H2; bd H3. destruct a; simpl in H. cs (d = dcl'). subst. generalize H3; clear; induction (introduce_classes x0 l0). simpl; auto. simpl. destruct a; case (eq_nat_dec dcl' d). auto. simpl; intros; bd H3. congruence. auto. bd H. congruence. apply IHl0; auto. apply (In_rm_dcl _ _ _ H3). unfold not; intros; apply H1; generalize H0 H4; clear. induction (introduce_classes nil l0). simpl; auto. destruct a; simpl. intros; bd H4. inversion H4; subst. case (eq_nat_dec d dcl'). congruence. simpl; po1. case (eq_nat_dec d d0). auto. simpl; po2; auto. generalize H8 H9; clear; induction l0. simpl; auto. destruct a; simpl. intros H9 H10; bd H10. po2; generalize H10 (IHl0 H9 H0); clear; induction (introduce_classes x l0). simpl; auto. destruct a; simpl. intros; bd H. inversion H; subst; clear H. case (eq_nat_dec d dcl'). congruence. simpl; po1. case (eq_nat_dec d d0). auto. simpl; po2; auto. intros. exact (IHl _ _ _ _ _ _ H H0 H9 H10 H11). discriminate. Qed. Theorem compose_distinct_ms : forall (ps : PSel) (p : P) (dcl': dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose ps = Some p -> In (cld_def dcl' cl' fds' mds') p -> (forall (rclds' : list rcld) (clds' : list cld) (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (feature_def rclds' clds') ps -> In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds'')) -> distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds'). induction ps. simpl; intros; inversion H; subst. simpl in H0; contradiction. simpl; caseEq (compose ps); intros. assert (forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), In (cld_def dcl' cl' fds' mds') p -> distinct ms (map (fun md' : md => match md' with | md_def ms' _ => ms' end) mds')). intros; apply (IHps p dcl'0 cl'0 fds'0 mds'0 H H3). intros; apply (H2 rclds' clds' dcl'' cl'' fds'' mds''). po2. auto. clear IHps. destruct a. assert (forall (dcl'' : dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (cld_def dcl'' cl'' fds'' mds'' ) l0 -> distinct ms (map (fun md' : md => match md' with | md_def ms' _ => ms' end) mds'')). intros; apply (H2 l l0 dcl'' cl'' fds'' mds''); auto. generalize p p0 dcl' cl' fds' mds' (distinct_compose_names _ _ H) H0 H1 H4 H3; clear. induction l. simpl. intros p p0 dcl' cl' fds' mds'; intros. inversion H0; subst; clear H0. induction l0. simpl in H1. apply (H3 _ _ _ _ H1); auto. simpl in H1; bd H1. rewrite H1 in H4. simpl in H4; apply (H4 _ _ _ _ (or_introl _ (refl_equal _))). apply IHl0. intros. simpl in H4; apply (H4 _ _ _ _ (or_intror _ H0)). apply (In_rm_dcl _ _ _ H1). destruct a; intros p p0 dcl' cl' fds' mds' H H1. import (ex_composed_prog' _ _ _ _ _ H1); bd H0. case (eq_nat_dec dcl' d); intro e; subst. cs ( In (cld_def d cl' fds' mds') (introduce_classes nil l0)). intros; apply (IHl _ _ _ _ _ _ H H0 (In_introduce_classes' x _ _ H2)); intros. apply (H6 _ _ _ _ H8). simpl in H7; apply (H7 _ _ _ _ H8). intros H3. import (not_In_introduce_classes _ _ _ H3 H2). assert (distinct _ (names x)). generalize x H H4; clear; induction l. simpl; congruence. simpl in *|-*. destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l). caseEq (compose_refines_class p0 a). intros p1 H x H5 H4; import (IHl _ H5 (refl_equal _)). inversion H4; subst; apply (distinct_refines_class _ _ _ H0 H). intros; discriminate. intros; discriminate. import (in_compose_rcld_in_p' _ _ _ _ _ _ _ _ _ _ (not_In_introduce_classes _ _ _ H3 H2) H7 H5). bd H8; subst. assert (In (cld_def d x4 x3 x1) (introduce_classes x l0)). assert (~ In (cl_dcl d) (names l0)). generalize H3 H2 H6; clear; induction l0. simpl. unfold not; intros; bd H. discriminate. simpl; intros. unfold not; intros; bd H2; bd H3. destruct a; simpl in H. cs (d0 = d). subst. generalize H3; clear; induction (introduce_classes x0 l0). simpl; auto. simpl. destruct a; case (eq_nat_dec d d0). auto. simpl; intros; bd H3. congruence. auto. bd H. congruence. apply IHl0; auto. apply (In_rm_dcl _ _ _ H3). unfold not; intros; apply H1; generalize H0 H4; clear. induction (introduce_classes nil l0). simpl; auto. destruct a; simpl. intros; bd H4. inversion H4; subst. case (eq_nat_dec d0 d). congruence. simpl; po1. case (eq_nat_dec d0 d1). auto. simpl; po2; auto. generalize H8 H9; clear; induction l0. simpl; auto. destruct a; simpl. intros H9 H10; bd H10. po2; generalize H10 (IHl0 H9 H0); clear; induction (introduce_classes x l0). simpl; auto. destruct a; simpl. intros; bd H. inversion H; subst; clear H. case (eq_nat_dec d0 d). congruence. simpl; po1. case (eq_nat_dec d0 d1). auto. simpl; po2; auto. intros. apply distinct_introduce_mds. apply (distinct_compose_mds _ _ _ (IHl _ _ _ _ _ _ H H0 H9 H10 H12) H11). cs ( In (cld_def dcl' cl' fds' mds') (introduce_classes nil l0)). intros; apply (IHl _ _ _ _ _ _ H H0 (In_introduce_classes' x _ _ H2)); intros. apply (H6 _ _ _ _ H8). apply (H7 _ _ _ _ H8). intros H3. import (not_In_introduce_classes _ _ _ H3 H2). assert (distinct _ (names x)). generalize x H H4; clear; induction l. simpl; congruence. simpl in *|-*. destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l). caseEq (compose_refines_class p0 a). intros p1 H x H5 H4; import (IHl _ H5 (refl_equal _)). inversion H4; subst; apply (distinct_refines_class _ _ _ H0 H). intros; discriminate. intros; discriminate. import (in_compose_rcld_in_p _ _ _ _ _ _ _ _ _ _ _ e H6 H5). assert (In (cld_def dcl' cl' fds' mds') (introduce_classes x l0)). assert (~ In (cl_dcl dcl') (names l0)). generalize H3 H2 H6; clear; induction l0. simpl. unfold not; intros; bd H. discriminate. simpl; intros. unfold not; intros; bd H2; bd H3. destruct a; simpl in H. cs (d = dcl'). subst. generalize H3; clear; induction (introduce_classes x0 l0). simpl; auto. simpl. destruct a; case (eq_nat_dec dcl' d). auto. simpl; intros; bd H3. congruence. auto. bd H. congruence. apply IHl0; auto. apply (In_rm_dcl _ _ _ H3). unfold not; intros; apply H1; generalize H0 H4; clear. induction (introduce_classes nil l0). simpl; auto. destruct a; simpl. intros; bd H4. inversion H4; subst. case (eq_nat_dec d dcl'). congruence. simpl; po1. case (eq_nat_dec d d0). auto. simpl; po2; auto. generalize H8 H9; clear; induction l0. simpl; auto. destruct a; simpl. intros H9 H10; bd H10. po2; generalize H10 (IHl0 H9 H0); clear; induction (introduce_classes x l0). simpl; auto. destruct a; simpl. intros; bd H. inversion H; subst; clear H. case (eq_nat_dec d dcl'). congruence. simpl; po1. case (eq_nat_dec d d0). auto. simpl; po2; auto. intros. exact (IHl _ _ _ _ _ _ H H0 H9 H10 H11). discriminate. Qed. Lemma sat_unique_constraint_unique: forall (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_unique_constraint (cld_gen_unique_constraint (cld_def dcl' cl' fds' mds' :: p)) = true -> ~ In (cl_dcl dcl') (names p) -> sat_unique_constraint (cld_gen_unique_constraint (cld_def dcl' cl' fds' mds' :: nil)) = true. simpl. induction fds'. simpl. induction mds'. simpl. auto. simpl. destruct a; destruct m; simpl; case (eq_nat_dec dcl' dcl'). intros. destruct (andb_prop _ _ H); clear H. apply andb_true_intro; pa; auto. clear H2. generalize H1; clear IHmds' H1; induction mds'. simpl; auto. destruct a; simpl. destruct m1; case (eq_nat_dec dcl' dcl'). case (eq_nat_dec m m1). destruct t0; destruct t. intros e2 e3; subst. case (eq_nat_dec m1 m1). caseEq (cl_eq c c0). caseEq (vd_list_eq l0 l); simpl. destruct (ms_repeated dcl' (ty_def c0) m1 l (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). intros; discriminate. destruct (ms_repeated dcl' (ty_def c0) m1 l (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)). destruct (ms_repeated dcl' (ty_def c) m1 l0 (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). intros; discriminate. intros; apply (IHmds' H2). caseEq (ms_repeated dcl' (ty_def c) m1 l0 (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). intros; discriminate. intros. rewrite H3 in IHmds'. rewrite (IHmds' (refl_equal _)). caseEq (ms_repeated dcl' (ty_def c) m1 l0 (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)); intros. elimtype False; generalize H H4; clear; induction mds'. simpl; intros; discriminate. destruct a; destruct m; simpl; case (eq_nat_dec dcl' dcl'). case (eq_nat_dec m1 m). destruct t. case (eq_nat_dec m m1). caseEq (cl_eq c0 c). caseEq (vd_list_eq l l0); simpl. auto. intros; discriminate. simpl; intros; discriminate. simpl; intros; discriminate. auto. congruence. auto. simpl; intros; discriminate. simpl; intros; discriminate. simpl; intros; discriminate. destruct (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). simpl; intros; discriminate. destruct (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)). caseEq (ms_repeated dcl' t0 m1 l0 (fold_right (fun (md' : md) (m3 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m3 end) nil mds' ++ cld_gen_unique_constraint p)). auto. intros; apply (IHmds' H1). caseEq (ms_repeated dcl' t0 m1 l0 (fold_right (fun (md' : md) (m3 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m3 end) nil mds' ++ cld_gen_unique_constraint p)). intros; discriminate. caseEq (ms_repeated dcl' t0 m1 l0 (fold_right (fun (md' : md) (m3 : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m3 end) nil mds' ++ nil)); intros. elimtype False; generalize H0 H1 H; clear; induction mds'. simpl; intros; discriminate. destruct a; destruct m; simpl; case (eq_nat_dec dcl' dcl'). case (eq_nat_dec m1 m). destruct t; destruct t0. case (eq_nat_dec m m1). caseEq (cl_eq c c0). caseEq (vd_list_eq l l0); simpl. auto. intros; discriminate. simpl; intros; discriminate. simpl; intros; discriminate. auto. congruence. auto. congruence. congruence. destruct a; simpl. intros; destruct (andb_prop _ _ H); apply andb_true_intro; pa; auto. generalize H1; clear H1; destruct t; simpl; case (eq_nat_dec dcl' dcl'). caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). intros; discriminate. caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)). intros. elimtype False; generalize H1 H3 H0; clear. induction fds'. simpl. induction mds'. simpl. intros; discriminate. destruct a; simpl; auto. simpl. destruct a; case (eq_nat_dec dcl' dcl'). destruct t; case (eq_nat_dec f f0). caseEq (cl_eq c c0); auto. intros; discriminate. auto. destruct t; auto. intros. generalize H0 H4; clear; induction fds'. simpl. induction mds'. simpl. auto. destruct a; simpl. auto. destruct a; destruct t; simpl; case (eq_nat_dec dcl' dcl'). caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). intros; discriminate. caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)). intros. elimtype False; generalize H1 H H0; clear. induction fds'. simpl. induction mds'. simpl. intros; discriminate. destruct a; simpl; auto. simpl. destruct a; case (eq_nat_dec dcl' dcl'). destruct t; case (eq_nat_dec f f0). caseEq (cl_eq c c0); auto. intros; discriminate. auto. destruct t; auto. intros. generalize H0 H4; clear; induction fds'. simpl. induction mds'. simpl. auto. destruct a; simpl. auto. destruct a; destruct t; simpl; case (eq_nat_dec dcl' dcl'). caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)). case (eq_nat_dec f f0). case (cl_eq c c0); intros; discriminate. intros; discriminate. case (eq_nat_dec f f0). caseEq (cl_eq c c0); intros; try discriminate. subst; rewrite ((proj1 (eq_cl_eq _ _)) H) in *|-*. rewrite H0 in H4. rewrite (IHfds' H0 H4). caseEq (f_repeated dcl' c0 f0 (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)); intros. elimtype False; generalize H2 H0; clear. induction fds'. simpl. induction mds'. simpl. intros; discriminate. destruct a; simpl; auto. simpl. destruct a; case (eq_nat_dec dcl' dcl'). destruct t; case (eq_nat_dec f0 f). caseEq (cl_eq c0 c); auto. intros; discriminate. auto. destruct t; auto. auto. intros. caseEq (f_repeated dcl' c0 f0 (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_unique_constraint p)); intros; rewrite H1 in H4. discriminate. rewrite (IHfds' H H4). caseEq (f_repeated dcl' c0 f0 (fold_right (fun (fd' : fd) (m : list unique_constraint) => unique_fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list unique_constraint) => match md' with | md_def ms' _ => unique_methods_constraint dcl' ms' :: m end) nil mds' ++ nil)); intros. elimtype False; generalize H1 H2; clear. induction fds'. simpl. induction mds'. simpl. intros; discriminate. destruct a; simpl; auto. simpl. destruct a; case (eq_nat_dec dcl' dcl'). destruct t; case (eq_nat_dec f0 f). caseEq (cl_eq c0 c); auto. intros; discriminate. auto. destruct t; auto. auto. congruence. congruence. congruence. Qed. Lemma sat_unique_constraint_unique': forall (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_unique_constraint (cld_gen_unique_constraint (cld_def dcl' cl' fds' mds' :: p)) = true -> ~ In (cl_dcl dcl') (names p) -> sat_unique_constraint (cld_gen_unique_constraint p) = true. simpl. induction fds'. simpl. induction mds'. simpl. auto. simpl. destruct a; destruct m; simpl; case (eq_nat_dec dcl' dcl'). intros. destruct (andb_prop _ _ H); clear H. auto. congruence. intros. apply (IHfds' mds'); auto. simpl in H. destruct (andb_prop _ _ H). exact H2. Qed. Theorem sat_constr_distinct : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose ps = Some p -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> In (cld_def dcl' cl' fds' mds') p -> (forall (rclds' : list rcld) (clds' : list cld) (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (feature_def rclds' clds') ps -> In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds'')) -> (forall (rclds' : list rcld) (clds' : list cld) (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (feature_def rclds' clds') ps -> In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ fds'') -> distinct _ (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') /\ distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds'). intros. assert (forall (d : unique_constraint), In d (cld_gen_unique_constraint p) -> In d (ps_gen_unique_constraint ps)). intros; apply (gen_unique_constraint ps p d H H4). import (sat_subset_constr _ _ H4 H0). import (distinct_compose_names _ _ H); import (compose_distinct_fields _ _ _ _ _ _ H H1 H3); import (compose_distinct_ms _ _ _ _ _ _ H H1 H2); clear H0 H H4 H2 H3. induction p. simpl in H1; contradiction. cs (names (a :: nil) = cl_dcl dcl' :: cl_object :: nil). simpl in H1; bd H1. rewrite H1 in *; simpl in H. simpl in H6; bd H6. import (sat_unique_constraint_unique _ _ _ _ _ H5 H3). generalize H0 H7 H8; clear; induction fds'. induction mds'. simpl; pa. intros. pa. destruct a. import (sat_unique_constraint_all (cld_gen_unique_constraint (cld_def dcl' cl' nil (md_def m m0 :: mds') :: nil)) m (fd_def (ty_def cl_object) 0) dcl'). destruct (H (or_intror _ (or_introl _ (refl_equal _))) H0). apply (sat_unique_constraint_ms _ _ _ _ H2 H8). intros. destruct a. import (sat_unique_constraint_all (cld_gen_unique_constraint (cld_def dcl' cl' (fd_def t f :: fds') mds' :: nil)) (ms_def (ty_def cl_object) 0 nil) (fd_def t f) dcl'). destruct (H (or_introl _ (or_introl _ (refl_equal _))) H0). pa. apply (sat_fd_unique_constraint _ _ _ _ H1 H7). apply (sat_unique_constraint_ms _ _ _ _ H2 H8). destruct a; simpl in H6; simpl in H; inversion H; subst. bd H6; elimtype False; apply H3; apply (In_names _ _ _ _ _ H1). destruct a; simpl in H1; bd H1. inversion H1; subst. simpl in H; congruence. simpl in H6; bd H6. apply IHp; auto. apply (sat_unique_constraint_unique' _ _ _ _ _ H5 H3). Qed. Fixpoint clds_distinct_fds_mds (clds : list cld) : bool := match clds with (cld_def _ _ fds' mds' ) :: clds' => distinct_list (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') && distinct_list (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds') && clds_distinct_fds_mds clds' | nil => true end. Fixpoint PS_distinct_fds_mds (ps : PSel) : bool := match ps with feature_def _ clds :: ps' => clds_distinct_fds_mds clds && PS_distinct_fds_mds ps' | nil => true end. Lemma clds_distinct_distinct : forall (clds' : list cld) (dcl': dcl) (cl' : cl) (fds' : list fd) (mds' : list md), In (cld_def dcl' cl' fds' mds') clds' -> clds_distinct_fds_mds clds' = true -> distinct _ fds' /\ distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds'). induction clds'. simpl; intros; contradiction. destruct a. simpl; intros. bd H. inversion H; subst. destruct (andb_prop _ _ H0); destruct (andb_prop _ _ H1); clear H0 H1. pa. generalize ((proj1 (distinct_distinct_list _)) H3); clear; induction fds'. simpl; auto. simpl; intros H; bd H; pa; auto. unfold not; intros; apply H2; generalize H0; clear; induction fds'. simpl; auto. simpl; intros; bd H0; subst. po1. po2; auto. generalize ((proj1 (distinct_distinct_list _)) H4); clear; induction mds'. simpl; auto. simpl; intros H; bd H; pa; auto. unfold not; intros; apply H2; generalize H0; clear; induction mds'. simpl; auto. simpl; intros; bd H0. destruct a0; destruct a; simpl in *|-*. subst. po1. po2; auto. destruct (andb_prop _ _ H0); clear H0 H1. apply (IHclds' _ _ _ _ H H2). Qed. Lemma PS_distinct_distinct : forall (ps : PSel) (rclds' : list rcld) (clds' : list cld), PS_distinct_fds_mds ps = true -> In (feature_def rclds' clds') ps -> (forall (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds'') /\ distinct _ fds''). induction ps. simpl; intros; contradiction. simpl; intros; bd H0; subst. destruct (andb_prop _ _ H). destruct (clds_distinct_distinct _ _ _ _ _ H1 H0). pa. destruct a; destruct (andb_prop _ _ H). apply (IHps _ _ H3 H0 _ _ _ _ H1). Qed. Corollary PS_distinct_distinct' : forall (ps : PSel), PS_distinct_fds_mds ps = true -> (forall (rclds' : list rcld) (clds' : list cld) (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (feature_def rclds' clds') ps -> In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ (map (fun (md' : md) => match md' with md_def ms' _ => ms' end) mds'')) /\ (forall (rclds' : list rcld) (clds' : list cld) (dcl'': dcl) (cl'' : cl) (fds'' : list fd) (mds'' : list md), In (feature_def rclds' clds') ps -> In (cld_def dcl'' cl'' fds'' mds'') clds' -> distinct _ fds''). intros; pa; intros; destruct (PS_distinct_distinct _ _ _ H H0 _ _ _ _ H1 ); auto. Qed. Corollary sat_constr_distinct' : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose ps = Some p -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> PS_distinct_fds_mds ps = true -> In (cld_def dcl' cl' fds' mds') p -> distinct _ (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') /\ distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds'). intros; apply (sat_constr_distinct ps p dcl' cl' fds' mds'); auto. intros. destruct (PS_distinct_distinct ps _ _ H1 H3 _ _ _ _ H4). auto. intros; destruct (PS_distinct_distinct ps _ _ H1 H3 _ _ _ _ H4). auto. Qed. Lemma f_repeated_app_comm : forall (dcl' : dcl) (cl' : cl) (f' : f) (uc_list uc_list' : list unique_constraint), f_repeated dcl' cl' f' (uc_list ++ uc_list') = f_repeated dcl' cl' f' (uc_list' ++ uc_list). induction uc_list. simpl; intros; rewrite <- app_nil_end; reflexivity. destruct a; simpl. destruct f; destruct t. case (eq_nat_dec dcl' d). case (eq_nat_dec f' f). caseEq (cl_eq cl' c); intros; subst. rewrite ((proj1 (eq_cl_eq _ _)) H) in *|-*; clear H. rewrite IHuc_list; clear IHuc_list; induction uc_list'. simpl; case (eq_nat_dec d d); case (eq_nat_dec f f); try congruence. rewrite ((proj2 (eq_cl_eq _ _)) (refl_equal _)); intros; subst; auto. destruct a; simpl. destruct f0; destruct t; case (eq_nat_dec d d0); case (eq_nat_dec f f0); caseEq (cl_eq c c0); intros; subst; auto. auto. generalize H; clear; induction uc_list'. simpl; case (eq_nat_dec d d); case (eq_nat_dec f f); try congruence. intros; rewrite H; auto. destruct a; simpl. destruct f0; destruct t; case (eq_nat_dec d d0); case (eq_nat_dec f f0); caseEq (cl_eq cl' c0); intros; subst; auto. auto. intros; subst. rewrite IHuc_list; clear IHuc_list; induction uc_list'. simpl; case (eq_nat_dec d d); case (eq_nat_dec f' f); try congruence. destruct a; simpl. destruct f0; destruct t; case (eq_nat_dec d d0); case (eq_nat_dec f' f0); caseEq (cl_eq cl' c0); intros; subst; auto. auto. intros; simpl; rewrite IHuc_list; generalize n; clear; induction uc_list'. simpl; case (eq_nat_dec dcl' d); try congruence. destruct a; simpl. destruct f0; destruct t; case (eq_nat_dec dcl' d0); case (eq_nat_dec f' f0); caseEq (cl_eq cl' c0); intros; subst; auto. auto. intros; rewrite IHuc_list; clear IHuc_list; induction uc_list'; simpl; auto. destruct a. destruct f; destruct t. case (eq_nat_dec dcl' d0); auto; case (eq_nat_dec f' f); auto; caseEq (cl_eq cl' c); auto; intros; subst. auto. Qed. Lemma ms_repeated_app_comm : forall (dcl' : dcl) (ty' : ty) (m' : m) (vd_list : list vd) (uc_list uc_list': list unique_constraint), ms_repeated dcl' ty' m' vd_list (uc_list ++ uc_list') = ms_repeated dcl' ty' m' vd_list (uc_list' ++ uc_list). induction uc_list. simpl; intros; rewrite <- app_nil_end; reflexivity. destruct a; simpl. intro; rewrite IHuc_list. clear; induction uc_list'. simpl; reflexivity. destruct a; simpl; auto. rewrite IHuc_list'; auto. destruct m; case (eq_nat_dec dcl' d). case (eq_nat_dec m' m). destruct t; destruct ty'. case (eq_nat_dec m m'). caseEq (cl_eq c c0). caseEq (vd_list_eq l vd_list); simpl; intros. clear e; subst. rewrite IHuc_list; rewrite ((proj1 (eq_cl_eq _ _)) H0); rewrite ((proj1 (eq_vd_list_eq _ _)) H); clear. induction uc_list'. simpl. case (eq_nat_dec d d). case (eq_nat_dec m m). rewrite ((proj2 (eq_cl_eq _ _)) (refl_equal _)). rewrite ((proj2 (eq_vd_list_eq _ _)) (refl_equal _)). simpl; auto. congruence. congruence. destruct a; simpl; rewrite <- IHuc_list'; auto. clear e; subst; generalize H; clear; induction uc_list'. simpl. case (eq_nat_dec d d). case (eq_nat_dec m m). destruct (cl_eq c c0); intros; rewrite H; simpl; auto. congruence. congruence. intros; destruct a; simpl; rewrite <- IHuc_list'; auto. destruct m0; case (eq_nat_dec d d0); case (eq_nat_dec m m0). destruct t. case (eq_nat_dec m0 m). destruct (cl_eq c1 c0 && vd_list_eq l0 vd_list); auto. congruence. auto. auto. auto. simpl. intros; clear e; subst; generalize H; clear; induction uc_list'. simpl. case (eq_nat_dec d d). case (eq_nat_dec m m). intros; rewrite H; simpl; auto. congruence. congruence. intros; destruct a; simpl; rewrite <- IHuc_list'; auto. destruct m0; case (eq_nat_dec d d0); case (eq_nat_dec m m0). destruct t. case (eq_nat_dec m0 m). destruct (cl_eq c1 c0 && vd_list_eq l0 vd_list); auto. congruence. auto. auto. auto. simpl. intros; congruence. intros; rewrite IHuc_list. intros; subst; generalize n; clear; induction uc_list'. simpl. case (eq_nat_dec d d). case (eq_nat_dec m' m). congruence. auto. auto. intros; destruct a; simpl; rewrite <- IHuc_list'; auto. intros; rewrite IHuc_list; clear IHuc_list; induction uc_list'. simpl; case (eq_nat_dec dcl' d). congruence. auto. destruct a; simpl; rewrite <- IHuc_list'. auto. destruct m0; case (eq_nat_dec dcl' d0); case (eq_nat_dec m' m0). destruct t0; destruct ty'. case (eq_nat_dec m0 m'). destruct (cl_eq c c0 && vd_list_eq l0 vd_list); auto. auto. auto. auto. auto. Qed. Lemma sat_f_unique_app_comm : forall (dcl' : dcl) (uc_list uc_list': list unique_constraint), sat_f_unique_constraint dcl' (uc_list ++ uc_list') = sat_f_unique_constraint dcl' (uc_list' ++ uc_list). induction uc_list. simpl; intros; rewrite <- app_nil_end; reflexivity. destruct a; simpl. destruct f; destruct t; intros; subst. rewrite IHuc_list; rewrite f_repeated_app_comm. clear; induction uc_list'. simpl; auto. destruct a; simpl. destruct f0; destruct t. rewrite (f_repeated_app_comm dcl' c0 f0 _ ( _ :: uc_list)); simpl. revert IHuc_list'. case (eq_nat_dec dcl' d0); case (eq_nat_dec dcl' d). case (eq_nat_dec f f0); case (eq_nat_dec f0 f). caseEq (cl_eq c c0); intros. rewrite ((proj1 (eq_cl_eq _ _) ) H) in *|-*. rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)). clear e e1; subst. rewrite IHuc_list'. rewrite f_repeated_app_comm; reflexivity. caseEq (cl_eq c0 c); intros. rewrite ((proj1 (eq_cl_eq _ _) ) H0) in H; rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)) in H; discriminate. reflexivity. congruence. congruence. intros; clear e0; subst. rewrite (f_repeated_app_comm d c0 f0 uc_list); destruct (f_repeated d c f (uc_list' ++ uc_list)); destruct (f_repeated d c0 f0 (uc_list' ++ uc_list)); auto. rewrite (f_repeated_app_comm dcl' c0 f0 uc_list); destruct (f_repeated dcl' c0 f0 (uc_list' ++ uc_list)); auto. auto. auto. auto. intros; rewrite IHuc_list; clear; induction uc_list'. simpl; auto. destruct a; simpl. destruct f; destruct t. case (eq_nat_dec dcl' d0). rewrite (f_repeated_app_comm _ _ _ _ ( _ :: uc_list)); rewrite IHuc_list'; rewrite f_repeated_app_comm; simpl; auto. auto. auto. Qed. Lemma sat_ms_unique_app_comm : forall (dcl' : dcl) (uc_list uc_list': list unique_constraint), sat_ms_unique_constraint dcl' (uc_list ++ uc_list') = sat_ms_unique_constraint dcl' (uc_list' ++ uc_list). induction uc_list. simpl; intros; rewrite <- app_nil_end; reflexivity. destruct a; simpl. intro; rewrite IHuc_list; clear; induction uc_list'. simpl; auto. destruct a; simpl; rewrite <- IHuc_list'; auto. destruct m; case (eq_nat_dec dcl' d0). rewrite (ms_repeated_app_comm _ _ _ _ _ (_ :: _)); simpl; rewrite ms_repeated_app_comm; reflexivity. reflexivity. intro; rewrite IHuc_list; destruct m; case (eq_nat_dec dcl' d). rewrite ms_repeated_app_comm; intro; subst. clear. induction uc_list'. simpl; case (eq_nat_dec d d); auto. congruence. destruct a; simpl; rewrite <- IHuc_list'. auto. destruct m0. case (eq_nat_dec d d0). rewrite (ms_repeated_app_comm _ _ _ _ _ (_ :: _)); simpl. destruct (eq_nat_dec d d). auto. case (eq_nat_dec m m0); case (eq_nat_dec m0 m). destruct t; destruct t0; intros; clear e1; subst. caseEq (cl_eq c0 c); intros. caseEq (vd_list_eq l0 l); intros; simpl. rewrite ((proj1 (eq_cl_eq _ _) ) H) in *|-*; simpl. rewrite ((proj1 (eq_vd_list_eq _ _) ) H0) in *|-*; simpl. rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)); rewrite ((proj2 (eq_vd_list_eq _ _) ) (refl_equal _)); simpl. rewrite ms_repeated_app_comm; auto. rewrite ((proj1 (eq_cl_eq _ _) ) H) in *|-*; rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)); simpl. caseEq (vd_list_eq l l0); intros. rewrite ((proj1 (eq_vd_list_eq _ _) ) H1) in H0; rewrite ((proj2 (eq_vd_list_eq _ _) ) (refl_equal _)) in H0; discriminate. auto. caseEq (cl_eq c c0); intros. rewrite ((proj1 (eq_cl_eq _ _) ) H0) in H; rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)) in H; discriminate. reflexivity. congruence. congruence. intros; subst; rewrite ms_repeated_app_comm; auto. repeat rewrite ms_repeated_app_comm with (uc_list := uc_list). destruct (ms_repeated d0 t m l (uc_list' ++ uc_list)); destruct (ms_repeated d0 t0 m0 l0 (uc_list' ++ uc_list)); auto. congruence. reflexivity. clear; induction uc_list'. simpl; case (eq_nat_dec dcl' d); congruence. intros; destruct a; simpl; rewrite <- IHuc_list'; auto. destruct m0. case (eq_nat_dec dcl' d0). rewrite (ms_repeated_app_comm _ _ _ _ _ (_ :: _)); simpl. case (eq_nat_dec dcl' d). congruence. rewrite ms_repeated_app_comm; reflexivity. reflexivity. Qed. Lemma sat_unique_constr_comm : forall (uc_list uc_list' : list unique_constraint), sat_unique_constraint (uc_list ++ uc_list') = true -> sat_unique_constraint (uc_list' ++ uc_list) = true. induction uc_list. simpl; intros; rewrite <- app_nil_end; trivial. intros; destruct a; unfold app in H; fold (app uc_list uc_list') in H; unfold sat_unique_constraint in H; fold (sat_unique_constraint (uc_list ++ uc_list')) in H; destruct (andb_prop _ _ H); clear H. unfold sat_f_unique_constraint in H0; rewrite sat_f_unique_app_comm in H0. destruct f; destruct t. rewrite f_repeated_app_comm in H0. caseEq (f_repeated d c f (uc_list' ++ uc_list)); intros; rewrite H in H0; revert H0; case (eq_nat_dec d d); try congruence; intros. generalize H H0 (IHuc_list _ H1); clear; induction uc_list'. simpl; intros; auto. case (eq_nat_dec d d). rewrite H; intros; apply andb_true_intro; split; auto. congruence. destruct a; intros; unfold app at 1; fold (app uc_list'); rewrite <- IHuc_list'. unfold sat_unique_constraint; fold (sat_unique_constraint); destruct (sat_unique_constraint (uc_list' ++ unique_fields_constraint d (fd_def c f) :: uc_list)); try (rewrite andb_false_r); auto. rewrite andb_true_r. assert (unique_fields_constraint d0 f0 :: uc_list' ++ unique_fields_constraint d (fd_def c f) :: uc_list = (unique_fields_constraint d0 f0 :: uc_list') ++ unique_fields_constraint d (fd_def c f) :: uc_list) by reflexivity. rewrite H2; clear H2. rewrite sat_f_unique_app_comm. unfold app; fold (app uc_list). simpl; case (eq_nat_dec d0 d). caseEq (f_repeated d0 c f (uc_list ++ unique_fields_constraint d0 f0 :: uc_list')); intros. subst; elimtype False; rewrite (f_repeated_app_comm d) in H2; simpl; congruence. subst; rewrite sat_f_unique_app_comm; auto. intros; rewrite sat_f_unique_app_comm. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. simpl in H; destruct f0; destruct t. destruct (eq_nat_dec d d0); auto. destruct (eq_nat_dec f f0); auto. destruct (cl_eq c c0); auto. discriminate. unfold app in H0; fold (app uc_list') in H0; unfold sat_f_unique_constraint in H0; fold sat_f_unique_constraint in H0. simpl in H; destruct f0; destruct t. destruct (eq_nat_dec d d0); auto. destruct (eq_nat_dec f f0); auto. destruct (f_repeated d c0 f0 (uc_list' ++ uc_list)); auto. discriminate. destruct (f_repeated d c0 f0 (uc_list' ++ uc_list)); auto; discriminate. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. unfold sat_unique_constraint; fold (sat_unique_constraint); destruct (sat_unique_constraint (uc_list' ++ unique_fields_constraint d (fd_def c f) :: uc_list)); try (rewrite andb_false_r); auto. rewrite andb_true_r. assert (unique_methods_constraint d0 m :: uc_list' ++ unique_fields_constraint d (fd_def c f) :: uc_list = (unique_methods_constraint d0 m :: uc_list') ++ unique_fields_constraint d (fd_def c f) :: uc_list) by reflexivity. rewrite H2; clear H2. rewrite sat_ms_unique_app_comm; simpl; rewrite sat_ms_unique_app_comm. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. simpl in H; auto. simpl in H0; auto. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. unfold sat_ms_unique_constraint in H0; rewrite sat_ms_unique_app_comm in H0. destruct m. rewrite ms_repeated_app_comm in H0. caseEq (ms_repeated d t m l (uc_list' ++ uc_list)); intros; rewrite H in H0; revert H0; case (eq_nat_dec d d); try congruence; intros. generalize H H0 (IHuc_list _ H1); clear; induction uc_list'. simpl; intros; auto. case (eq_nat_dec d d); try congruence. rewrite H; intros; apply andb_true_intro; split; auto. destruct a; intros; unfold app at 1; fold (app uc_list'); rewrite <- IHuc_list'. unfold sat_unique_constraint; fold (sat_unique_constraint); destruct (sat_unique_constraint (uc_list' ++ unique_methods_constraint d (ms_def t m l) :: uc_list)); try (rewrite andb_false_r); auto; rewrite andb_true_r. assert (unique_fields_constraint d0 f :: uc_list' ++ unique_methods_constraint d (ms_def t m l) :: uc_list = (unique_fields_constraint d0 f :: uc_list') ++ unique_methods_constraint d (ms_def t m l) :: uc_list) by reflexivity. rewrite H2; clear H2. rewrite sat_f_unique_app_comm; simpl; rewrite sat_f_unique_app_comm. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. simpl in H; auto. simpl in H0; auto. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. unfold sat_unique_constraint; fold (sat_unique_constraint); destruct (sat_unique_constraint (uc_list' ++ unique_methods_constraint d (ms_def t m l) :: uc_list)); try (rewrite andb_false_r); auto. rewrite andb_true_r. assert (unique_methods_constraint d0 m0 :: uc_list' ++ unique_methods_constraint d (ms_def t m l) :: uc_list = (unique_methods_constraint d0 m0 :: uc_list') ++ unique_methods_constraint d (ms_def t m l) :: uc_list) by reflexivity. rewrite H2; clear H2. rewrite sat_ms_unique_app_comm. unfold app; fold (app uc_list). simpl; case (eq_nat_dec d0 d). caseEq (ms_repeated d0 t m l (uc_list ++ unique_methods_constraint d0 m0 :: uc_list')); intros. subst; elimtype False; rewrite (ms_repeated_app_comm d) in H2; simpl; congruence. subst; rewrite sat_ms_unique_app_comm; auto. intros; rewrite sat_ms_unique_app_comm. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. simpl in H; destruct m0. destruct (eq_nat_dec d d0); auto. destruct (eq_nat_dec m m0); auto. destruct t0; destruct t. destruct (eq_nat_dec m0 m). destruct (cl_eq c c0 && vd_list_eq l0 l); auto. discriminate. discriminate. unfold app in H0; fold (app uc_list') in H0; unfold sat_ms_unique_constraint in H0; fold sat_ms_unique_constraint in H0. simpl in H; destruct m0. destruct (eq_nat_dec d d0); auto. destruct ( ms_repeated d t0 m0 l0 (uc_list' ++ uc_list)); auto; discriminate. unfold app in H1; fold (app uc_list') in H1; unfold sat_unique_constraint in H1; fold sat_unique_constraint in H1. destruct (andb_prop _ _ H1); auto. Qed. Lemma sat_unique_constr_comm' : forall (uc_list uc_list' : list unique_constraint), sat_unique_constraint (uc_list ++ uc_list') = sat_unique_constraint (uc_list' ++ uc_list). intros; caseEq (sat_unique_constraint (uc_list ++ uc_list')); intros. apply sym_eq; apply sat_unique_constr_comm; auto. caseEq (sat_unique_constraint (uc_list' ++ uc_list)); intros. rewrite sat_unique_constr_comm in H. discriminate. auto. auto. Qed. Lemma f_repeated_double : forall (dcl' : dcl) (cl' : cl) (f : f) (uc_list uc_list' : list unique_constraint), f_repeated dcl' cl' f uc_list = true -> f_repeated dcl' cl' f (uc_list ++ uc_list') = true. clear; induction uc_list. simpl; intros; discriminate. destruct a; simpl; intros. destruct f0; destruct t. destruct (eq_nat_dec dcl' d). destruct (eq_nat_dec f f0). destruct (cl_eq cl' c). auto. auto. auto. auto. auto. Qed. Lemma f_repeated_app_split : forall (dcl' : dcl) (cl' : cl) (f : f) (uc_list uc_list' : list unique_constraint), f_repeated dcl' cl' f (uc_list ++ uc_list') = true -> f_repeated dcl' cl' f uc_list = true \/ f_repeated dcl' cl' f uc_list' = true. induction uc_list. simpl; auto. destruct a; simpl. destruct f0; destruct t. destruct (eq_nat_dec dcl' d). destruct (eq_nat_dec f f0). caseEq (cl_eq cl' c); intros. auto. auto. auto. auto. auto. Qed. Lemma f_repeated_app_split' : forall (dcl' : dcl) (cl' : cl) (f : f) (uc_list uc_list' : list unique_constraint), f_repeated dcl' cl' f (uc_list ++ uc_list') = false -> f_repeated dcl' cl' f uc_list = false /\ f_repeated dcl' cl' f uc_list' = false. induction uc_list. simpl; auto. destruct a; simpl. destruct f0; destruct t. destruct (eq_nat_dec dcl' d). destruct (eq_nat_dec f f0). caseEq (cl_eq cl' c); intros. auto. discriminate. auto. auto. auto. Qed. Lemma ms_repeated_app_split : forall (dcl' : dcl) (ty' : ty) (m : m) (vd_list : list vd) (uc_list uc_list' : list unique_constraint), ms_repeated dcl' ty' m vd_list (uc_list ++ uc_list') = true -> ms_repeated dcl' ty' m vd_list uc_list = true \/ ms_repeated dcl' ty' m vd_list uc_list' = true. induction uc_list. simpl; auto. destruct a; simpl. auto. destruct m0; destruct (eq_nat_dec dcl' d). destruct ty'; destruct t. destruct (eq_nat_dec m0 m). destruct (eq_nat_dec m m0). caseEq (cl_eq c0 c); intros. caseEq (vd_list_eq l vd_list); intros; rewrite H1 in H0; simpl in H0; simpl; auto. auto. congruence. destruct (eq_nat_dec m m0). congruence. auto. auto. Qed. Lemma ms_repeated_app_split' : forall (dcl' : dcl) (ty' : ty) (m : m) (vd_list : list vd) (uc_list uc_list' : list unique_constraint), ms_repeated dcl' ty' m vd_list (uc_list ++ uc_list') = false -> ms_repeated dcl' ty' m vd_list uc_list = false /\ ms_repeated dcl' ty' m vd_list uc_list' = false. induction uc_list. simpl; auto. destruct a; simpl; auto. destruct m0; destruct (eq_nat_dec dcl' d). destruct ty'; destruct t. destruct (eq_nat_dec m0 m). destruct (eq_nat_dec m m0). caseEq (cl_eq c0 c); intros. caseEq (vd_list_eq l vd_list); intros; rewrite H1 in H0; simpl in H0; simpl; auto. discriminate. simpl in H0; discriminate. congruence. destruct (eq_nat_dec m m0). intros; discriminate. auto. auto. Qed. Lemma sat_f_unique_double : forall (dcl' : dcl) (uc_list uc_list' : list unique_constraint), sat_f_unique_constraint dcl' uc_list = false -> sat_f_unique_constraint dcl' (uc_list ++ uc_list') = false. clear; induction uc_list. simpl; intros; discriminate. destruct a; simpl; intros. destruct f; destruct t. destruct (eq_nat_dec dcl' d). caseEq (f_repeated dcl' c f uc_list); intros. rewrite H0 in H. rewrite (f_repeated_double _ _ _ _ _ H0); auto. caseEq (f_repeated dcl' c f (uc_list ++ uc_list')); intros. auto. rewrite H0 in H; auto. auto. auto. Qed. Lemma sat_unique_constraint_double : forall (uc_list : list unique_constraint), sat_unique_constraint uc_list = true -> sat_unique_constraint (uc_list ++ uc_list) = true. intros; apply sat_subset_constr with (dc_list' := uc_list); auto. intros. destruct (in_app_or _ _ _ H0); auto. Qed. Lemma sat_PSpec_unique' : forall (fc_list : list feature_constraint) (ps : PSpec) (n n': nat) (cc_list cc_list' : list comp_constraint) (uc_list uc_list' : list unique_constraint) (tyc_list tyc_list' : list ty_constraint), In (feature_constr n cc_list uc_list tyc_list) fc_list-> sat_feature_unique_constr ps fc_list -> In (feature_constr n' cc_list' uc_list' tyc_list') fc_list-> In n ps -> In n' ps -> sat_unique_constraint (uc_list ++ uc_list') = true. induction fc_list; intros. simpl in H; contradiction. simpl in H, H1; destruct H; destruct H1; subst. inversion H1; subst. inversion H0; subst. apply sat_unique_constraint_double; auto. inversion H0; subst. eapply H9. apply H1. auto. inversion H0; subst. rewrite sat_unique_constr_comm'. eapply H9. apply H. auto. inversion H0; subst. eapply IHfc_list; auto. apply H. apply H9. apply H1. auto. auto. Qed. Inductive wf_PSel : PSel -> list feature_constraint -> Prop := Cons_wf_PSel : forall (fd : FD) (fc : feature_constraint) (n : nat) (ps : PSel) (fc_list : list feature_constraint), wf_feature n fd fc -> wf_PSel ps fc_list -> wf_PSel (fd :: ps) (fc :: fc_list) | Nil_wf_PSel : wf_PSel nil nil. Lemma wf_PSel_gen_unique : forall (ps : PSel) (fc_list : list feature_constraint), wf_PSel ps fc_list -> ps_gen_unique_constraint ps = fold_right (fun fc uc_list => match fc with feature_constr _ _ uc_list' _ => uc_list' ++ uc_list end) nil fc_list. induction ps; intros. inversion H; simpl; auto. inversion H; subst; clear H. destruct a; simpl. inversion H2; subst; simpl. rewrite <- (IHps _ H4). assert (rcld_gen_unique_constraint l = uc_list2). generalize n cc_list uc_list2 tyc_list2 H5; clear; induction l; intros; inversion H5; subst; simpl. reflexivity. inversion H1; subst; rewrite app_ass; rewrite (IHl _ _ _ _ H6); reflexivity. assert (cld_gen_unique_constraint l0 = uc_list1). generalize uc_list1 tyc_list1 H1; clear; induction l0; intros; inversion H1; subst; simpl. reflexivity. inversion H2; subst; rewrite app_ass; rewrite (IHl0 _ _ H5); reflexivity. rewrite H; rewrite H0; reflexivity. Qed. Lemma ex_wf_PSel : forall (ft : FT) (fc_list : list feature_constraint) (ps : PSpec) (ps' : PSel), wf_FT 0 ft fc_list -> build_PSel ft ps = Some ps' -> exists fc_list', wf_PSel ps' fc_list' /\ (forall (n : nat) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), In (feature_constr n cc_list uc_list tyc_list) fc_list' -> In (feature_constr n cc_list uc_list tyc_list) fc_list /\ In n ps). intros; assert (forall fd n, nth_error ft n = Some fd -> exists fc, In fc fc_list /\ wf_feature (n + 0) fd fc). intros; eapply wf_FT_wf_fd; eauto. clear H; generalize ps' fc_list H0 H1; clear; induction ps; intros. simpl in H0; inversion H0; subst. exists nil; split. constructor. simpl; intros; contradiction. simpl in H0; caseEq (nth_error ft a); intros; rewrite H in H0. caseEq (build_PSel ft ps); intros; rewrite H2 in H0; simpl in H0; inversion H0; subst; clear H0. destruct (IHps _ _ H2 H1) as [fc_list' [WF_ps' Sub_fcl']]. destruct (H1 _ _ H) as [fc [In_fc WF_fc]]. exists (fc :: fc_list'); split. eapply Cons_wf_PSel; eauto. intros; simpl in H0; destruct H0 as [Eq_fc | In_fc']. rewrite plus_0_r in WF_fc; inversion WF_fc; subst; simpl; auto. inversion WF_fc; subst; auto. simpl; split; destruct (Sub_fcl' _ _ _ _ In_fc'); auto. discriminate. Qed. Lemma In_WF_ft_gt : forall (ft : FT) (m n : nat) (fc_list : list feature_constraint) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), wf_FT m ft fc_list -> n < m -> ~ In (feature_constr n cc_list uc_list tyc_list) fc_list. induction ft; intros; inversion H; subst. simpl; tauto. simpl; unfold not; intros; destruct H1; subst. inversion H5; subst; omega. apply (IHft _ n _ cc_list uc_list tyc_list H7); auto. Qed. Lemma In_fc_list_WF_FT : forall (ft : FT) (m n : nat) (fc_list : list feature_constraint) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), wf_FT m ft fc_list -> In (feature_constr (m + n) cc_list uc_list tyc_list) fc_list -> exists fd, nth_error ft n = Some fd /\ wf_feature (m + n) fd (feature_constr (m + n) cc_list uc_list tyc_list). induction ft; intros. inversion H; subst; simpl in H0; contradiction. inversion H; subst; clear H. simpl in H0; destruct H0; subst. exists a. destruct n; simpl. rewrite plus_0_r in *|-*; auto. rewrite plus_comm in H5; simpl in H5; inversion H5. elimtype False; omega. destruct n. rewrite plus_0_r in H; elimtype False; eapply In_WF_ft_gt; eauto. simpl; rewrite plus_comm in *|-*; simpl in *|-*; rewrite plus_comm in *|-*. destruct (IHft _ n _ cc_list uc_list tyc_list H7) as [fd' [Nth_fd' wf_fd']]. simpl; auto. exists fd'; split; simpl; auto. Qed. Lemma wf_PSel_In : forall (ps' : PSel) (fc_list : list feature_constraint) (fc : feature_constraint), wf_PSel ps' fc_list -> In fc fc_list -> exists fd, exists n', In fd ps' /\ wf_feature n' fd fc. induction ps'; intros; inversion H; subst; simpl in H0; destruct H0; subst. exists a; exists n; simpl; auto. destruct (IHps' _ _ H5 H0) as [fd' [n' [In_fd' wf_fd']]]. exists fd'; exists n'; simpl; auto. Qed. Lemma In_PSel_In_FT : forall (ps : PSpec) (ps' : PSel) (ft : FT) (fd : FD), build_PSel ft ps = Some ps' -> In fd ps' -> In fd ft. induction ps; simpl; intros. inversion H; subst; simpl in H0; contradiction. caseEq (nth_error ft a); intros; rewrite H1 in H. caseEq (build_PSel ft ps); intros; rewrite H2 in H. inversion H; subst; clear H. simpl in H0; destruct H0; subst. generalize ft H1; clear; induction a. destruct ft; simpl; intros. discriminate. inversion H1; auto. destruct ft; simpl. intros; discriminate. intros; right; eauto. eauto. simpl in H; discriminate. discriminate. Qed. Lemma In_PSel_nth_FT : forall (ps : PSpec) (ps' : PSel) (ft : FT) (fd : FD), build_PSel ft ps = Some ps' -> In fd ps' -> exists n, In n ps /\ nth_error ft n = Some fd. induction ps; simpl; intros. inversion H; subst; simpl in H0; contradiction. caseEq (nth_error ft a); intros; rewrite H1 in H. caseEq (build_PSel ft ps); intros; rewrite H2 in H. inversion H; subst; clear H. simpl in H0; destruct H0; subst. exists a; auto. destruct (IHps _ _ _ H2 H) as [n'[In_n' Nth_n]]. exists n'; auto. simpl in H; discriminate. discriminate. Qed. Lemma sat_unique_cons_split : forall (uc : unique_constraint) (uc_list : list unique_constraint), sat_unique_constraint (uc :: uc_list) = true -> sat_unique_constraint uc_list = true. destruct uc; simpl. destruct f; destruct t; case (eq_nat_dec d d). intros; destruct (f_repeated d c f uc_list). simpl in H; discriminate. destruct (andb_prop _ _ H); auto. congruence. destruct m; case (eq_nat_dec d d); intros. destruct (ms_repeated d t m l uc_list). simpl in H; discriminate. destruct (andb_prop _ _ H); auto. congruence. Qed. Lemma sat_unique_app_split : forall (uc_list uc_list' : list unique_constraint), sat_unique_constraint (uc_list ++ uc_list') = true -> sat_unique_constraint uc_list = true /\ sat_unique_constraint uc_list' = true. split. apply sat_subset_constr with (dc_list' := (uc_list ++ uc_list')); auto. intros; apply in_or_app; auto. apply sat_subset_constr with (dc_list' := (uc_list ++ uc_list')); auto. intros; apply in_or_app; auto. Qed. Lemma sat_unique_cons_cons_drop : forall (uc uc' : unique_constraint) (uc_list : list unique_constraint), sat_unique_constraint (uc :: uc' :: uc_list) = true -> sat_unique_constraint (uc :: uc_list) = true. intros; assert (uc :: uc' :: uc_list = app (uc :: nil) (uc' :: uc_list)). simpl; reflexivity. rewrite H0 in H; clear H0. rewrite sat_unique_constr_comm' in H; unfold app in H; fold (app uc_list (uc :: nil)) in H. import (sat_unique_cons_split _ _ H); rewrite sat_unique_constr_comm' in H0. unfold app in H0; assumption. Qed. Lemma sat_unique_cons_cons_drop' : forall (uc uc' : unique_constraint) (uc_list : list unique_constraint), sat_unique_constraint (uc :: uc' :: uc_list) = true -> sat_unique_constraint (uc :: uc' :: nil) = true. intros; assert (uc :: uc' :: uc_list = app (uc :: uc' :: nil) uc_list). simpl; reflexivity. rewrite H0 in H; clear H0. destruct (sat_unique_app_split _ _ H); auto. Qed. Lemma sat_unique_app_cons_drop : forall (uc : unique_constraint) (uc_list uc_list' : list unique_constraint), sat_unique_constraint (uc :: uc_list ++ uc_list') = true -> sat_unique_constraint (uc :: uc_list') = true. intros; assert (uc :: uc_list ++ uc_list' = app (uc :: nil) (uc_list ++ uc_list')). simpl; reflexivity. rewrite H0 in H; clear H0. rewrite sat_unique_constr_comm' in H; rewrite app_ass in H. destruct (sat_unique_app_split _ _ H); rewrite sat_unique_constr_comm' in H1. simpl in H1; assumption. Qed. Lemma f_repeated_in : forall (uc_list : list unique_constraint) (dcl' : dcl) (cl' cl'' : cl) (f' : f), f_repeated dcl' cl' f' uc_list = false -> In (unique_fields_constraint dcl' (fd_def cl'' f')) uc_list -> cl' = cl''. induction uc_list. simpl; intros; contradiction. destruct a; simpl; intros. destruct H0. inversion H0; subst. destruct (eq_nat_dec dcl' dcl'). destruct (eq_nat_dec f' f'). caseEq (cl_eq cl' cl''); intros; rewrite H1 in H. apply (proj1 (eq_cl_eq _ _)); auto. discriminate. congruence. congruence. destruct f; destruct t. destruct (eq_nat_dec dcl' d). destruct (eq_nat_dec f' f). caseEq (cl_eq cl' c); intros; rewrite H1 in H. eapply IHuc_list; eauto. discriminate. eapply IHuc_list; eauto. eapply IHuc_list; eauto. destruct H0. inversion H0. eapply IHuc_list; eauto. Qed. Lemma In_uc_list_dec : forall (uc : unique_constraint) (uc_list : list unique_constraint), In uc uc_list \/ ~ In uc uc_list. induction uc_list. auto. destruct uc; destruct a; simpl. destruct (eq_nat_dec d0 d); subst. destruct f0; destruct f; destruct t; destruct t0. destruct (eq_nat_dec f0 f); subst. caseEq (cl_eq c c0); intros. rewrite ((proj1 (eq_cl_eq _ _) ) H) in *|-*. auto. destruct IHuc_list. left; right; auto. right. unfold not; intros; destruct H1. inversion H1; subst; rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)) in H. discriminate. auto. destruct IHuc_list. left; right; auto. right; unfold not; intros; destruct H0; congruence. destruct IHuc_list. left; right; auto. right; unfold not; intros; destruct H0; congruence. destruct IHuc_list. left; right; auto. right; unfold not; intros; destruct H0; congruence. destruct IHuc_list. left; right; auto. right; unfold not; intros; destruct H0; congruence. destruct IHuc_list. left; right; auto. destruct m0; destruct m; destruct t; destruct t0. destruct (eq_nat_dec d d0). destruct (eq_nat_dec m m0). caseEq (cl_eq c c0); intros. caseEq (vd_list_eq l l0); intros. rewrite ((proj1 (eq_cl_eq _ _) ) H0) in *|-*; rewrite ((proj1 (eq_vd_list_eq _ _) ) H1) in *|-*. subst; auto. right. unfold not; intros; destruct H2; auto. subst; inversion H2; subst. rewrite ((proj2 (eq_vd_list_eq _ _) ) (refl_equal _)) in H1; discriminate. subst. right. unfold not; intros; destruct H1; auto. subst; inversion H1; subst. rewrite ((proj2 (eq_cl_eq _ _) ) (refl_equal _)) in H0; discriminate. subst. right; unfold not; intros; destruct H0; congruence. right; unfold not; intros; destruct H0; congruence. Qed. Lemma sat_unique_iff : forall (uc_list uc_list' : list unique_constraint), (sat_unique_constraint uc_list' = true) -> (sat_unique_constraint uc_list = true) -> (sat_unique_constraint (uc_list ++ uc_list') = true <-> (forall (uc : unique_constraint), In uc uc_list -> sat_unique_constraint (uc :: uc_list') = true)). split. intros; apply sat_subset_constr with (dc_list' := (uc_list ++ uc_list')); auto. intros; simpl in H3; destruct H3; subst; apply in_or_app; auto. revert uc_list' H H0; induction uc_list. intros; simpl; auto. intros. unfold app; fold (app uc_list); destruct a; simpl. destruct f; destruct t; case (eq_nat_dec d d). caseEq (f_repeated d c f (uc_list ++ uc_list')); intros. simpl; destruct (f_repeated_app_split _ _ _ _ _ H2). simpl in H0; rewrite H3 in H0; destruct (eq_nat_dec d d). simpl in H0; discriminate. congruence. simpl in H1; import (H1 _ (or_introl _ (refl_equal _))); simpl in H4. destruct (eq_nat_dec d d). rewrite H3 in H4; simpl in H4; discriminate. congruence. rewrite IHuc_list; auto. rewrite andb_true_r. simpl in H0; destruct (eq_nat_dec d d). intros; destruct (f_repeated_app_split' _ _ _ _ _ H2); rewrite H3 in H0; destruct (andb_prop _ _ H0). assert (sat_unique_constraint (uc_list ++ uc_list') = true) by (apply IHuc_list; auto; intros; apply H1; simpl; auto). generalize H7; clear; induction (uc_list ++ uc_list'). simpl; auto. destruct a; simpl. destruct f; destruct t. case (eq_nat_dec d0 d0); case (eq_nat_dec d d0); intros; try congruence; subst. destruct (f_repeated d0 c f l); auto. destruct (andb_prop _ _ H7); auto. destruct (f_repeated d0 c f l); simpl in H7. discriminate. destruct (andb_prop _ _ H7); auto. destruct m. case (eq_nat_dec d0 d0); intros. destruct (andb_prop _ _ H7); auto. congruence. congruence. simpl in H0; destruct (eq_nat_dec d d). destruct (andb_prop _ _ H0); auto. congruence. intros; apply H1; simpl; auto. congruence. destruct m; case (eq_nat_dec d d). caseEq (ms_repeated d t m l (uc_list ++ uc_list')); intros. simpl; destruct (ms_repeated_app_split _ _ _ _ _ _ H2). simpl in H0; rewrite H3 in H0; destruct (eq_nat_dec d d). simpl in H0; discriminate. congruence. simpl in H1; import (H1 _ (or_introl _ (refl_equal _))); simpl in H4. destruct (eq_nat_dec d d). rewrite H3 in H4; simpl in H4; discriminate. congruence. rewrite IHuc_list; auto. rewrite andb_true_r. simpl in H0; destruct (eq_nat_dec d d). intros; destruct (ms_repeated_app_split' _ _ _ _ _ _ H2); rewrite H3 in H0; destruct (andb_prop _ _ H0). assert (sat_unique_constraint (uc_list ++ uc_list') = true) by (apply IHuc_list; auto; intros; apply H1; simpl; auto). generalize H7; clear; induction (uc_list ++ uc_list'). simpl; auto. destruct a; simpl. destruct f; destruct t. case (eq_nat_dec d0 d0); case (eq_nat_dec d d0); intros; try congruence; subst. destruct (f_repeated d0 c f l); auto. destruct (andb_prop _ _ H7); auto. destruct (andb_prop _ _ H7); auto. destruct (f_repeated d0 c f l); simpl in H7. discriminate. destruct (andb_prop _ _ H7); auto. destruct m. case (eq_nat_dec d0 d0); intros. destruct (andb_prop _ _ H7); auto. destruct (eq_nat_dec d d0); subst. destruct (ms_repeated d0 t m l0 l). discriminate. auto. auto. congruence. congruence. simpl in H0; destruct (eq_nat_dec d d). destruct (andb_prop _ _ H0); auto. congruence. intros; apply H1; simpl; auto. congruence. Qed. Lemma sat_unique_app : forall (uc_list1 uc_list2 uc_list3 : list unique_constraint), sat_unique_constraint (uc_list1 ++ uc_list2) = true -> sat_unique_constraint (uc_list1 ++ uc_list3) = true -> sat_unique_constraint (uc_list2 ++ uc_list3) = true -> sat_unique_constraint (uc_list1 ++ uc_list2 ++ uc_list3) = true. intros; applyI sat_unique_iff. destruct (sat_unique_app_split _ _ H); auto. intros. assert (uc :: uc_list2 ++ uc_list3 = (uc :: uc_list2) ++ uc_list3) by reflexivity. rewrite H3; clear H3. intros; applyI sat_unique_iff. destruct (sat_unique_app_split _ _ H0); auto. apply sat_subset_constr with (dc_list' := (uc_list1 ++ uc_list2)); auto. intros. simpl in H3; destruct H3; subst; apply in_or_app; auto. intros. simpl in H3; destruct H3; subst. apply sat_subset_constr with (dc_list' := (uc_list1 ++ uc_list3)); auto. intros. simpl in H3; destruct H3; subst; apply in_or_app; auto. apply sat_subset_constr with (dc_list' := (uc_list2 ++ uc_list3)); auto. intros. simpl in H4; destruct H4; subst; apply in_or_app; auto. Qed. Lemma sat_wf_PSel : forall (ps : PSpec) (ps' : PSel) (ft : FT) (fc_list : list feature_constraint), wf_FT 0 ft fc_list -> sat_feature_unique_constr ps fc_list -> build_PSel ft ps = Some ps' -> exists fc_list', wf_PSel ps' fc_list' /\ sat_unique_constraint (fold_right(fun fc uc_list => match fc with feature_constr _ _ uc_list' _ => uc_list' ++ uc_list end) nil fc_list') = true. intros; assert (forall fd n, nth_error ft n = Some fd -> exists fc, In fc fc_list /\ wf_feature (n + 0) fd fc). intros; eapply wf_FT_wf_fd; eauto. intros; destruct (ex_wf_PSel _ _ _ _ H H1) as [fc_list' [WF_ps' Sub_fcl]]. exists fc_list'; split; auto. assert (forall (n n': nat) (cc_list cc_list' : list comp_constraint) (uc_list uc_list' : list unique_constraint) (tyc_list tyc_list' : list ty_constraint), In (feature_constr n cc_list uc_list tyc_list) fc_list' -> In (feature_constr n' cc_list' uc_list' tyc_list') fc_list'-> sat_unique_constraint (uc_list ++ uc_list') = true). intros; eapply sat_PSpec_unique'. apply (proj1 (Sub_fcl _ _ _ _ H3)). apply H0. apply (proj1 (Sub_fcl _ _ _ _ H4)). apply (proj2 (Sub_fcl _ _ _ _ H3)). apply (proj2 (Sub_fcl _ _ _ _ H4)). generalize H3; clear; induction fc_list'. simpl; auto. simpl; intros. destruct a. assert (sat_unique_constraint (fold_right (fun (fc : feature_constraint) (uc_list : list unique_constraint) => match fc with | feature_constr _ _ uc_list' _ => uc_list' ++ uc_list end) nil fc_list') = true). apply IHfc_list'; intros. eapply H3; eauto. clear IHfc_list'. assert (forall (n' : nat) (cc_list' : list comp_constraint) (uc_list' : list unique_constraint) (tyc_list' : list ty_constraint), In (feature_constr n' cc_list' uc_list' tyc_list') fc_list' -> sat_unique_constraint (l0 ++ uc_list') = true). intros; eapply H3. left; reflexivity. right; apply H0. destruct (sat_unique_app_split _ _ (H3 _ _ _ _ _ _ _ _ (or_introl _ (refl_equal _)) (or_introl _ (refl_equal _)))). generalize fc_list' l0 H H0 H1; clear. induction fc_list'. simpl; intros; rewrite <- app_nil_end; auto. destruct a; simpl; intros. import (H0 _ _ _ _ (or_introl _ (refl_equal _))). destruct (sat_unique_app_split _ _ H). assert (sat_unique_constraint (l2 ++ fold_right (fun (fc : feature_constraint) (uc_list : list unique_constraint) => match fc with | feature_constr _ _ uc_list' _ => uc_list' ++ uc_list end) nil fc_list') = true). apply IHfc_list'; intros; auto. apply (H0 _ _ _ _ (or_intror _ H5)). apply sat_unique_app; auto. Qed. Lemma ps_gen_subset : forall (ft : FT) (ps : PSpec) (ps' : PSel) (fc_list : list feature_constraint) (uc : unique_constraint), wf_FT 0 ft fc_list -> build_PSel ft ps = Some ps' -> In uc (ps_gen_unique_constraint ps') -> exists n, exists cc_list, exists uc_list, exists tyc_list, In uc uc_list /\ In n ps /\ In (feature_constr n cc_list uc_list tyc_list) fc_list. intros; assert (forall fd n, nth_error ft n = Some fd -> exists fc, In fc fc_list /\ wf_feature (n + 0) fd fc). intros; eapply wf_FT_wf_fd; eauto. generalize ps' fc_list uc H0 H1 H2; clear; induction ps; intros. simpl in H0; inversion H0; subst; simpl in H1; contradiction. simpl in H0; caseEq (nth_error ft a); intros; rewrite H in H0. caseEq (build_PSel ft ps); intros; rewrite H3 in H0; simpl in H0. inversion H0; subst; clear H0. simpl in H1; destruct (in_app_or _ _ _ H1); clear H1. destruct (H2 _ _ H) as [fc [In_fc WF_fc]]; rewrite plus_0_r in WF_fc. destruct fc; exists n; exists l; exists l0; exists l1; repeat split; auto. revert H0 WF_fc; clear; intros. inversion WF_fc; subst. simpl in H0. apply in_or_app; destruct (in_app_or _ _ _ H0). left; generalize l uc_list2 tyc_list2 H6 H; clear; induction rclds; intros. simpl in H; contradiction. destruct a; simpl in H; destruct (in_app_or _ _ _ H); clear H. inversion H6; subst. inversion H2; subst; repeat (apply in_or_app; left); auto. simpl in H0. destruct (in_app_or _ _ _ H0). inversion H6; subst; apply in_or_app; left. inversion H3; subst; apply in_or_app; right; auto. destruct (in_app_or _ _ _ H0). inversion H6; subst; apply in_or_app; right; eauto. inversion H6; subst. apply in_or_app; right; eauto. right; generalize uc_list1 tyc_list1 H3 H; clear; induction clds; intros. simpl in H; contradiction. destruct a; simpl in H; destruct (in_app_or _ _ _ H); clear H. inversion H3; subst. inversion H2; subst; repeat (apply in_or_app; left); auto. destruct (in_app_or _ _ _ H0). inversion H3; subst; apply in_or_app; left. inversion H4; subst; apply in_or_app; right; auto. destruct (in_app_or _ _ _ H0). inversion H3; subst; apply in_or_app; right; eauto. inversion H3; subst. apply in_or_app; right; eauto. inversion WF_fc; subst; simpl; auto. destruct (IHps _ _ _ H3 H0 H2) as [n' [cc_list' [uc_list' [tyc_list' [In_uc [In_n' In_fc]]]]]]. exists n'; exists cc_list'; exists uc_list'; exists tyc_list'; repeat split; auto. simpl; right; auto. discriminate. discriminate. Qed. End Uniqueness. Section Well_Formedness. Lemma get_refined_cl_object : forall (ps : PSel), get_refined_cld ps cl_object = None. induction ps; intros. simpl; reflexivity. simpl; destruct a. rewrite path_cl_object. rewrite IHps; reflexivity. Qed. Lemma f_path_nil : forall (n : nat) (ps : PSel), f_path ps cl_object n = nil. induction n; intros. simpl; reflexivity. simpl; rewrite get_refined_cl_object; reflexivity. Qed. Lemma build_refine_eq_compose_refine : forall (dcl' : dcl) (cl' cl'' : cl) (fds' fds'' : list fd) (mds' mds'' : list md) (rmds : list rmd) (p p' : P), distinct _ (names p) -> In (cld_def dcl' cl' fds' mds') p -> compose_refines_class p (refines_cld_def dcl' cl'' fds'' mds'' rmds) = Some p' -> In (build_refined_class (cld_def dcl' cl' fds' mds') (refines_cld_def dcl' cl'' fds'' mds'' rmds)) p'. induction p; simpl. tauto. destruct a; simpl; intros p' H H0; bd H; bd H0. inversion H0; subst; clear H0; case (eq_nat_dec dcl' dcl'). destruct (compose_refined_mds mds' rmds). intros _ H0; inversion H0; simpl; po1. intros; discriminate. congruence. case (eq_nat_dec d dcl'). intros; subst; elimtype False; apply H3. apply (In_names _ _ _ _ _ H0). intros n H1; destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1; inversion H1; clear H1. import (IHp _ H H0 H2); simpl; po2; auto. Qed. Lemma build_refine_eq_compose_refine' : forall (p p' : P) (dcl' dcl'' : dcl) (cl' cl'' : cl) (fds' fds'' : list fd) (mds' mds'' : list md) (rmds : list rmd), distinct _ (names p) -> In (cld_def dcl' cl' fds' mds') p -> dcl' <> dcl'' -> compose_refines_class p (refines_cld_def dcl'' cl'' fds'' mds'' rmds) = Some p' -> In (cld_def dcl' cl' fds' mds') p'. induction p; simpl. tauto. destruct a; simpl; intros p' dcl' dcl'' cl' cl'' fds' fds'' mds' mds'' rmds H H0; bd H; bd H0. inversion H0; subst; clear H0; case (eq_nat_dec dcl' dcl''). congruence. intros n _ H1; destruct (cons_option_Some _ _ _ _ H1); rewrite H0 in H1; simpl in H1; inversion H1; clear H1. simpl; po1. case (eq_nat_dec d dcl''). caseEq (compose_refined_mds l0 rmds); intros. inversion H4; subst; clear H4; po2. discriminate. intros n n0 H1; destruct (cons_option_Some _ _ _ _ H1); rewrite H2 in H1; simpl in H1; inversion H1; clear H1 H5. cs (dcl' = d); subst. simpl; po2. apply (IHp _ _ _ _ _ _ _ _ _ _ H H0 n H2). simpl; po2. apply (IHp _ _ _ _ _ _ _ _ _ _ H H0 n0 H2). Qed. Lemma get_cld_in_p : forall (dcl' : dcl) (p : P) (cld' : cld), get_cld p (cl_dcl dcl') = Some cld' -> In cld' p. unfold get_cld. intros dcl' p cld; caseEq (path p (cl_dcl dcl')). simpl; intros; discriminate. simpl; intros; inversion H0; subst; clear H0. induction p; simpl in H. discriminate. destruct a; generalize H; clear H; case (eq_nat_dec dcl' d). intros _ H; inversion H; subst; simpl; po1. intros; simpl; po2; auto. Qed. Lemma get_cld_not_in_p : forall (dcl' : dcl) (p : P), get_cld p (cl_dcl dcl') = None -> ~ In (cl_dcl dcl') (names p). unfold get_cld. induction p; simpl; auto. unfold not; intros H H0; destruct H0; congruence. destruct a; case (eq_nat_dec dcl' d). simpl; intros; discriminate. unfold not; intros. simpl in H0; bd H0. inversion H0; congruence. apply (IHp H H0). Qed. Lemma distinct_refines_class' : forall (rcld' : rcld) (cld_list cld_list': list cld), distinct _ (names cld_list') -> compose_refines_class cld_list rcld' = Some cld_list' -> distinct _ (names cld_list). induction cld_list. simpl; auto. destruct rcld'; destruct a; simpl; case (eq_nat_dec d0 d); intros. caseEq (compose_refined_mds l3 l1); intros; rewrite H1 in H0. inversion H0; subst. simpl in H; bd H; pa. discriminate. destruct (cons_option_Some _ _ _ _ H0); rewrite H1 in H0; simpl in H0; inversion H0. subst; simpl in H; bd H. pa. generalize x H4 H1; clear; induction cld_list. simpl; intros; discriminate. destruct a; simpl; case (eq_nat_dec d1 d). case (compose_refined_mds l3 l1); simpl; intros. inversion H1; subst; simpl in H4; bd H4. unfold not; intros; bd H. discriminate. intros n x H H0; destruct (cons_option_Some _ _ _ _ H0); rewrite H1 in H0; simpl in H0; inversion H0; subst; clear H0. simpl in H; bd H. unfold not; intros H3; bd H3. import (IHcld_list _ H2 H1); auto. apply (IHcld_list _ H H1). Qed. Lemma in_p_get_cld : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (p : P), In (cld_def dcl' cl' fds' mds') p -> distinct _ (names p) -> get_cld p (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds'). unfold get_cld. intros; generalize (In_prog_In_path _ _ _ _ _ H H0); caseEq (path p (cl_dcl dcl')). simpl; contradiction. simpl; intros; destruct H2. subst; simpl. reflexivity. destruct c; import (path_eq_self _ _ _ _ _ _ _ H1); subst. assert (forall c, distinct _ (names (path p c))). generalize H0; clear; induction p. simpl; auto. destruct a; simpl; intros H; bd H. intros; destruct c0. case (eq_nat_dec d0 d); simpl; auto. intros; pa; auto. unfold not; intros; apply H2. generalize c H0; clear; induction p; simpl; intro c. auto. destruct a; destruct c; simpl. case (eq_nat_dec d1 d0); simpl; intros H H0; bd H0. po1. po2; apply (IHp _ H0). po2; apply (IHp _ H0). intros H; bd H. discriminate. simpl; tauto. import (H3 (cl_dcl d)); rewrite H1 in H4; simpl in H4; bd H4. elimtype False; apply H7. apply (In_names _ _ _ _ _ H2). Qed. Lemma fold_nil : forall (rclds' : list rcld), fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some nil) rclds' = None \/ fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some nil) rclds' = Some nil. induction rclds'. simpl; po2. bd IHrclds'; simpl; rewrite IHrclds'. po1. simpl; po1. Qed. Lemma compose_nil : forall (rcld' : rcld) (rclds' : list rcld) (clds : list cld), compose_fd (feature_def (rcld' :: rclds') clds) nil = None. intros; simpl; rewrite <- (rev_involutive rclds'). rewrite (fold_left_rev_right). induction (rev rclds'). simpl; auto. simpl. clear; induction l. simpl; auto. simpl; exact IHl. Qed. Theorem get_cld_eq_get_refined_cld : forall (cl' : cl) (ps : PSel) (p : P), compose ps = Some p -> get_cld p cl' = get_refined_cld ps cl'. destruct cl'. induction ps. intros; unfold get_cld; simpl in *|-*; inversion H; simpl; auto. import (distinct_compose_names ps). destruct a; simpl; destruct (compose ps). import (H _ (refl_equal _)); clear H. intro; fold (compose_fd (feature_def l l0) p); import (IHps _ (refl_equal _)); clear IHps. caseEq (path l0 (cl_dcl d)). rewrite <- H; clear H; caseEq (get_cld p (cl_dcl d)); intros. simpl in H2. import (get_cld_in_p _ _ _ H). caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros; rewrite H4 in H2. assert (distinct _ (names p1)). generalize p1 H0 H4; clear; induction l. simpl; congruence. destruct a; simpl; caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. import (IHl _ H0 H). apply (distinct_refines_class _ _ _ H1 H4). discriminate. inversion H2. assert (get_cld (introduce_classes p1 l0) (cl_dcl d) = get_cld p1 (cl_dcl d)). generalize H1; clear; induction l0. simpl; auto. unfold get_cld; simpl; destruct a; simpl; case (eq_nat_dec d d0). intros; discriminate. intros n H; generalize (IHl0 H); clear H IHl0; unfold get_cld; induction (introduce_classes p1 l0); simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1); case (eq_nat_dec d d1); simpl; auto. congruence. case (eq_nat_dec d d1); simpl; auto. congruence. case (eq_nat_dec d d1); simpl; auto. congruence. rewrite H6; clear H6 H0 H7 H1 H2. generalize p1 H H3 H4 H5; clear; induction l. simpl; congruence. destruct a; simpl; destruct (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. import (IHl _ H H3 (refl_equal _) (distinct_refines_class' _ _ _ H5 H4)). import (get_cld_in_p _ _ _ H0). import (distinct_refines_class' _ _ _ H5 H4). destruct (build_refined_classes c l). cs (d1 = d0); subst. import (build_refine_eq_compose_refine _ _ _ _ _ _ _ _ _ _ H2 H1 H4). import (IHl _ H H3 (refl_equal _) H2). unfold get_cld in H7. caseEq (path p0 (cl_dcl d)); intros; rewrite H8 in H7. simpl in H7; discriminate. destruct c2; import (path_eq_self _ _ _ _ _ _ _ H8); simpl in H7; inversion H7. assert (names (build_refined_class (cld_def d0 c1 l3 l4) (refines_cld_def d0 c0 l0 l1 l2) :: nil) = (cl_dcl d0) :: cl_object :: nil). simpl; case (eq_nat_dec d0 d0). destruct (compose_refined_mds l4 l2); simpl; auto. congruence. destruct (build_refined_class (cld_def d0 c1 l3 l4) (refines_cld_def d0 c0 l0 l1 l2)). simpl in H10; inversion H10; subst. apply (in_p_get_cld _ _ _ _ _ H6 H5). import (build_refine_eq_compose_refine' _ _ _ _ _ _ _ _ _ _ _ H2 H1 H6 H4). simpl; case (eq_nat_dec d1 d0). congruence. unfold get_cld in H0; caseEq (path p0 (cl_dcl d)); intros; rewrite H8 in H0; simpl in H0. discriminate. destruct c2; import (path_eq_self _ _ _ _ _ _ _ H8); inversion H0; subst. intros; apply (in_p_get_cld _ _ _ _ _ H7 H5). discriminate. discriminate. generalize p0 H H1 H2; clear; induction l. simpl; intros; inversion H2; clear H2 H3. unfold get_cld. induction l0. simpl; exact H. destruct a; generalize H1; clear H1; simpl; case (eq_nat_dec d d0). intros; discriminate. intros; import (IHl0 H1); clear H1 IHl0 H. induction (introduce_classes p l0); simpl; auto. generalize H0; clear H0; destruct a; simpl; case (eq_nat_dec d0 d1); simpl; auto; case (eq_nat_dec d d1); auto. simpl. intros; discriminate. simpl. caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. simpl in IHl; rewrite H in IHl; import (IHl (introduce_classes p0 l0) H0 H1 (refl_equal _)). caseEq (compose_refines_class p0 a); intros; rewrite H4 in H2; inversion H2. assert (forall p, get_cld (introduce_classes p l0) (cl_dcl d) = get_cld p (cl_dcl d)). generalize H1; unfold get_cld; clear; induction l0; simpl. reflexivity. destruct a; case (eq_nat_dec d d0). intros; discriminate. intros H H0 p; rewrite <- (IHl0 H0 p); clear H0 IHl0; induction (introduce_classes p l0). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1). case (eq_nat_dec d d1); simpl. congruence. auto. simpl; case (eq_nat_dec d d1); simpl; auto. rewrite H5; rewrite H5 in H3. generalize p2 H3 H4; clear; induction p0. simpl; intros; discriminate. destruct a0; destruct a; simpl; case (eq_nat_dec d0 d1). destruct (compose_refined_mds l0 l3). unfold get_cld; intros; inversion H4. generalize H3; clear H3; simpl; case (eq_nat_dec d d0); simpl. intros; discriminate. auto. intros; discriminate. intros n p' H H0. generalize H; clear H; unfold get_cld; simpl; case (eq_nat_dec d d0); intros. simpl in H; discriminate. destruct (cons_option_Some _ _ _ _ H0); rewrite H1 in H0; simpl in H0; inversion H0; unfold get_cld in IHp0; import (IHp0 _ H H1). simpl; case (eq_nat_dec d d0). congruence. intros; exact H2. discriminate. generalize p0; clear; induction l0. intros; simpl in H; discriminate. destruct a; simpl; case (eq_nat_dec d d0). caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. inversion H1; simpl. unfold get_cld; simpl; case (eq_nat_dec d d0); simpl. inversion H0; simpl; auto. congruence. discriminate. caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. simpl in IHl0; rewrite H in IHl0; rewrite <- (IHl0 _ _ _ H0 (refl_equal _)). inversion H1; unfold get_cld; simpl; case (eq_nat_dec d d0). congruence. clear; induction (introduce_classes p0 l0). simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d1). case (eq_nat_dec d d1). congruence. auto. simpl; case (eq_nat_dec d d1); simpl; auto. discriminate. intros; discriminate. intros; rewrite (get_refined_cl_object ps). unfold get_cld; rewrite path_cl_object; simpl; reflexivity. Qed. Theorem path'_eq_f_path : forall (ps : PSel) (p : P) (n : nat) (cl' : cl), compose ps = Some p -> path' p cl' n = f_path ps cl' n. induction n. simpl; auto. simpl; intros. rewrite (get_cld_eq_get_refined_cld cl' ps p H). destruct (get_refined_cld ps cl'); auto; destruct c. rewrite (IHn c H); reflexivity. Qed. Lemma distinct_permute : forall (A : Type) (l l' : list A), distinct _ l -> Permutation l l' -> distinct _ l'. intros; induction H0. exact H. simpl in *|-*; bd H; pa; auto. unfold not; intros; apply H3. apply (Permutation_in (A:= A) (l' := l) (l :=l') x). apply (Permutation_sym H0). exact H1. simpl in *|-*; bd H; pa. unfold not; intros; bd H0; auto. pa. auto. Qed. Lemma permute_names : forall (p p' : P), Permutation p p' -> Permutation (names p) (names p'). intros p p' H; induction H. simpl; apply Permutation_refl. simpl; destruct x. apply perm_skip; auto. destruct y; destruct x; simpl. apply perm_swap. apply (perm_trans IHPermutation1 IHPermutation2). Qed. Lemma distinct_permute_names : forall (p p' : P), distinct _ (names p) -> Permutation p p' -> distinct _ (names p'). intros. import (permute_names _ _ H0). apply (distinct_permute _ _ _ H H1). Qed. Lemma ordered_no_loops : forall (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (cld' : cld), acyclic_hierarchy (cld_def dcl' cl' fds' mds' :: p) -> distinct _ (names (cld_def dcl' cl' fds' mds' :: p)) -> In cld' p -> get_parent cld' <> (cl_dcl dcl'). induction p. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. rewrite <- H1; clear H1; simpl. inversion H; bd H4; inversion H3; bd H9; subst. simpl in H9; bd H0; unfold not; intros. rewrite H1 in H9. apply (H2 H9). bd H0; inversion H; bd H8; subst. simpl in H8; bd H8; subst. destruct cld'. apply (IHp dcl' c0 l1 l2); auto. inversion H7; bd H9; subst. apply cons_p; auto. exists c0; simpl; pa. import (list_ordered_parent _ _ H1 H8); bd H2. simpl in H11; congruence. simpl; pa. destruct cld'. apply (IHp dcl' c l l0); auto. inversion H7; bd H10; subst. apply cons_p; auto. inversion H7; exact H12. simpl; pa. Qed. Lemma path'_eq_self : forall (dcl' : dcl) (fds' : list fd) (mds' : list md) (p : list cld) (n : nat) (cl' : cl), (forall cld' : cld, In cld' p -> get_parent cld' <> cl_dcl dcl') -> ~ In (cl_dcl dcl') (names p) -> forall cl'' : cl, cl'' <> cl_dcl dcl' -> path' (cld_def dcl' cl' fds' mds' :: p) cl'' n = path' p cl'' n. induction n; simpl. auto. intros cl'; unfold get_cld; simpl; destruct cl''. case (eq_nat_dec d dcl'); intros; subst; simpl. congruence. import (in_path_in_prog p (cl_dcl d)). unfold get_cld; simpl; destruct (path p (cl_dcl d)); simpl; intros. auto. destruct c. rewrite (IHn cl' H H0 c); auto. apply (H (cld_def d0 c l0 l1)). apply H2; simpl; po1. unfold get_cld; rewrite path_cl_object; simpl; auto. Qed. Lemma head_path_eq_get_cld : forall (p p': P) (cl' : cl), distinct _ (names p) -> Permutation p p' -> head (path p cl') = get_cld p' cl'. intros; induction H0; unfold get_cld. simpl; auto. destruct x; destruct cl'; simpl. simpl in H; bd H. case (eq_nat_dec d0 d); simpl; intros. auto. auto. auto. destruct y; destruct x; destruct cl'; simpl. case (eq_nat_dec d1 d0); case (eq_nat_dec d1 d); simpl; auto. simpl in H; bd H. congruence. auto. unfold get_cld in *; rewrite <- IHPermutation2; auto. apply (distinct_permute_names _ _ H H0_). Qed. Lemma permute_get_cld_eq : forall (p p' : P) (cl' : cl), distinct _ (names p) -> Permutation p p' -> get_cld p cl' = get_cld p' cl'. intros; induction H0. auto. destruct x; destruct cl'; unfold get_cld; simpl. case (eq_nat_dec d0 d); simpl. reflexivity. simpl in H; bd H. auto. auto. destruct x; destruct cl'; destruct y; unfold get_cld; simpl. case (eq_nat_dec d0 d1); case (eq_nat_dec d0 d); simpl; auto. simpl in H; bd H; congruence. auto. rewrite <- IHPermutation2; auto. apply (distinct_permute_names _ _ H H0_). Qed. Lemma permute_path'_eq : forall (n : nat) (p p' : P), distinct _ (names p) -> Permutation p p' -> forall (cl' : cl), path' p cl' n = path' p' cl' n. induction n. simpl; auto. intros; induction H0. simpl; auto. simpl; unfold get_cld; simpl; destruct x; destruct cl'. case (eq_nat_dec d0 d); simpl. intros; rewrite (IHn (cld_def d c l0 l1 ::l) (cld_def d c l0 l1 :: l') H); try reflexivity. apply perm_skip; auto. fold (get_cld l (cl_dcl d0)); fold (get_cld l' (cl_dcl d0)). simpl in H; bd H. rewrite (permute_get_cld_eq _ _ (cl_dcl d0) H H0). destruct (get_cld l' (cl_dcl d0)); simpl. destruct c0. rewrite (IHn (cld_def d c l0 l1 ::l) (cld_def d c l0 l1 :: l')); try reflexivity. simpl; pa. apply perm_skip; auto. auto. simpl; auto. destruct x; destruct cl'; destruct y; simpl; unfold get_cld; simpl. case (eq_nat_dec d0 d1); case (eq_nat_dec d0 d); simpl; auto. simpl in H; bd H; congruence. rewrite (IHn _ (cld_def d c l0 l1 :: cld_def d1 c0 l2 l3 :: l) H); try reflexivity. apply perm_swap. rewrite (IHn _ (cld_def d c l0 l1 :: cld_def d1 c0 l2 l3 :: l) H); try reflexivity. apply perm_swap. intros; destruct (head (path l (cl_dcl d0))). destruct c1. rewrite (IHn _ (cld_def d c l0 l1 :: cld_def d1 c0 l2 l3 :: l) H); try reflexivity. apply perm_swap. auto. auto. intros. rewrite <- IHPermutation2. rewrite IHPermutation1; auto. apply (distinct_permute_names _ _ H H0_). Qed. Lemma path_eq_parent' : forall (p : P) (cl' : cl) (dcl' : dcl) (fds' : list fd) (md_list : list md), acyclic_hierarchy p -> distinct _ (names p) -> In (cld_def dcl' cl' fds' md_list) p -> path p (cl_dcl dcl') = (cld_def dcl' cl' fds' md_list) :: (path p cl'). intros. induction p. simpl in H1; elimtype False; apply H1. generalize (distinct_acyclic_hierarchy _ _ H1 H H0); intros H8; simpl in H8. destruct a. simpl in H, H1; inversion H; subst. bd H1. rewrite H1. simpl. case (eq_nat_dec dcl' dcl'); intros H6; try (elimtype False; apply H6; apply refl_equal). destruct cl'. case (eq_nat_dec d0 dcl'); intros. rewrite e in H8; elimtype False; apply H8; apply refl_equal. apply refl_equal. rewrite path_cl_object. apply refl_equal. simpl in H0; bd H0. import (IHp H4 H0 H1). simpl. case (eq_nat_dec dcl' d); intros H7; subst. elimtype False; apply H6. apply (In_names _ _ _ _ _ H1). rewrite H2. destruct cl'. case (eq_nat_dec d0 d); intros. destruct H5; bd H3. simpl in H10; rewrite <- H10 in *|-*; clear H10. rewrite e in *|-*. import (list_ordered_parent _ _ H1 H4); bd H5. simpl in H11; rewrite <- H11 in H5. elimtype False; apply H6; exact H5. apply refl_equal. rewrite path_cl_object; apply refl_equal. Qed. Lemma path'_eq_path : forall (p : P) (cl' : cl), distinct _ (names p) -> acyclic_hierarchy p -> path' p cl' (length p) = path p cl'. induction p. simpl; auto. destruct a; destruct cl'. intros; simpl; unfold get_cld; simpl; case (eq_nat_dec d0 d); intros; subst; simpl. rewrite path'_eq_self. rewrite IHp; auto. simpl in H; bd H. inversion H0; auto. intros; apply (ordered_no_loops _ _ _ _ _ _ H0 H H1). simpl in H; bd H. apply (distinct_acyclic_hierarchy (cld_def d c l l0 :: p) (cld_def d c l l0)); auto. simpl; po1. cs (exists cl', exists fds', exists mds', In (cld_def d0 cl' fds' mds') p). bd H1. inversion H0; simpl in H; bd H. rewrite (path_eq_parent' _ _ _ _ _ H4 H H1); simpl. rewrite path'_eq_self. rewrite IHp; auto. intros; apply (ordered_no_loops _ _ _ _ _ cld'0 H0); auto. simpl; pa. exact H8. import (list_ordered_parent _ _ H1 H4). bd H6. simpl in H10; unfold not; intros; subst. subst. apply (H8 H6). assert (path p (cl_dcl d0) = nil). generalize H1; clear; induction p. simpl; auto. destruct a; simpl; case (eq_nat_dec d0 d); intros. bd H1; import (H1 c); clear H1; bd H; import (H l); clear H; bd H0; import (H0 l0); bd H; clear H0. congruence. rewrite IHp; auto. unfold not; intros H; bd H. bd H1; import (H1 x); clear H1; bd H0; import (H0 x0); clear H0; bd H1; import (H1 x1); bd H0; clear H1. rewrite H2; simpl; reflexivity. simpl; auto. Qed. Theorem permute_path_eq : forall (p p' : P), distinct _ (names p) -> Permutation p p' -> (forall cl', acyclic_hierarchy p' -> path' p cl' (length p) = path p' cl'). intros. rewrite <- (path'_eq_path _ cl' (distinct_permute_names _ _ H H0) H1). rewrite (Permutation_length H0). apply (permute_path'_eq); auto. Qed. Lemma length_compose_refines_class : forall (rcld' : rcld) (p p' : P), compose_refines_class p rcld' = Some p' -> length p = length p'. induction p. intros; inversion H. destruct a; destruct rcld'; simpl. case (eq_nat_dec d d0); intros; subst. caseEq (compose_refined_mds l0 l3); intros; rewrite H0 in H. inversion H; simpl; reflexivity. discriminate. destruct (cons_option_Some _ _ _ _ H); rewrite H0 in H; simpl in H; inversion H; subst; clear H. simpl; rewrite (IHp _ H0); reflexivity. Qed. Lemma names_compose_refines_class : forall (rcld' : rcld) (p p' : P), compose_refines_class p rcld' = Some p' -> names p = names p'. induction p. intros; inversion H. destruct a; destruct rcld'; simpl. case (eq_nat_dec d d0); intros; subst. caseEq (compose_refined_mds l0 l3); intros; rewrite H0 in H. inversion H; simpl; reflexivity. discriminate. destruct (cons_option_Some _ _ _ _ H); rewrite H0 in H; simpl in H; inversion H; subst; clear H. simpl; rewrite (IHp _ H0); reflexivity. Qed. Lemma length_names : forall (p : P), S (length p) = length (names p). induction p; simpl; auto. rewrite IHp; destruct a; simpl; auto. Qed. Lemma rm_dcl_names : forall (cld' : cld) (p p' : P), names p = names p' -> names (rm_dcl p cld') = names (rm_dcl p' cld'). induction p. simpl; destruct p'. simpl; tauto. intros; destruct c; discriminate. destruct p'; simpl; destruct a. intros; discriminate. destruct c; intros H; inversion H; subst. import (IHp _ H2). destruct cld'; case (eq_nat_dec d d0); intros; simpl; congruence. Qed. Lemma names_introduce_classes : forall (p'' p p' : P), names p = names p' -> names (introduce_classes p p'') = names (introduce_classes p' p''). induction p''. simpl; auto. destruct a; simpl. intros. rewrite (rm_dcl_names (cld_def d c l l0) _ _ (IHp'' _ _ H)); auto. Qed. Lemma names_introduce_all : forall (ps : PSel) (p : P), compose ps = Some p -> names (introduce_all ps) = names p. induction ps. intros; inversion H; subst; simpl; reflexivity. destruct a; simpl. caseEq (compose ps). intros p H p0; caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l). caseEq (fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. inversion H2; inversion H1; clear H1 H2; subst. import (IHps _ H); clear IHps. assert (names p2 = names p). generalize p2 H0; clear; induction l. simpl; congruence. simpl; caseEq ( fold_right (fun (rcld' : rcld) (op : option P) => match op with | Some p' => compose_refines_class p' rcld' | None => None (A:=P) end) (Some p) l); intros. rewrite <- (IHl _ H). rewrite (names_compose_refines_class _ _ _ H0); reflexivity. discriminate. rewrite <- H2 in H1; generalize p2 H1; clear; induction (introduce_all ps). destruct p2; simpl. auto. intros; destruct c; discriminate. destruct p2; destruct a; simpl; intros. discriminate. destruct c; inversion H1; subst. generalize (IHl _ H2) H2; clear; induction l0. simpl; congruence. destruct a; simpl; intros; inversion H; subst. rewrite (rm_dcl_names (cld_def d c1 l5 l6) (introduce_classes (cld_def d0 c0 l1 l2 :: l) l0) (introduce_classes (cld_def d0 c l3 l4 :: p2) l0)); auto. apply IHl0. apply names_introduce_classes; auto. auto. discriminate. intros; discriminate. intros; discriminate. Qed. Lemma length_ps : forall (ps : PSel) (p : P), compose ps = Some p -> length (introduce_all ps) = length p. intros. import (length_names (introduce_all ps)). import (length_names p). rewrite (names_introduce_all _ _ H) in H0. rewrite <- H1 in H0. congruence. Qed. Lemma f_path_eq_path : forall (ps : PSel) (cl' : cl) (p p' : P), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> f_path ps cl' (length p) = path p' cl'. intros. rewrite <- (path'_eq_f_path _ _ (length p) cl' H). apply permute_path_eq; auto. apply (distinct_compose_names _ _ H). Qed. Lemma ps_ftype_eq_ftype : forall (ps : PSel) (cl' : cl) (f' : f) (p p' : P), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_ftype ps cl' f' (length (introduce_all ps)) = ftype p' cl' f'. intros. rewrite (length_ps _ _ H). unfold ps_ftype; unfold ftype. rewrite (f_path_eq_path _ cl' _ _ H H0 H1); auto. Qed. Lemma ps_get_md_eq_get_md : forall (ps : PSel) (cl' : cl) (m' : m) (p p' : P), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_get_md ps cl' m' (length (introduce_all ps)) = get_md p' cl' m'. intros. rewrite (length_ps _ _ H). unfold ps_get_md; unfold get_md. rewrite (f_path_eq_path _ cl' _ _ H H0 H1); auto. Qed. Lemma ps_mtype_eq_mtype : forall (ps : PSel) (cl' : cl) ( m' : m) (p p' : P), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_mtype ps cl' m' (length (introduce_all ps)) = mtype p' cl' m'. intros. unfold ps_mtype; unfold mtype. rewrite (ps_get_md_eq_get_md _ cl' m' _ _ H H0 H1). reflexivity. Qed. Lemma ps_fields_eq_fields : forall (ps : PSel) (cl' : cl) (p p' : P), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_fields ps cl' (length (introduce_all ps)) = fields p' cl'. intros. rewrite (length_ps _ _ H). unfold ps_fields; unfold fields. rewrite (f_path_eq_path _ cl' _ _ H H0 H1); auto. Qed. Lemma ps_methods_eq_methods : forall (ps : PSel) (cl' : cl) (p p' : P), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_methods ps cl' (length (introduce_all ps)) = methods p' cl'. intros. rewrite (length_ps _ _ H). unfold ps_methods; unfold methods. rewrite (f_path_eq_path _ cl' _ _ H H0 H1); auto. Qed. Lemma sat_distinct_constr_app : forall (dc_list dc_list': list unique_constraint), sat_unique_constraint (dc_list ++ dc_list') = true -> sat_unique_constraint dc_list' = true. induction dc_list. simpl; auto. destruct a; simpl; intros; apply (IHdc_list _(proj2 (andb_prop _ _ H))). Qed. Lemma build_refined_self : forall (rclds : list rcld) (dcl' dcl'' : dcl) (cl' cl'' : cl) (fds' fds'' : list fd) (mds' mds'': list md), build_refined_classes (cld_def dcl' cl' fds' mds') rclds = cld_def dcl'' cl'' fds'' mds'' -> dcl' = dcl''. induction rclds. simpl; congruence. destruct a; simpl; intros. caseEq (build_refined_classes (cld_def dcl' cl' fds' mds') rclds); intros. rewrite H0 in H. rewrite (IHrclds _ _ _ _ _ _ _ _ H0) in *|-*. simpl in H; generalize H; clear H; case (eq_nat_dec d0 d). destruct (compose_refined_mds l3 l1). intros; congruence. intros; congruence. intros; congruence. Qed. Lemma get_refined_eq_self : forall (ps : PSel) (d dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), get_refined_cld ps (cl_dcl d) = Some (cld_def dcl' cl' fds' mds') -> d = dcl'. induction ps. simpl; intros; discriminate. destruct a; simpl. intros; caseEq (path l0 (cl_dcl d)); intros; rewrite H0 in H. caseEq (get_refined_cld ps (cl_dcl d)); intros; rewrite H1 in H. destruct c. import (IHps _ _ _ _ _ H1); subst. inversion H. apply (build_refined_self _ _ _ _ _ _ _ _ _ H3). discriminate. destruct c; rewrite <- (path_eq_self _ _ _ _ _ _ _ H0) in H. congruence. Qed. Lemma gen_stmt_list_app : forall (s' s1 : list s) (c_list c_list1 : list ty_constraint) (d : dcl) (l3 : list vd), gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s') = Some c_list -> gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s1) = Some c_list1 -> gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s (s' ++ s1)) = Some (c_list ++ c_list1). induction s'. simpl. intros; auto. inversion H; subst; auto. destruct a; simpl; intros; caseEq (gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s')); intros; rewrite H1 in H; try discriminate; try (rewrite (IHs' _ _ _ _ _ H1 H0)). destruct (XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))). inversion H; subst; auto. discriminate. destruct (match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty' ty'' :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); try discriminate. destruct ( match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => Some (sty_cl_constr (ty_def c) ty' :: nil) | None => None (A:=list ty_constraint) end); simpl in H; discriminate. destruct (XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))); discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty' ty'' :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). inversion H; subst; auto. rewrite app_ass; reflexivity. discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty' ty'' :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. destruct ( match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some (ty_def cl') => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => Some (sty_field_rconstr cl' f ty' :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). inversion H; subst; rewrite app_ass; auto. discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some (ty_def cl') => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => Some (sty_field_rconstr cl' f ty' :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some (ty_def cl') => match XMap.find x0 (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => Some (sty_field_wconstr ty' cl' f :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). inversion H; subst; rewrite app_ass; auto. discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some (ty_def cl') => match XMap.find x0 (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => Some (sty_field_wconstr ty' cl' f :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. destruct ( match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some (ty_def cl') => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match fold_right (fun (y : lj_definitions.x) (m0 : option (list ty)) => match XMap.find y (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'0 => match m0 with | Some m' => Some (ty'0 :: m') | None => None (A:=list ty) end | None => None (A:=list ty) end) (Some nil) l with | Some ty_list => Some (sty_meth_constr cl' m ty' ty_list :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). inversion H; subst; rewrite app_ass; auto. discriminate. destruct ( match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some (ty_def cl') => match XMap.find (x_var v) (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match fold_right (fun (y : lj_definitions.x) (m0 : option (list ty)) => match XMap.find y (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'0 => match m0 with | Some m' => Some (ty'0 :: m') | None => None (A:=list ty) end | None => None (A:=list ty) end) (Some nil) l with | Some ty_list => Some (sty_meth_constr cl' m ty' ty_list :: nil) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match XMap.find x0 (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => match gen_stmt_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) a1 with | Some c_list2 => match gen_stmt_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) a2 with | Some c_list3 => Some (sty_if_constr ty' ty'' :: c_list2 ++ c_list3) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). inversion H; subst; rewrite app_ass; auto. discriminate. destruct (match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty' => match XMap.find x0 (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => match gen_stmt_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) a1 with | Some c_list2 => match gen_stmt_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) a2 with | Some c_list3 => Some (sty_if_constr ty' ty'' :: c_list2 ++ c_list3) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. destruct (gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) l). inversion H; subst; rewrite app_ass; auto. discriminate. destruct (gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) l); discriminate. Qed. Lemma gen_constr_introduce_mds : forall (d : dcl) (m_list1 m_list2 : list md) (c_list1 c_list2 : list ty_constraint), fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) m_list1 = Some c_list1 -> fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) m_list2 = Some c_list2 -> exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) (introduce_methods m_list1 m_list2) = Some c_list'. induction m_list2. simpl. intros. exists c_list1; exact H. destruct a; simpl. caseEq (fold_right (fun (md' : md) (m1 : option (list ty_constraint)) => match m1 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) m_list2); intros. destruct (IHm_list2 _ _ H0 H). generalize x H2 H1; clear; induction (introduce_methods m_list1 m_list2). simpl; intros. destruct (match m with | ms_def ty' _ vd_list => match m0 with | mb_def s_list y => if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) vd_list) then match gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s_list) with | Some c_list => match XMap.find y (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' ty' :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) vd_list ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end end). exists (l0 ++ nil); auto. discriminate. destruct a; simpl. caseEq (fold_right (fun (md' : md) (m3 : option (list ty_constraint)) => match m3 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). destruct m; destruct m0. intros. caseEq (ms_eq m1 (ms_def t m l1)). intros; import ((proj1 (eq_ms_eq _ _ )) H0); subst. simpl; rewrite H. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l1)). destruct (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l1) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l2)). destruct (XMap.find x (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l1) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))). exists ((sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l1 ++ l4) ++ l3); auto. discriminate. discriminate. discriminate. intros; simpl. destruct (IHl0 _ H H1). rewrite H3. destruct (match m1 with | ms_def ty' _ vd_list => match m2 with | mb_def s_list y => if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) vd_list) then match gen_stmt_list_constr (fold_left (fun (m0 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m0) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s_list) with | Some c_list => match XMap.find y (fold_left (fun (m0 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m0) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' ty' :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) vd_list ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end end ). exists (l4 ++ x1); auto. discriminate. intros; discriminate. discriminate. Qed. Definition gen_refines_meth_constr (ty1: ty) (rmd' : rmd) : option (list ty_constraint) := match rmd' with rmd_def (ms_def ty' m' vd_list) (rmb_def s_list_before s_list_after y) => if (distinct_list (map (fun (vd' : vd) => match vd' with vd_def ty' var' => var' end) vd_list)) then let g := (fold_left (fun (m : XMap.t ty) (p : x*ty) => XMap.add (fst p) (snd p) m) (cons (x_this, ty1) (map (fun (vd' : vd) => match vd' with vd_def ty' var' => (x_var var', ty') end) vd_list)) (XMap.empty ty)) in match gen_stmt_list_constr g (make_list_s s_list_before), gen_stmt_list_constr g (make_list_s s_list_after), XMap.find y g with Some c_list, Some c_list', Some ty'' => Some ((sty_cl_constr ty'' ty') :: ( (map (fun (vd' : vd) => match vd' with vd_def (ty_def cl') var' => in_prog_constr cl' end) vd_list) ++ c_list ++ c_list')) | _, _, _ => None end else None end. Definition gen_refines_class_constr (rcld': rcld) : option (list ty_constraint) := match rcld' with refines_cld_def dcl' (cl_dcl dcl'') fds' mds' rmds' => if (eq_nat_dec dcl' dcl'') then None else let f_list := (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') in let m_list := (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds') in match (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_meth_constr (ty_def (cl_dcl dcl')) md') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) mds') with Some c_list => match (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) rmds') with Some c_list' => Some ((in_prog_constr (cl_dcl dcl'')) :: (inherited_fields_constr f_list (cl_dcl dcl')) :: (inherited_methods_constr mds' (cl_dcl dcl')) :: ((map (fun (fd' : fd) => match fd' with fd_def (ty_def cl') _ => in_prog_constr cl' end) fds') ++ c_list ++ c_list')) | None => None end | None => None end | refines_cld_def dcl' cl_object fds' mds' rmds' => let f_list := (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') in let m_list := (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds') in match (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_meth_constr (ty_def (cl_dcl dcl')) md') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) mds') with Some c_list => match (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) rmds') with Some c_list' => Some (inherited_fields_constr f_list (cl_dcl dcl') :: (inherited_methods_constr mds' (cl_dcl dcl')) :: (map (fun (fd' : fd) => match fd' with fd_def (ty_def cl') _ => in_prog_constr cl' end) fds') ++ c_list ++ c_list') | None => None end | None => None end end. Definition gen_class_constr' (cld': cld) : option (list ty_constraint) := match cld' with cld_def dcl' (cl_dcl dcl'') fds' mds' => if (eq_nat_dec dcl' dcl'') then None else let f_list := (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') in let m_list := (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds') in if distinct_list f_list && distinct_list m_list then match (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_meth_constr (ty_def (cl_dcl dcl')) md') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) mds') with Some c_list => Some ((in_prog_constr (cl_dcl dcl'')) :: (inherited_fields_constr f_list (cl_dcl dcl')) :: (inherited_methods_constr mds' (cl_dcl dcl')) :: ((map (fun (fd' : fd) => match fd' with fd_def (ty_def cl') _ => in_prog_constr cl' end) fds') ++ c_list)) | None => None end else None | cld_def dcl' cl_object fds' mds' => let f_list := (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') in let m_list := (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds') in if distinct_list f_list && distinct_list m_list then match (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_meth_constr (ty_def (cl_dcl dcl')) md') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) mds') with Some c_list => Some ((inherited_fields_constr f_list (cl_dcl dcl')) :: (inherited_methods_constr mds' (cl_dcl dcl')) :: (map (fun (fd' : fd) => match fd' with fd_def (ty_def cl') _ => in_prog_constr cl' end) fds') ++ c_list) | None => None end else None end. Definition gen_f_constr (f : FD) : option (list ty_constraint) := match f with feature_def rclds' clds' => match fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_refines_class_constr rcld') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) rclds' with Some c_list' => match fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with Some c_list' => match (gen_class_constr' cld') with Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) clds' with Some c_list'' => Some (c_list' ++ c_list'') | None => None end | None => None end end. Fixpoint gen_ps_constr (ps: PSel) : option (list ty_constraint) := match ps with f' :: ps' => match gen_f_constr f', gen_ps_constr ps' with Some c_list, Some c_list' => Some (c_list ++ c_list') | _, _ => None end | nil => Some nil end. Lemma gen_constr_compose_refined_mds : forall (d : dcl) (rmd_list : list rmd) (c_list1 c_list2 : list ty_constraint) (m_list1 m_list': list md), fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) m_list1 = Some c_list1 -> fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) rmd_list = Some c_list2 -> compose_refined_mds m_list1 rmd_list = Some m_list' -> exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) (m_list') = Some c_list'. induction rmd_list. simpl. intros; exists c_list1; congruence. destruct a; simpl. caseEq (fold_right (fun (rmd' : rmd) (m0 : option (list ty_constraint)) => match m0 with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) rmd_list); intros. caseEq (compose_refined_mds m_list1 rmd_list); intros; rewrite H3 in H2. destruct (IHrmd_list _ _ _ _ H0 H H3). generalize x m_list' H1 H4 H2; clear; induction l0. simpl. intros; discriminate. destruct a; simpl; intros. destruct m1; destruct r; generalize H2. caseEq (ms_eq m0 m); intros. inversion H0; subst. simpl. destruct (fold_right (fun (md' : md) (m1 : option (list ty_constraint)) => match m1 with | Some c_list'0 => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). destruct m0. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l5)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l5) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l1)); intros; rewrite H3 in H4. destruct m. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l7)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l7) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l2)); intros; rewrite H5 in H1. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l7) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l3)); intros; rewrite H6 in H1. import ((proj1 (eq_ms_eq _ _ )) H); inversion H7; subst. rewrite (gen_stmt_list_app l2 (l1 ++ l3) _ _ _ _ H5 (gen_stmt_list_app _ _ _ _ _ _ H3 H6)). destruct (XMap.find x1 (fold_left (fun (m0 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m0) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l7) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))). exists ((sty_cl_constr t t0 :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l7 ++ l8 ++ l6 ++ l9) ++ l4); auto. discriminate. discriminate. discriminate. discriminate. discriminate. discriminate. discriminate. destruct (cons_option_Some _ _ _ _ H0); rewrite H3 in H0; inversion H0; subst; clear H0. simpl. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H0 in H4. destruct (IHl0 _ _ H1 H0 H3). rewrite H5. destruct m0. destruct ( (if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l5) then match gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l5) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l1) with | Some c_list => match XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l5) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l5 ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint))). exists (l6 ++ x3); auto. discriminate. discriminate. discriminate. discriminate. Qed. Lemma ex_gen_ps_gen_p : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (t_list : list ty_constraint), compose ps = Some p -> gen_ps_constr ps = Some t_list -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> PS_distinct_fds_mds ps = true -> get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds') -> exists t_list', gen_cld_constr (cld_def dcl' cl' fds' mds' :: nil) = Some t_list'. intros. rewrite <- (get_cld_eq_get_refined_cld (cl_dcl dcl') _ _ H) in H3. import (get_cld_in_p _ _ _ H3). import (sat_constr_distinct' _ _ _ _ _ _ H H1 H2 H4). bd H5. rewrite (get_cld_eq_get_refined_cld (cl_dcl dcl') _ _ H) in H3. unfold gen_cld_constr. simpl. rewrite ((proj2 (distinct_distinct_list _)) H8). rewrite ((proj2 (distinct_distinct_list _)) H5); simpl; clear H8 H5 H4 H1 H2 H. generalize ps dcl' cl' fds' mds' t_list H0 H3; clear; induction ps. simpl. intros; discriminate. destruct a; intros. cs (In (cld_def dcl' cl' fds' mds') l0). generalize H3 H H0; clear. simpl; intros. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H1 in H0. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H2 in H0. generalize l2 t_list H0 H H2 H1; clear. induction l0. simpl; intros; contradiction. destruct a; intros. simpl in H; bd H. inversion H; subst. simpl in H2. caseEq (gen_ps_constr ps); intros; rewrite H3 in H0. simpl in H0. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H4 in H2. simpl. generalize H2; clear H2; destruct cl'. case (eq_nat_dec dcl' d). intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds')). destruct (distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). simpl. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'); intros. exists ((in_prog_constr (cl_dcl d) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') (cl_dcl d) :: inherited_methods_constr mds' (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) fds' ++ l5) ++ nil); auto. discriminate. simpl; intros; discriminate. simpl; intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds')). destruct (distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). simpl. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'); intros. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) fds' ++ l5) ++ nil); auto. discriminate. simpl; intros; discriminate. simpl; intros; discriminate. discriminate. discriminate. simpl in H2. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H3 in H2. caseEq (gen_ps_constr ps); intros; rewrite H4 in IHl0. apply (IHl0 _ _ (refl_equal _) H H3 H1). rewrite H4 in H0; discriminate. discriminate. discriminate. discriminate. simpl in H3; caseEq (path l0 (cl_dcl dcl')); intros; rewrite H1 in H3. unfold gen_ps_constr in H0; fold (gen_ps_constr ps) in H0. caseEq (gen_f_constr (feature_def l l0)); intros; rewrite H2 in H0. caseEq (gen_ps_constr ps); intros; rewrite H4 in H0. caseEq (get_refined_cld ps (cl_dcl dcl')); intros; rewrite H5 in H3. destruct c; inversion H3; clear H3. import (build_refined_self _ _ _ _ _ _ _ _ _ H7); subst. destruct (IHps _ _ _ _ _ H4 H5); clear IHps. generalize l l1 dcl' c l4 l3 cl' l0 x fds' mds' H3 H7 H2; clear; induction l. simpl; intros. inversion H7; subst; clear H7. exists x; congruence. destruct a; intros; simpl in H7. caseEq (build_refined_classes (cld_def dcl' c0 l5 l4) l); intros; rewrite H in H7. import (build_refined_self _ _ _ _ _ _ _ _ _ H); subst. generalize H7; simpl; clear H7; case (eq_nat_dec d0 d); subst. caseEq (compose_refined_mds l8 l2); intros. simpl in H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H1 in H2. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l6); intros; rewrite H4 in H2. destruct (IHl (l10 ++ l11) _ _ _ _ _ l6 _ _ _ H3 H); clear IHl. simpl; rewrite H1; rewrite H4; auto. inversion H7; subst; clear H7. generalize H2; clear H2; destruct cl'. case (eq_nat_dec d d0). intros; discriminate. assert (exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8 = Some c_list'). generalize H5; clear. destruct c1. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8); intros. exists l; auto. discriminate. destruct H2; generalize l10 l11 l3 l9 x1 H0 H2; clear. induction l1; simpl. induction l2; simpl. intros; inversion H0; subst; rewrite H2. exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr l9 (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ x1) ++ nil); auto. intros l10 l11 l3 l9 x1. caseEq (compose_refined_mds l8 l2). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros l1 H H2 H3 n; destruct (IHl2 l10 l11 _ _ _ H H3 n (refl_equal _)); clear IHl2. caseEq (match gen_refines_meth_constr (ty_def (cl_dcl d)) a with | Some c_list'' => Some (c_list'' ++ l) | None => None (A:=list ty_constraint) end); intros. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); intros. rewrite H5 in H0; simpl in H0. generalize l9 l5 H5 H1 H2; clear. destruct a; induction l1. simpl; intros. discriminate. destruct a; simpl. caseEq (fold_right (fun (md' : md) (m2 : option (list ty_constraint)) => match m2 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct m1; destruct r; caseEq (ms_eq m0 m). intros. inversion H2; subst; clear H2; simpl; rewrite H0; destruct m0. rewrite <- ((proj1 (eq_ms_eq _ _ )) H) in H1; simpl in H1. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l9)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l3)); intros; rewrite H2 in H1. caseEq ( gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l5)); intros; rewrite H3 in H1. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l2)); intros; rewrite H4 in H5. rewrite (gen_stmt_list_app l3 (l2 ++ l5) _ _ _ _ H2 (gen_stmt_list_app _ _ _ _ _ _ H4 H3)). destruct (XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))). exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr (md_def (ms_def t m0 l9) (mb_def (l3 ++ l2 ++ l5) x0) :: l1) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ (sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l9 ++ l10 ++ l12 ++ l11) ++ l6) ++ nil); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros. rewrite H0 in IHl1. destruct (cons_option_Some _ _ _ _ H2). rewrite H3 in H2; simpl in H2; inversion H2; subst. destruct (IHl1 x1 _ (refl_equal _)). simpl. destruct m. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l9)). rewrite H1. reflexivity. discriminate. auto. simpl. destruct (fold_right (fun (md' : md) (m1 : option (list ty_constraint)) => match m1 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) x1). destruct (match m0 with | ms_def ty' _ vd_list => if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) vd_list) then match gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l2) with | Some c_list => match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' ty' :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) vd_list ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end). exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr (md_def m0 (mb_def l2 x) :: x1) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l10 ++ l9) ++ nil); auto. discriminate. discriminate. intros; discriminate. rewrite H5 in H0. discriminate. discriminate. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (gen_meth_constr (ty_def (cl_dcl d)) a); intros. destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). destruct (IHl1 l10 l11 _ _ _ H0 H2 n (refl_equal _)). destruct a; generalize x H H3; clear. induction (introduce_methods l9 l1). simpl. intros. rewrite H. exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr (md_def m m0 :: nil) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l3 ++ nil) ++ nil). auto. destruct a; simpl. caseEq (ms_eq m1 m); intros. simpl; rewrite ((proj1 (eq_ms_eq _ _ )) H) in H3; simpl in H3. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct m; destruct m0; destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l4)). rewrite H0. exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr (md_def (ms_def t m l4) (mb_def l5 x0) :: l) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l3 ++ l2) ++ nil); auto. discriminate. discriminate. simpl. simpl in IHl. rewrite H0 in IHl. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct (IHl _ (refl_equal _) (refl_equal _)). destruct (fold_right (fun (md' : md) (m3 : option (list ty_constraint)) => match m3 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) (introduce_method l (md_def m m0))). destruct (match m1 with | ms_def ty' _ vd_list => match m2 with | mb_def s_list y => if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) vd_list) then match gen_stmt_list_constr (fold_left (fun (m3 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m3) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s_list) with | Some c_list => match XMap.find y (fold_left (fun (m3 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m3) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' ty' :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) vd_list ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end end). exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr (md_def m1 m2 :: introduce_method l (md_def m m0)) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l5 ++ l4) ++ nil); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros; discriminate. assert (exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8 = Some c_list'). generalize H5; clear. destruct c1. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8); intros. exists l; auto. discriminate. destruct H2; generalize l8 l3 l9 x1 H0 H2; clear. induction l1; simpl. induction l2; simpl. intros; inversion H0; subst; rewrite H2. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ x1) ++ nil); auto. intros l8 l3 l9 x1. caseEq (compose_refined_mds l8 l2). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros l1 H H2 H3 n; destruct (IHl2 _ _ _ _ H H3 (refl_equal _)); clear IHl2. caseEq (match gen_refines_meth_constr (ty_def (cl_dcl d)) a with | Some c_list'' => Some (c_list'' ++ l) | None => None (A:=list ty_constraint) end); intros. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); intros. simpl. rewrite H4 in H0; simpl in H0. generalize l5 l9 H4 H1 H2; clear. destruct a; induction l1. simpl; intros. discriminate. destruct a; simpl. caseEq (fold_right (fun (md' : md) (m2 : option (list ty_constraint)) => match m2 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct m1; destruct r; caseEq (ms_eq m0 m). intros. inversion H2; subst; clear H2; simpl; rewrite H0; destruct m0. rewrite <- ((proj1 (eq_ms_eq _ _ )) H) in H1; simpl in H1. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l9)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l3)); intros; rewrite H2 in H1. caseEq ( gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l5)); intros; rewrite H3 in H1. simpl. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l2)); intros; rewrite H5 in H4. rewrite (gen_stmt_list_app l3 (l2 ++ l5) _ _ _ _ H2 (gen_stmt_list_app _ _ _ _ _ _ H5 H3)). destruct (XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l9) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))). exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ (sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l9 ++ l10 ++ l12 ++ l11) ++ l6) ++ nil); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros. rewrite H0 in IHl1. destruct (cons_option_Some _ _ _ _ H2). rewrite H3 in H2; simpl in H2; inversion H2; subst. destruct (IHl1 _ x1 (refl_equal _)). simpl. destruct m. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l9)). rewrite H1. reflexivity. discriminate. auto. simpl. destruct (fold_right (fun (md' : md) (m1 : option (list ty_constraint)) => match m1 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) x1). destruct (match m0 with | ms_def ty' _ vd_list => if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) vd_list) then match gen_stmt_list_constr (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s l2) with | Some c_list => match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' ty' :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) vd_list ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end). exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l10 ++ l9) ++ nil); auto. discriminate. discriminate. intros; discriminate. intros. rewrite H4 in H0. discriminate. intros. rewrite H1 in n. discriminate. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (gen_meth_constr (ty_def (cl_dcl d)) a); intros. destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). destruct (IHl1 _ _ _ _ H0 H2 (refl_equal _)). destruct a; generalize x H H3; clear. induction (introduce_methods l9 l1). simpl. intros. rewrite H. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l3 ++ nil) ++ nil); auto. destruct a; simpl. caseEq (ms_eq m1 m); intros. simpl; rewrite ((proj1 (eq_ms_eq _ _ )) H) in H3; simpl in H3. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct m; destruct m0; destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l4)). rewrite H0. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l3 ++ l2) ++ nil); auto. discriminate. discriminate. simpl; simpl in IHl; rewrite H0 in IHl. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct (IHl _ (refl_equal _) (refl_equal _)). destruct (fold_right (fun (md' : md) (m3 : option (list ty_constraint)) => match m3 with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) (introduce_method l (md_def m m0))). destruct (match m1 with | ms_def ty' _ vd_list => match m2 with | mb_def s_list y => if distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) vd_list) then match gen_stmt_list_constr (fold_left (fun (m3 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m3) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s_list) with | Some c_list => match XMap.find y (fold_left (fun (m3 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m3) (map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) vd_list) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) with | Some ty'' => Some (sty_cl_constr ty'' ty' :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) vd_list ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end end). exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ l5 ++ l4) ++ nil); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros; discriminate. inversion H7; subst; clear H7. destruct cl'. generalize H2; clear H2. case (eq_nat_dec d d0). intros; discriminate. assert (exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4 = Some c_list'). generalize H3; clear. destruct c0. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros. discriminate. discriminate. intros; discriminate. intros. assert (exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4 = Some c_list'). generalize H3; clear. destruct c0. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros. rewrite H6 in H2; rewrite H7 in H2; simpl in H2. discriminate. rewrite H6 in H2; rewrite H7 in H2; simpl in H2. discriminate. intros G1; rewrite G1 in H2; simpl in H2. discriminate. discriminate. inversion H7; subst; clear H7. unfold gen_f_constr in H2; simpl in H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H1 in H2. generalize H2; clear H2; destruct cl'. case (eq_nat_dec d d0). intros; discriminate. assert (exists c_list', fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4 = Some c_list'). generalize H3; clear. destruct c0. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros. exists l; auto. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros. exists l; auto. discriminate. destruct H2; generalize d c1 l7 mds' l8 l3 H H1 H2; clear; induction l. simpl; intros; inversion H. subst. rewrite H2. exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields l7 l0)) (cl_dcl d0) :: inherited_methods_constr mds' (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields l7 l0) ++ x0) ++ nil); auto. destruct a; simpl. intros d1 c1 f2 mds' g1 g2; caseEq (build_refined_classes (cld_def d1 c0 l5 l4) l); intros. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H4 in H1. import (build_refined_self _ _ _ _ _ _ _ _ _ H); subst. caseEq (match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d2)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => match fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d2)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2 with | Some c_list' => Some (in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l0) (cl_dcl d2) :: inherited_methods_constr l1 (cl_dcl d2) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l0 ++ c_list ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). intros; rewrite H5 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l6); intros; rewrite H6 in H3. intros; destruct (IHl _ _ _ _ _ ((l12 ++ l11) ++ l13) H H4 H2 n). rewrite H5; rewrite H6. auto. generalize H0; clear H0; simpl. case (eq_nat_dec d2 d). caseEq (compose_refined_mds l10 l8); intros. inversion H8; subst. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l10); intros; rewrite H9 in H7. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l8); intros; rewrite H10 in H1. destruct (gen_constr_compose_refined_mds _ _ _ _ _ _ H9 H10 H0). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l7); intros; rewrite H12 in H1. destruct (gen_constr_introduce_mds _ _ _ _ _ H11 H12). rewrite H13. exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields (introduce_fields l9 l3) l0)) (cl_dcl d0) :: inherited_methods_constr (introduce_methods l14 l7) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields (introduce_fields l9 l3) l0) ++ x2) ++ nil); auto. generalize H1; clear H1; destruct c1. case (eq_nat_dec d d1); intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); try discriminate. destruct c1; generalize H1; clear H1. case (eq_nat_dec d d1); intros; destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l7); try discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l7); intros; discriminate. generalize H1; clear H1; destruct c1. case (eq_nat_dec d d1); intros; discriminate. intros; discriminate. inversion H8; subst. destruct ( fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). exists _; reflexivity. discriminate. intros. inversion H0; subst. destruct ( fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d2)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). exists _; reflexivity. discriminate. discriminate. intros. rewrite H5 in H3. discriminate. discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros; rewrite H2 in H3. generalize d c1 l7 mds' l8 l3 H H1 H2; clear; induction l. simpl. intros. inversion H; subst. rewrite H2. exists _; reflexivity. destruct a; simpl. intros; caseEq (build_refined_classes (cld_def d0 c0 l5 l4) l); simpl. intros d1 c2 f3 l11 H3; rewrite H3 in H. generalize H; simpl. case (eq_nat_dec d1 d); intros. caseEq (compose_refined_mds l11 l3); intros. rewrite H4 in H0. inversion H0; subst. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H5 in H1. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H6 in H1. subst. destruct (IHl _ _ _ _ _ nil H3 H7 H2). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l11). intros; rewrite H8 in H6. destruct (gen_constr_compose_refined_mds _ _ _ _ _ _ H8 H5 H4). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H10 in H1. destruct (gen_constr_introduce_mds _ _ _ _ _ H9 H10); rewrite H11. exists _; reflexivity. auto. rewrite H7 in H1. generalize H1; clear H1; destruct c1. case (eq_nat_dec d0 d); intros; discriminate. intros; discriminate. intros; rewrite H8 in H6. discriminate. rewrite H7 in H1. discriminate. rewrite H5 in H1. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). generalize H1; clear H1; destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); destruct c1. case (eq_nat_dec d d1); intros; discriminate. intros; discriminate. case (eq_nat_dec d d1); intros; discriminate. intros; discriminate. discriminate. rewrite H4 in H0. inversion H0; subst; clear H0. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H0 in H1. subst; destruct (IHl _ _ _ _ _ nil H3 H0 H2). destruct ( fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). exists _; reflexivity. discriminate. discriminate. inversion H0; subst; clear H0. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H0 in H1. subst; destruct (IHl _ _ _ _ _ nil H3 H0 H2). destruct ( fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). exists _; auto. discriminate. discriminate. generalize H3; clear H3; destruct c0. case (eq_nat_dec d d0); intros; discriminate. intros; discriminate. discriminate. intros. inversion H7; subst. unfold gen_f_constr in H2. simpl in H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H0 in H2. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l6); intros; rewrite H1 in H2. destruct (IHl (l7 ++ l8) _ _ _ _ _ l6 _ _ _ H3 H). simpl. rewrite H0; rewrite H1. auto. rewrite H4. exists x0; auto. generalize H2; destruct c. case (eq_nat_dec d d1). intros; discriminate. destruct (match match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => match fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2 with | Some c_list' => Some (in_prog_constr (cl_dcl d1) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl'0) _ => in_prog_constr cl'0 end) l0 ++ c_list ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end with | Some c_list'' => Some (c_list'' ++ l7) | None => None (A:=list ty_constraint) end). intros; discriminate. intros; discriminate. destruct (match match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => match fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2 with | Some c_list' => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl'0) _ => in_prog_constr cl'0 end) l0 ++ c_list ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end with | Some c_list'' => Some (c_list'' ++ l7) | None => None (A:=list ty_constraint) end); intros; discriminate. discriminate. discriminate. discriminate. discriminate. elimtype False; apply H. inversion H3; subst. apply (in_path_in_prog l0 (cl_dcl dcl') (cld_def dcl' cl' fds' mds')). simpl; rewrite H1; po1. Qed. Lemma In_stmt_meth_constr : forall (s_list : list_s) (g : G) (tyc' : ty_constraint) (t_list : list ty_constraint), gen_stmt_list_constr g s_list = Some t_list -> In tyc' t_list -> (forall cl''', tyc' <> in_prog_constr cl''') /\ (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl'). intros s_list g tyc'. elim s_list using s_list_ind with (P := fun s => forall t_list', gen_stmt_constr g s = Some t_list' -> In tyc' t_list' -> (forall cl''', tyc' <> in_prog_constr cl''') /\ (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl')). simpl. intros; destruct (XMap.find (x_var var) g); inversion H; subst. simpl in H0; bd H0; subst. repeat (pa; intros); congruence. simpl. intros; destruct (XMap.find (x_var var) g); destruct (XMap.find x g); inversion H; subst. simpl in H0; bd H0; subst. repeat (pa; intros); congruence. simpl. intros; destruct (XMap.find (x_var var) g); destruct (XMap.find x g); intros; try destruct t0; inversion H; subst. simpl in H0; bd H0; subst. repeat (pa; intros); congruence. destruct t; inversion H; subst. simpl. intros; destruct (XMap.find x g); destruct (XMap.find y g); intros; try destruct t; inversion H; subst. simpl in H0; bd H0; subst. repeat (pa; intros); congruence. simpl. intros; destruct (XMap.find x g); destruct (XMap.find (x_var var) g); intros; try destruct t. destruct (fold_right (fun (y : lj_definitions.x) (m : option (list ty)) => match XMap.find y g with | Some ty' => match m with | Some m' => Some (ty' :: m') | None => None (A:=list ty) end | None => None (A:=list ty) end) (Some nil) l); inversion H; subst. simpl in H0; bd H0; subst. repeat (pa; intros); congruence. discriminate. discriminate. discriminate. simpl. intros; destruct (XMap.find x g); destruct (XMap.find y g); intros. destruct (gen_stmt_constr g s1). destruct (gen_stmt_constr g s2). inversion H1; subst; simpl in H2; bd H2. repeat (pa; intros); congruence. destruct (in_app_or _ _ _ H2). apply (H l); auto. apply (H0 l0); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros. simpl in H0. apply (H _ H0 H1); auto. simpl; intros. inversion H; subst; contradiction. intros. simpl in H1. destruct (gen_stmt_constr g s). destruct (gen_stmt_list_constr g l). inversion H1; subst. destruct (in_app_or _ _ _ H2). apply (H _ (refl_equal _) H3). apply (H0 _ (refl_equal _) H3). discriminate. discriminate. Qed. Lemma In_gen_meth_constr : forall (ty' : ty) (md' : md) (t_list : list ty_constraint) (tyc' : ty_constraint), gen_meth_constr ty' md' = Some t_list -> In tyc' t_list -> (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl'). unfold gen_meth_constr. destruct md'; destruct m; destruct m0; destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l)). caseEq ( gen_stmt_list_constr (fold_left (fun (m0 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m0) ((x_this, ty') :: map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l) (XMap.empty ty)) (make_list_s l0)). destruct (XMap.find x (fold_left (fun (m0 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m0) ((x_this, ty') :: map (fun vd' : vd => match vd' with | vd_def ty'0 var' => (x_var var', ty'0) end) l) (XMap.empty ty))). intros. inversion H0; subst; simpl in H1; bd H1. repeat (pa; intros); congruence. destruct (in_app_or _ _ _ H1). generalize H2; clear; induction l. simpl; intros; contradiction. simpl; intros; bd H2. destruct a; simpl in H2; rewrite <- H2. destruct t. repeat (pa; intros); congruence. apply IHl; auto. import (In_stmt_meth_constr _ _ _ _ H H2). bd H3. intros; discriminate. intros; discriminate. intros; discriminate. Qed. Lemma in_rcld_gen_p_subset_gen_ps : forall (ps : PSel) (l0 : list cld) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (cl'': cl) (t_list t_list' : list ty_constraint) (l : list rcld), gen_ps_constr (feature_def l l0 :: ps) = Some t_list -> gen_cld_constr (cld_def dcl' cl' fds' mds' :: nil) = Some t_list' -> In (cld_def dcl' cl' fds' mds') l0 -> In (in_prog_constr cl'') t_list' -> In (in_prog_constr cl'') t_list. induction l0. simpl; intros; contradiction. destruct a; simpl; intros. cs (cld_def d c l l1 = cld_def dcl' cl' fds' mds'). inversion H3; subst. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). destruct (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). generalize H H0; clear H H0. destruct cl'. case (eq_nat_dec dcl' d). intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')); try (intros; simpl; discriminate). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros. destruct (gen_ps_constr ps). inversion H0; inversion H; subst. simpl in H2; bd H2. apply in_or_app; po1; apply in_or_app; po2. simpl; po1. discriminate. discriminate. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po1. rewrite <- app_nil_end in H2; exact H2. discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')); try (intros; simpl; discriminate). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros. destruct (gen_ps_constr ps). inversion H0; inversion H; subst. simpl in H2; bd H2. apply in_or_app; po1; apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po1. rewrite <- app_nil_end in H2; exact H2. discriminate. intros; discriminate. discriminate. discriminate. bd H1. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H4 in H. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H5 in H. caseEq (gen_ps_constr ps); intros; rewrite H6 in H. generalize H; clear H; destruct c. case (eq_nat_dec d d0); try (intros; discriminate). destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l)); try (simpl; intros; discriminate). destruct (distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); try (simpl; intros; discriminate). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); try (simpl; intros; discriminate). simpl; intros. inversion H. import (IHl0 dcl' cl' fds' mds' cl'' ((l3 ++ l4) ++ l5) t_list' l2). simpl in H7; rewrite H4 in H7; rewrite H5 in H7; rewrite H6 in H7. destruct (match cl' with | cl_dcl dcl'' => if eq_nat_dec dcl' dcl'' then None (A:=list ty_constraint) else if distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds') then match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds' with | Some c_list => Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') (cl_dcl dcl'') :: inherited_methods_constr mds' (cl_dcl dcl'') :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) fds' ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) | cl_object => if distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds') then match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds' with | Some c_list => Some (map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) fds' ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end). import (H7 (refl_equal _) H0 H1 H2). destruct (in_app_or _ _ _ H9). destruct (in_app_or _ _ _ H10). repeat (apply in_or_app; po1). apply in_or_app; po1; repeat (apply in_or_app; po2). simpl; repeat po2; repeat (apply in_or_app; po2). apply in_or_app; po2. discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l)); try (simpl; intros; discriminate). destruct (distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); try (simpl; intros; discriminate). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); try (simpl; intros; discriminate). simpl; intros. inversion H0. fold (gen_cld_constr (cld_def dcl' cl' fds' mds' :: nil)) in H1. import (IHl0 dcl' cl' fds' mds' cl'' ((l3 ++ l4) ++ l5) t_list' l2). simpl in H7; rewrite H4 in H7; rewrite H5 in H7; rewrite H6 in H7. destruct (match cl' with | cl_dcl dcl'' => if eq_nat_dec dcl' dcl'' then None (A:=list ty_constraint) else if distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds') then match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds' with | Some c_list => Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') (cl_dcl dcl'') :: inherited_methods_constr mds' (cl_dcl dcl'') :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) fds' ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) | cl_object => if distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds') then match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds' with | Some c_list => Some (map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) fds' ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end). import (H7 (refl_equal _) H0 H1 H2). inversion H; subst. destruct (in_app_or _ _ _ H9). destruct (in_app_or _ _ _ H10). repeat (apply in_or_app; po1). apply in_or_app; po1; repeat (apply in_or_app; po2). simpl; repeat po2; repeat (apply in_or_app; po2). apply in_or_app; po2. discriminate. destruct (match match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else if distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1) then match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) | cl_object => if distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1) then match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end with | Some c_list'' => Some (c_list'' ++ l4) | None => None (A:=list ty_constraint) end with | Some c_list'' => Some (l3 ++ c_list'') | None => None (A:=list ty_constraint) end); discriminate. discriminate. discriminate. Qed. Lemma in_rcld_gen_p_subset_gen_ps_inherited : forall (ps : PSel) (l0 : list cld) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (t_list : list ty_constraint) (l : list rcld), gen_ps_constr (feature_def l l0 :: ps) = Some t_list -> In (cld_def dcl' cl' fds' mds') l0 -> In (inherited_fields_constr (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') (cl_dcl dcl')) t_list. induction l0. simpl; intros; contradiction. destruct a; intros. cs (cld_def d c l l1 = cld_def dcl' cl' fds' mds'). inversion H1; subst. simpl in *|-*. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). destruct (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). generalize H; clear H H0. destruct cl'. case (eq_nat_dec dcl' d). intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')); try (intros; simpl; discriminate). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros. destruct (gen_ps_constr ps). inversion H0; subst; clear H0. apply in_or_app; po1; apply in_or_app; po2. simpl; po2; po1. discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')); try (intros; simpl; discriminate). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros. destruct (gen_ps_constr ps). inversion H0; subst; clear H0. apply in_or_app; po1; apply in_or_app; po2. simpl; po1. discriminate. intros; discriminate. discriminate. discriminate. simpl in H0; bd H0. simpl in H. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H2 in H. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H3 in H. generalize H; clear H. destruct c. case (eq_nat_dec d d0). intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (gen_ps_constr ps); intros. inversion H5; subst; clear H5. import (IHl0 dcl' cl' fds' mds' ((l3 ++ l4) ++ l5) l2). simpl gen_ps_constr in H. simpl in H5; rewrite H2 in H5; rewrite H3 in H5; rewrite H in H5. import (H5 (refl_equal _) H0). destruct (in_app_or _ _ _ H6). destruct (in_app_or _ _ _ H7). repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po2. discriminate. intros; discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (gen_ps_constr ps); intros. inversion H; subst; clear H. import (IHl0 dcl' cl' fds' mds' ((l3 ++ l4) ++ l5) l2). simpl gen_ps_constr in H. rewrite H2 in H; rewrite H3 in H; rewrite H7 in H. import (H (refl_equal _) H0). inversion H5; subst; clear H5. destruct (in_app_or _ _ _ H6). destruct (in_app_or _ _ _ H5). repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po2. discriminate. intros; discriminate. intros; discriminate. discriminate. discriminate. Qed. Lemma in_rcld_gen_p_subset_gen_class' : forall (ps : PSel) (l0 : list cld) (cld' : cld) (t_list : list ty_constraint) (l : list rcld) (tyc' : ty_constraint), gen_ps_constr (feature_def l l0 :: ps) = Some t_list -> In cld' l0 -> exists t_list', gen_class_constr' cld' = Some t_list' /\ (In tyc' t_list' -> In tyc' t_list). induction l0. simpl; intros; contradiction. destruct a; intros. cs (cld_def d c l l1 = cld'). subst; clear H0. simpl in *|-*. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). destruct (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). revert H. destruct c. case (eq_nat_dec d d0). intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); try (intros; simpl; discriminate). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. destruct (gen_ps_constr ps). inversion H0; subst; clear H0. exists ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l ++ l5)); pa; auto. intros. apply in_or_app; po1. apply in_or_app; po2. simpl; simpl in H0; bd H0. po1. po2; po1. po2; po2; po1. po2; po2; po2; apply in_or_app; po1. discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); try (intros; simpl; discriminate). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. destruct (gen_ps_constr ps). inversion H0; subst; clear H0. exists (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l ++ l5); pa; auto. intros. apply in_or_app; po1. apply in_or_app; po2. simpl; simpl in H0; bd H0. po1. po2; po1. po2; po2; apply in_or_app; po1. discriminate. intros; discriminate. discriminate. discriminate. simpl in H0; bd H0. simpl in *|-*. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H2 in H. destruct (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). revert H. destruct c. case (eq_nat_dec d d0). intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); try (intros; simpl; discriminate). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. destruct (gen_ps_constr ps). inversion H2; subst; clear H2. import (IHl0 cld' ((l3 ++ l4) ++ l6 ) l2 tyc'). rewrite H5 in H2. inversion H3; subst. import (H2 (refl_equal _) H0); clear H2. bd H4. exists x; pa. intros; import (H4 H2). destruct (in_app_or _ _ _ H6). destruct (in_app_or _ _ _ H8). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1; apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po2. discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); try (intros; simpl; discriminate). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. destruct (gen_ps_constr ps). inversion H2; subst; clear H2. import (IHl0 cld' ((l3 ++ l4) ++ l6 ) l2 tyc'). rewrite H5 in H2. inversion H3; subst. import (H2 (refl_equal _) H0); clear H2. bd H4. exists x; pa. intros; import (H4 H2). destruct (in_app_or _ _ _ H6). destruct (in_app_or _ _ _ H8). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1; apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po2. discriminate. intros; discriminate. discriminate. discriminate. Qed. Lemma in_prog_gen_p_gen_ps : forall (ps : PSel) (dcl' dcl'' : dcl) (fds' : list fd) (mds' : list md) (t_list t_list' : list ty_constraint), get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' (cl_dcl dcl'') fds' mds') -> gen_ps_constr ps = Some t_list -> gen_cld_constr (cld_def dcl' (cl_dcl dcl'') fds' mds' :: nil) = Some t_list' -> In (in_prog_constr (cl_dcl dcl'')) t_list' -> In (in_prog_constr (cl_dcl dcl'')) t_list. induction ps. simpl; intros; discriminate. destruct a; intros. cs (In (cld_def dcl' (cl_dcl dcl'') fds' mds') l0). apply (in_rcld_gen_p_subset_gen_ps ps l0 dcl' (cl_dcl dcl'') fds' mds' (cl_dcl dcl'') _ t_list' l H0 H1 H3 H2). simpl in H; caseEq (path l0 (cl_dcl dcl')); intros; rewrite H4 in H. clear H3. caseEq (get_refined_cld ps (cl_dcl dcl')); intros; rewrite H3 in H. generalize t_list dcl' dcl'' fds' mds' c H1 H H2 H3 H4 H0; clear t_list dcl' dcl'' fds' mds' c H1 H H3 H2 H4 H0. induction l. intros. simpl in H; inversion H; subst; clear H. simpl in H0. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H in H0. caseEq (gen_ps_constr ps); intros; rewrite H5 in H0. inversion H0; apply in_or_app; po2; apply (IHps _ _ _ _ _ _ H3 H5 H1 H2). discriminate. discriminate. destruct a; intros. inversion H; clear H. destruct c0. caseEq (build_refined_classes (cld_def d0 c0 l4 l5) l); intros; rewrite H in H6. generalize H6; clear H6; simpl. case (eq_nat_dec d1 d). caseEq (compose_refined_mds l7 l3). intros; subst. simpl in H0. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H7 in H0. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H8 in H0. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H9 in H0. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0) ; intros; rewrite H10 in H0. generalize H0; clear H0. inversion H6; subst; clear H6. case (eq_nat_dec dcl' dcl''). intros; discriminate. caseEq ( gen_ps_constr ps); intros. inversion H6; subst; clear H6. simpl; po1. discriminate. inversion H6; subst; clear H6. generalize H0; clear H0. case (eq_nat_dec dcl' dcl''). intros; discriminate. intros; discriminate. inversion H6; subst; clear H6. generalize H0; clear H0. case (eq_nat_dec dcl' dcl''). intros; discriminate. intros; discriminate. inversion H6; subst; clear H6. generalize H0; clear H0. case (eq_nat_dec dcl' dcl''). intros; discriminate. intros; discriminate. inversion H6; subst; clear H6. generalize H0; clear H0. case (eq_nat_dec dcl' dcl''). intros; discriminate. intros; discriminate. intros. inversion H6; subst; clear H6. subst. generalize H0; clear H0; simpl. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). case (eq_nat_dec dcl' dcl''). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). destruct (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). destruct (gen_ps_constr ps); intros. inversion H0; subst. simpl; po1. discriminate. intros; discriminate. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst; rewrite H6 in H. simpl in H0. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H5 in H0. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H7 in H0. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H8 in H0. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H9 in H0. generalize H0; clear H0. destruct c. case (eq_nat_dec d d2). intros; discriminate. caseEq (gen_ps_constr ps); intros. inversion H0; subst; clear H0. import (IHl ((l8 ++ l11) ++ l12) _ _ _ _ (cld_def d0 c0 l4 l5) H1); auto. rewrite H in H0; rewrite H3 in H0. simpl in H0. rewrite H5 in H0; rewrite H9 in H0; rewrite H12 in H0. import (H0 (refl_equal _) H2 (refl_equal _) H4 (refl_equal _) ). inversion H10; subst; clear H10. simpl. repeat po2. generalize H11; clear; induction (map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l1 ++ l9 ++ l10). simpl; auto. simpl; intros; po2; auto. discriminate. caseEq (gen_ps_constr ps); intros. inversion H0; subst; clear H0. import (IHl ((l8 ++ l11) ++ l12) _ _ _ _ (cld_def d0 c0 l4 l5) H1); auto. rewrite H in H0; rewrite H3 in H0. simpl in H0. rewrite H5 in H0; rewrite H9 in H0; rewrite H12 in H0. import (H0 (refl_equal _) H2 (refl_equal _) H4 (refl_equal _) ). inversion H10; subst; clear H10. simpl. repeat po2. generalize H11; clear; induction (map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l1 ++ l9 ++ l10). simpl; auto. simpl; intros; po2; auto. discriminate. generalize H0; clear H0. destruct c. case (eq_nat_dec d d2). intros; discriminate. intros; discriminate. intros; discriminate. generalize H0; clear H0. destruct c. case (eq_nat_dec d d2). intros; discriminate. intros; discriminate. intros; discriminate. generalize H0; clear H0. destruct c. case (eq_nat_dec d d2). intros; discriminate. intros; discriminate. intros; discriminate. generalize H0; clear H0. destruct c. case (eq_nat_dec d d2). intros; discriminate. intros; discriminate. intros; discriminate. discriminate. elimtype False; apply H3. inversion H; subst. apply (in_path_in_prog l0 (cl_dcl dcl') (cld_def dcl' (cl_dcl dcl'') fds' mds')). rewrite H4; simpl; po1. Qed. Lemma In_introduce_fields : forall (fd' : fd) (fds' fds'' : list fd), In fd' (introduce_fields fds' fds'') -> In fd' fds'' \/ In fd' fds'. induction fds''. simpl. po2. destruct a; simpl. induction (introduce_fields fds' fds''). simpl. intros; bd H. repeat po1. destruct a; simpl. destruct t0; destruct t. case (eq_nat_dec f0 f). caseEq (cl_eq c c0); intros. import (IHfds'' H0). bd H1. po1; po2. po2. simpl in H0; bd H0. simpl in IHfds''. import (IHfds'' (or_introl _ H0)). bd H1. po1; po2. repeat po2. apply IHl. intros. apply IHfds''. simpl; po2. exact H0. intros. simpl in H; bd H. import (IHfds'' (or_introl _ H)); bd H0. po1; po2. po2. apply IHl. intros. apply IHfds''. simpl; po2. exact H. Qed. Lemma In_introduce_mds : forall (md' : md) (mds' mds'' : list md), In md' (introduce_methods mds' mds'') -> In md' mds'' \/ In md' mds'. induction mds''. simpl. po2. destruct a; simpl. induction (introduce_methods mds' mds''). simpl. intros; bd H. repeat po1. destruct a; simpl. caseEq (ms_eq m1 m); intros. simpl in H0; bd H0. repeat po1. simpl in H0; import (IHmds'' (or_intror _ H0)). bd H1. po1; po2. repeat po2. simpl in H0; bd H0. simpl in H0; import (IHmds'' (or_introl _ H0)). bd H1. po1; po2. po2. apply IHl. intros. apply IHmds''. simpl; po2. exact H0. Qed. Lemma inherit_fds_gen_p_gen_ps : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (fd' : fd) (t_list : list ty_constraint), get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds') -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> PS_distinct_fds_mds ps = true -> compose ps = Some p -> gen_ps_constr ps = Some t_list -> In fd' fds' -> exists fds', In fd' fds' /\ In (inherited_fields_constr (map (fun (fd' : fd) => match fd' with fd_def ty' f'=> f' end) fds') (cl_dcl dcl')) t_list. induction ps. simpl; intros; discriminate. destruct a; intros. cs (In (cld_def dcl' cl' fds' mds') l0). exists fds'; pa; auto. apply (in_rcld_gen_p_subset_gen_ps_inherited ps l0 dcl' cl' fds' mds' _ l H3 H5). simpl in H; caseEq (path l0 (cl_dcl dcl')); intros; rewrite H6 in H. clear H5. caseEq (get_refined_cld ps (cl_dcl dcl')); intros; rewrite H5 in H; try discriminate. simpl in H2; caseEq (compose ps); intros; rewrite H7 in H2; try discriminate; clear H2. simpl in H1; destruct (andb_prop _ _ H1); clear H2 H1. simpl in H0; import (sat_distinct_constr_app _ _ H0); clear H0. destruct c. import (get_refined_eq_self _ _ _ _ _ _ H5); subst. caseEq (gen_ps_constr ps); intros. destruct (ex_gen_ps_gen_p _ _ _ _ _ _ _ H7 H0 H1 H8 H5). assert (forall fd'', In fd'' l1 -> exists fds' : list fd, In fd'' fds' /\ In (inherited_fields_constr (map (fun fd'0 : fd => match fd'0 with | fd_def _ f' => f' end) fds') (cl_dcl d)) l3). intros. exact (IHps _ _ _ _ _ _ _ H5 H1 H8 H7 H0 H9). inversion H; subst; clear x p0 IHps H7 H8 H1 H2 H. revert t_list d c fds' mds' l1 l2 H3 H4 H6 H5 H0 H9 H11; clear. induction l. intros. simpl in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H in H3. rewrite H0 in H3; inversion H3; subst; clear H3. simpl in H11; inversion H11; subst. import (H9 _ H4). bd H1. exists x; pa. apply in_or_app; po2. discriminate. destruct a; intros. caseEq (build_refined_classes (cld_def d0 c0 l5 l6) l); intros; simpl in H11; rewrite H in H11. import (build_refined_self _ _ _ _ _ _ _ _ _ H); subst. generalize H11; clear H11; simpl; case (eq_nat_dec d1 d). caseEq (compose_refined_mds l8 l4). intros; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H7 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros; rewrite H8 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H10 in H3. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. rewrite H0; intros. inversion H3; subst; clear H3. cs (In fd' l1). exists l1; pa; auto. simpl; po2; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l8 l10 l7 l1 c0 c1 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ H11). bd H0; exists x; pa. repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros l8 l10 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 l5 l6) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f' l9; subst; case (compose_refined_mds l9 l4). intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst. simpl in H2. inversion H2; subst; clear H2; revert H4. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c. case (eq_nat_dec d1 d2). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros; inversion H4; subst; clear H4. inversion H0; subst; clear H0. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H0 H4). import (IHl _ _ _ _ _ _ H0 H4 H2 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H4; subst; clear H4. simpl. inversion H0; subst; clear H0. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H0 H4). import (IHl _ _ _ _ _ _ H0 H4 H2 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). simpl in H2; revert H2. destruct c. case (eq_nat_dec d1 d3). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H2. simpl in H2; bd H2. discriminate. exists x; pa. simpl; po2; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H2). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. exists x; pa; simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. exists x; pa; simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. exists x; pa; simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po2. exists x; pa; simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. inversion H0; subst; clear H0. import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H0. exists x; pa; simpl. simpl in H0; bd H0. discriminate. po2; po1. discriminate. destruct (in_app_or _ _ _ H0). destruct (in_app_or _ _ _ H2); clear H2. destruct (in_app_or _ _ _ H4); clear H4. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. discriminate. rewrite H0. simpl. intros H11; inversion H11; subst; clear H11. cs (In fd' l1). exists l1; pa; auto. simpl; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l8 l10 l7 l1 c0 c1 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ H11). bd H0; exists x; pa. repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros l8 l10 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 l5 l6) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f' l9; subst; case (compose_refined_mds l9 l4). intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). destruct ( fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). generalize H2; clear H2; destruct c. case (eq_nat_dec d0 d2). intros; discriminate. intros. inversion H2. bd H1; exists x; pa. simpl in H1; bd H1. simpl; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H1). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. simpl; apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros. inversion H2. bd H1; exists x; pa. simpl in H1; bd H1. simpl; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H1). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. simpl; apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. destruct c; generalize H2; clear H2. case (eq_nat_dec d0 d2); intros; discriminate. intros; discriminate. destruct c; generalize H2; clear H2. case (eq_nat_dec d0 d2); intros; discriminate. intros; discriminate. discriminate. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. discriminate. intros; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H7 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros; rewrite H8 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H10 in H3. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. rewrite H0; intros. inversion H3; subst; clear H3. cs (In fd' l1). exists l1; pa; auto. simpl; po2; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l1 mds' l5 l7 c0 c1 l9 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ H11). bd H0; exists x; pa. repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros l5 mds' f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f2 l6) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' l7 l8; subst; case (compose_refined_mds l8 l4). intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst. simpl in H2. inversion H2; subst; clear H2; revert H4. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c. case (eq_nat_dec d1 d2). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros; inversion H4; subst; clear H4. inversion H0; subst; clear H0. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H0 H4). import (IHl _ _ _ _ _ _ _ H0 H4 H2 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H4; subst; clear H4. simpl. inversion H0; subst; clear H0. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H0 H4). import (IHl _ _ _ _ _ _ _ H0 H4 H2 H H9). bd H5. simpl in H5; bd H5. discriminate. inversion H5. exists x; pa. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. discriminate H5. exists x; pa; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). simpl in H2; revert H2. destruct c. case (eq_nat_dec d1 d3). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H2. simpl in H2; bd H2. discriminate. exists x; pa. simpl; po2; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H2). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. exists x; pa; simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. exists x; pa; simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. exists x; pa; simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po2. exists x; pa; simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. inversion H0; subst; clear H0. import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H0. exists x; pa; simpl. simpl in H0; bd H0. discriminate. po2; po1. discriminate. destruct (in_app_or _ _ _ H0). destruct (in_app_or _ _ _ H2); clear H2. destruct (in_app_or _ _ _ H4); clear H4. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. discriminate. rewrite H0. simpl. intros H11; inversion H11; subst; clear H11. cs (In fd' l1). exists l1; pa; auto. simpl; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l1 mds' l6 l7 c0 c1 l9 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ H11). bd H0; exists x; pa. repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros l6 mds' f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 l5 f2) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f' l8; subst; case (compose_refined_mds l8 l4). intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). intros. inversion H2; subst; clear H2. simpl. cs (In fd' l0). exists l0; pa; auto; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po1. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H3 H4 H1 H H9). bd H5. exists x; pa. simpl in H5; bd H5. simpl; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. discriminate H5. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. simpl. apply in_or_app; po1. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). destruct ( fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4). generalize H2; clear H2; destruct c. case (eq_nat_dec d0 d2). intros; discriminate. intros. inversion H2. bd H1; exists x; pa. simpl in H1; bd H1. simpl; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H1). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. simpl; apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros. inversion H2. bd H1; exists x; pa. simpl in H1; bd H1. simpl; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H1). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. simpl; apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. destruct c; generalize H2; clear H2. case (eq_nat_dec d0 d2); intros; discriminate. intros; discriminate. destruct c; generalize H2; clear H2. case (eq_nat_dec d0 d2); intros; discriminate. intros; discriminate. discriminate. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. discriminate. intros. rewrite H11 in H. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros. rewrite H1 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H2 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l4); intros; rewrite H7 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H8 in H3. generalize H3; clear H3. inversion H11; subst; clear H11. destruct c. case (eq_nat_dec d d0). intros; discriminate. rewrite H0. intros. inversion H3; subst; clear H3. import (IHl ((l9 ++ l12) ++ l3) d1 c0 fds' mds' l5 l6). simpl in H3; rewrite H0 in H3; rewrite H8 in H3; rewrite H1 in H3. import (H3 (refl_equal _) H4 H6 H5 (refl_equal _) H9 H). bd H10. exists x; pa. simpl; repeat po2. destruct (in_app_or _ _ _ H10). destruct (in_app_or _ _ _ H11); clear H11. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. rewrite H0. intros. inversion H3; subst; clear H3. import (IHl ((l9 ++ l12) ++ l3) d1 c0 fds' mds' l5 l6). simpl in H3; rewrite H0 in H3; rewrite H8 in H3; rewrite H1 in H3. import (H3 (refl_equal _) H4 H6 H5 (refl_equal _) H9 H). bd H10. exists x; pa. simpl; repeat po2. destruct (in_app_or _ _ _ H10). destruct (in_app_or _ _ _ H11); clear H11. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. destruct (match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l1) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l1 ++ l10 ++ l11) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l1) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) l1 ++ l10 ++ l11) end with | Some c_list'' => Some (c_list'' ++ l9) | None => None (A:=list ty_constraint) end). discriminate. discriminate. generalize H3; clear H3. destruct c. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. generalize H3; clear H3. destruct c. case (eq_nat_dec d d0). intros; discriminate. intros; discriminate. intros; discriminate. rewrite H1 in H3. discriminate. simpl in H3; rewrite H0 in H3. destruct (match fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l with | Some c_list' => match fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0 with | Some c_list'' => Some (c_list' ++ c_list'') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. elimtype False; apply H5. inversion H; subst. apply (in_path_in_prog l0 (cl_dcl dcl') (cld_def dcl' cl' fds' mds')). rewrite H6; simpl; po1. Qed. Definition fds := list fd. Lemma inherit_mds_gen_p_gen_ps : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' : cl) (fds' : fds) (mds' : list md) (ms' : ms) (mb' : mb) (t_list : list ty_constraint), get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds') -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> PS_distinct_fds_mds ps = true -> compose ps = Some p -> gen_ps_constr ps = Some t_list -> In (md_def ms' mb') mds' -> exists mb'', exists mds'', In (md_def ms' mb'') mds'' /\ In (inherited_methods_constr mds'' (cl_dcl dcl')) t_list. induction ps. simpl; intros; discriminate. destruct a; intros. cs (In (cld_def dcl' cl' fds' mds') l0). exists mb'; exists mds'; pa; auto. import (in_rcld_gen_p_subset_gen_class' _ _ _ _ _ (inherited_methods_constr mds' (cl_dcl dcl')) H3 H5). bd H6; apply H6; revert H9; simpl; destruct cl'. case (eq_nat_dec dcl' d); try (intros; discriminate). destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros; inversion H9. simpl; po2; po2; po1. intros; discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros; inversion H9. simpl; po2; po1. intros; discriminate. intros; discriminate. simpl in H; caseEq (path l0 (cl_dcl dcl')); intros; rewrite H6 in H. clear H5. caseEq (get_refined_cld ps (cl_dcl dcl')); intros; rewrite H5 in H; try discriminate. simpl in H2; caseEq (compose ps); intros; rewrite H7 in H2; try discriminate; clear H2. simpl in H1; destruct (andb_prop _ _ H1); clear H2 H1. simpl in H0; import (sat_distinct_constr_app _ _ H0); clear H0. destruct c. import (get_refined_eq_self _ _ _ _ _ _ H5); subst. caseEq (gen_ps_constr ps); intros. destruct (ex_gen_ps_gen_p _ _ _ _ _ _ _ H7 H0 H1 H8 H5). rename l1 into f0; rename l2 into l1; rename l3 into l2. assert (forall ms'' m, In (md_def ms'' m) l1 -> exists mb'': mb, exists mds'' : list md, In (md_def ms'' mb'') mds'' /\ In (inherited_methods_constr mds'' (cl_dcl d)) l2). intros. exact (IHps _ _ _ _ _ _ _ _ H5 H1 H8 H7 H0 H9). inversion H; clear x p0 IHps H7 H8 H1 H2 H. revert t_list d c cl' fds' mds' f0 l1 H3 H4 H6 H5 H0 H9 H11; clear. induction l. intros. simpl in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H in H3. rewrite H0 in H3; inversion H3; subst; clear H3. simpl in H11; inversion H11; subst. import (H9 _ _ H4). bd H1. exists x; exists x0; pa. apply in_or_app; po2. discriminate. destruct a; intros. rename l1 into f; rename l3 into l1; rename l4 into l3; rename l5 into l4. simpl in H11. caseEq (build_refined_classes (cld_def d0 c0 f0 l4) l); intros; simpl in H11; rewrite H in H11. import (build_refined_self _ _ _ _ _ _ _ _ _ H); subst. generalize H11; clear H11; simpl; case (eq_nat_dec d1 d). rename l5 into f1; rename l6 into l5. caseEq (compose_refined_mds l5 l3). intros; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); intros; rewrite H7 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H8 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H10 in H3. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. rewrite H0; intros. inversion H3; subst; clear H3. cs (In (md_def ms' mb') l1). exists mb'; exists l1; pa; auto. simpl; po2; po2; po1. destruct (In_introduce_mds _ _ _ H4). elimtype False; apply (H3 H11). assert (exists m, In (md_def ms' m) l5). generalize mb' l6 H11 H1; clear. induction l3. simpl. intros; exists mb'; congruence. destruct a; simpl. caseEq (compose_refined_mds l5 l3); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H1 H11). destruct (IHl3 _ _ H0 H). exists x0; exact H2. discriminate. bd H12. clear H11; rename H12 into H11. generalize x l7 l5 l4 l3 l6 f0 f f1 l1 c0 c1 H3 H11 H2 H H9 H1; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ _ H11). bd H0; exists x0; exists x1; pa. repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros until c1; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). rename l0 into f2; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4; rename l6 into l5; rename l7 into l6; rename l8 into l7; rename l9 into l8; rename l10 into l9; rename l11 into l10; rename l12 into l11. rename l1 into tycl; rename l2 into l1. intros until l12; subst; rename l2 into f3; caseEq (compose_refined_mds l12 l1). intros. inversion H1; subst; clear H1. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. simpl. cs (exists x, In (md_def ms' x) l0). bd H5. exists x0; exists l0; pa; auto. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po2; po1. bd H5. destruct (In_introduce_mds _ _ _ H11). elimtype False; apply (H5 _ H6). assert (exists m, In (md_def ms' m) l12). generalize x l2 H6 H; clear. induction l1. simpl. intros; exists x; congruence. destruct a; simpl. caseEq (compose_refined_mds l12 l1); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H0 H6). destruct (IHl1 _ _ H1 H). exists x1; exact H2. discriminate. bd H7. import (IHl _ _ _ _ _ _ _ f _ _ _ _ (H5 mb') H7 H2 H0 H9 H). bd H8. exists x1; exists x2; pa. simpl in H8; bd H8. discriminate. discriminate. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po2; po2; po1. repeat po2. destruct (in_app_or _ _ _ H8); clear H8. destruct (in_app_or _ _ _ H10); clear H10. destruct (in_app_or _ _ _ H8); clear H8. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. simpl. cs (exists x, In (md_def ms' x) l0). bd H5. exists x0; exists l0; pa; auto. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. bd H5. destruct (In_introduce_mds _ _ _ H11). elimtype False; apply (H5 _ H6). assert (exists m, In (md_def ms' m) l12). generalize x l2 H6 H; clear. induction l1. simpl. intros; exists x; congruence. destruct a; simpl. caseEq (compose_refined_mds l12 l1); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H0 H6). destruct (IHl1 _ _ H1 H). exists x1; exact H2. discriminate. bd H7. import (IHl _ _ _ _ _ _ _ f _ _ _ _ (H5 mb') H7 H2 H0 H9 H). bd H8. exists x1; exists x2; pa. simpl in H8; bd H8. discriminate. discriminate. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po2; po1. repeat po2. destruct (in_app_or _ _ _ H8); clear H8. destruct (in_app_or _ _ _ H10); clear H10. destruct (in_app_or _ _ _ H8); clear H8. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. revert H2; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). inversion H1; subst; clear H1. destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H0 H9 H4). bd H5; exists x0; exists x1; simpl in H5; simpl; pa; bd H5. discriminate. discriminate. po2; po2; po1. repeat po2; destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H5); clear H5. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H0 H9 H4). bd H5; exists x0; exists x1; simpl in H5; simpl; pa; bd H5. discriminate. discriminate. po2; po2; po1. repeat po2; destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H5); clear H5. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. revert H2; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). inversion H0; subst; clear H0. destruct c. case (eq_nat_dec d1 d2). intros; discriminate. rename l0 into f2; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4; rename l6 into l5; rename l7 into l6; rename l8 into l7; rename l9 into l8; rename l10 into l9; rename l11 into l10; rename l12 into l11. rename l1 into tycl; rename l2 into l1. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H4; subst; clear H4. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H H9 H1). bd H4; exists x0; exists x1; simpl in H4; simpl; pa; bd H4. discriminate. discriminate. po2; po2; po1. repeat po2; destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H4); clear H4. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. rename l0 into f2; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4; rename l6 into l5; rename l7 into l6; rename l8 into l7; rename l9 into l8; rename l10 into l9; rename l11 into l10; rename l12 into l11. rename l1 into tycl; rename l2 into l1. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H4; subst; clear H4. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H H9 H1). bd H4; exists x0; exists x1; simpl in H4; simpl; pa; bd H4. discriminate. discriminate. po2; po2; po1. repeat po2; destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H4); clear H4. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. rewrite H0. intros. inversion H3; subst; clear H3. cs (In (md_def ms' mb') l1). exists mb'; exists l1; pa; auto. simpl; po2; po1. destruct (In_introduce_mds _ _ _ H4). elimtype False; apply (H3 H11). assert (exists m, In (md_def ms' m) l5). generalize mb' l6 H11 H1; clear. induction l3. simpl. intros; exists mb'; congruence. destruct a; simpl. caseEq (compose_refined_mds l5 l3); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H1 H11). destruct (IHl3 _ _ H0 H). exists x0; exact H2. discriminate. bd H12. clear H11; rename H12 into H11. generalize x l7 l5 l4 l3 l6 f0 f f1 l1 c0 c1 H3 H11 H2 H H9 H1; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ _ H11). bd H0; exists x0; exists x1; pa. repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros until c1; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). rename l0 into f2; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4; rename l6 into l5; rename l7 into l6; rename l8 into l7; rename l9 into l8; rename l10 into l9; rename l11 into l10; rename l12 into l11. rename l1 into tycl; rename l2 into l1. intros until l12; subst; caseEq (compose_refined_mds l12 l1). intros. inversion H1; subst; clear H1. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. simpl. cs (exists x, In (md_def ms' x) l0). bd H5. exists x0; exists l0; pa; auto. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po2; po1. bd H5. destruct (In_introduce_mds _ _ _ H11). elimtype False; apply (H5 _ H6). assert (exists m, In (md_def ms' m) l12). generalize x l13 H6 H; clear. induction l1. simpl. intros; exists x; congruence. destruct a; simpl. caseEq (compose_refined_mds l12 l1); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H0 H6). destruct (IHl1 _ _ H1 H). exists x1; exact H2. discriminate. bd H7. import (IHl _ _ _ _ _ _ _ f _ _ _ _ (H5 mb') H7 H2 H0 H9 H). bd H8. exists x1; exists x2; pa. simpl in H8; bd H8. discriminate. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po2; po2; po1. repeat po2. destruct (in_app_or _ _ _ H8); clear H8. destruct (in_app_or _ _ _ H10); clear H10. destruct (in_app_or _ _ _ H8); clear H8. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. simpl. cs (exists x, In (md_def ms' x) l0). bd H5. exists x0; exists l0; pa; auto. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. po2; po1. bd H5. destruct (In_introduce_mds _ _ _ H11). elimtype False; apply (H5 _ H6). assert (exists m, In (md_def ms' m) l12). generalize x l13 H6 H; clear. induction l1. simpl. intros; exists x; congruence. destruct a; simpl. caseEq (compose_refined_mds l12 l1); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H0 H6). destruct (IHl1 _ _ H1 H). exists x1; exact H2. discriminate. bd H7. import (IHl _ _ _ _ _ _ _ f _ _ _ _ (H5 mb') H7 H2 H0 H9 H). bd H8. exists x1; exists x2; pa. simpl in H8; bd H8. discriminate. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; po2; po1. repeat po2. destruct (in_app_or _ _ _ H8); clear H8. destruct (in_app_or _ _ _ H10); clear H10. destruct (in_app_or _ _ _ H8); clear H8. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. revert H2; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). inversion H1; subst; clear H1. destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H0 H9 H4). bd H5; exists x0; exists x1; simpl in H5; simpl; pa; bd H5. discriminate. po2; po1. repeat po2; destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H5); clear H5. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H5; subst; clear H5. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H0 H9 H4). bd H5; exists x0; exists x1; simpl in H5; simpl; pa; bd H5. discriminate. po2; po1. repeat po2; destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H5); clear H5. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. revert H2; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). inversion H0; subst; clear H0. destruct c. case (eq_nat_dec d0 d1). intros; discriminate. rename l0 into f2; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4; rename l6 into l5; rename l7 into l6; rename l8 into l7; rename l9 into l8; rename l10 into l9; rename l11 into l10; rename l12 into l11; rename l1 into tycl; rename l2 into l1. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H4; subst; clear H4. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H H9 H1). bd H4; exists x0; exists x1; simpl in H4; simpl; pa; bd H4. discriminate. po2; po1. repeat po2; destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H4); clear H4. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. rename l0 into f2; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4; rename l6 into l5; rename l7 into l6; rename l8 into l7; rename l9 into l8; rename l10 into l9; rename l11 into l10; rename l12 into l11; rename l1 into tycl; rename l2 into l1. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). intros. inversion H4; subst; clear H4. import (IHl _ _ _ _ _ _ _ f _ _ _ _ H3 H11 H2 H H9 H1). bd H4; exists x0; exists x1; simpl in H4; simpl; pa; bd H4. discriminate. po2; po1. repeat po2; destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. destruct (in_app_or _ _ _ H4); clear H4. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. destruct (match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f ++ l8 ++ l9) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f ++ l8 ++ l9) end with | Some c_list'' => Some (c_list'' ++ l7) | None => None (A:=list ty_constraint) end); discriminate. revert H3; destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. revert H3; destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. discriminate. intros. inversion H11; subst; clear H11. revert H3; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct cl'. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H0 in H10. inversion H10. subst; clear H10. simpl. import (IHl ((l8 ++ l7) ++ l2) d c0 c1 f1 mds' f0 l4). simpl in H10; rewrite H8 in H10; rewrite H7 in H10; rewrite H0 in H10. import (H10 (refl_equal _) H4 H6 H5 (refl_equal _ ) H9 H); bd H11. exists x; exists x0; pa; simpl; repeat po2. destruct (in_app_or _ _ _ H11); clear H11. destruct (in_app_or _ _ _ H12); clear H12. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H0 in H10. inversion H10. subst; clear H10. simpl. import (IHl ((l8 ++ l7) ++ l2) d c0 c1 f1 mds' f0 l4). simpl in H10; rewrite H8 in H10; rewrite H7 in H10; rewrite H0 in H10. import (H10 (refl_equal _) H4 H6 H5 (refl_equal _ ) H9 H); bd H11. exists x; exists x0; pa; simpl; repeat po2. destruct (in_app_or _ _ _ H11); clear H11. destruct (in_app_or _ _ _ H12); clear H12. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. discriminate. destruct cl'; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. destruct cl'. case (eq_nat_dec d d0); try (intros; discriminate). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros; discriminate. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros; discriminate. intros; discriminate. intros; discriminate. intros; discriminate. intros. inversion H11; subst; clear H11. revert H3; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct c. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H0 in H8. inversion H8; subst; clear H8. import (IHl ((l8 ++ l7) ++ l2) d1 c0 cl' fds' mds' f0 l4). simpl in H8; rewrite H3 in H8; rewrite H7 in H8; rewrite H0 in H8. import (H8 (refl_equal _) H4 H6 H5 (refl_equal _ ) H9 H); bd H10. exists x; exists x0; pa; simpl; repeat po2. destruct (in_app_or _ _ _ H10); clear H10. destruct (in_app_or _ _ _ H11); clear H11. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H0 in H8. inversion H8; subst; clear H8. simpl. import (IHl ((l8 ++ l7) ++ l2) d1 c0 cl' fds' mds' f0 l4). simpl in H8; rewrite H3 in H8; rewrite H7 in H8; rewrite H0 in H8. import (H8 (refl_equal _) H4 H6 H5 (refl_equal _ ) H9 H); bd H10. exists x; exists x0; pa; simpl; repeat po2. destruct (in_app_or _ _ _ H10); clear H10. destruct (in_app_or _ _ _ H11); clear H11. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. discriminate. destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. destruct c. case (eq_nat_dec d d0); try (intros; discriminate). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros; discriminate. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros; discriminate. intros; discriminate. intros; discriminate. intros; discriminate. simpl in H3; rewrite H0 in H3. destruct (match fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l with | Some c_list' => match fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0 with | Some c_list'' => Some (c_list' ++ c_list'') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). discriminate. discriminate. elimtype False; apply H5. inversion H; subst. apply (in_path_in_prog l0 (cl_dcl dcl') (cld_def dcl' cl' fds' mds')). rewrite H6; simpl; po1. Qed. Lemma in_prog_fds_gen_p_gen_ps : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' cl'': cl) (fds' : list fd) (mds' : list md) (f' : f) (t_list : list ty_constraint), get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds') -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> PS_distinct_fds_mds ps = true -> compose ps = Some p -> gen_ps_constr ps = Some t_list -> In (fd_def (ty_def cl'') f') fds' -> In (in_prog_constr cl'') t_list. induction ps. simpl; intros; discriminate. destruct a; intros. cs (In (cld_def dcl' cl' fds' mds') l0). import (in_rcld_gen_p_subset_gen_class' _ _ _ _ _ (in_prog_constr cl'') H3 H5). bd H6; apply H6; revert H9; simpl; destruct cl'. case (eq_nat_dec dcl' d); try (intros; discriminate). destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros; inversion H9. simpl; repeat po2. revert H4; clear; induction fds'. simpl; intros; contradiction. destruct a; simpl; intros. bd H4; subst. inversion H4; subst; clear H4. po1. po2; auto. intros; discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros; inversion H9; subst. simpl; repeat po2. apply in_or_app. po1. revert H4; clear; induction fds'. simpl; intros; contradiction. destruct a; simpl; intros. bd H4; subst. inversion H4; subst; clear H4. po1. po2; auto. intros; discriminate. intros; discriminate. simpl in H; caseEq (path l0 (cl_dcl dcl')); intros; rewrite H6 in H. clear H5. caseEq (get_refined_cld ps (cl_dcl dcl')); intros; rewrite H5 in H; try discriminate. simpl in H2; caseEq (compose ps); intros; rewrite H7 in H2; try discriminate; clear H2. simpl in H1; destruct (andb_prop _ _ H1); clear H2 H1. simpl in H0; import (sat_distinct_constr_app _ _ H0); clear H0. destruct c. import (get_refined_eq_self _ _ _ _ _ _ H5); subst. caseEq (gen_ps_constr ps); intros. rename l1 into f; rename l2 into l1; rename l3 into l2. destruct (ex_gen_ps_gen_p _ _ _ _ _ _ _ H7 H0 H1 H8 H5). assert (forall cl'' f', In (fd_def (ty_def cl'') f') f -> In (in_prog_constr cl'') l2). intros. exact (IHps _ _ _ _ _ _ _ _ H5 H1 H8 H7 H0 H9). inversion H; clear x p0 IHps H7 H8 H1 H2 H. revert t_list d c cl' fds' mds' f l1 H3 H4 H6 H5 H0 H9 H11; clear. induction l. intros. simpl in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H in H3. rewrite H0 in H3; inversion H3; subst; clear H3. simpl in H11; inversion H11; subst. import (H9 _ _ H4). apply in_or_app; po2. discriminate. destruct a; intros. rename l1 into f0; rename l2 into tyc; rename l3 into l1; rename l4 into l3; rename l5 into l4. caseEq (build_refined_classes (cld_def d0 c0 f l4) l); intros; simpl in H11; rewrite H in H11. import (build_refined_self _ _ _ _ _ _ _ _ _ H); subst. generalize H11; clear H11; simpl; case (eq_nat_dec d1 d). caseEq (compose_refined_mds l5 l3). intros; subst. simpl in H3. rename l2 into f1. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); intros; rewrite H7 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H8 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H10 in H3. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. rewrite H0; intros. inversion H3; subst; clear H3. cs (In (fd_def (ty_def cl'') f') f0). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear. induction f0; simpl; intros. contradiction. bd H3; subst. po1. po2; auto. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l2 l5 f0 f1 c0 c1 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ _ H11). repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. rename l0 into f1; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3. intros tcl' l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f l3) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f'' l6; subst; case (compose_refined_mds l6 l2). intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst. simpl in H2. inversion H0; subst; clear H0; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. simpl; po2. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). simpl in H2; revert H2. destruct c. case (eq_nat_dec d1 d3). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H2. simpl in H2; bd H2. simpl; po1. discriminate. discriminate. destruct (in_app_or _ _ _ H2). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. simpl; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. inversion H0; subst; clear H0. import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). simpl in H0; bd H0. simpl; po1. discriminate. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H0). destruct (in_app_or _ _ _ H2); clear H2. destruct (in_app_or _ _ _ H4); clear H4. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. discriminate. rewrite H0. simpl. intros H11; inversion H11; subst; clear H11. cs (In (fd_def (ty_def cl'') f') f0). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear; induction f0. simpl; intros; contradiction. destruct a; simpl; intros. bd H3. inversion H3; po1. po2; auto. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l2 l5 f0 f1 c0 c1 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ _ H11). repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. rename l0 into f1; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3. intros tcl' l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f l3) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f'' l6; subst; case (compose_refined_mds l6 l2). intros. inversion H0; subst; clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst. simpl in H2. inversion H0; subst; clear H0; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. simpl; po2. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). simpl in H2; revert H2. destruct c. case (eq_nat_dec d0 d2). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H2. simpl in H2; bd H2. simpl; po1. discriminate. destruct (in_app_or _ _ _ H2). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. simpl; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. inversion H0; subst; clear H0. import (IHl _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). simpl in H0; bd H0. simpl; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H0). destruct (in_app_or _ _ _ H2); clear H2. destruct (in_app_or _ _ _ H4); clear H4. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. discriminate. destruct (match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l7 ++ l8) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l7 ++ l8) end with | Some c_list'' => Some (c_list'' ++ l2) | None => None (A:=list ty_constraint) end). discriminate. discriminate. revert H3; destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. revert H3; destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. discriminate. intros; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1); intros; rewrite H7 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H8 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H10 in H3. generalize H3; clear H3. inversion H11; subst; clear H11. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. rewrite H0; intros. inversion H3; subst; clear H3. cs (In (fd_def (ty_def cl'') f') f0). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear. induction f0; simpl; intros. contradiction. bd H3; subst. po1. po2; auto. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l6 l2 mds' f0 f c0 c1 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ _ H11). repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. rename l0 into f1; rename l1 into l0; rename l2 into l1; rename l3 into l2; rename l4 into l3. intros tcl' l6 mds' f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f3 l3) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f'' l10; subst; case (compose_refined_mds l10 l2). intros. inversion H0; subst. clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst. simpl in H2. inversion H0; subst; clear H0; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d1). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. simpl; po2. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f1). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f1. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). simpl in H2; revert H2. destruct c. case (eq_nat_dec d1 d3). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H2. simpl in H2; bd H2. simpl; po1. discriminate. discriminate. destruct (in_app_or _ _ _ H2). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. simpl; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d1)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d1)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). intros. inversion H2; subst; clear H2. inversion H0; subst; clear H0. import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). simpl in H0; bd H0. simpl; po1. discriminate. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H0). destruct (in_app_or _ _ _ H2); clear H2. destruct (in_app_or _ _ _ H4); clear H4. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. discriminate. rewrite H0. simpl. intros H11; inversion H11; subst; clear H11. cs (In (fd_def (ty_def cl'') f') f0). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear; induction f0. simpl; intros; contradiction. destruct a; simpl; intros. bd H3. inversion H3; po1. po2; auto. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l6 l2 mds' f0 f c0 c1 H3 H11 H2 H H9; clear. induction l. simpl; intros. inversion H; subst. import (H9 _ _ H11). repeat po2. apply in_or_app; po2. destruct a; simpl build_refined_classes. intros until c0; caseEq (build_refined_classes (cld_def d c0 f l4) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f1 l11; subst; case (compose_refined_mds l11 l3). intros. inversion H0; subst. clear H0. simpl in H2; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros. inversion H2; subst; clear H2. simpl. rename l0 into f2. cs (In (fd_def (ty_def cl'') f') f2). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f2. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros. inversion H2; subst; clear H2. simpl. rename l0 into f2. cs (In (fd_def (ty_def cl'') f') f2). repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; repeat (apply in_or_app; po1). revert H2; clear; induction f2. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros; subst. simpl in H2. inversion H0; subst; clear H0; revert H2. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct c1. case (eq_nat_dec d d0). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros; inversion H2; subst; clear H2. rename l0 into f2. cs (In (fd_def (ty_def cl'') f') f2). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl. simpl; po2. repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f2. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros. inversion H2; subst; clear H2. simpl. rename l0 into f2. cs (In (fd_def (ty_def cl'') f') f2). simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). revert H2; clear; induction f2. simpl; intros; contradiction. destruct a; simpl; intros. bd H2. inversion H2; po1. po2; auto. destruct (In_introduce_fields _ _ _ H11). elimtype False; apply (H2 H4). import (IHl _ _ _ _ _ _ _ H2 H4 H1 H H9). simpl in H5; bd H5. simpl; po1. discriminate. discriminate. repeat po2. destruct (in_app_or _ _ _ H5). destruct (in_app_or _ _ _ H6); clear H6. destruct (in_app_or _ _ _ H7); clear H7. destruct (in_app_or _ _ _ H6); clear H6. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. repeat (apply in_or_app; po1). apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. intros; discriminate. intros. rewrite H0 in H. simpl in H2. destruct (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). simpl in H2; revert H2. destruct c. case (eq_nat_dec d0 d2). intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros. inversion H2; subst; clear H2. import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). bd H2. simpl in H2; bd H2. simpl; po1. discriminate. destruct (in_app_or _ _ _ H2). destruct (in_app_or _ _ _ H4); clear H4. destruct (in_app_or _ _ _ H5); clear H5. simpl; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d0)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2). caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d0)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3). intros. inversion H2; subst; clear H2. inversion H0; subst; clear H0. import (IHl _ _ _ _ _ _ _ H3 H11 (refl_equal _) H H9). simpl in H0; bd H0. simpl; po1. discriminate. simpl; repeat po2. destruct (in_app_or _ _ _ H0). destruct (in_app_or _ _ _ H2); clear H2. destruct (in_app_or _ _ _ H4); clear H4. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po1. repeat po2. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2. simpl; repeat po2. apply in_or_app; po2. repeat po2. apply in_or_app; po1. apply in_or_app; po2. repeat po2. apply in_or_app; po2. intros; discriminate. intros; discriminate. discriminate. simpl. destruct (match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l7 ++ l8) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l7 ++ l8) end with | Some c_list'' => Some (c_list'' ++ l6) | None => None (A:=list ty_constraint) end). discriminate. discriminate. revert H3; destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. revert H3; destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. discriminate. intros. subst. revert H3; simpl. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct c. case (eq_nat_dec d d0). intros; discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H0 in H8. inversion H8; subst; clear H8. import (IHl ((l9 ++ l8) ++ tyc) d1 c0 c1 fds' l5 f l4). simpl in H8; rewrite H3 in H8; rewrite H7 in H8; rewrite H0 in H8. inversion H; subst; clear H. inversion H11; subst; clear H11. import (H8 (refl_equal _) H4 H6 H5 (refl_equal _ ) H9 H12); bd H10. simpl; repeat po2. destruct (in_app_or _ _ _ H); clear H. destruct (in_app_or _ _ _ H10); clear H10. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. rewrite H0 in H8. inversion H8; subst; clear H8. simpl. import (IHl ((l9 ++ l8) ++ tyc) d1 c0 c1 fds' l5 f l4). simpl in H8; rewrite H3 in H8; rewrite H7 in H8; rewrite H0 in H8. inversion H; subst; clear H. inversion H11; subst; clear H11. import (H8 (refl_equal _) H4 H6 H5 (refl_equal _ ) H9 H12); bd H10. simpl; repeat po2. destruct (in_app_or _ _ _ H); clear H. destruct (in_app_or _ _ _ H10); clear H10. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. discriminate. destruct c; try (intros; discriminate); case (eq_nat_dec d d0); intros; discriminate. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros. destruct ( match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ c_list ++ l6) | None => None (A:=list ty_constraint) end | cl_object => match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some c_list => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l1 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ c_list ++ l6) | None => None (A:=list ty_constraint) end end with | Some c_list'' => Some (c_list'' ++ l7) | None => None (A:=list ty_constraint) end). discriminate. discriminate. destruct (match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some _ => None (A:=list ty_constraint) | None => None (A:=list ty_constraint) end | cl_object => match fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1 with | Some _ => None (A:=list ty_constraint) | None => None (A:=list ty_constraint) end end with | Some c_list'' => Some (c_list'' ++ l6) | None => None (A:=list ty_constraint) end). discriminate. discriminate. intros; discriminate. simpl in H3; rewrite H0 in H3. destruct (match fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l with | Some c_list' => match fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0 with | Some c_list'' => Some (c_list' ++ c_list'') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end). discriminate. discriminate. elimtype False; apply H5. inversion H; subst. apply (in_path_in_prog l0 (cl_dcl dcl') (cld_def dcl' cl' fds' mds')). rewrite H6; simpl; po1. Qed. Lemma In_fold_meth_constr : forall (dcl' : dcl) (mds' : list md) (tyc' : ty_constraint) (md' : md) (t_list t_list' : list ty_constraint), gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list' -> In tyc' t_list' -> In md' mds' -> fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds' = Some t_list -> In tyc' t_list. induction mds'. simpl; intros; contradiction. intros; simpl in H1; bd H1; subst. simpl in H2; destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'); revert H2. rewrite H. intros. inversion H2; subst; clear H2. apply in_or_app; po1. intros; discriminate. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'); intros. simpl in H2; rewrite H3 in H2. destruct (gen_meth_constr (ty_def (cl_dcl dcl')) a); inversion H2; subst; clear H2. apply in_or_app; po2. eapply IHmds'; auto. apply H. auto. auto. simpl in H2; rewrite H3 in H2; discriminate. Qed. Lemma In_tyc_compose_refined_md : forall (ms' : ms) (mb' mb'' : mb) (mds' mds'': list md) (rmd' : rmd) (t_list t_list' t_list'': list ty_constraint) (tyc' : ty_constraint) (dcl' : dcl), In (md_def ms' mb'') mds'' -> In (md_def ms' mb') mds' -> compose_refined_md mds' rmd' = Some mds'' -> gen_meth_constr (ty_def (cl_dcl dcl')) (md_def ms' mb') = Some t_list -> gen_meth_constr (ty_def (cl_dcl dcl')) (md_def ms' mb'') = Some t_list'' -> distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds'') -> gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd' = Some t_list' -> In tyc' t_list'' -> In tyc' t_list' \/ In tyc' t_list. induction mds'. simpl; intros; discriminate. intros; simpl in H0, H1. bd H0; subst. destruct mb'; destruct rmd'; destruct r; caseEq (ms_eq ms' m); intros; rewrite H0 in H1. inversion H1; subst; clear H1. simpl in H. bd H. inversion H; subst; clear H. rewrite <- ((proj1 (eq_ms_eq _ _ )) H0) in H5. clear H4 IHmds' H0. simpl in *. destruct ms'. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l2)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l2) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s l0)); intros; rewrite H in H5. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l2) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s l1)); intros; rewrite H0 in H5. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l2) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s l)); intros; rewrite H1 in H2. rewrite (gen_stmt_list_app _ _ _ _ _ _ H (gen_stmt_list_app _ _ _ _ _ _ H1 H0)) in H3. destruct (XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l2) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty)))). inversion H3; subst; clear H3. destruct (XMap.find x (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l2) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty)))); simpl in H5; inversion H5; subst; inversion H2; subst. clear H5 H2. simpl in H6; bd H6. po1; simpl; po1. destruct (in_app_or _ _ _ H6); clear H6. simpl; po1; repeat po2; repeat (apply in_or_app; po1). destruct (in_app_or _ _ _ H2); clear H2. simpl; po1; repeat po2. apply in_or_app; po2. apply in_or_app; po1. destruct (in_app_or _ _ _ H3); clear H3. simpl; repeat po2. apply in_or_app; po2. simpl; po1; repeat po2; apply in_or_app; po2. apply in_or_app; po2. discriminate. discriminate. discriminate. discriminate. discriminate. simpl in H4; bd H4. elimtype False; apply H8; revert H; clear; induction mds'. simpl; intros; contradiction. simpl; intros. bd H; subst. po1. po2; auto. destruct (cons_option_Some _ _ _ _ H1); rewrite H7 in H1; simpl in H1; inversion H1; subst; clear H1. simpl in H; bd H. inversion H; subst; clear H. rewrite H2 in H3; subst. po2; congruence. simpl in H4; bd H4. elimtype False; apply H9; revert H; clear; induction x1. simpl; intros; contradiction. simpl; intros. bd H; subst. po1. po2; auto. destruct a; destruct rmd'; destruct r; destruct m0; simpl in H1. caseEq (ms_eq m m1); intros; rewrite H7 in H1. inversion H1; subst; clear H1. simpl in H. cs (m = ms'); subst. simpl in H4; bd H4. elimtype False; apply H9; revert H0; clear; induction mds'. simpl; intros; contradiction. simpl; intros. bd H0; subst. po1. po2; auto. bd H. congruence. assert (mb' = mb''). simpl in H4; bd H4. generalize H H0 H4; clear; induction mds'. simpl; intros; contradiction. simpl; intros. bd H; bd H0. congruence. subst. bd H4. destruct ms'. elimtype False; apply H2; revert H0; clear; induction mds'. simpl; intros; contradiction. simpl; destruct a; intros. bd H0; subst. inversion H0; subst; po1. po2; auto. subst. bd H4. destruct ms'. elimtype False; apply H2; revert H; clear; induction mds'. simpl; intros; contradiction. simpl; destruct a; intros. bd H; subst. inversion H; subst; po1. po2; auto. bd H4; auto. subst. rewrite H3 in H2; inversion H2; po2; congruence. destruct (cons_option_Some _ _ _ _ H1); rewrite H8 in H1; inversion H1; subst; clear H1. simpl in H; bd H. inversion H; subst; clear H. simpl in H4; bd H4. elimtype False; apply H9. generalize x1 H8 H7 H0; clear. induction mds'; intros. simpl in H0; contradiction. simpl in H0; bd H0. subst. simpl in H8; rewrite H7 in H8. destruct mb'. destruct (cons_option_Some _ _ _ _ H8); rewrite H in H8; simpl in H8; inversion H8; subst; clear H8. simpl; po1. simpl in H8. destruct a. destruct m0. caseEq (ms_eq m m1); intros; rewrite H in H8. inversion H8; subst. simpl; po2. revert H0; clear; induction mds'. simpl; intros; contradiction. destruct a; intros; bd H0; subst. simpl in H0; bd H0; subst. inversion H0; subst; clear H0. simpl; po1. simpl; po2; auto. destruct (cons_option_Some _ _ _ _ H8). rewrite H1 in H8; simpl in H8; inversion H8; subst; clear H8. simpl; po2. apply (IHmds' _ H1 H7). exact H0. simpl in H4; bd H4. apply (IHmds' _ _ _ _ _ _ _ H H0 H8 H2 H3 H4 H5 H6). Qed. Lemma distinct_compose_refined_mds : forall (rmds' : list rmd) (mds' mds'': list md), compose_refined_mds mds' rmds' = Some mds'' -> distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds'') -> distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds'). induction rmds'. simpl; congruence. intros until mds''; simpl; caseEq (compose_refined_mds mds' rmds'); intros. apply (IHrmds' mds' l H). generalize mds'' H1 H0; clear; induction l. simpl; intros; discriminate. simpl. destruct a. destruct a0. destruct m1. destruct r. caseEq (ms_eq m0 m); intros. inversion H0; subst. simpl in H1; bd H1; pa. destruct (cons_option_Some _ _ _ _ H0); rewrite H2 in H0; inversion H0; subst; clear H0. simpl in H1; bd H1; import (IHl _ H1 H2). pa; auto. unfold not; intros; apply H4; destruct m0; generalize x1 H3 H2; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. destruct m2. caseEq (ms_eq m1 m); intros; rewrite H in H2. inversion H2; subst; clear H2. simpl; exact H3. bd H3. destruct m1; subst. destruct (cons_option_Some _ _ _ _ H2); rewrite H0 in H2; simpl in H2; inversion H2; subst; clear H2. simpl; po1. destruct (cons_option_Some _ _ _ _ H2); rewrite H0 in H2; simpl in H2; inversion H2; subst; clear H2. simpl; po2; apply (IHl _ H3 H0) . discriminate. Qed. Lemma In_tyc_compose_refined_mds : forall (ms' : ms) (rmds' : list rmd) (mb' mb'' : mb) (mds' mds'': list md) (t_list t_list' t_list'': list ty_constraint) (tyc' : ty_constraint) (dcl' : dcl), In (md_def ms' mb'') mds'' -> In (md_def ms' mb') mds' -> compose_refined_mds mds' rmds' = Some mds'' -> gen_meth_constr (ty_def (cl_dcl dcl')) (md_def ms' mb') = Some t_list -> gen_meth_constr (ty_def (cl_dcl dcl')) (md_def ms' mb'') = Some t_list'' -> distinct _ (map (fun (md' : md) => match md' with md_def (ms_def _ m' _) _=> m' end) mds'') -> fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) rmds' = Some t_list' -> In tyc' t_list'' -> In tyc' t_list' \/ In tyc' t_list. induction rmds'. simpl compose_refined_mds; intros. inversion H1; subst. assert (mb' = mb''). generalize H H0 H4; clear; induction mds''. simpl; intros; contradiction. simpl; intros. bd H; bd H0. congruence. subst. bd H4. destruct ms'. elimtype False; apply H2; revert H0; clear; induction mds''. simpl; intros; contradiction. simpl; destruct a; intros. bd H0; subst. inversion H0; subst; po1. po2; auto. bd H4; destruct ms'. subst; elimtype False; apply H3; revert H; clear; induction mds''. simpl; intros; contradiction. simpl; destruct a; intros. bd H; subst. inversion H; subst; po1. po2; auto. bd H4; auto. subst. rewrite H3 in H2; inversion H2; subst. po2; congruence. intros; simpl in H5. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) rmds'); intros; rewrite H7 in H5; try discriminate. simpl in H1. caseEq (compose_refined_mds mds' rmds'); intros; rewrite H8 in H1. caseEq (gen_refines_meth_constr (ty_def (cl_dcl dcl')) a); intros. assert (exists mb', In (md_def ms' mb') l0 /\ exists t_list''', gen_meth_constr (ty_def (cl_dcl dcl')) (md_def ms' mb') = Some t_list'''). import ( distinct_compose_refined_mds (a :: nil) l0 mds''). simpl in H10. rewrite H1 in H10. generalize l l0 mds'' (H10 (refl_equal _) H4) H8 H0 H2 H7; clear; induction rmds'. intros; simpl in H8; exists mb'; pa; try congruence. exists t_list; exact H2. intros. simpl in H8. simpl in H8; destruct (compose_refined_mds mds' rmds'); try discriminate H8; simpl in H7. destruct (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl dcl')) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) rmds'); try discriminate H7. import ( distinct_compose_refined_mds (a :: nil) l1 l0). simpl in H1. rewrite H8 in H1; import (H1 (refl_equal _) H). simpl distinct in IHrmds'. destruct (IHrmds' _ _ nil H3 (refl_equal _) H0 H2 (refl_equal _)). bd H4. caseEq (gen_refines_meth_constr (ty_def (cl_dcl dcl')) a); intros; rewrite H5 in H7; try discriminate. generalize l0 l H9 H3 H4 H8 H5; clear; induction l1. simpl; intros; contradiction. intros. simpl in H9; bd H9; subst. destruct a; simpl in H8. destruct x; destruct r. caseEq (ms_eq ms' m); intros; rewrite H in H8. inversion H8; subst. rename l4 into s0; rename l2 into s; rename l5 into s1. exists (mb_def (s0 ++ s ++ s1) x1); pa. simpl; po1. rewrite <- ((proj1 (eq_ms_eq _ _ )) H) in H5. simpl in H4; simpl in H5; simpl. destruct ms'. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l0)); try discriminate. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l0) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s s1)); intros; rewrite H0 in H5. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l0) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s s0)); intros; rewrite H1 in H5. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l0) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s s)); intros; rewrite H2 in H4. rewrite (gen_stmt_list_app _ _ _ _ _ _ H1 (gen_stmt_list_app _ _ _ _ _ _ H2 H0)). destruct (XMap.find x1 (fold_left (fun (m1 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m1) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l0) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty)))). exists (sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l0 ++ l4 ++ l5 ++ l2); auto. discriminate. discriminate. discriminate. destruct (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l0) (XMap.add x_this (ty_def (cl_dcl dcl')) (XMap.empty ty))) (make_list_s s0)); discriminate. destruct (cons_option_Some _ _ _ _ H8); rewrite H0 in H8; simpl in H8; inversion H8; subst; clear H8. rename l4 into s0; rename l2 into s; rename l5 into s1. exists (mb_def s x); pa. simpl; po1. simpl in H3; bd H3. exists x0; exact H4. simpl in H8; destruct a; destruct a0. destruct m1; destruct r. caseEq (ms_eq m0 m); intros; rewrite H in H8. inversion H8; subst; clear H8. cs (ms' = m0); subst. simpl in H3; bd H3. elimtype False; apply H2; revert H9; clear; induction l1. simpl; intros; contradiction. simpl; intros; bd H9. subst. po1. po2; auto. exists x; pa. simpl; po2. exists x0; exact H4. destruct (cons_option_Some _ _ _ _ H8); rewrite H0 in H8; simpl in H8; inversion H8; subst; clear H8. simpl in H3; bd H3. import (IHl1 _ nil H9 H3 H4 H0 H5). destruct H1; bd H1. exists x4; pa. simpl; po2. exists x5; exact H1. bd H10. destruct (In_tyc_compose_refined_md _ _ _ _ _ _ _ _ _ tyc' _ H H13 H1 H10 H3 H4 H9 H6). rewrite H9 in H5; inversion H5; subst. po1. apply in_or_app; po1. import (distinct_compose_refined_mds (a :: nil) l0 mds''). simpl in H12; rewrite H1 in H12. import (IHrmds' _ _ _ _ _ _ _ _ _ H13 H0 H8 H2 H10 (H12 (refl_equal _) H4) H7 H11). bd H14. destruct ( gen_refines_meth_constr (ty_def (cl_dcl dcl')) a); simpl in H5; inversion H5; subst; clear H5. po1. apply in_or_app; po2. po2. rewrite H9 in H5; discriminate. discriminate. Qed. Lemma ex_gen_meth_constr_build : forall (rclds' : list rcld) (dcl' : dcl) (cl' cl'' : cl) (fds' fds'' : fds) (mds' mds'' : list md) (md' : md) (t_list : list ty_constraint), (forall md', In md' mds' -> exists t_list', gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list') -> build_refined_classes (cld_def dcl' cl' fds' mds') rclds' = cld_def dcl' cl'' fds'' mds'' -> In md' mds'' -> gen_f_constr (feature_def rclds' nil) = Some t_list -> exists t_list'', gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list''. induction rclds'. simpl; intros. inversion H0; subst; apply H. exact H1. simpl. intros until t_list. caseEq (build_refined_classes (cld_def dcl' cl' fds' mds') rclds'). caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) rclds'). destruct a. rename l into f; rename l0 into l; rename l1 into l0. simpl build_refined_class. intros until l3; rename l2 into f0; rename l3 into l2; case (eq_nat_dec d0 d). caseEq (compose_refined_mds l2 l0); intros; import (build_refined_self _ _ _ _ _ _ _ _ _ H1); subst. simpl in IHrclds'. inversion H3; do 2 subst; clear H3. destruct (In_introduce_mds _ _ _ H4). caseEq (gen_refines_class_constr (refines_cld_def d cl'' f l l0)); intros; rewrite H6 in H5; simpl in H5; try discriminate; inversion H5; subst; clear H5. simpl in H6. revert H6; destruct cl''. case (eq_nat_dec d d0); try (intros; discriminate). caseEq (fold_right (fun (md'0 : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md'0 with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros. generalize l5 H5 H3; clear; induction l. simpl; intros; contradiction. simpl; intros; bd H3; subst. destruct (fold_right (fun (md'0 : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md'0 with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct ( gen_meth_constr (ty_def (cl_dcl d)) md'). exists l1; auto. discriminate. discriminate. destruct (fold_right (fun (md'0 : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md'0 with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). apply (IHl _ (refl_equal _ ) H3). discriminate. discriminate. caseEq (fold_right (fun (md'0 : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md'0 with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros. generalize l5 H5 H3; clear; induction l. simpl; intros; contradiction. simpl; intros; bd H3; subst. destruct (fold_right (fun (md'0 : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md'0 with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). destruct ( gen_meth_constr (ty_def (cl_dcl d)) md'). exists l1; auto. discriminate. discriminate. destruct (fold_right (fun (md'0 : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md'0 with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). apply (IHl _ (refl_equal _ ) H3). discriminate. discriminate. caseEq (gen_refines_class_constr (refines_cld_def d cl'' f l l0)); intros; rewrite H6 in H5; simpl in H5; try discriminate. destruct md'. assert (exists mb', In (md_def m mb') l2). generalize m0 l3 H3 H0; clear; induction l0. simpl ; intros; exists m0; congruence. simpl compose_refined_mds. caseEq (compose_refined_mds l2 l0); intros. destruct a; import (In_compose_In_mds _ _ _ _ _ _ H0 H3). destruct H1. apply (IHl0 _ _ H1 H). discriminate. destruct H7. assert (forall md', In md' l2 -> exists t_list'' : list ty_constraint, gen_meth_constr (ty_def (cl_dcl d)) md' = Some t_list''). intros. import (IHrclds' d cl' c0 fds' f0 mds' l2 md' (l1 ++ nil) H2 H1 H8). rewrite H in H9; apply (H9 (refl_equal _)). caseEq (fold_right (fun (rmd' : rmd) (m1 : option (list ty_constraint)) => match m1 with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0). generalize m x m0 l3 H7 H8 H3 H0; clear. induction l0; intros. simpl in H0; inversion H0; subst; clear H0. simpl in H. apply (H8 _ H3). simpl in H. caseEq ( fold_right (fun (rmd' : rmd) (m1 : option (list ty_constraint)) => match m1 with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros. rewrite H1 in H. caseEq (gen_refines_meth_constr (ty_def (cl_dcl d)) a); intros; rewrite H2 in H. simpl in H0. caseEq (compose_refined_mds l2 l0); intros; rewrite H4 in H0. destruct a. caseEq (ms_eq m1 m). intros; rewrite ((proj1 (eq_ms_eq _ _ )) H5) in H0, H2. clear H5. destruct (In_compose_In_mds _ _ _ _ _ _ H0 H3). destruct x0; destruct r. assert (forall m0, In (md_def m m0) l5 ->exists t_list'' : list ty_constraint, gen_meth_constr (ty_def (cl_dcl d)) (md_def m m0) = Some t_list''). intros. apply (IHl0 _ _ _ _ H7 H8 H6 H4 _ H1). rename l6 into s. generalize m m0 l3 s x0 H3 H0 H5 H6 H2; clear. induction l5. simpl; intros; contradiction. intros. destruct a. simpl in H0. destruct m2; caseEq (ms_eq m1 m); intros; rewrite H in H0; simpl in H0. rewrite ((proj1 (eq_ms_eq _ m )) H) in H6, H5, H0; inversion H0; subst; clear H0; simpl in H3; bd H3. rewrite <- H3. simpl in H6; generalize (H6 _ (or_introl _ (refl_equal _))) H2; clear. simpl; intros. destruct H. destruct m. rename l into s; rename l7 into s0; rename l8 into s1; rename l0 into l. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s0)); intros; rewrite H0 in H2. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s1)); intros; rewrite H1 in H2. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s)); intros; rewrite H3 in H. rewrite (gen_stmt_list_app _ _ _ _ _ _ H0 (gen_stmt_list_app _ _ _ _ _ _ H3 H1)). destruct (XMap.find x1 (fold_left (fun (m0 : XMap.t ty) (p : lj_definitions.x * ty) => XMap.add (fst p) (snd p) m0) (map (fun vd' : vd => match vd' with | vd_def ty' var' => (x_var var', ty') end) l) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty)))). exists _; reflexivity. discriminate. discriminate. discriminate. discriminate. discriminate. apply (H6 m0); simpl; po2. destruct (cons_option_Some _ _ _ _ H0). rewrite H1 in H0; simpl in H0; inversion H0; clear H0. subst. simpl in H5. bd H5. inversion H5. rewrite ((proj2 (eq_ms_eq _ _ )) H4) in H. discriminate. simpl in H3; bd H3. inversion H3. rewrite ((proj2 (eq_ms_eq _ _ )) H4) in H; discriminate. apply (IHl5 _ _ _ _ _ H3 H1 H5). intros; apply (H6 m2). simpl; po2. exact H2. intros; assert (In (md_def m m0) l5). revert l3 H0 H3 H5; clear; induction l5. simpl; intros; discriminate. destruct a; simpl. destruct m3; destruct r; caseEq (ms_eq m2 m1); intros. inversion H0; subst; clear H0. simpl in H3; bd H3. inversion H3; subst. rewrite ((proj1 (eq_ms_eq _ _ )) H) in H5. rewrite ((proj2 (eq_ms_eq _ m1 )) (refl_equal _)) in H5. discriminate. po2. destruct (cons_option_Some _ _ _ _ H0); rewrite H1 in H0; inversion H0. subst; simpl in H3; bd H3. inversion H3. po1. po2; auto. apply (IHl5 _ H1 H3 H5). apply (IHl0 _ _ _ _ H7 H8 H6 H4 _ H1). discriminate. discriminate. rewrite H1 in H; discriminate. intros; simpl in H6; rewrite H9 in H6. revert H6; destruct cl''; destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l). case (eq_nat_dec d d0); intros; discriminate. case (eq_nat_dec d d0); intros; discriminate. intros; discriminate. intros; discriminate. caseEq (gen_refines_class_constr (refines_cld_def d c f l l0)); intros; rewrite H6 in H5. inversion H5; subst. inversion H3; subst; clear H3. import (IHrclds' _ _ _ _ _ _ _ _ l1 H2 H1 H4). apply H3; simpl; rewrite H; auto. rewrite <- app_nil_end; auto. discriminate. intros. inversion H2; subst. apply (IHrclds' _ _ _ _ _ _ _ _ l1 H1 H0 H3). simpl; rewrite H; rewrite <- app_nil_end; auto. intros; discriminate. Qed. Lemma distinct_introduce_mds' : forall (mds' mds'' : list md), distinct m (map (fun md' : md => match md' with | md_def (ms_def _ m _) _ => m end) (introduce_methods mds' mds'')) -> distinct m (map (fun md' : md => match md' with | md_def (ms_def _ m _) _ => m end) mds'). induction mds''. simpl; auto. simpl. generalize a IHmds''; clear. induction (introduce_methods mds' mds''). simpl; intros; apply IHmds''; auto. simpl; auto. simpl; destruct a; destruct a. intros. caseEq (ms_eq m m1); intros; rewrite H0 in H. simpl in H; bd H. rewrite <- ((proj1 (eq_ms_eq _ _ )) H0) in H3. destruct m. apply IHmds''. pa. simpl in H. bd H. apply (IHl (md_def m1 m2)). intros. apply IHmds''. pa; auto. destruct m; unfold not; intros; apply H3. revert H2; clear; induction l. simpl; auto. destruct a; simpl; intros. caseEq (ms_eq m0 m1); intros. bd H2. subst. destruct m0; simpl. rewrite <- ((proj1 (eq_ms_eq _ _ )) H). po1. simpl. po2. bd H2. subst; simpl; po1. simpl; po2; auto. exact H. Qed. Lemma In_stmt_gen_p_gen_ps : forall (ps : PSel) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (tyc' : ty_constraint) (md' : md) (t_list t_list' : list ty_constraint), get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds') -> sat_unique_constraint (ps_gen_unique_constraint ps) = true -> PS_distinct_fds_mds ps = true -> compose ps = Some p -> gen_ps_constr ps = Some t_list -> In md' mds' -> gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list' -> In tyc' t_list' -> In tyc' t_list. induction ps. simpl; intros; discriminate. destruct a; intros. import (get_cld_eq_get_refined_cld (cl_dcl dcl') _ _ H2). rewrite H in H7. destruct (sat_constr_distinct' _ _ _ _ _ _ H2 H0 H1 (get_cld_in_p _ _ _ H7)). clear H7 H8; rename H9 into H14. cs (In (cld_def dcl' cl' fds' mds') l0). import (in_rcld_gen_p_subset_gen_class' _ _ _ _ _ tyc' H3 H7). bd H8; apply H8; revert H11; simpl; destruct cl'. case (eq_nat_dec dcl' d); try (intros; discriminate). destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros; inversion H11. simpl; repeat po2. apply in_or_app; po2. apply (In_fold_meth_constr _ _ _ _ _ _ H5 H6 H4 H9). intros; discriminate. intros; discriminate. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) fds') && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) mds')). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl dcl')) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) mds'). intros; inversion H11. simpl; repeat po2. apply in_or_app; po2. apply (In_fold_meth_constr _ _ _ _ _ _ H5 H6 H4 H9). intros; discriminate. intros; discriminate. simpl in H; caseEq (path l0 (cl_dcl dcl')); intros; rewrite H8 in H. clear H7. caseEq (get_refined_cld ps (cl_dcl dcl')); intros; rewrite H7 in H; try discriminate. simpl in H2; caseEq (compose ps); intros; rewrite H9 in H2; try discriminate; clear H2. simpl in H1; destruct (andb_prop _ _ H1); clear H2 H1. simpl in H0; import (sat_distinct_constr_app _ _ H0); clear H0. destruct c. rename l1 into f. rename l2 into l1. import (get_refined_eq_self _ _ _ _ _ _ H7); subst. caseEq (gen_ps_constr ps); intros. destruct (ex_gen_ps_gen_p _ _ _ _ _ _ _ H9 H0 H1 H10 H7). assert (forall tyc' md'', In md'' l1 -> exists t_list'', gen_meth_constr (ty_def (cl_dcl d)) md'' = Some t_list'' /\ (In tyc' t_list'' -> In tyc' l2)). intros. assert (exists t_list'', gen_meth_constr (ty_def (cl_dcl d)) md'' = Some t_list''). caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). revert H11; clear; induction l1. simpl; intros; contradiction. simpl; intros. bd H11; subst. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). destruct (gen_meth_constr (ty_def (cl_dcl d)) md''); auto. exists l2; auto. discriminate. discriminate. destruct (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l1). apply (IHl1 H11 _ (refl_equal _) ). discriminate. intros; simpl in H2. rewrite H12 in H2. generalize H2; clear; destruct c. rename f into l. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); case (eq_nat_dec d d0); intros; discriminate. rename f into l. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) l) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l1)); intros; discriminate. bd H12. exists x0; pa; auto. intros. exact (IHps _ _ _ _ _ _ _ _ _ H7 H1 H10 H9 H0 H11 H12 H13). inversion H. generalize t_list t_list' d c cl' fds' mds' f l1 md' H3 H4 H5 H6 H8 H7 H0 H11 H13 H14; clear. induction l. intros. simpl in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H in H3. rewrite H0 in H3; inversion H3; subst; clear H3. simpl in H13; inversion H13; subst. import (H11 tyc' _ H4). bd H1. rewrite H5 in H9; inversion H9; subst. apply in_or_app; po2. auto. discriminate. destruct a; intros. rename l1 into f0; rename l2 into l1; rename l3 into l2; rename l4 into l3; rename l5 into l4. simpl in H13. caseEq (build_refined_classes (cld_def d0 c0 f l4) l); intros; simpl in H13; rewrite H in H13. import (build_refined_self _ _ _ _ _ _ _ _ _ H); subst. revert H13; simpl; case (eq_nat_dec d1 d). rename l5 into f1; rename l6 into l5. caseEq (compose_refined_mds l5 l3). intros; subst. inversion H13; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H9 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H10 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H12 in H3. generalize H3; clear H3. destruct cl'. case (eq_nat_dec d d0). intros; discriminate. rewrite H0; intros. inversion H3; subst; clear H3. cs (In md' l2). simpl; repeat po2. do 3 (apply in_or_app; po1). apply in_or_app; po2. apply in_or_app; po1. apply (In_fold_meth_constr _ _ _ _ _ _ H5 H6 H3 H9). clear H13. destruct (In_introduce_mds _ _ _ H4). elimtype False; apply (H3 H13). destruct md'. assert (exists mb', In (md_def m mb') l5). generalize m0 l6 H13 H1; clear. induction l3. simpl. intros; exists m0; congruence. destruct a; simpl. caseEq (compose_refined_mds l5 l3); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H1 H13). destruct (IHl3 _ _ H0 H). exists x0; exact H2. discriminate. bd H15. assert (forall (md'' : md), In md'' l4 -> exists t_list'' : list ty_constraint, gen_meth_constr (ty_def (cl_dcl d)) md'' = Some t_list''). intros; import (H11 tyc' _ H16). bd H17. exists x0; auto. import (ex_gen_meth_constr_build _ _ _ _ _ _ _ _ _ l7 H16 H H15). simpl gen_f_constr in H17; rewrite H2 in H17; rewrite <- app_nil_end in H17; destruct (H17 (refl_equal _)). import (IHl ((l7 ++ l10) ++ l1) x0 d c0 c1 f1 l5 f l4 (md_def m x)). import (distinct_introduce_mds' _ _ H14). import (distinct_compose_refined_mds _ _ _ H1 H20). import (In_tyc_compose_refined_mds _ _ _ _ _ _ _ _ _ _ _ H13 H15 H1 H18 H5 H20 H10 H6). bd H22. simpl; repeat po2. do 3 (apply in_or_app; po1). apply in_or_app; po2. apply in_or_app; po2. simpl gen_ps_constr in H19; rewrite H2 in H19; rewrite H12 in H19; rewrite H0 in H19. import (H19 (refl_equal _) H15 H18 H22 H8 H7 (refl_equal _) H11 H H21). simpl; repeat po2. destruct (in_app_or _ _ _ H23); clear H23. destruct (in_app_or _ _ _ H24); clear H24. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. rewrite H0. intros. inversion H3; subst; clear H3. cs (In md' l2). simpl; repeat po2. do 3 (apply in_or_app; po1). apply in_or_app; po2. apply in_or_app; po1. apply (In_fold_meth_constr _ _ _ _ _ _ H5 H6 H3 H9). clear H13. destruct (In_introduce_mds _ _ _ H4). elimtype False; apply (H3 H13). destruct md'. assert (exists mb', In (md_def m mb') l5). generalize m0 l6 H13 H1; clear. induction l3. simpl. intros; exists m0; congruence. destruct a; simpl. caseEq (compose_refined_mds l5 l3); intros. destruct (In_compose_In_mds _ _ _ _ _ _ H1 H13). destruct (IHl3 _ _ H0 H). exists x0; exact H2. discriminate. bd H15. assert (forall (md'' : md), In md'' l4 -> exists t_list'' : list ty_constraint, gen_meth_constr (ty_def (cl_dcl d)) md'' = Some t_list''). intros; import (H11 tyc' _ H16). bd H17. exists x0; auto. import (ex_gen_meth_constr_build _ _ _ _ _ _ _ _ _ l7 H16 H H15). simpl gen_f_constr in H17; rewrite H2 in H17; rewrite <- app_nil_end in H17; destruct (H17 (refl_equal _)). import (IHl ((l7 ++ l10) ++ l1) x0 d c0 c1 f1 l5 f l4 (md_def m x)). import (distinct_introduce_mds' _ _ H14). import (distinct_compose_refined_mds _ _ _ H1 H20). import (In_tyc_compose_refined_mds _ _ _ _ _ _ _ _ _ _ _ H13 H15 H1 H18 H5 H20 H10 H6). bd H22. simpl; repeat po2. do 3 (apply in_or_app; po1). apply in_or_app; po2. apply in_or_app; po2. simpl gen_ps_constr in H19; rewrite H2 in H19; rewrite H12 in H19; rewrite H0 in H19. import (H19 (refl_equal _) H15 H18 H22 H8 H7 (refl_equal _) H11 H H21). simpl; repeat po2. destruct (in_app_or _ _ _ H23); clear H23. destruct (in_app_or _ _ _ H24); clear H24. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. simpl. destruct (match match cl' with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l8 ++ l9) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l8 ++ l9) end with | Some c_list'' => Some (c_list'' ++ l7) | None => None (A:=list ty_constraint) end). discriminate. discriminate. generalize H3; clear H3; destruct cl'; try (intros; discriminate). case (eq_nat_dec d d0); intros; discriminate. generalize H3; clear H3; destruct cl'; try (intros; discriminate). case (eq_nat_dec d d0); intros; discriminate. discriminate. intros. inversion H13; subst; clear H13; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H2 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H9 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H10 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H12 in H3. import (IHl ((l5 ++ l8) ++ l1) t_list' d c0 c1 f1 mds' f l4 md'). simpl gen_ps_constr in H13; rewrite H12 in H13; rewrite H2 in H13; rewrite H0 in H13. import (H13 (refl_equal _) H4 H5 H6 H8 H7 (refl_equal _) H11 H). import (H15 H14). generalize H3; clear H3; destruct cl'. case (eq_nat_dec d d0); try (intros; discriminate). intros; inversion H3; subst; clear H3. rewrite H0 in H18; inversion H18; subst; clear H18. destruct (in_app_or _ _ _ H16); clear H16. destruct (in_app_or _ _ _ H3); clear H3. simpl; repeat po2; apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. rewrite H0; intros. inversion H3; subst; clear H3. simpl; repeat po2. destruct (in_app_or _ _ _ H16); clear H16. destruct (in_app_or _ _ _ H3); clear H3. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. destruct (match match cl' with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l6 ++ l7) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l6 ++ l7) end with | Some c_list'' => Some (c_list'' ++ l5) | None => None (A:=list ty_constraint) end). discriminate. discriminate. generalize H3; clear H3; destruct cl'; try (intros; discriminate). case (eq_nat_dec d d0); intros; discriminate. generalize H3; clear H3; destruct cl'; try (intros; discriminate). case (eq_nat_dec d d0); intros; discriminate. discriminate. intros. inversion H13; subst; clear H13; subst. simpl in H3. caseEq (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l); intros; rewrite H1 in H3. caseEq (fold_right (fun (md' : md) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_meth_constr (ty_def (cl_dcl d)) md' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l2); intros; rewrite H2 in H3. caseEq (fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr (ty_def (cl_dcl d)) rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l3); intros; rewrite H9 in H3. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0); intros; rewrite H10 in H3. import (IHl ((l5 ++ l8) ++ l1) t_list' d1 c0 cl' fds' mds' f l4 md'). simpl gen_ps_constr in H12; rewrite H1 in H12; rewrite H10 in H12; rewrite H0 in H12. import (H12 (refl_equal _) H4 H5 H6 H8 H7 (refl_equal _) H11 H H14). generalize H3; clear H3; destruct c. case (eq_nat_dec d d0); try (intros; discriminate). rewrite H0; intros; inversion H3; subst; clear H3. destruct (in_app_or _ _ _ H13); clear H13. destruct (in_app_or _ _ _ H3); clear H3. simpl; repeat po2; apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po1. apply in_or_app; po2. simpl; repeat po2; apply in_or_app; po2. rewrite H0; intros. inversion H3; subst; clear H3. simpl; repeat po2. destruct (in_app_or _ _ _ H13); clear H13. destruct (in_app_or _ _ _ H3); clear H3. apply in_or_app; po1. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po1. apply in_or_app; po2. apply in_or_app; po2. destruct (match match c with | cl_dcl dcl'' => if eq_nat_dec d dcl'' then None (A:=list ty_constraint) else Some (in_prog_constr (cl_dcl dcl'') :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l6 ++ l7) | cl_object => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f0) (cl_dcl d) :: inherited_methods_constr l2 (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f0 ++ l6 ++ l7) end with | Some c_list'' => Some (c_list'' ++ l5) | None => None (A:=list ty_constraint) end); discriminate. revert H3; destruct c; try (intros; discriminate). case (eq_nat_dec d d0); intros; discriminate. revert H3; destruct c; try (intros; discriminate). case (eq_nat_dec d d0); intros; discriminate. discriminate. simpl in H3; rewrite H0 in H3. destruct (match fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l with | Some c_list' => match fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end) (Some nil) l0 with | Some c_list'' => Some (c_list' ++ c_list'') | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end); discriminate. elimtype False; apply H7. inversion H; subst. apply (in_path_in_prog l0 (cl_dcl dcl') (cld_def dcl' cl' fds' mds')). rewrite H8; simpl; po1. Qed. Lemma in_sat_ps_list : forall (ps : PSel) (n : nat) (tyc' : ty_constraint) (c_list : list ty_constraint), In tyc' c_list -> ps_sat_constr_list ps c_list n = true -> ps_sat_constr ps tyc' n = true. induction c_list; simpl. intros; contradiction. intros; bd H; subst. apply (proj1 (andb_prop _ _ H0)). apply (IHc_list H (proj2 (andb_prop _ _ H0))). Qed. Lemma in_sat_list : forall (p : P) (tyc' : ty_constraint) (c_list : list ty_constraint), In tyc' c_list -> sat_constr_list p c_list = true -> sat_constr p tyc' = true. induction c_list; simpl. intros; contradiction. intros; bd H; subst. apply (proj1 (andb_prop _ _ H0)). apply (IHc_list H (proj2 (andb_prop _ _ H0))). Qed. Lemma ps_sat_constr_in_prog : forall (ps : PSel) (p p' : P) (cl' : cl), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_sat_constr ps (in_prog_constr cl') (length (introduce_all ps)) = sat_constr p' (in_prog_constr cl'). simpl; intros; destruct cl'. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1). clear. induction p'; simpl; auto. destruct a; simpl. case (eq_nat_dec d d0); intros. simpl. case (eq_nat_dec d d0); intros; congruence. exact IHp'. auto. Qed. Lemma ps_sat_constr_compos_sty_field_r : forall (ps : PSel) (p p' : P) (cl' : cl) (f' : f) (ty' : ty), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_sat_constr ps (sty_field_rconstr cl' f' ty') (length (introduce_all ps)) = sat_constr p' (sty_field_rconstr cl' f' ty'). simpl; intros; destruct ty'. destruct c. rewrite (ps_ftype_eq_ftype _ cl' f' _ _ H H0 H1). destruct (ftype p' cl' f'). destruct t. destruct c. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d0) _ _ H H0 H1); auto. auto. auto. rewrite (ps_ftype_eq_ftype _ cl' f' _ _ H H0 H1). destruct (ftype p' cl' f'). destruct t. destruct c. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. auto. auto. Qed. Lemma ps_sat_constr_compos_sty_field_w : forall (ps : PSel) (p p' : P) (cl' : cl) (f' : f) (ty' : ty), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_sat_constr ps (sty_field_wconstr ty' cl' f') (length (introduce_all ps)) = sat_constr p' (sty_field_wconstr ty' cl' f'). simpl; intros; destruct ty'. destruct c. rewrite (ps_ftype_eq_ftype _ cl' f' _ _ H H0 H1). destruct (ftype p' cl' f'). destruct t. destruct c. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. auto. rewrite (ps_ftype_eq_ftype _ cl' f' _ _ H H0 H1). destruct (ftype p' cl' f'). destruct t. destruct c. auto. auto. auto. Qed. Lemma ps_sat_constr_compose_sty_meth : forall (ps : PSel) (p p' : P) (cl' : cl) (m' : m) (ty' : ty) (ty_list : list ty), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_sat_constr ps (sty_meth_constr cl' m' ty' ty_list) (length (introduce_all ps)) = sat_constr p' (sty_meth_constr cl' m' ty' ty_list). simpl; intros; destruct ty'; destruct c. rewrite (ps_mtype_eq_mtype _ cl' m' _ _ H H0 H1). destruct (mtype p' cl' m'); auto. destruct m; destruct t; destruct c. case (eq_nat_dec (length ty_list) (length l)); auto. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d0) _ _ H H0 H1); auto. destruct (in_path (path p' (cl_dcl d0)) d); simpl; auto. intros; induction (combine ty_list l); simpl. auto. destruct a; destruct t; destruct t0; destruct c; destruct c0; try (rewrite IHl0; rewrite (f_path_eq_path _ (cl_dcl d1) _ _ H H0 H1); auto). auto. auto. auto. rewrite (ps_mtype_eq_mtype _ cl' m' _ _ H H0 H1). destruct (mtype p' cl' m'); auto. destruct m; destruct t; destruct c. case (eq_nat_dec (length ty_list) (length l)); auto. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. destruct (in_path (path p' (cl_dcl d)) d); simpl; auto. intros; induction (combine ty_list l); simpl. auto. destruct a; destruct t; destruct t0; destruct c; destruct c0; try (rewrite IHl0; rewrite (f_path_eq_path _ (cl_dcl d0) _ _ H H0 H1); auto). auto. auto. case (eq_nat_dec (length ty_list) (length l)); auto. rewrite (length_ps ps p); auto. intros; induction (combine ty_list l); simpl. auto. destruct a; destruct t; destruct t0; destruct c; destruct c0; try (rewrite IHl0; rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto). auto. auto. Qed. Lemma ps_sat_constr_compos_sty_cl : forall (ps : PSel) (p p' : P) (ty' ty'' : ty), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_sat_constr ps (sty_cl_constr ty' ty'') (length (introduce_all ps)) = sat_constr p' (sty_cl_constr ty' ty''). simpl; intros; destruct ty'; destruct ty''; destruct c; destruct c0. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. rewrite (length_ps ps p); auto; rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. rewrite (length_ps ps p); auto; rewrite (f_path_eq_path _ cl_object _ _ H H0 H1); auto. reflexivity. Qed. Lemma ps_sat_constr_compos_sty_if : forall (ps : PSel) (p p' : P) (ty' ty'' : ty), compose ps = Some p -> Permutation p p' -> acyclic_hierarchy p' -> ps_sat_constr ps (sty_if_constr ty' ty'') (length (introduce_all ps)) = sat_constr p' (sty_if_constr ty' ty''). simpl; intros; destruct ty'; destruct ty''; destruct c; destruct c0. rewrite (length_ps ps p); auto. rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); rewrite (f_path_eq_path _ (cl_dcl d0) _ _ H H0 H1); auto. rewrite (length_ps ps p); auto; rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. rewrite (length_ps ps p); auto; rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto. reflexivity. Qed. Lemma WF_cld_constr_gen_class_constr' : forall (cld' : cld) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), wf_cld_constr cld' uc_list tyc_list -> gen_class_constr' cld' = Some tyc_list. intros; inversion H; subst; simpl. simpl; destruct (eq_nat_dec dcl' dcl''). congruence. rewrite ((proj2 (distinct_distinct_list _)) H4); rewrite ((proj2 (distinct_distinct_list _)) H3); simpl. rewrite (wf_meth_list_if_gen_meth_list _ _ _ H5). auto. rewrite ((proj2 (distinct_distinct_list _)) H3); rewrite ((proj2 (distinct_distinct_list _)) H2); simpl. rewrite (wf_meth_list_if_gen_meth_list _ _ _ H4). auto. Qed. Lemma WF_rmd_constr_gen_class_constr' : forall (n : nat) (dcl' : dcl) (rmd' : rmd) (cc : comp_constraint) (tyc_list : list ty_constraint), wf_refined_meth_constr n dcl' rmd' cc tyc_list -> gen_refines_meth_constr dcl' rmd' = Some tyc_list. intros; inversion H; subst; simpl. rewrite H7. rewrite (wf_stmt_if_gen_stmt_constr _ _ _ H4); rewrite (wf_stmt_if_gen_stmt_constr _ _ _ H5); rewrite ((proj2 (distinct_distinct_list _)) H2); auto. Qed. Lemma WF_rmd_list_constr_gen_class_constr' : forall (n : nat) (dcl' : dcl) (rmds' : list rmd) (cc_list : list comp_constraint) (tyc_list : list ty_constraint), wf_refined_meth_list_constr n dcl' rmds' cc_list tyc_list -> fold_right (fun (rmd' : rmd) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_meth_constr dcl' rmd' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) rmds' = Some tyc_list. induction rmds'; simpl; intros. inversion H; subst; auto. inversion H; subst; simpl. rewrite (IHrmds' _ _ H5). rewrite (WF_rmd_constr_gen_class_constr' _ _ _ _ _ H2); auto. Qed. Lemma WF_rcld_constr_gen_class_constr' : forall (n : nat) (rcld' : rcld) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), wf_rcld_constr n rcld' cc_list uc_list tyc_list -> gen_refines_class_constr rcld' = Some tyc_list. intros; inversion H; subst; simpl. simpl; destruct (eq_nat_dec dcl' dcl''). congruence. rewrite (WF_rmd_list_constr_gen_class_constr' _ _ _ _ _ H3). rewrite (wf_meth_list_if_gen_meth_list _ _ _ H2); auto. rewrite (WF_rmd_list_constr_gen_class_constr' _ _ _ _ _ H2). rewrite (wf_meth_list_if_gen_meth_list _ _ _ H1); auto. Qed. Lemma rev_flip_app :forall (A : Type) (a c : list A), rev (a ++ c) = rev c ++ rev a. induction a; intros. simpl; rewrite <- app_nil_end; reflexivity. simpl; rewrite IHa; rewrite app_ass; auto. Qed. Lemma reass_app :forall (A : Type) (b : A) (a c : list A), a ++ (b :: c) = (a ++ (b :: nil) ++ c). induction a; simpl; intros; auto. Qed. Lemma nil_eq_app_cons_false : forall (A : Type) (a : A) (b : list A), nil <> b ++ a :: nil. destruct b; simpl; congruence. Qed. Lemma rev_eq : forall (A : Type) (a c : list A), rev a = rev c -> a = c. induction a. destruct c; simpl; auto; intros. elimtype False; eapply app_cons_not_nil; eauto. destruct c; intros. elimtype False; import (sym_eq H); eapply app_cons_not_nil; simpl in H0; eauto. simpl in H; destruct (app_inj_tail _ _ _ _ H); subst. rewrite (IHa c); auto. Qed. Lemma split_app_eq : forall (A : Type) (c a b : list A), a ++ c = b ++ c -> a = b. intros; apply rev_eq. cut (rev (a ++ c) = rev (b ++ c)); intros. clear H; repeat rewrite rev_flip_app in H0; induction (rev c). simpl in H0; auto. apply IHl; simpl in H0; inversion H0; auto. congruence. Qed. Lemma WF_FD_gen_ps_constr : forall (n : nat) (fd' : FD) (cc_list : list comp_constraint) (uc_list : list unique_constraint) (tyc_list : list ty_constraint), wf_feature n fd' (feature_constr n cc_list uc_list tyc_list) -> gen_f_constr fd' = Some tyc_list. destruct fd'; simpl; generalize l0. induction l. induction l1. simpl; intros; inversion H; subst. inversion H3; inversion H6; subst; rewrite <- app_nil_end; reflexivity. simpl in IHl1. intro; simpl; caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) l1); intros; inversion H0; inversion H4; subst. inversion H7; subst. assert (l = tyc_list3). generalize uc_list3 l tyc_list3 H H13; clear; induction l1; simpl; intros; inversion H; inversion H13; subst; auto. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) l1); intros; rewrite H0 in H, H1. caseEq (gen_class_constr' a); intros; rewrite H2 in H; inversion H; subst. rewrite (IHl1 _ _ _ H0 H6). rewrite (WF_cld_constr_gen_class_constr' _ _ _ H3) in H1; inversion H1; auto. cut (l2 = tyc_list1). inversion H1; auto. intros; rewrite H4; auto. eapply split_app_eq; eauto. discriminate. rewrite (WF_cld_constr_gen_class_constr' _ _ _ H10); rewrite H1; simpl; reflexivity. elimtype False; generalize uc_list3 tyc_list3 H H13; clear; induction l1; simpl; intros. discriminate. inversion H13; subst. caseEq (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) l1); intros; rewrite H0 in H. rewrite (WF_cld_constr_gen_class_constr' _ _ _ H2) in H; discriminate. eapply IHl1; eauto. intros; inversion H; inversion H6; subst. assert (fold_right (fun (rcld' : rcld) (m : option (list ty_constraint)) => match m with | Some c_list' => match gen_refines_class_constr rcld' with | Some c_list'' => Some (c_list'' ++ c_list') | None => None end | None => None end) (Some nil) l = Some tyc_list3). generalize cc_list2 uc_list3 tyc_list3 H13; clear; induction l; intros; inversion H13; subst. simpl; auto. simpl; rewrite (WF_rcld_constr_gen_class_constr' _ _ _ _ _ H1). rewrite (IHl _ _ _ H5); reflexivity. assert (fold_right (fun (cld' : cld) (m : option (list ty_constraint)) => match m with | Some c_list'0 => match gen_class_constr' cld' with | Some c_list'' => Some (c_list'' ++ c_list'0) | None => None end | None => None end) (Some nil) l1 = Some tyc_list1). generalize uc_list1 tyc_list1 H3; clear; induction l1; intros; inversion H3; subst. simpl; auto. simpl; rewrite (WF_cld_constr_gen_class_constr' _ _ _ H1). rewrite (IHl1 _ _ H5); reflexivity. simpl; rewrite H0; rewrite H1. simpl; rewrite (WF_rcld_constr_gen_class_constr' _ _ _ _ _ H9); auto. Qed. Lemma wf_FT_sat_constr_list : forall (fc_list : list feature_constraint) (ft : FT) (ps : PSpec) (ps' : PSel) (fd' : FD), wf_FT 0 ft fc_list -> build_PSel ft ps = Some ps' -> sat_feature_ty_constr ft ps fc_list -> In fd' ps' -> exists n, In n ps /\ exists cc_list, exists uc_list, exists tyc_list, wf_feature n fd' (feature_constr n cc_list uc_list tyc_list) /\ ps_sat_constr_list ps' tyc_list (length (introduce_all ps')) = true. intros. destruct (In_PSel_nth_FT _ _ _ _ H0 H2) as [n' [In_n' ne_n']]. destruct (ex_wf_PSel _ _ _ _ H H0) as [fc_list' [WF_ps' sub_fc_list']]. assert (exists fc, exists n'', wf_feature n'' fd' fc /\ In fc fc_list'). generalize fc_list' H2 WF_ps'; clear; induction ps'. simpl; intros; contradiction. simpl; intros; destruct H2 as [eq_fd' | In_fd']. subst; inversion WF_ps'; subst. exists fc; exists n; simpl; auto. inversion WF_ps'; subst; destruct (IHps' _ In_fd' H3) as [n' [fc' [wf_fd' In_fc']]]. exists n'; exists fc'; simpl; split; auto. destruct H3 as [fc [n'' [WF_fd' In_fc']]]. destruct fc; destruct (sub_fc_list' _ _ _ _ In_fc') as [In_fcl In_n]. inversion WF_fd'; subst; exists n; split; auto. exists _; exists _; exists _; split. apply WF_fd'. generalize H0 H1 In_n In_fcl; clear; induction fc_list. simpl; intros; contradiction. simpl; intros; destruct In_fcl as [eq_fc | In_fc]. subst; inversion H1; subst. rewrite H0 in H5; inversion H5; subst; assumption. contradiction. inversion H1; subst; auto. Qed. Lemma wf_FT_sat_constr_list' : forall (fc_list : list feature_constraint) (ft : FT) (ps : PSpec) (ps' : PSel), wf_FT 0 ft fc_list -> build_PSel ft ps = Some ps' -> sat_feature_ty_constr ft ps fc_list -> exists tyc_list, gen_ps_constr ps' = Some tyc_list. intros. assert (forall fd', In fd' ps' -> exists n, In n ps /\ exists tyc_list, gen_f_constr fd' = Some tyc_list). intros; destruct (wf_FT_sat_constr_list _ _ _ _ _ H H0 H1 H2) as [n' [H3 [cc_list' [uc_list' [tyc_list' [wf_a' Sat_a']]]]]]. exists n'; split; auto; exists tyc_list'; auto. eapply WF_FD_gen_ps_constr; eauto. generalize H2; clear; induction ps'; intros. exists nil; simpl; auto. simpl; simpl in H2; destruct (H2 a (or_introl _ (refl_equal _))) as [n [_ [tyc_list wf_a]]]. destruct IHps' as [tyc_list']. intros; destruct (H2 _ (or_intror _ H)) as [n' [H3 [tyc_list' wf_a']]]. exists n'; split; auto. exists tyc_list'; auto. rewrite wf_a; rewrite H; exists _; auto. Qed. Lemma In_tyc_gen_ps : forall (ps' : PSel) (tyc' : ty_constraint) (tyc_list : list ty_constraint), In tyc' tyc_list -> gen_ps_constr ps' = Some tyc_list -> exists fd', In fd' ps' /\ exists tyc_list', gen_f_constr fd' = Some tyc_list' /\ In tyc' tyc_list'. induction ps'. intros; simpl in H0; inversion H0; subst; inversion H. intros; simpl in H0; caseEq (gen_f_constr a); intros; rewrite H1 in H0. caseEq (gen_ps_constr ps'); intros; rewrite H2 in H0; inversion H0; subst; clear H0. destruct (in_app_or _ _ _ H); clear H. exists a; simpl; split; auto; exists l; split; auto. destruct (IHps' _ _ H0 H2) as [fd' [In_fd' [tycl [Gen_tycl In_tyc']]]]. exists fd'; simpl; split; auto; exists tycl; split; auto. discriminate. Qed. Lemma In_sat_constr : forall (ps' : PSel) (tyc' : ty_constraint) (tyc_list : list ty_constraint) (n : nat), In tyc' tyc_list -> ps_sat_constr_list ps' tyc_list n = true -> ps_sat_constr ps' tyc' n = true. induction tyc_list; simpl; intros; destruct H; destruct (andb_prop _ _ H0); subst; auto. Qed. Lemma wf_FT_sat_constr_list'' : forall (fc_list : list feature_constraint) (ft : FT) (ps : PSpec) (ps' : PSel) (tyc_list : list ty_constraint), wf_FT 0 ft fc_list -> build_PSel ft ps = Some ps' -> sat_feature_ty_constr ft ps fc_list -> gen_ps_constr ps' = Some tyc_list -> ps_sat_constr_list ps' tyc_list (length (introduce_all ps')) = true. intros. assert (forall fd', In fd' ps' -> exists tyc_list, gen_f_constr fd' = Some tyc_list /\ ps_sat_constr_list ps' tyc_list (length (introduce_all ps')) = true). intros; destruct (wf_FT_sat_constr_list _ _ _ _ _ H H0 H1 H3) as [n' [H4 [cc_list' [uc_list' [tyc_list' [wf_a' Sat_a']]]]]]. exists tyc_list'; split; auto. eapply WF_FD_gen_ps_constr; eauto. assert (forall tyc', In tyc' tyc_list -> ps_sat_constr ps' tyc' (length (introduce_all ps')) = true). intros; destruct (In_tyc_gen_ps _ _ _ H4 H2) as [fd' [In_fd' [tycl [Gen_tycl In_tyc']]]]. apply In_sat_constr with (tyc_list := tycl); auto. destruct (H3 _ In_fd') as [tyc_list' [Gen_tcl' Sat_tcl']]. rewrite Gen_tycl in Gen_tcl'; inversion Gen_tcl'; subst; auto. generalize H4; clear; induction tyc_list; simpl; intros. reflexivity. rewrite IHtyc_list. rewrite (H4 a); auto. intros; apply H4; auto. Qed. Lemma wf_FT_sat_constr_list''' : forall (fc_list : list feature_constraint) (ft : FT) (ps : PSpec) (ps' : PSel), wf_FT 0 ft fc_list -> build_PSel ft ps = Some ps' -> sat_feature_ty_constr ft ps fc_list -> exists tyc_list, gen_ps_constr ps' = Some tyc_list /\ ps_sat_constr_list ps' tyc_list (length (introduce_all ps')) = true. intros; destruct (wf_FT_sat_constr_list' _ _ _ _ H H0 H1). exists x; split; auto. eapply wf_FT_sat_constr_list''; eauto. Qed. Lemma WF_FT_fd_distinct : forall (ft : FT) (fc_list : list feature_constraint) (n : nat) (clds : list cld) (rclds : list rcld), wf_FT n ft fc_list -> In (feature_def rclds clds) ft -> clds_distinct_fds_mds clds = true. induction ft; simpl; intros; destruct H0; subst. inversion H; subst; inversion H4; subst; generalize uc_list1 tyc_list1 H3; clear; induction clds. reflexivity. simpl; intros; inversion H3; inversion H1; subst. rewrite ((proj2 (distinct_distinct_list _)) H9); rewrite ((proj2 (distinct_distinct_list _)) H10); rewrite (IHclds _ _ H5); reflexivity. rewrite ((proj2 (distinct_distinct_list _)) H9); rewrite ((proj2 (distinct_distinct_list _)) H8); rewrite (IHclds _ _ H5); reflexivity. inversion H; subst; eauto. Qed. Lemma WF_FT_PS_distinct : forall (ps : PSpec) (ps' : PSel) (ft : FT) (fc_list : list feature_constraint) (n : nat), wf_FT n ft fc_list -> build_PSel ft ps = Some ps' -> PS_distinct_fds_mds ps' = true. intros; cut (forall clds rclds, In (feature_def rclds clds) ps' -> clds_distinct_fds_mds clds = true). clear; induction ps'; simpl; intros; auto. destruct a; rewrite (H _ _ (or_introl _ (refl_equal _))); rewrite IHps'; auto. intros; eapply H; eauto. intros; apply (WF_FT_fd_distinct _ _ _ _ _ H (In_PSel_In_FT _ _ _ _ H0 H1)). Qed. End Well_Formedness.