Library rt.util.bigcat
(* ----------------------------------[ coqtop ]---------------------------------
Welcome to Coq 8.10.1 (October 2019)
----------------------------------------------------------------------------- *)
Require Export rt.util.tactics rt.util.notation.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop.
(* Lemmas about the big concatenation operator. *)
Section BigCatLemmas.
Lemma mem_bigcat_nat:
∀ (T: eqType) x m n j (f: _ → list T),
m ≤ j < n →
x \in (f j) →
x \in \cat_(m ≤ i < n) (f i).
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 38)
============================
forall (T : eqType) (x : T) (m n j : nat) (f : nat -> seq T),
m <= j < n -> x \in f j -> x \in \big[cat/[::]]_(m <= i < n) f i
----------------------------------------------------------------------------- *)
Proof.
intros T x m n j f LE IN; move: LE ⇒ /andP [LE LE0].
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 88)
T : eqType
x : T
m, n, j : nat
f : nat -> seq T
IN : x \in f j
LE : m <= j
LE0 : j < n
============================
x \in \big[cat/[::]]_(m <= i < n) f i
----------------------------------------------------------------------------- *)
rewrite → big_cat_nat with (n := j); simpl; [| by ins | by apply ltnW].
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 93)
T : eqType
x : T
m, n, j : nat
f : nat -> seq T
IN : x \in f j
LE : m <= j
LE0 : j < n
============================
x \in \big[cat/[::]]_(m <= i < j) f i ++ \big[cat/[::]]_(j <= i < n) f i
----------------------------------------------------------------------------- *)
rewrite mem_cat; apply/orP; right.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 132)
T : eqType
x : T
m, n, j : nat
f : nat -> seq T
IN : x \in f j
LE : m <= j
LE0 : j < n
============================
x \in \big[cat/[::]]_(j <= i < n) f i
----------------------------------------------------------------------------- *)
destruct n; first by rewrite ltn0 in LE0.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 144)
T : eqType
x : T
m, n, j : nat
f : nat -> seq T
IN : x \in f j
LE : m <= j
LE0 : j < n.+1
============================
x \in \big[cat/[::]]_(j <= i < n.+1) f i
----------------------------------------------------------------------------- *)
rewrite big_nat_recl; last by ins.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 193)
T : eqType
x : T
m, n, j : nat
f : nat -> seq T
IN : x \in f j
LE : m <= j
LE0 : j < n.+1
============================
x \in f j ++ \big[cat/[::]]_(j <= i < n) f i.+1
----------------------------------------------------------------------------- *)
by rewrite mem_cat; apply/orP; left.
(* ----------------------------------[ coqtop ]---------------------------------
No more subgoals.
----------------------------------------------------------------------------- *)
Qed.
Lemma mem_bigcat_nat_exists :
∀ (T: eqType) x m n (f: nat → list T),
x \in \cat_(m ≤ i < n) (f i) →
∃ i, x \in (f i) ∧
m ≤ i < n.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 59)
============================
forall (T : eqType) (x : T) (m n : nat) (f : nat -> seq T),
x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
----------------------------------------------------------------------------- *)
Proof.
intros T x m n f IN.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 65)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IN : x \in \big[cat/[::]]_(m <= i < n) f i
============================
exists i : nat, x \in f i /\ m <= i < n
----------------------------------------------------------------------------- *)
induction n; first by rewrite big_geq // in IN.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 79)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IN : x \in \big[cat/[::]]_(m <= i < n.+1) f i
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
============================
exists i : nat, x \in f i /\ m <= i < n.+1
----------------------------------------------------------------------------- *)
destruct (leqP m n); last by rewrite big_geq ?in_nil // ltnW in IN.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 146)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IN : x \in \big[cat/[::]]_(m <= i < n.+1) f i
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
============================
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
rewrite big_nat_recr // /= mem_cat in IN.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 261)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
IN : (x \in \big[cat/[::]]_(m <= i < n) f i) || (x \in f n)
============================
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
move: IN ⇒ /orP [HEAD | TAIL].
(* ----------------------------------[ coqtop ]---------------------------------
2 subgoals (ID 306)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
HEAD : x \in \big[cat/[::]]_(m <= i < n) f i
============================
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
subgoal 2 (ID 307) is:
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
{
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 306)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
HEAD : x \in \big[cat/[::]]_(m <= i < n) f i
============================
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
apply IHn in HEAD; destruct HEAD; ∃ x0.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 316)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
x0 : nat
H : x \in f x0 /\ m <= x0 < n
============================
x \in f x0 /\ m <= x0 < n.+1
----------------------------------------------------------------------------- *)
move: H ⇒ [H /andP [H0 H1]].
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 368)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
x0 : nat
H : x \in f x0
H0 : m <= x0
H1 : x0 < n
============================
x \in f x0 /\ m <= x0 < n.+1
----------------------------------------------------------------------------- *)
split; first by done.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 371)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
x0 : nat
H : x \in f x0
H0 : m <= x0
H1 : x0 < n
============================
m <= x0 < n.+1
----------------------------------------------------------------------------- *)
by apply/andP; split; [by done | by apply ltnW].
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 307)
subgoal 1 (ID 307) is:
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
}
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 307)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
TAIL : x \in f n
============================
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
{
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 307)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
TAIL : x \in f n
============================
exists i0 : nat, x \in f i0 /\ m <= i0 < n.+1
----------------------------------------------------------------------------- *)
∃ n; split; first by done.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 404)
T : eqType
x : T
m, n : nat
f : nat -> seq T
IHn : x \in \big[cat/[::]]_(m <= i < n) f i ->
exists i : nat, x \in f i /\ m <= i < n
i : m <= n
TAIL : x \in f n
============================
m <= n < n.+1
----------------------------------------------------------------------------- *)
apply/andP; split; [by done | by apply ltnSn].
(* ----------------------------------[ coqtop ]---------------------------------
No more subgoals.
----------------------------------------------------------------------------- *)
}
(* ----------------------------------[ coqtop ]---------------------------------
No more subgoals.
----------------------------------------------------------------------------- *)
Qed.
Lemma bigcat_nat_uniq :
∀ (T: eqType) n1 n2 (F: nat → list T),
(∀ i, uniq (F i)) →
(∀ x i1 i2,
x \in (F i1) → x \in (F i2) → i1 = i2) →
uniq (\cat_(n1 ≤ i < n2) (F i)).
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 85)
============================
forall (T : eqType) (n1 n2 : nat) (F : nat -> seq T),
(forall i : nat, uniq (F i)) ->
(forall (x : T) (i1 i2 : nat), x \in F i1 -> x \in F i2 -> i1 = i2) ->
uniq (\big[cat/[::]]_(n1 <= i < n2) F i)
----------------------------------------------------------------------------- *)
Proof.
intros T n1 n2 f SINGLE UNIQ.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 91)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
============================
uniq (\big[cat/[::]]_(n1 <= i < n2) f i)
----------------------------------------------------------------------------- *)
case (leqP n1 n2) ⇒ [LE | GT]; last by rewrite big_geq // ltnW.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 94)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
============================
uniq (\big[cat/[::]]_(n1 <= i < n2) f i)
----------------------------------------------------------------------------- *)
rewrite -[n2](addKn n1).
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 140)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
============================
uniq (\big[cat/[::]]_(n1 <= i < n1 + n2 - n1) f i)
----------------------------------------------------------------------------- *)
rewrite -addnBA //; set delta := n2 - n1.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 171)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta := n2 - n1 : nat
============================
uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
----------------------------------------------------------------------------- *)
induction delta; first by rewrite addn0 big_geq.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 180)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
============================
uniq (\big[cat/[::]]_(n1 <= i < n1 + delta.+1) f i)
----------------------------------------------------------------------------- *)
rewrite addnS big_nat_recr /=; last by apply leq_addr.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 212)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
============================
uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i ++ f (n1 + delta))
----------------------------------------------------------------------------- *)
rewrite cat_uniq; apply/andP; split; first by apply IHdelta.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 245)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
============================
~~
has
(pred_of_simpl (T:=T) (mem (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)))
(f (n1 + delta)) && uniq (f (n1 + delta))
----------------------------------------------------------------------------- *)
apply /andP; split; last by apply SINGLE.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 271)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
============================
~~
has
(pred_of_simpl (T:=T) (mem (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)))
(f (n1 + delta))
----------------------------------------------------------------------------- *)
rewrite -all_predC; apply/allP; intros x INx.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 308)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
x : T
INx : x \in f (n1 + delta)
============================
predC
(pred_of_simpl (T:=T) (mem (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)))
x
----------------------------------------------------------------------------- *)
simpl; apply/negP; unfold not; intro BUG.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 333)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
x : T
INx : x \in f (n1 + delta)
BUG : x \in \big[cat/[::]]_(n1 <= i < n1 + delta) f i
============================
False
----------------------------------------------------------------------------- *)
apply mem_bigcat_nat_exists in BUG.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 334)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
x : T
INx : x \in f (n1 + delta)
BUG : exists i : nat, x \in f i /\ n1 <= i < n1 + delta
============================
False
----------------------------------------------------------------------------- *)
move: BUG ⇒ [i [IN /andP [_ LTi]]].
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 397)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
x : T
INx : x \in f (n1 + delta)
i : nat
IN : x \in f i
LTi : i < n1 + delta
============================
False
----------------------------------------------------------------------------- *)
apply UNIQ with (i1 := i) in INx; last by done.
(* ----------------------------------[ coqtop ]---------------------------------
1 subgoal (ID 398)
T : eqType
n1, n2 : nat
f : nat -> seq T
SINGLE : forall i : nat, uniq (f i)
UNIQ : forall (x : T) (i1 i2 : nat), x \in f i1 -> x \in f i2 -> i1 = i2
LE : n1 <= n2
delta : nat
IHdelta : uniq (\big[cat/[::]]_(n1 <= i < n1 + delta) f i)
x : T
i : nat
INx : i = n1 + delta
IN : x \in f i
LTi : i < n1 + delta
============================
False
----------------------------------------------------------------------------- *)
by rewrite INx ltnn in LTi.
(* ----------------------------------[ coqtop ]---------------------------------
No more subgoals.
----------------------------------------------------------------------------- *)
Qed.
End BigCatLemmas.