Library mcertikos.layerlib.ListLemma2


Require Import Arith.
Require Import Omega.
Require Export List.
Require Import ZArith.
Require Import ListLemma.
Require Import GlobalOracle.
Require Import Coqlib.

Lemma list_prefix_nil:
   {A:Type} (i: A) q q0 q1,
    ¬ In i q
    q ++ i :: q0 = i :: q1
    q = nil.
Proof.
  intros.
  destruct q.
  + auto.
  + simpl in ×.
    injection H0;intros.
    contradict H. auto.
Qed.

Lemma list_In_middle:
   {A: Type} (i: A) q q0,
    In i (q ++ i :: q0).
Proof.
  induction q; simpl; intros; auto.
Qed.

Lemma list_valid_In_append:
   a curid l,
    ( i0 e, In (TEVENT i0 e) (a :: l) → i0 curid) →
    ( i0 e, In (TEVENT i0 e) li0 curid).
Proof.
  intros.
  apply (H i0 e).
  right.
  auto.
Qed.

Lemma list_valid_In_append´:
   a l P,
    ( i0 e, In (TEVENT i0 e) (a :: l) → P i0 e) →
    ( i0 e, In (TEVENT i0 e) lP i0 e).
Proof.
  intros; eauto. eapply X.
  right. trivial.
Qed.

Lemma list_append_trans:
   {A: Type} (i: A) l0 l,
    i :: (l0 ++ l) = (i::l0) ++ l.
Proof.
  reflexivity.
Qed.

Lemma list_append_neq0:
   {A: Type} l (a: A),
    l = a :: lFalse.
Proof.
  induction l; intros.
  - inv H.
  - inversion H. eauto.
Qed.

Lemma list_append_neq:
   {A: Type} l (a: A),
    l = ++ a :: lFalse.
Proof.
  induction l; intros.
  - destruct ; inv H.
  - destruct ; inversion H.
    + eapply list_append_neq0 in H2; eauto.
    + specialize (IHl ( ++ a0 :: nil) a1). eapply IHl.
      rewrite <- app_assoc.
      rewrite <- app_comm_cons.
      rewrite app_nil_l. assumption.
Qed.

Lemma list_append_neq´:
   {A: Type} (l : list A),
    l = ++ l = nil.
Proof.
  destruct l; intros.
  - rewrite app_nil_r in H. congruence.
  - destruct ; trivial.
    inversion H. clear H.
    eapply list_append_neq in H2. inv H2.
Qed.

Lemma list_append_e_eq:
   {A : Type} l0 l (e e0: A),
    l0 ++ e :: l = e0 :: l
    l0 = nil e = e0.
Proof.
  induction l0; intros.
  - inv H. eauto.
  - inversion H.
    symmetry in H2.
    apply list_append_neq in H2. inv H2.
Qed.

Lemma list_not_e_nil:
   {A:Type} (e: A) l ,
    l ++ e :: nil.
Proof.
  destruct l.
  - intros HF. inv HF.
  - intros HF. inv HF.
Qed.

Lemma list_same_tail:
   {A : Type} l0 l1 (i j: A),
    l0 ++ i :: nil = l1 ++ j :: nil
    l0 = l1 i = j.
Proof.
  induction l0; simpl; intros.
  - destruct l1.
    + inv H. auto.
    + inv H. symmetry in H2.
      eapply list_not_e_nil in H2. inv H2.
  - destruct l1.
    + inv H. eapply list_not_e_nil in H2. inv H2.
    + inv H. exploit IHl0; eauto.
      intros (? & ?); subst.
      auto.
Qed.

Lemma list_append_rewrite:
   {A: Type} l (a b: A),
    a :: b :: l = (a:: nil) ++ (b :: l).
Proof.
  intros.
  rewrite <- app_comm_cons. trivial.
Qed.

Lemma list_tail_one_element:
   {A : Type} l2 l0 l1 (i j: A)
         (Heq: l0 ++ i :: nil = l1 ++ j :: l2),
    (i = j l2 = nil)
    ( l2´, l0 = l1 ++ j :: l2´).
Proof.
  induction l2; simpl; intros.
  - eapply list_same_tail in Heq.
    destruct Heq as (? & ?); subst.
    left; auto.
  - right. rewrite list_append_rewrite in Heq.
    rewrite app_assoc in Heq.
    exploit IHl2; eauto.
    intros HF.
    destruct HF as [(? & ?) | HF´]; subst.
    + eapply list_same_tail in Heq.
      destruct Heq as (? & _); subst.
      eauto.
    + destruct HF´ as (l2´ & HF´).
      rewrite <- app_assoc in HF´.
      rewrite <- app_comm_cons in HF´.
      eauto.
