Tactic Notation "assert_specialize" hyp(H) :=
match type of H with
forall x : ?P, _ =>
let Htemp := fresh "Htemp" in
assert P as Htemp; [ | specialize (H Htemp); try clear Htemp ]
end.
(** * Ramsey theorem (with the necessary set-theoretic definitions) *)
Definition intersection {X} (A B : X -> Prop) := fun x => A x /\ B x.
Definition minus {X} (A B : X -> Prop) := fun x => A x /\ ~B x.
Definition subset {X} (A B : X -> Prop) := forall x, A x -> B x.
Definition finite {X} (A : X -> Prop) := exists n f, forall x, A x -> exists i, i < n /\ f i = x.
Definition infinite (A : nat -> Prop) := forall b, exists a, b <= a /\ A a.
Definition image {X Y} (f : X -> Y) (A : X -> Prop) : Y -> Prop := fun y => exists x, A x /\ y = f x.
Definition preimage {X Y} (f : X -> Y) (B : Y -> Prop) : X -> Prop := fun x => B (f x).
Fixpoint zip {X} (f1 f2 : nat -> X) n :=
match n with
| O => f1 O
| S O => f2 0
| S (S n) => zip (fun n => f1 (S n)) (fun n => f2 (S n)) n
end.

Lemma finite_product:
forall {A B}
{PA : A -> Prop}
{PB : B -> Prop},
finite PA ->
finite PB ->
finite (fun ab => PA (fst ab) /\ PB (snd ab)).