Section sec_exteq_congruence.
Variable T: Type.
(* All useful predicates are extensional in the following sense *)
Definition extensional (P: infseq T -> Prop) :=
forall s1 s2, exteq s1 s2 -> P s1 -> P s2.
Proof using.
intros s1 s2 eq; auto.
Qed.
Proof using.
intros s1 s2 eq; auto.
Qed.
Proof using.
intros P Q eP eQ s1 s2 e. destruct e; simpl. unfold and_tl. intuition.
- apply eP with (Cons x s1); [constructor; assumption | assumption].
- apply eQ with (Cons x s1); [constructor; assumption | assumption].
Qed.
Proof using.
intros P Q eP eQ s1 s2 e. destruct e; simpl. unfold or_tl. intuition.
- left; apply eP with (Cons x s1); [constructor; assumption | assumption].
- right; apply eQ with (Cons x s1); [constructor; assumption | assumption].
Qed.
Proof using.
intros P Q eP eQ s1 s2 e. destruct e; simpl. unfold impl_tl.
intros PQ1 P2.
apply eQ with (Cons x s1); [constructor; assumption | idtac].
apply PQ1. apply eP with (Cons x s2).
- constructor. apply exteq_sym. assumption.
- assumption.
Qed.
Proof using.
intros P eP s1 s2 e; destruct e; simpl. unfold not_tl.
intros P1 nP2.
contradict P1.
apply eP with (Cons x s2); trivial.
apply exteq_sym.
apply exteq_intro.
assumption.
Qed.
Proof using.
intros P s1 s2 e. destruct e; simpl. trivial.
Qed.
Proof using.
intros P eP s1 s2 exP; destruct exP; simpl.
apply eP; assumption.
Qed.
Proof using.
intros P s1 s2 e. do 2 destruct e; simpl. trivial.
Qed.
Proof using.
intros P eP. cofix cf.
intros (x1, s1) (x2, s2) e al1. case (always_Cons al1); intros Px1s1 als1. constructor.
- eapply eP; eassumption.
- simpl. apply cf with s1; try assumption. case (exteq_inversion e); trivial.
Qed.
Proof using.
intros P Q eP eQ. cofix cf.
intros (x1, s1) (x2, s2) e un1. case (weak_until_Cons un1).
- intro Q1. constructor 1. eapply eQ; eassumption.
- intros (Px1s1, uns1). constructor 2.
* eapply eP; eassumption.
* simpl. apply cf with s1; try assumption. case (exteq_inversion e); trivial.
Qed.
Proof using.
intros P Q eP eQ s1 s2 e un1; genclear e; genclear s2.
induction un1.
- intros s2 e; apply U0; apply eQ with s; assumption.
- intros (x2, s2) e.
apply U_next.
* apply eP with (Cons x s); assumption.
* apply IHun1.
case (exteq_inversion e). trivial.
Qed.
Proof using.
intros P Q eP eQ. cofix cf.
intros (x1, s1) (x2, s2) e rl1. case (release_Cons rl1). intros Qx orR. case orR; intro orRx.
- apply R0.
* eapply eQ; eassumption.
* eapply eP; eassumption.
- apply R_tl.
* eapply eQ; eassumption.
* simpl. apply cf with s1; trivial. case (exteq_inversion e); trivial.
Qed.
Proof using.
intros P eP s1 s2 e ev1. genclear e; genclear s2.
induction ev1 as [s1 ev1 | x1 s1 ev1 induc_hyp].
- intros s2 e. constructor 1. apply eP with s1; assumption.
- intros (x2, s2) e. constructor 2. apply induc_hyp.
case (exteq_inversion e). trivial.
Qed.

Lemma extensional_inf_often :
forall (P: infseq T -> Prop),
extensional P -> extensional (inf_often P).