Qed.

Lemma list_unique_element:
   {A: Type} q q0 q1 (z: A)
         (Heq: q ++ z :: q0 = ++ z :: q1)
         (Hnin: ¬ In z q)
         (Hnin0: ¬ In z q0),
    q = q0 = q1.
Proof.
  induction q; simpl; intros.
  - destruct .
    + inv Heq. auto.
    + inv Heq. elim Hnin0.
      eapply list_In_middle; eauto.
  - destruct .
    + inv Heq. elim Hnin. left; trivial.
    + inv Heq. exploit IHq; eauto.
      intros (? & ?); subst. auto.
Qed.

Lemma list_not_in_append_re:
   {A: Type} (i: A) i0 l,
    ¬ In i (i0 :: l) →
    ¬ In i l.
Proof.
  intros.
  simpl in H.
  tauto.
Qed.

Lemma list_not_in_append:
   {A: Type} (i: A) i0 l,
    ¬ In i l
    i0 i
    ¬ In i (i0 :: l).
Proof.
  intros.
  simpl.
  tauto.
Qed.


  Lemma NoDup_app : A (xs ys : list A),
    NoDup (xs++ys)
      (NoDup xs NoDup ys
           ( x, ¬ (In x xs In x ys))).
  Proof.
    induction xs.
    + simpl.
      intros.
      intuition.
      constructor.
    + simpl.
      intros.
      intuition.
      - inversion H; subst.
        constructor.
        rewrite in_app in H2.
        auto.
        specialize IHxs with ys.
        tauto.
      - inversion H; subst.
        specialize IHxs with ys.
        tauto.
      - subst.
        inversion H.
        subst.
        contradict H3.
        rewrite in_app.
        auto.
      - inversion H; subst.
        specialize IHxs with ys.
        firstorder.
      - specialize IHxs with ys.
        inversion H0; subst.
        constructor.
        × rewrite in_app.
          specialize H2 with a.
          tauto.
        × rewrite IHxs.
          intuition.
          firstorder.

  Qed.

  Lemma NoDup_app_commute : A (xs ys : list A),
    NoDup (xs ++ ys) → NoDup (ys ++ xs).
  Proof.
    intros A xs ys.
    repeat rewrite NoDup_app.
    firstorder.
  Qed.

  Lemma prepend_inj : A (xs ys ys´ : list A),
    (xs ++ ys) = (xs ++ ys´)ys=ys´.
  Proof.
    induction xs; simpl; intros.
      auto.
      injection H; auto.
  Qed.

  Lemma NoDup_singleton : A (x:A),
      NoDup (x :: nil).
  Proof.
    intros; constructor; simpl; auto; constructor.
  Qed.

  Lemma In_map : A B (f : AB) x xs,
                   In x xsIn (f x) (map f xs).
  Proof.
    induction xs.
    + simpl; tauto.
    + simpl.
      destruct 1.
      - left; congruence.
      - right; auto.
  Qed.

  Lemma split_lists : A (xs xs´ ys ys´ : list A),
      xs ++ xs´ = ys ++ ys´
      ( xs1, xs ++ xs1 = ys) ( ys1, xs = ys ++ ys1).
  Proof.
    induction xs.
    + simpl. intros.
      eauto.
    + destruct ys; simpl; intros.
    - right.
      eauto.
    - injection H.
      intros.
      assert (IH := IHxs xs´ ys ys´ H0).
      clear IHxs.
      subst.
      destruct IH as [[xs1 ?] | [ys1 ?]]; subst; eauto.
  Qed.

  Lemma prepend_injectivity : A xs (x:A) l xs´ ,
      xs ++ x :: l = xs´ ++ x ::
      ¬In x xs
      ¬In x xs´
      xs = xs´.
  Proof.
    induction xs as [|a xs].
    + simpl.
      destruct xs´ as [|b xs´].
    - simpl.
      auto.
    - simpl.
      intros H.
      inversion H.
      intuition.
      + destruct xs´ as [|b xs´].
    - simpl.
      intros H.
      inversion H.
      intuition.
    - simpl.
      intros H.
      intros.
      inversion H.
      f_equal; apply (IHxs x l _ ).
      auto.
      intuition.
      intuition.
  Qed.