Require Import Arith. Require Import Bool. Require Import List. Require Import Natmap. Require Import FMaps. Require Import EqNat. Require Import lj. Require Import FMapFacts. Require Import Natmap. Require Import Classical. Require Import base2. Require Import Max. Require Import lj_sound. Require Import lj_constr_sound. Require Import lfj. Definition build_refined_class (cld' : cld) (rcld' : rcld) : cld := match cld', rcld' with cld_def dcl' cl' fds' mds', refines_cld_def dcl'' cl'' fds'' mds'' rmds => if (eq_nat_dec dcl' dcl'') then match compose_refined_mds mds' rmds with Some mds''' => cld_def dcl' cl'' (introduce_fields fds' fds'') (introduce_methods mds''' mds'') | None => cld_def dcl' cl'' (introduce_fields fds' fds'') mds' end else cld' end. Definition build_refined_classes (cld' : cld) (list_rcld' : list rcld) : cld := fold_right (fun (rcld' : rcld) (cld'' : cld) => build_refined_class cld'' rcld') cld' list_rcld'. Fixpoint get_refined_cld (ps : PS) (cl' : cl) {struct ps} : option cld := match ps with | cons (feature_def refined_cld introed_cld) ps' => let path_frag := (path introed_cld cl') in match path_frag with nil => match get_refined_cld ps' cl' with Some cld'=> Some (build_refined_classes cld' refined_cld) | None => None end | cons cld' _ => Some cld' end | _ => None end. Fixpoint f_path (ps : PS) (cl' : cl) (n : nat) {struct n} : list cld := match n, (get_refined_cld ps cl') with S n', Some (cld_def dcl'' cl'' fds'' mds'') => (cld_def dcl'' cl'' fds'' mds'') :: (f_path ps cl'' n') | _, _ => nil end. Definition get_cld (p : P) (cl' : cl) : option cld := head (path p cl'). Fixpoint path' (p : P) (cl' : cl) (n : nat) {struct n} : list cld := match n, get_cld p cl' with S n', Some (cld_def dcl'' cl'' fds'' mds'') => (cld_def dcl'' cl'' fds'' mds'') :: (path' p cl'' n') | _, _ => nil end. Lemma get_refined_cl_object : forall (ps : PS), 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 : PS), 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 l 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 l1 l0); 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 l1 l0); 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 nil (feature_def (rcld' :: rclds') clds) = 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 : PS) (p : P), compose_all 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_all ps). import (H _ (refl_equal _)); clear H. intro; fold (compose p (feature_def l l0)); 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 f0 l2) (refines_cld_def d0 c0 f l0 l1) :: nil) = (cl_dcl d0) :: cl_object :: nil). simpl; case (eq_nat_dec d0 d0). destruct (compose_refined_mds l2 l1); simpl; auto. congruence. destruct (build_refined_class (cld_def d0 c1 f0 l2) (refines_cld_def d0 c0 f l0 l1)). 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. (*** Break One ***) 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 l l1). 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 : PS) (p : P) (n : nat) (cl' : cl), compose_all 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), ordered_p (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 f0 l0); 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 f l); 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 f l0)). 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 f l0 ::l) (cld_def d c f l0 :: 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 f l0 ::l) (cld_def d c f l0 :: 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 f l0 :: cld_def d1 c0 f0 l1 :: l) H); try reflexivity. apply perm_swap. rewrite (IHn _ (cld_def d c f l0 :: cld_def d1 c0 f0 l1 :: l) H); try reflexivity. apply perm_swap. intros; destruct (head (path l (cl_dcl d0))). destruct c1. rewrite (IHn _ (cld_def d c f l0 :: cld_def d1 c0 f0 l1 :: 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' : fds) (md_list : list md), ordered_p 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_ordered_p _ _ 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) -> ordered_p 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_ordered_p (cld_def d c f l :: p) (cld_def d c f l)); 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 f); clear H; bd H0; import (H0 l); 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', ordered_p 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. Definition ps_ftype (ps : PS) (cl' : cl) (f' : f) (n :nat) : option ty := ext_fty (f_path ps cl' n) f'. Definition ps_get_md (ps : PS) (cl' : cl) ( m' : m) (n : nat) : option md := head (filter_mds (get_all_mds (f_path ps cl' n)) m'). Definition ps_mtype (ps : PS) (cl' : cl) ( m' : m) (n : nat) : option mty := match (ps_get_md ps cl' m' n) with Some x => Some (ext_mty x) | None => None end. Definition ps_fields (ps : PS) (cl' : cl) (n : nat) : list f := ext_fs (f_path ps cl' n). Definition ps_methods (ps : PS) (cl' : cl) (n: nat): M := ext_ms (f_path ps cl' n). Definition get_ps_parent (ps : PS) (cl' : cl) : option cl := match get_refined_cld ps cl' with Some cld' => Some (get_parent cld') | None => None end. Definition ps_sat_constr (ps : PS) (c : ty_constraint) (n : nat) : bool := match c with | sty_field_rconstr cl' f' (ty_def cl'') => match cl'', (ps_ftype ps cl' f' n) with cl_dcl dcl', Some (ty_def (cl_dcl dcl'')) => in_path (f_path ps (cl_dcl dcl'') n) dcl' | cl_object, Some (ty_def (cl_dcl dcl'')) => in_path (f_path ps (cl_dcl dcl'') n) dcl'' | cl_object, Some (ty_def cl_object) => true | _, _ => false end | sty_field_wconstr (ty_def cl') cl'' f' => match cl', (ps_ftype ps cl'' f' n) with cl_dcl dcl'', Some (ty_def (cl_dcl dcl')) => in_path (f_path ps (cl_dcl dcl'') n) dcl' | cl_dcl dcl'', Some (ty_def cl_object) => in_path (f_path ps (cl_dcl dcl'') n) dcl'' | cl_object, Some (ty_def cl_object) => true | _, _ => false end | sty_meth_constr cl' m' (ty_def cl'') ty_list => match (ps_mtype ps cl' m' n), cl'' with Some (mty_def (ty_list') (ty_def (cl_dcl dcl''))), cl_dcl dcl' => if (eq_nat_dec (length ty_list) (length ty_list')) then (in_path (f_path ps (cl_dcl dcl'') n) dcl') && (fold_right (fun (x : ty*ty) (m : bool) => match x with ((ty_def (cl_dcl dcl2)), (ty_def (cl_dcl dcl1))) => (in_path (f_path ps (cl_dcl dcl2) n) dcl1) && m | ((ty_def (cl_dcl dcl1)), (ty_def cl_object)) => (in_path (f_path ps (cl_dcl dcl1) n) dcl1) && m | ((ty_def cl_object), (ty_def cl_object)) => m | _ => false end) true (combine ty_list ty_list')) else false | Some (mty_def (ty_list') (ty_def (cl_dcl dcl''))), cl_object => if (eq_nat_dec (length ty_list) (length ty_list')) then (in_path (f_path ps (cl_dcl dcl'') n) dcl'') && (fold_right (fun (x : ty*ty) (m : bool) => match x with ((ty_def (cl_dcl dcl2)), (ty_def (cl_dcl dcl1))) => (in_path (f_path ps (cl_dcl dcl2) n) dcl1) && m | ((ty_def (cl_dcl dcl1)), (ty_def cl_object)) => (in_path (f_path ps (cl_dcl dcl1) n) dcl1) && m | ((ty_def cl_object), (ty_def cl_object)) => m | _ => false end) true (combine ty_list ty_list')) else false | Some (mty_def (ty_list') (ty_def cl_object)), cl_object => if (eq_nat_dec (length ty_list) (length ty_list')) then (fold_right (fun (x : ty*ty) (m : bool) => match x with ((ty_def (cl_dcl dcl2)), (ty_def (cl_dcl dcl1))) => (in_path (f_path ps (cl_dcl dcl2) n) dcl1) && m | ((ty_def (cl_dcl dcl1)), (ty_def cl_object)) => (in_path (f_path ps (cl_dcl dcl1) n) dcl1) && m | ((ty_def cl_object), (ty_def cl_object)) => m | _ => false end) true (combine ty_list ty_list')) else false | _, _ => false end | sty_cl_constr ty1 ty2 => match ty1, ty2 with ty_def cl', ty_def (cl_dcl dcl') => in_path (f_path ps cl' n) dcl' | ty_def cl_object, ty_def cl_object => true | ty_def (cl_dcl dcl'), ty_def cl_object => in_path (f_path ps (cl_dcl dcl') n) dcl' end | sty_if_constr (ty_def cl1) (ty_def cl2) => match cl1, cl2 with cl_dcl dcl1, cl_dcl dcl2 => in_path (f_path ps (cl_dcl dcl1) n) dcl2 || in_path (f_path ps (cl_dcl dcl2) n) dcl1 | cl_object, cl_dcl dcl2 => in_path (f_path ps (cl_dcl dcl2) n) dcl2 | cl_dcl dcl1, cl_object => in_path (f_path ps (cl_dcl dcl1) n) dcl1 | cl_object, cl_object => true end | in_prog_constr cl' => match cl' with cl_dcl dcl' => in_path (f_path ps (cl_dcl dcl') n) dcl' | cl_object => true end | inherited_fields_constr fds' cl' => match (get_ps_parent ps cl') with Some cl'' => match (list_inter _ fds' (ps_fields ps cl'' n) in_nat_list) with nil => true | _ => false end | None => false end | inherited_methods_constr mds' cl' => match (get_ps_parent ps cl') with Some cl'' => let pmds' := ps_methods ps cl'' n in fold_right (fun (md' : md) (b : bool) => match md' with md_def (ms_def ty' m' vd_list ) _ => if (negb (not_in_list m' pmds')) then match (ps_mtype ps cl'' m' n) with Some mty' => (mty_eq mty' (mty_def (map (fun (vd' : vd) => match vd' with vd_def ty'' _ => ty'' end) vd_list) ty')) && b | None => false end else true && b end) true mds' | None => false end end. Fixpoint introduce_all (ps : PS) : list cld := match ps with nil => nil | feature_def _ l :: ps' => introduce_classes (introduce_all ps') l end. 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 l l1); 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 l l1); 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 f l) _ _ (IHp'' _ _ H)); auto. Qed. Lemma names_introduce_all : forall (ps : PS) (p : P), compose_all ps = Some p -> names (introduce_all ps) = names p. induction ps. intros; inversion H; subst; simpl; reflexivity. destruct a; simpl. caseEq (compose_all 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 f1 l3) (introduce_classes (cld_def d0 c0 f l1 :: l) l0) (introduce_classes (cld_def d0 c f0 l2 :: p2) l0)); auto. apply IHl0. apply names_introduce_classes; auto. auto. discriminate. intros; discriminate. intros; discriminate. Qed. Lemma length_ps : forall (ps : PS) (p : P), compose_all 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 : PS) (cl' : cl) (p p' : P), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (cl' : cl) (f' : f) (p p' : P), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (cl' : cl) (m' : m) (p p' : P), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (cl' : cl) ( m' : m) (p p' : P), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (cl' : cl) (p p' : P), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (cl' : cl) (p p' : P), compose_all ps = Some p -> Permutation p p' -> ordered_p 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. Inductive distinct_constr : Set := fields_constraint : dcl -> fd -> distinct_constr | methods_constraint : dcl -> ms -> distinct_constr. Fixpoint cld_gen_distinct_constr (cld_list : list cld) : list distinct_constr := match cld_list with cld_def dcl' _ fds' mds' :: cld_list' => fold_right (fun (fd' : fd) (m : list distinct_constr) => fields_constraint dcl' fd' :: m) (nil : list distinct_constr) fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with md_def ms' _ => methods_constraint dcl' ms' :: m end) (nil : list distinct_constr) mds' ++ cld_gen_distinct_constr cld_list' | nil => nil end. Fixpoint rcld_gen_distinct_constr (rcld_list : list rcld) : list distinct_constr := match rcld_list with refines_cld_def dcl' _ fds' mds' _ :: rcld_list' => fold_right (fun (fd' : fd) (m : list distinct_constr) => fields_constraint dcl' fd' :: m) (nil : list distinct_constr) fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with md_def ms' _ => methods_constraint dcl' ms' :: m end) (nil : list distinct_constr) mds' ++ rcld_gen_distinct_constr rcld_list' | nil => nil end. Definition f_gen_distinct_constr (f : F) : list distinct_constr := match f with feature_def rclds clds => rcld_gen_distinct_constr rclds ++ cld_gen_distinct_constr clds end. Fixpoint ps_gen_distinct_constr (ps : PS) {struct ps} : list distinct_constr := match ps with f' :: ps' => f_gen_distinct_constr f' ++ ps_gen_distinct_constr ps' | nil => nil end. Fixpoint f_repeated (dcl' : dcl) (cl' : cl) (f' : f) (dc_list : list distinct_constr) {struct dc_list} : bool := match dc_list with fields_constraint dcl'' (fd_def (ty_def cl'') f'') :: dc_list' => if (eq_nat_dec dcl' dcl'') then if (eq_nat_dec f' f'') then if (cl_eq cl' cl'') then f_repeated dcl' cl' f' dc_list' else true else f_repeated dcl' cl' f' dc_list' else f_repeated dcl' cl' f' dc_list' | _ :: dc_list' => f_repeated dcl' cl' f' dc_list' | nil => false end. Fixpoint sat_f_distinct_constr (dcl' : dcl) (dc_list : list distinct_constr) {struct dc_list} : bool := match dc_list with fields_constraint dcl'' (fd_def (ty_def cl') f') :: dc_list' => if (eq_nat_dec dcl' dcl'') then if f_repeated dcl' cl' f' dc_list' then false else sat_f_distinct_constr dcl' dc_list' else sat_f_distinct_constr dcl' dc_list' | _ :: dc_list' => sat_f_distinct_constr dcl' dc_list' | nil => true end. Fixpoint ms_repeated (dcl' : dcl) (ty' : ty) (m' : m) (vd_list' : list vd) (dc_list : list distinct_constr) {struct dc_list} : bool := match dc_list with methods_constraint dcl'' (ms_def ty'' m'' vd_list'') :: dc_list' => if (eq_nat_dec dcl' dcl'') then if (eq_nat_dec m' m'') then if ms_eq (ms_def ty'' m'' vd_list'') (ms_def ty' m' vd_list') then ms_repeated dcl' ty' m' vd_list' dc_list' else true else ms_repeated dcl' ty' m' vd_list' dc_list' else ms_repeated dcl' ty' m' vd_list' dc_list' | _ :: dc_list' => ms_repeated dcl' ty' m' vd_list' dc_list' | nil => false end. Fixpoint sat_ms_distinct_constr (dcl' : dcl) (dc_list : list distinct_constr) {struct dc_list} : bool := match dc_list with methods_constraint dcl'' (ms_def ty' m' vd_list') :: dc_list' => if (eq_nat_dec dcl' dcl'') then if ms_repeated dcl' ty' m' vd_list' dc_list' then false else sat_ms_distinct_constr dcl' dc_list' else sat_ms_distinct_constr dcl' dc_list' | _ :: dc_list' => sat_ms_distinct_constr dcl' dc_list' | nil => true end. Lemma in_fd_gen_distinct_constr : forall (cld_list : list cld) (dcl' : dcl) (fd' : fd), In (fields_constraint dcl' fd') (cld_gen_distinct_constr 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 f; exists l; pa. po1. assert (d = dcl'). generalize H0; clear; induction f. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. apply (IHf H0). congruence. generalize H0; clear; induction f. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. po2; apply (IHf H0). destruct (in_app_or _ _ _ H0). elimtype False; generalize H1; clear; induction l. 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 distinct_constr) => fields_constraint d fd'0 :: m) nil f) (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint d ms' :: m end) nil l ++ cld_gen_distinct_constr cld_list) (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_distinct_constr : forall (cld_list : list cld) (dcl' : dcl) (ms' : ms), In (methods_constraint dcl' ms') (cld_gen_distinct_constr 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 f. simpl; auto. destruct a; simpl; intros; bd H0. discriminate. auto. destruct (in_app_or _ _ _ H0). exists c; exists f; exists l; pa. po1. assert (d = dcl'). generalize H1; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. inversion H1; auto. apply (IHl H1). congruence. generalize H1; clear; induction l. 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 distinct_constr) => fields_constraint d fd'0 :: m) nil f) (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint d ms' :: m end) nil l ++ cld_gen_distinct_constr cld_list) (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_distinct_constr_rcld : forall (rcld_list : list rcld) (dcl' : dcl) (fd' : fd), In (fields_constraint dcl' fd') (rcld_gen_distinct_constr 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 f; exists l; exists l0; pa. po1. assert (d = dcl'). generalize H0; clear; induction f. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. apply (IHf H0). congruence. generalize H0; clear; induction f. simpl; intros; contradiction. destruct a; simpl; intros. bd H0. inversion H0; auto. po2; apply (IHf H0). destruct (in_app_or _ _ _ H0). elimtype False; generalize H1; clear; induction l. 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 distinct_constr) => fields_constraint d fd'0 :: m) nil f) (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint d ms' :: m end) nil l ++ rcld_gen_distinct_constr rcld_list) (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_distinct_constr_rcld : forall (rcld_list : list rcld) (dcl' : dcl) (ms' : ms), In (methods_constraint dcl' ms') (rcld_gen_distinct_constr 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 f. simpl; auto. destruct a; simpl; intros; bd H0. discriminate. auto. destruct (in_app_or _ _ _ H0). exists c; exists f; exists l; exists l0; pa. po1. assert (d = dcl'). generalize H1; clear; induction l. simpl; intros; contradiction. destruct a; simpl; intros. bd H1. inversion H1; auto. apply (IHl H1). congruence. generalize H1; clear; induction l. 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 distinct_constr) => fields_constraint d fd'0 :: m) nil f) (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint d ms' :: m end) nil l ++ rcld_gen_distinct_constr rcld_list) (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 : PS) (f' : F), compose_all (f' :: ps) = Some p -> exists p'', compose_all ps = Some p''. simpl. intros; destruct (compose_all 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 p' (feature_def (rcld' :: rcld_list) cld_list) = Some p -> exists p'', compose p' (feature_def rcld_list nil) = Some p'' /\ exists p''', compose_refines_class p'' rcld' = Some p'''/\ p = introduce_classes p''' cld_list /\ compose p' (feature_def rcld_list cld_list) = 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 cld_list (feature_def rcld_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 (IHl0 H4); bd H; pa. po2. bd H4. pa. po1. congruence. import (IHl0 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 (IHl0 H H0). simpl; intros; po2; apply (IHl0 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' f). generalize H0; clear; induction f; simpl. po1. induction (introduce_fields x3 f). simpl. intros; bd H0. po2; po1. destruct a0; destruct a; destruct t; destruct t0; simpl. case (eq_nat_dec f0 f1); intros; subst. caseEq (cl_eq c c0); intros; rewrite H in H0. destruct (IHf H0). po1. repeat po2. simpl in H0; bd H0. simpl in IHf; destruct (IHf (or_introl _ H0)). po1. repeat po2. apply IHl. intros; apply IHf; po2. exact H0. simpl in H0; bd H0. simpl in IHf; destruct (IHf (or_introl _ H0)). po1. repeat po2. apply IHl. intros; apply IHf; 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 IHl0; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl0; 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 f; exists l; exists l0; 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 IHl0; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl0; 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 cld_list (feature_def rcld_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 (IHl0 H4); bd H; pa. po2. bd H4. pa. po1. congruence. import (IHl0 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 (IHl0 H H0). simpl; intros; po2; apply (IHl0 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 l ms'); intros. repeat po2; exists c; exists f; exists l; exists l0; 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 IHl0; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl0; 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 IHl0; auto. simpl in H0; bd H0; intros. unfold not; intros H3; bd H3. apply IHl0; 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_distinct_constr : forall (ps : PS) (p : P) (dc : distinct_constr), compose_all ps = Some p -> In dc (cld_gen_distinct_constr p) -> In dc (ps_gen_distinct_constr ps). induction ps; simpl. intros; inversion H; subst; simpl in H0; exact H0. caseEq (compose_all ps); intros. destruct dc. import ((proj1 (in_fd_gen_distinct_constr _ _ _ )) 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 _ (fields_constraint d f) H). applyI in_fd_gen_distinct_constr. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po2. applyI in_fd_gen_distinct_constr. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po1. applyI in_fd_gen_distinct_constr_rcld. exists x2; exists x3; exists x4; exists x5; pa. import ((proj1 (in_ms_gen_distinct_constr _ _ _ )) 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 _ (methods_constraint d m) H). applyI in_ms_gen_distinct_constr. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po2. applyI in_ms_gen_distinct_constr. exists x2; exists x3; exists x4; pa. apply in_or_app; po1; simpl; apply in_or_app; po1. applyI in_ms_gen_distinct_constr_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 distinct_constr), cl_eq cl'' cl' = false -> In (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 distinct_constr), ms_eq (ms_def ty' m' vd_list) (ms_def ty'' m' vd_list') = false -> In (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 distinct_constr), (forall (d : distinct_constr), In d dc_list -> In d dc_list') -> sat_f_distinct_constr dcl' dc_list' = true -> sat_f_distinct_constr 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 (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 distinct_constr), (forall (d : distinct_constr), In d dc_list -> In d dc_list') -> sat_ms_distinct_constr dcl' dc_list' = true -> sat_ms_distinct_constr 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_distinct_constr : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_f_distinct_constr dcl' (cld_gen_distinct_constr (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_distinct_constr dcl' (fold_right (fun (fd' : fd) (m : list distinct_constr) => 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 distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ nil)); intros. discriminate. caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list distinct_constr) => 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 distinct_constr) => 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_distinct_constr_ms : forall (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_ms_distinct_constr dcl' (cld_gen_distinct_constr (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_distinct_constr dcl' (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m1 end) nil mds')). caseEq (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m1 : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => match md' with | md_def ms' _ => 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. Fixpoint sat_distinct_constr (dc_list : list distinct_constr) {struct dc_list} : bool := match dc_list with fields_constraint dcl' _ :: dc_list' => sat_f_distinct_constr dcl' dc_list && sat_distinct_constr dc_list' | methods_constraint dcl' _ :: dc_list' => sat_ms_distinct_constr dcl' dc_list && sat_distinct_constr dc_list' | nil => true end. Lemma sat_ms_distinct_constr_none : forall (dc_list : list distinct_constr) (dcl' : dcl), (forall ms', ~ In (methods_constraint dcl' ms') dc_list) -> sat_ms_distinct_constr 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_distinct_constr_none : forall (dc_list : list distinct_constr) (dcl' : dcl), (forall fd', ~ In (fields_constraint dcl' fd') dc_list) -> sat_f_distinct_constr 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_distinct_constr_all : forall (dc_list : list distinct_constr) (ms' : ms) (fd' : fd) (dcl' : dcl), In (fields_constraint dcl' fd') dc_list \/ In (methods_constraint dcl' ms') dc_list -> sat_distinct_constr dc_list = true -> sat_f_distinct_constr dcl' dc_list = true /\ sat_ms_distinct_constr 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 (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_distinct_constr_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 (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_distinct_constr_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 (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_distinct_constr_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 distinct_constr), (forall (d : distinct_constr), In d dc_list -> In d dc_list') -> sat_distinct_constr dc_list' = true -> sat_distinct_constr dc_list = true. induction dc_list. simpl; auto. destruct a. intros; import (H _ (or_introl _ (refl_equal _))). intros; import (sat_distinct_constr_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 (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_distinct_constr_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 (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 : PS) (p : P) (dcl': dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose_all 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_all 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. (**** Break 1 ***) 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 f). (*** dcl' <> d***) 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 : PS) (p : P) (dcl': dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose_all 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_all 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). (*** dcl' <> d***) 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_distinct_constr_unique: forall (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_distinct_constr (cld_gen_distinct_constr (cld_def dcl' cl' fds' mds' :: p)) = true -> ~ In (cl_dcl dcl') (names p) -> sat_distinct_constr (cld_gen_distinct_constr (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 distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr p)). intros; discriminate. destruct (ms_repeated dcl' (ty_def c0) m1 l (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr p)). intros; discriminate. intros; apply (IHmds' H2). caseEq (ms_repeated dcl' (ty_def c) m1 l0 (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr 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 distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr p)). simpl; intros; discriminate. destruct (ms_repeated dcl' t m l (fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ nil)). caseEq (ms_repeated dcl' t0 m1 l0 (fold_right (fun (md' : md) (m3 : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m3 end) nil mds' ++ cld_gen_distinct_constr p)). auto. intros; apply (IHmds' H1). caseEq (ms_repeated dcl' t0 m1 l0 (fold_right (fun (md' : md) (m3 : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m3 end) nil mds' ++ cld_gen_distinct_constr p)). intros; discriminate. caseEq (ms_repeated dcl' t0 m1 l0 (fold_right (fun (md' : md) (m3 : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr p)). intros; discriminate. caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr p)). intros; discriminate. caseEq (f_repeated dcl' c f (fold_right (fun (fd' : fd) (m : list distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr 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 distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => 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 distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => methods_constraint dcl' ms' :: m end) nil mds' ++ cld_gen_distinct_constr p)); intros; rewrite H1 in H4. discriminate. rewrite (IHfds' H H4). caseEq (f_repeated dcl' c0 f0 (fold_right (fun (fd' : fd) (m : list distinct_constr) => fields_constraint dcl' fd' :: m) nil fds' ++ fold_right (fun (md' : md) (m : list distinct_constr) => match md' with | md_def ms' _ => 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_distinct_constr_unique': forall (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), sat_distinct_constr (cld_gen_distinct_constr (cld_def dcl' cl' fds' mds' :: p)) = true -> ~ In (cl_dcl dcl') (names p) -> sat_distinct_constr (cld_gen_distinct_constr 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 : PS) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose_all ps = Some p -> sat_distinct_constr (ps_gen_distinct_constr 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 : distinct_constr), In d (cld_gen_distinct_constr p) -> In d (ps_gen_distinct_constr ps)). intros; apply (gen_distinct_constr 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_distinct_constr_unique _ _ _ _ _ H5 H3). generalize H0 H7 H8; clear; induction fds'. induction mds'. simpl; pa. intros. pa. destruct a. import (sat_distinct_constr_all (cld_gen_distinct_constr (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_distinct_constr_ms _ _ _ _ H2 H8). intros. destruct a. import (sat_distinct_constr_all (cld_gen_distinct_constr (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_distinct_constr _ _ _ _ H1 H7). apply (sat_distinct_constr_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_distinct_constr_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 : PS) : 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 : PS) (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 : PS), 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 : PS) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md), compose_all ps = Some p -> sat_distinct_constr (ps_gen_distinct_constr 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. 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 : F) : 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: PS) : 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 sat_distinct_constr_app : forall (dc_list dc_list': list distinct_constr), sat_distinct_constr (dc_list ++ dc_list') = true -> sat_distinct_constr 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 l1 l0). intros; congruence. intros; congruence. intros; congruence. Qed. Lemma get_refined_eq_self : forall (ps : PS) (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 : lj.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 : lj.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 : lj.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.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 : lj.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 : lj.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.x) (m0 : option (list ty)) => match XMap.find y (fold_left (fun (m1 : XMap.t ty) (p : lj.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.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.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.x) (m0 : option (list ty)) => match XMap.find y (fold_left (fun (m1 : XMap.t ty) (p : lj.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.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.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.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.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.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.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.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.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 : 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 : 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.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.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.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 s)). destruct (XMap.find x (fold_left (fun (m : XMap.t ty) (p : lj.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 ++ l3) ++ l2); 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.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.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 (l3 ++ x1); auto. discriminate. intros; discriminate. discriminate. Qed. 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) l2)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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 d)) (XMap.empty ty))) (make_list_s s)); intros; rewrite H3 in H4. destruct m. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l4)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l4) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s0)); intros; rewrite H5 in H1. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l4) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s1)); intros; rewrite H6 in H1. import ((proj1 (eq_ms_eq _ _ )) H); inversion H7; subst. rewrite (gen_stmt_list_app s0 (s ++ s1) _ _ _ _ H5 (gen_stmt_list_app _ _ _ _ _ _ H3 H6)). destruct (XMap.find x1 (fold_left (fun (m0 : XMap.t ty) (p : lj.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) l4) (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) l4 ++ l5 ++ l3 ++ l6) ++ l1); 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) l2) then match gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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 d)) (XMap.empty ty))) (make_list_s s) with | Some c_list => match XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj.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 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) l2 ++ c_list) | None => None (A:=list ty_constraint) end | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint))). exists (l3 ++ x3); auto. discriminate. discriminate. discriminate. discriminate. Qed. Lemma ex_gen_ps_gen_p : forall (ps : PS) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (mds' : list md) (t_list : list ty_constraint), compose_all ps = Some p -> gen_ps_constr ps = Some t_list -> sat_distinct_constr (ps_gen_distinct_constr 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 f l3 cl' 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 f0 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 l5 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) l0); intros; rewrite H4 in H2. destruct (IHl (l7 ++ l8) _ _ _ _ _ _ _ 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) l5 = 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) l5); 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) l5); intros. exists l; auto. discriminate. destruct H2; generalize l5 l6 l3 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 f1 f)) (cl_dcl d0) :: inherited_methods_constr l6 (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f1 f) ++ x1) ++ nil); auto. intros l5 l6 l3 x1. caseEq (compose_refined_mds l5 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 l0 H H2 H3 n; destruct (IHl2 _ _ _ _ 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) l0); intros. rewrite H5 in H0; simpl in H0. generalize l6 l4 H5 H1 H2; clear. destruct a; induction l0. 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) l0). 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) l3)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s0)); intros; rewrite H2 in H1. caseEq ( gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s1)); intros; rewrite H3 in H1. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s)); intros; rewrite H4 in H5. rewrite (gen_stmt_list_app s0 (s ++ s1) _ _ _ _ H2 (gen_stmt_list_app _ _ _ _ _ _ H4 H3)). destruct (XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (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 f1 f)) (cl_dcl d0) :: inherited_methods_constr (md_def (ms_def t m0 l3) (mb_def (s0 ++ s ++ s1) x0) :: l0) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f1 f) ++ (sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l3 ++ l5 ++ l7 ++ l6) ++ l2) ++ nil); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros. rewrite H0 in IHl0. destruct (cons_option_Some _ _ _ _ H2). rewrite H3 in H2; simpl in H2; inversion H2; subst. destruct (IHl0 x1 _ (refl_equal _)). simpl. destruct m. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l3)). 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.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 s) with | Some c_list => match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj.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 f1 f)) (cl_dcl d0) :: inherited_methods_constr (md_def m0 (mb_def s x) :: x1) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f1 f) ++ l5 ++ l3) ++ 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 _ _ _ _ H0 H2 n (refl_equal _)). destruct a; generalize x H H3; clear. induction (introduce_methods l6 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 f1 f)) (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 f1 f) ++ l0 ++ 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) l3)). 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 f1 f)) (cl_dcl d0) :: inherited_methods_constr (md_def (ms_def t m l3) (mb_def s x0) :: l) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f1 f) ++ l0 ++ 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.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.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 f1 f)) (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 f1 f) ++ l4 ++ l3) ++ 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) l5 = 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) l5); 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) l5); intros. exists l; auto. discriminate. destruct H2; generalize l5 l6 l3 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 f1 f) ++ x1) ++ nil); auto. intros l5 l6 l3 x1. caseEq (compose_refined_mds l5 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 l0 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) l0); intros. simpl. rewrite H4 in H0; simpl in H0. generalize l6 l4 H4 H1 H2; clear. destruct a; induction l0. 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) l0). 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) l3)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s0)); intros; rewrite H2 in H1. caseEq ( gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s1)); intros; rewrite H3 in H1. simpl. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (XMap.add x_this (ty_def (cl_dcl d)) (XMap.empty ty))) (make_list_s s)); intros; rewrite H5 in H4. rewrite (gen_stmt_list_app s0 (s ++ s1) _ _ _ _ H2 (gen_stmt_list_app _ _ _ _ _ _ H5 H3)). destruct (XMap.find x0 (fold_left (fun (m : XMap.t ty) (p : lj.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) l3) (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 f1 f) ++ (sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l3 ++ l5 ++ l7 ++ l6) ++ l2) ++ nil); auto. discriminate. discriminate. discriminate. discriminate. discriminate. intros. rewrite H0 in IHl0. destruct (cons_option_Some _ _ _ _ H2). rewrite H3 in H2; simpl in H2; inversion H2; subst. destruct (IHl0 x1 _ (refl_equal _)). simpl. destruct m. destruct (distinct_list (map (fun vd' : vd => match vd' with | vd_def _ var' => var' end) l3)). 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.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 s) with | Some c_list => match XMap.find x (fold_left (fun (m1 : XMap.t ty) (p : lj.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 f1 f) ++ l5 ++ l3) ++ 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 l6 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 f1 f) ++ l0 ++ 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) l3)). rewrite H0. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f1 f) ++ l0 ++ 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.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.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 f1 f) ++ l4 ++ l3) ++ 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 f1 mds' l5 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 f1 f)) (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 f1 f) ++ x0) ++ nil); auto. destruct a; simpl. intros d1 c1 f2 mds' l7; caseEq (build_refined_classes (cld_def d1 c0 f0 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) f) (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) f ++ 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) l0); intros; rewrite H6 in H3. intros; destruct (IHl _ _ _ _ _ ((l10 ++ l9) ++ l11) H H4 H2 n). rewrite H5; rewrite H6. auto. generalize H0; clear H0; simpl. case (eq_nat_dec d2 d). caseEq (compose_refined_mds l6 l5); 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) l6); 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) l5); 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) l3); 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 f3 f1) f)) (cl_dcl d0) :: inherited_methods_constr (introduce_methods l12 l3) (cl_dcl d0) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields (introduce_fields f3 f1) f) ++ 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) l3); try discriminate. destruct c1; generalize H1; clear H1. case (eq_nat_dec d d1); intros; discriminate. intros; discriminate. generalize H1; clear H1; destruct c1. case (eq_nat_dec d d1); intros; discriminate. intros; discriminate. 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 ((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 f3 f1) f)) (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 (introduce_fields f3 f1) f) ++ l6) ++ nil); auto. 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 ((in_prog_constr (cl_dcl d0) :: inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) (introduce_fields f2 f)) (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 f2 f) ++ l6) ++ nil); auto. 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 f1 l5 mds' H2 H1 H; clear; induction l. simpl. intros. inversion H; subst. rewrite H2. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f1 f) ++ l6) ++ nil); auto. destruct a; simpl. intros; caseEq (build_refined_classes (cld_def d0 c0 f0 l4) l); simpl. intros d1 c2 f3 l2 H3; rewrite H3 in H. generalize H; simpl. case (eq_nat_dec d1 d); intros. caseEq (compose_refined_mds l2 l1); 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) l1); 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 _ _ _ _ _ H2 H7 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 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). 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) l0); intros; rewrite H10 in H1. destruct (gen_constr_introduce_mds _ _ _ _ _ H9 H10); rewrite H11. exists ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields (introduce_fields f3 f1) f) ++ x1) ++ nil). 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) l0); 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 _ _ _ _ _ H2 H0 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 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 ((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields (introduce_fields f3 f1) f) ++ l3) ++ nil); auto. 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 _ _ _ _ _ H2 H0 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 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((map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) (introduce_fields f2 f) ++ l3) ++ nil); 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) l0); intros; rewrite H1 in H2. destruct (IHl (l5 ++ 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) f) (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) f ++ 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'' ++ l5) | 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) f) (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) f ++ 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'' ++ l5) | 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.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.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 s)). destruct (XMap.find x (fold_left (fun (m0 : XMap.t ty) (p : lj.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 : PS) (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 f l = 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) l1). 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) l1); 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) f)); try (simpl; intros; discriminate). destruct (distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)); 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) l); try (simpl; intros; discriminate). simpl; intros. inversion H. import (IHl0 dcl' cl' fds' mds' cl'' ((l2 ++ l3) ++ l4) t_list' l1). 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) f)); try (simpl; intros; discriminate). destruct (distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)); 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) l); 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'' ((l2 ++ l3) ++ l4) t_list' l1). 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l) 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) l 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) f) (cl_dcl d) :: inherited_methods_constr l (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f ++ 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l) 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) l with | Some c_list => Some (inherited_fields_constr (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f) (cl_dcl d) :: inherited_methods_constr l (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f ++ c_list) | None => None (A:=list ty_constraint) end else None (A:=list ty_constraint) end with | Some c_list'' => Some (c_list'' ++ l3) | None => None (A:=list ty_constraint) end with | Some c_list'' => Some (l2 ++ c_list'') | None => None (A:=list ty_constraint) end); discriminate. discriminate. discriminate. Qed. Lemma in_rcld_gen_p_subset_gen_ps_inherited : forall (ps : PS) (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 f l = 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) l1). 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) l1); 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)). 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) l). caseEq (gen_ps_constr ps); intros. inversion H5; subst; clear H5. import (IHl0 dcl' cl' fds' mds' ((l2 ++ l3) ++ l4) l1). 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)). 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) l). caseEq (gen_ps_constr ps); intros. inversion H; subst; clear H. import (IHl0 dcl' cl' fds' mds' ((l2 ++ l3) ++ l4) l1). 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 : PS) (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 f l = 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) l1). 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)); 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) l). 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) f) (cl_dcl d) :: inherited_methods_constr l (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f ++ l4)); 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)); 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) l). 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) f) (cl_dcl d) :: inherited_methods_constr l (cl_dcl d) :: map (fun fd' : fd => match fd' with | fd_def (ty_def cl') _ => in_prog_constr cl' end) f ++ l4); 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) l1); 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)); 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) l). intros. destruct (gen_ps_constr ps). inversion H2; subst; clear H2. import (IHl0 cld' ((l2 ++ l3) ++ l5 ) l1 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) f) && distinct_list (map (fun md' : md => match md' with | md_def (ms_def _ m' _) _ => m' end) l)); 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) l). intros. destruct (gen_ps_constr ps). inversion H2; subst; clear H2. import (IHl0 cld' ((l2 ++ l3) ++ l5 ) l1 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 : PS) (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 f0 l3) l); intros; rewrite H in H6. generalize H6; clear H6; simpl. case (eq_nat_dec d1 d). caseEq (compose_refined_mds l4 l2). 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) l1); 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) l2); 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) 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 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) 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). 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) l1); 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) l2); 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 ((l5 ++ l8) ++ l9) _ _ _ _ (cld_def d0 c0 f0 l3) 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) f ++ l6 ++ l7). simpl; auto. simpl; intros; po2; auto. discriminate. caseEq (gen_ps_constr ps); intros. inversion H0; subst; clear H0. import (IHl ((l5 ++ l8) ++ l9) _ _ _ _ (cld_def d0 c0 f0 l3) 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) f ++ l6 ++ l7). 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 : PS) (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_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all 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_all 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'' f -> 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)) 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 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). bd H1. exists x; pa. apply in_or_app; po2. discriminate. destruct a; intros. 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). 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 fd' f). exists f; pa; auto. simpl; po2; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l7 l5 f f1 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 l7 l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f' l6; subst; case (compose_refined_mds l6 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 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros; inversion H4; subst; clear H4. inversion H0; subst; clear H0. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H4; subst; clear H4. simpl. inversion H0; subst; clear H0. cs (In fd' f). exists f; 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) 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) l3). 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) 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) l3). 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' f). exists f; pa; auto. simpl; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l7 l5 f f1 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 l7 l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f' l6; subst; case (compose_refined_mds l6 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) l0). 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) l3). 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) 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' f). exists f; pa; auto. simpl; po2; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l6 mds' f f1 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 l6 l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f' l10; subst; case (compose_refined_mds l10 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 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros; inversion H4; subst; clear H4. inversion H0; subst; clear H0. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H4; subst; clear H4. simpl. inversion H0; subst; clear H0. cs (In fd' f). exists f; 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) 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) l3). 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) 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) l3). 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' f). exists f; pa; auto. simpl; po1. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l6 mds' f f1 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 l6 mds' f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f' l5; subst; case (compose_refined_mds l5 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In fd' f). exists f; 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) l0). 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) l3). 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) l1); 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 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 ((l6 ++ l9) ++ l2) d1 c0 fds' mds' f0 l4). 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 ((l6 ++ l9) ++ l2) d1 c0 fds' mds' f0 l4). 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) 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 ++ l7 ++ l8) | 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 ++ l7 ++ l8) end with | Some c_list'' => Some (c_list'' ++ l6) | 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. Lemma inherit_mds_gen_p_gen_ps : forall (ps : PS) (p : P) (dcl' : dcl) (cl' : cl) (fds' : list fd) (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_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all 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_all 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 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' 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). bd H1. exists x; exists x0; pa. apply in_or_app; po2. discriminate. destruct a; intros. 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). 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). 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 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 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 _ _ _ _ _ _ _ f1 _ _ _ _ (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 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 _ _ _ _ _ _ _ f1 _ _ _ _ (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 _ _ _ _ _ _ _ f1 _ _ _ _ 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 _ _ _ _ _ _ _ f1 _ _ _ _ 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. 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 _ _ _ _ _ _ _ f1 _ _ _ _ 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. 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 _ _ _ _ _ _ _ f1 _ _ _ _ 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). 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 _ _ _ _ _ _ _ f1 _ _ _ _ (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 _ _ _ _ _ _ _ f1 _ _ _ _ (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 _ _ _ _ _ _ _ f1 _ _ _ _ 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 _ _ _ _ _ _ _ f1 _ _ _ _ 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. 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 _ _ _ _ _ _ _ f1 _ _ _ _ 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. 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 _ _ _ _ _ _ _ f1 _ _ _ _ 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 : PS) (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_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all 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_all 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 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. 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). 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 (fd_def (ty_def cl'') f') f). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear. induction f; simpl; intros. contradiction. bd H3; subst. po1. po2; auto. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l7 l5 f 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. intros l7 l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f'' l6; subst; case (compose_refined_mds l6 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 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) 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. 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) 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) 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. 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') f). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear; induction f. 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 l7 l5 f 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. intros l7 l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f'' l6; subst; case (compose_refined_mds l6 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) 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) 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) 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. 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. 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') f). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear. induction f; simpl; intros. contradiction. bd H3; subst. po1. po2; auto. destruct (In_introduce_fields _ _ _ H4). elimtype False; apply (H3 H11). generalize l6 mds' f 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. intros l6 l5 f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d2 d1). intros e cl' f'' l10; subst; case (compose_refined_mds l10 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 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) 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. 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) 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) 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. 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') f). simpl; repeat po2. repeat (apply in_or_app; po1). revert H3; clear; induction f. 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 mds' f 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. intros l6 mds' f2 f3 c0; caseEq (build_refined_classes (cld_def d c0 f0 l4) l). simpl build_refined_class. intro; case (eq_nat_dec d1 d0). intros e cl' f1 l5; subst; case (compose_refined_mds l5 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros; inversion H2; subst; clear H2. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) l3). intros. inversion H2; subst; clear H2. simpl. cs (In (fd_def (ty_def cl'') f') f). 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 f. 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) 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) 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) 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) 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) 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 ++ l7 ++ l8) | 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 ++ 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) ++ l2) d1 c0 c1 f1 l5 f0 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) ++ l2) d1 c0 c1 f1 l5 f0 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) 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 ++ 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) 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 ++ 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) l)). caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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 dcl')) (XMap.empty ty))) (make_list_s s0)); intros; rewrite H in H5. caseEq (gen_stmt_list_constr (fold_left (fun (m : XMap.t ty) (p : lj.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 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.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 dcl')) (XMap.empty ty))) (make_list_s s)); 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.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 dcl')) (XMap.empty ty)))). inversion H3; subst; clear H3. destruct (XMap.find x (fold_left (fun (m : XMap.t ty) (p : lj.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 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; 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. 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.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.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.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.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.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. 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. simpl build_refined_class. intros until 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). 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. 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.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.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.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 s2)); 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.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 (sty_cl_constr t0 t :: map (fun vd' : vd => match vd' with | vd_def (ty_def cl') _ => in_prog_constr cl' end) l ++ l0 ++ l2 ++ l1); 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 : PS) (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_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all 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_all 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. 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. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f) && 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. destruct (distinct_list (map (fun fd' : fd => match fd' with | fd_def _ f' => f' end) f) && 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. caseEq (build_refined_classes (cld_def d0 c0 f0 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). 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) l1); 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' l1). 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) ++ l2) x0 d c0 c1 f1 l5 f0 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' l1). 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) ++ l2) x0 d c0 c1 f1 l5 f0 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) 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. 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) l1); 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) ++ l2) t_list' d c0 c1 f1 mds' f0 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) 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 ++ l6 ++ l7) | 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 ++ 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) l1); 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) ++ l2) t_list' d1 c0 cl' fds' mds' f0 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) 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 ++ l6 ++ l7) | 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 ++ 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. Fixpoint ps_sat_constr_list (ps : PS) (c_list : list ty_constraint) (n : nat) {struct c_list}: bool := match c_list with constr :: c_list' => ps_sat_constr ps constr n && ps_sat_constr_list ps c_list' n | nil => true end. Lemma in_sat_ps_list : forall (ps : PS) (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 : PS) (p p' : P) (cl' : cl), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (p p' : P) (cl' : cl) (f' : f) (ty' : ty), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (p p' : P) (cl' : cl) (f' : f) (ty' : ty), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (p p' : P) (cl' : cl) (m' : m) (ty' : ty) (ty_list : list ty), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 t0; destruct c. case (eq_nat_dec (length ty_list) (length t)); 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 t); simpl. auto. destruct a; destruct t0; destruct t1; destruct c; destruct c0; try (rewrite IHl; 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 t0; destruct c. case (eq_nat_dec (length ty_list) (length t)); 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 t); simpl. auto. destruct a; destruct t0; destruct t1; destruct c; destruct c0; try (rewrite IHl; rewrite (f_path_eq_path _ (cl_dcl d0) _ _ H H0 H1); auto). auto. auto. case (eq_nat_dec (length ty_list) (length t)); auto. rewrite (length_ps ps p); auto. intros; induction (combine ty_list t); simpl. auto. destruct a; destruct t0; destruct t1; destruct c; destruct c0; try (rewrite IHl; rewrite (f_path_eq_path _ (cl_dcl d) _ _ H H0 H1); auto). auto. auto. Qed. Lemma ps_sat_constr_compos_sty_cl : forall (ps : PS) (p p' : P) (ty' ty'' : ty), compose_all ps = Some p -> Permutation p p' -> ordered_p 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 : PS) (p p' : P) (ty' ty'' : ty), compose_all ps = Some p -> Permutation p p' -> ordered_p 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. Theorem sat_ps_sat_p : forall (ps : PS) (p p' : P) (dcl' : dcl) (cl' : cl) (fds' : fds) (mds' : list md) (t_list : list ty_constraint), get_refined_cld ps (cl_dcl dcl') = Some (cld_def dcl' cl' fds' mds') -> Permutation p p' -> ordered_p p' -> sat_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all ps = Some p -> gen_ps_constr ps = Some t_list -> ps_sat_constr_list ps t_list (length (introduce_all ps)) = true -> exists t_list', gen_cld_constr (cld_def dcl' cl' fds' mds' :: nil) = Some t_list' /\ sat_constr_list p' t_list' = true. intros. destruct (ex_gen_ps_gen_p _ _ _ _ _ _ _ H4 H5 H2 H3 H). exists x; pa. generalize H7; simpl gen_cld_constr. destruct cl'; 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; discriminate). case (eq_nat_dec dcl' d); try (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; try discriminate. inversion H9; subst; clear H9. import (in_prog_gen_p_gen_ps _ _ _ _ _ _ _ H H5 H7). simpl in H9; import (H9 (or_introl _ (refl_equal _))); clear H9. assert (forall fd', 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). intros. apply (inherit_fds_gen_p_gen_ps _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H9). assert (forall ms' mb', 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). intros; apply (inherit_mds_gen_p_gen_ps _ _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H11). assert (forall cl'' f', In (fd_def (ty_def cl'') f') fds' -> In (in_prog_constr cl'') t_list). intros; apply (in_prog_fds_gen_p_gen_ps _ _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H12). simpl; repeat (apply andb_true_intro; pa). import (in_sat_ps_list _ _ _ _ H10 H6). rewrite (ps_sat_constr_in_prog _ _ _ (cl_dcl d) H4 H0 H1) in H13. apply H13. rewrite <- (ps_fields_eq_fields _ (cl_dcl d) _ _ H4 H0 H1). assert (get_ps_parent ps (cl_dcl dcl') = Some (cl_dcl d)). unfold get_ps_parent; rewrite H; simpl; reflexivity. clear H; rename H13 into H. generalize H9 H6 H; clear. induction fds'; intros. simpl; auto. simpl. destruct a. simpl in H9; import (H9 _ (or_introl _ (refl_equal _))). bd H0. import (in_sat_ps_list _ _ _ _ H0 H6). simpl in H1. rewrite H in H1. assert (in_nat_list f (ps_fields ps (cl_dcl d) (length (introduce_all ps))) = false). generalize H1 H3; clear; induction x. simpl; intros; contradiction. destruct a; simpl. intros. bd H3. inversion H3; subst; clear H3. destruct (in_nat_list f (ps_fields ps (cl_dcl d) (length (introduce_all ps)))). discriminate. auto. apply IHx; auto. destruct (in_nat_list f0 (ps_fields ps (cl_dcl d) (length (introduce_all ps)))). discriminate. auto. rewrite H2. apply IHfds'; auto. rewrite <- (ps_methods_eq_methods _ (cl_dcl d) _ _ H4 H0 H1). assert (forall m', ps_mtype ps (cl_dcl d) m' (length (introduce_all ps)) = mtype p' (cl_dcl d) m'). intros; apply (ps_mtype_eq_mtype _ (cl_dcl d) m' _ _ H4 H0 H1). assert (get_ps_parent ps (cl_dcl dcl') = Some (cl_dcl d)). unfold get_ps_parent; rewrite H; simpl; reflexivity. clear H H0; rename H13 into H; rename H14 into H0. generalize H11 H6 H H0; clear. induction mds'; intros. simpl; auto. simpl. destruct a. simpl in H11; import (H11 _ _ (or_introl _ (refl_equal _))). bd H1. import (in_sat_ps_list _ _ _ _ H1 H6). simpl in H2. destruct m. rewrite <- H. rewrite H0 in H2. assert ((if negb (not_in_list m (ps_methods ps (cl_dcl d) (length (introduce_all ps)))) then match ps_mtype ps (cl_dcl d) m (length (introduce_all ps)) with | Some mty' => mty_eq mty' (mty_def (map (fun vd' : vd => match vd' with | vd_def ty'' _ => ty'' end) l) t) && true | None => false end else true) = true). revert H2 H4; clear; induction x0. simpl; intros; contradiction. simpl; intros. bd H4; subst. destruct (negb (not_in_list m (ps_methods ps (cl_dcl d) (length (introduce_all ps))))); auto. destruct (ps_mtype ps (cl_dcl d) m (length (introduce_all ps))). destruct (andb_prop _ _ H2); auto. rewrite H; auto. discriminate. apply IHx0; auto. destruct a; simpl. destruct m0. destruct (negb (not_in_list m0 (ps_methods ps (cl_dcl d) (length (introduce_all ps))))). destruct (ps_mtype ps (cl_dcl d) m0 (length (introduce_all ps))). destruct (andb_prop _ _ H2). exact H0. discriminate. exact H2. destruct (negb (not_in_list m (ps_methods ps (cl_dcl d) (length (introduce_all ps))))). destruct (ps_mtype ps (cl_dcl d) m (length (introduce_all ps))); try discriminate. rewrite (proj1 (andb_prop _ _ H3)). simpl. apply IHmds'; auto. intros; apply (H11 _ _ (or_intror _ H5)). apply IHmds'; auto. intros; apply (H11 _ _ (or_intror _ H5)). rewrite <- app_nil_end. cut (sat_constr_list p' l = true). revert H12 H6 H0 H1 H4; clear; induction fds'. simpl; auto. destruct a; intros. simpl. destruct t; simpl in H12; import (H12 _ _ (or_introl _ (refl_equal _))). rewrite <- (ps_sat_constr_in_prog _ _ _ c H4 H0 H1). rewrite (in_sat_ps_list _ _ _ _ H2 H6); simpl. apply IHfds'; auto. intros; apply (H12 _ _ (or_intror _ H3)). assert (forall md', In md' mds' -> exists t_list', gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list'). generalize l H8; clear; induction mds'. simpl; intros. contradiction. simpl; 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 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'); bd H; subst. destruct (gen_meth_constr (ty_def (cl_dcl dcl')) md'); try discriminate. exists l1; auto. apply (IHmds' l0); auto. discriminate. discriminate. assert (forall md', In md' mds' -> exists t_list', gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list' /\ (forall tyc', In tyc' t_list' -> (ps_sat_constr ps tyc' (length (introduce_all ps)) = true /\ (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl')))). intros. destruct (H13 _ H14). exists x. pa. intros. import (In_stmt_gen_p_gen_ps _ _ _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H14 H15 H16). import (In_gen_meth_constr _ _ _ _ H15 H16). bd H18; pa. apply (in_sat_ps_list _ _ _ _ H17 H6). pa. assert (forall tyc', In tyc' l -> (ps_sat_constr ps tyc' (length (introduce_all ps)) = true /\ (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl'))). generalize l H8 H14; clear; induction mds'. simpl; intros. inversion H8; subst; simpl in H; contradiction. intros. simpl in H8. 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'). simpl in H14; import (H14 a (or_introl _ (refl_equal _))). bd H0. rewrite H3 in H8. inversion H8; subst; clear H8. import (in_app_or _ _ _ H). bd H1; clear H. apply (H0 _ H1). apply (IHmds' l0); auto. discriminate. assert (forall tyc', In tyc' l -> sat_constr p' tyc' = true). intros. import (H15 _ H16). bd H17. destruct tyc'. rewrite <- (ps_sat_constr_in_prog _ _ _ c H4 H0 H1). exact H20. rewrite <- (ps_sat_constr_compos_sty_field_r _ _ _ c f t H4 H0 H1). exact H20. rewrite <- (ps_sat_constr_compos_sty_field_w _ _ _ c f t H4 H0 H1). exact H20. rewrite <- (ps_sat_constr_compose_sty_meth _ _ _ c m t l0 H4 H0 H1). exact H20. rewrite <- (ps_sat_constr_compos_sty_cl _ _ _ t t0 H4 H0 H1). exact H20. rewrite <- (ps_sat_constr_compos_sty_if _ _ _ t t0 H4 H0 H1). exact H20. import (H21 l0 c); congruence. import (H17 l0 c); congruence. generalize H16; clear; induction l. simpl; auto. simpl; intros. bd H16. rewrite (H16 _ (or_introl _ (refl_equal _))). rewrite IHl; auto. case (eq_nat_dec dcl' d); 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; try discriminate. inversion H9; subst; clear H9. assert (forall fd', 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). intros. apply (inherit_fds_gen_p_gen_ps _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H9). assert (forall ms' mb', 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). intros; apply (inherit_mds_gen_p_gen_ps _ _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H10). assert (forall cl'' f', In (fd_def (ty_def cl'') f') fds' -> In (in_prog_constr cl'') t_list). intros; apply (in_prog_fds_gen_p_gen_ps _ _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H11). rewrite <- app_nil_end. cut (sat_constr_list p' l = true). revert H11 H6 H0 H1 H4; clear; induction fds'. simpl; auto. destruct a; intros. simpl. destruct t; simpl in H11; import (H11 _ _ (or_introl _ (refl_equal _))). rewrite <- (ps_sat_constr_in_prog _ _ _ c H4 H0 H1). rewrite (in_sat_ps_list _ _ _ _ H2 H6); simpl. apply IHfds'; auto. intros; apply (H11 _ _ (or_intror _ H3)). assert (forall md', In md' mds' -> exists t_list', gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list'). generalize l H8; clear; induction mds'. simpl; intros. contradiction. simpl; 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 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'); bd H; subst. destruct (gen_meth_constr (ty_def (cl_dcl dcl')) md'); try discriminate. exists l1; auto. apply (IHmds' l0); auto. discriminate. discriminate. assert (forall md', In md' mds' -> exists t_list', gen_meth_constr (ty_def (cl_dcl dcl')) md' = Some t_list' /\ (forall tyc', In tyc' t_list' -> (ps_sat_constr ps tyc' (length (introduce_all ps)) = true /\ (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl')))). intros. destruct (H12 _ H13). exists x. pa. intros. import (In_stmt_gen_p_gen_ps _ _ _ _ _ _ _ _ _ _ H H2 H3 H4 H5 H13 H14 H15). import (In_gen_meth_constr _ _ _ _ H14 H15). bd H17; pa. apply (in_sat_ps_list _ _ _ _ H16 H6). pa. assert (forall tyc', In tyc' l -> (ps_sat_constr ps tyc' (length (introduce_all ps)) = true /\ (forall f cl'', tyc' <> inherited_fields_constr f cl'') /\ (forall md' cl', tyc' <> inherited_methods_constr md' cl'))). generalize l H8 H13; clear; induction mds'. simpl; intros. inversion H8; subst; simpl in H; contradiction. intros. simpl in H8. 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'). simpl in H13; import (H13 a (or_introl _ (refl_equal _))). bd H0. rewrite H3 in H8. inversion H8; subst; clear H8. import (in_app_or _ _ _ H). bd H1; clear H. apply (H0 _ H1). apply (IHmds' l0); auto. discriminate. assert (forall tyc', In tyc' l -> sat_constr p' tyc' = true). intros. import (H14 _ H15). bd H16. destruct tyc'. rewrite <- (ps_sat_constr_in_prog _ _ _ c H4 H0 H1). exact H19. rewrite <- (ps_sat_constr_compos_sty_field_r _ _ _ c f t H4 H0 H1). exact H19. rewrite <- (ps_sat_constr_compos_sty_field_w _ _ _ c f t H4 H0 H1). exact H19. rewrite <- (ps_sat_constr_compose_sty_meth _ _ _ c m t l0 H4 H0 H1). exact H19. rewrite <- (ps_sat_constr_compos_sty_cl _ _ _ t t0 H4 H0 H1). exact H19. rewrite <- (ps_sat_constr_compos_sty_if _ _ _ t t0 H4 H0 H1). exact H19. import (H20 l0 c); congruence. import (H16 l0 c); congruence. generalize H15; clear; induction l. simpl; auto. simpl; intros. bd H15. rewrite (H15 _ (or_introl _ (refl_equal _))). rewrite IHl; auto. Qed. Corollary sat_ps_sat_cld : forall (ps : PS) (p p' : P) (t_list : list ty_constraint), Permutation p p' -> ordered_p p' -> sat_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all ps = Some p -> gen_ps_constr ps = Some t_list -> ps_sat_constr_list ps t_list (length (introduce_all ps)) = true -> exists c_list, gen_cld_constr p' = Some c_list /\ sat_constr_list p' c_list = true. intros. assert (forall cld', In cld' p' -> exists t_list', gen_cld_constr (cld' :: nil) = Some t_list' /\ sat_constr_list p' t_list' = true). intros. import (distinct_compose_names _ _ H3). import (distinct_permute_names _ _ H7 H). destruct cld'. import (in_p_get_cld _ _ _ _ _ H6 H8). import (get_cld_eq_get_refined_cld (cl_dcl d) _ _ H3). rewrite (permute_get_cld_eq _ _ (cl_dcl d) H7 H) in H10. rewrite H10 in H9. exact (sat_ps_sat_p _ _ _ _ _ _ _ _ H9 H H0 H1 H2 H3 H4 H5). assert (forall p'', (forall cld', In cld' p' -> exists t_list' : list ty_constraint, gen_cld_constr (cld' :: nil) = Some t_list' /\ sat_constr_list p'' t_list' = true) -> exists c_list : list ty_constraint, gen_cld_constr p' = Some c_list /\ sat_constr_list p'' c_list = true). clear; induction p'; intros. simpl; exists (nil : list ty_constraint); pa; auto. simpl; intros. simpl in H; import (H _ (or_introl _ (refl_equal _))). bd H0. destruct (gen_class_constr a); simpl in H3; try discriminate. rewrite <- app_nil_end in H3. inversion H3; subst; clear H3. assert ( forall cld' : cld, In cld' p' -> exists t_list' : list ty_constraint, match gen_class_constr cld' with | Some c_list'' => Some (c_list'' ++ nil) | None => None (A:=list ty_constraint) end = Some t_list' /\ sat_constr_list p'' t_list' = true). intros; apply H; auto. import (IHp' _ H1). bd H2. rewrite H5. exists (x ++ x0); pa; auto. revert H0 H2; clear; induction x. simpl; auto. intros. simpl in H0. simpl. destruct (andb_prop _ _ H0); clear H0; apply andb_true_intro; pa; auto. apply H7. exact H6. Qed. Corollary sat_ps_type_check : forall (ps : PS) (p p' : P) (t_list : list ty_constraint), Permutation p p' -> ordered_p p' -> sat_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all ps = Some p -> gen_ps_constr ps = Some t_list -> ps_sat_constr_list ps t_list (length (introduce_all ps)) = true -> type_check p' = true. intros. import (distinct_compose_names _ _ H3). import (distinct_permute_names _ _ H6 H). generalize H0 (sat_ps_sat_cld _ _ _ _ H H0 H1 H2 H3 H4 H5) H7; clear. intros. unfold type_check. unfold gen_prog_constr. rewrite ((proj2 (distinct_distinct_cl_list _ )) H7). cut (fst (fold_right (fun (cld' : cld) (b : bool * list cld) => (in_list_parent cld' (snd b) && fst b, cld' :: snd b)) (true, nil) p') = true). intros. rewrite H1. bd H. rewrite H4; rewrite H; auto. applyI in_list_parent_ordered'. Qed. Corollary sat_ps_compose_wf_prog : forall (ps : PS) (p p' : P) (t_list : list ty_constraint), Permutation p p' -> ordered_p p' -> sat_distinct_constr (ps_gen_distinct_constr ps) = true -> PS_distinct_fds_mds ps = true -> compose_all ps = Some p -> gen_ps_constr ps = Some t_list -> ps_sat_constr_list ps t_list (length (introduce_all ps)) = true -> wf_prog p'. intros; applyI wf_iff_type_check. apply (sat_ps_type_check _ _ _ _ H H0 H1 H2 H3 H4 H5). Qed. Theorem safe_compose_wf_prog : forall (ps : PS) (t_list : list ty_constraint), sat_distinct_constr (ps_gen_distinct_constr ps) = true -> safe_compose ps = true -> PS_distinct_fds_mds ps = true -> gen_ps_constr ps = Some t_list -> ps_sat_constr_list ps t_list (length (introduce_all ps)) = true -> exists p, compose_all ps = Some p /\ (forall (p' : P), Permutation p p' -> ordered_p p' -> wf_prog p'). intros. destruct ((proj2 (compose_f_sat_comp_valid_iff _)) H0). exists x; pa. intros. apply (sat_ps_compose_wf_prog _ _ _ _ H5 H6 H H1 H4 H2 H3). Qed.