Commit 7dc8adcc authored by Marco Maida's avatar Marco Maida 🌱 Committed by Björn Brandenburg

Restructure and document util.bigcat

parent 12f79735
Pipeline #24004 passed with stages
in 4 minutes and 12 seconds
Require Export prosa.util.tactics prosa.util.notation.
From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop.
(* Lemmas about the big concatenation operator. *)
(** In this section, we introduce useful lemmas about the concatenation operation performed
over an arbitrary range of sequences. *)
Section BigCatLemmas.
Lemma mem_bigcat_nat:
forall (T: eqType) x m n j (f: _ -> list T),
m <= j < n ->
x \in (f j) ->
x \in \cat_(m <= i < n) (f i).
Proof.
intros T x m n j f LE IN; move: LE => /andP [LE LE0].
rewrite -> big_cat_nat with (n := j); simpl; [| by ins | by apply ltnW].
rewrite mem_cat; apply/orP; right.
destruct n; first by rewrite ltn0 in LE0.
rewrite big_nat_recl; last by ins.
by rewrite mem_cat; apply/orP; left.
Qed.
(** Consider any type supporting equality comparisons... *)
Variable T: eqType.
Lemma mem_bigcat_nat_exists :
forall (T: eqType) x m n (f: nat -> list T),
x \in \cat_(m <= i < n) (f i) ->
exists i, x \in (f i) /\
m <= i < n.
Proof.
intros T x m n f IN.
induction n; first by rewrite big_geq // in IN.
destruct (leqP m n); last by rewrite big_geq ?in_nil // ltnW in IN.
rewrite big_nat_recr // /= mem_cat in IN.
move: IN => /orP [HEAD | TAIL].
{
apply IHn in HEAD; destruct HEAD; exists x0. move: H => [H /andP [H0 H1]].
split; first by done.
by apply/andP; split; [by done | by apply ltnW].
}
{
exists n; split; first by done.
apply/andP; split; [by done | by apply ltnSn].
}
Qed.
(** ...and a function that, given an index, yields a sequence. *)
Variable f: nat -> list T.
Lemma bigcat_nat_uniq :
forall (T: eqType) n1 n2 (F: nat -> list T),
(forall i, uniq (F i)) ->
(forall x i1 i2,
x \in (F i1) -> x \in (F i2) -> i1 = i2) ->
uniq (\cat_(n1 <= i < n2) (F i)).
Proof.
intros T n1 n2 f SINGLE UNIQ.
case (leqP n1 n2) => [LE | GT]; last by rewrite big_geq // ltnW.
rewrite -[n2](addKn n1).
rewrite -addnBA //; set delta := n2 - n1.
induction delta; first by rewrite addn0 big_geq.
rewrite addnS big_nat_recr /=; last by apply leq_addr.
rewrite cat_uniq; apply/andP; split; first by apply IHdelta.
apply /andP; split; last by apply SINGLE.
rewrite -all_predC; apply/allP; intros x INx.
simpl; apply/negP; unfold not; intro BUG.
apply mem_bigcat_nat_exists in BUG.
move: BUG => [i [IN /andP [_ LTi]]].
apply UNIQ with (i1 := i) in INx; last by done.
by rewrite INx ltnn in LTi.
Qed.
(** In this section, we prove that the concatenation over sequences works as expected:
no element is lost during the concatenation, and no new element is introduced. *)
Section BigCatElements.
(** First, we show that the concatenation comprises all the elements of each sequence;
i.e. any element contained in one of the sequences will also be an element of the
result of the concatenation. *)
Lemma mem_bigcat_nat:
forall x m n j,
m <= j < n ->
x \in f j ->
x \in \cat_(m <= i < n) (f i).
Proof.
intros x m n j LE IN; move: LE => /andP [LE LE0].
rewrite -> big_cat_nat with (n := j); simpl; [| by ins | by apply ltnW].
rewrite mem_cat; apply/orP; right.
destruct n; first by rewrite ltn0 in LE0.
rewrite big_nat_recl; last by ins.
by rewrite mem_cat; apply/orP; left.
Qed.
(** Conversely, we prove that any element belonging to a concatenation of sequences
must come from one of the sequences. *)
Lemma mem_bigcat_nat_exists :
forall x m n,
x \in \cat_(m <= i < n) (f i) ->
exists i,
x \in f i /\ m <= i < n.
Proof.
intros x m n IN.
induction n; first by rewrite big_geq // in IN.
destruct (leqP m n); last by rewrite big_geq ?in_nil // ltnW in IN.
rewrite big_nat_recr // /= mem_cat in IN.
move: IN => /orP [HEAD | TAIL].
{
apply IHn in HEAD; destruct HEAD; exists x0. move: H => [H /andP [H0 H1]].
split; first by done.
by apply/andP; split; [by done | by apply ltnW]. }
{
exists n; split; first by done.
apply/andP; split; [by done | by apply ltnSn]. }
Qed.
End BigCatElements.
(** In this section, we show how we can preserve uniqueness of the elements
(i.e. the absence of a duplicate) over a concatenation of sequences. *)
Section BigCatDistinctElements.
(** Assume that there are no duplicates in each of the possible
sequences to concatenate... *)
Hypothesis H_uniq_seq: forall i, uniq (f i).
(** ...and that there are no elements in common between the sequences. *)
Hypothesis H_no_elements_in_common:
forall x i1 i2, x \in f i1 -> x \in f i2 -> i1 = i2.
(** We prove that the concatenation will yield a sequence with unique elements. *)
Lemma bigcat_nat_uniq :
forall n1 n2,
uniq (\cat_(n1 <= i < n2) (f i)).
Proof.
intros n1 n2.
case (leqP n1 n2) => [LE | GT]; last by rewrite big_geq // ltnW.
rewrite -[n2](addKn n1).
rewrite -addnBA //; set delta := n2 - n1.
induction delta; first by rewrite addn0 big_geq.
rewrite addnS big_nat_recr /=; last by apply leq_addr.
rewrite cat_uniq; apply/andP; split; first by apply IHdelta.
apply /andP; split; last by apply H_uniq_seq.
rewrite -all_predC; apply/allP; intros x INx.
simpl; apply/negP; unfold not; intro BUG.
apply mem_bigcat_nat_exists in BUG.
move: BUG => [i [IN /andP [_ LTi]]].
apply H_no_elements_in_common with (i1 := i) in INx; last by done.
by rewrite INx ltnn in LTi.
Qed.
End BigCatDistinctElements.
End BigCatLemmas.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment