regexp.concrete.subset

regexp.concrete:subset: Finite set concrete version



Overview

  • t s : Set over the type universe.t s. These are the concrete representation of the mathcomp type {set universe.t s}
  • denote: Gives the denotational semantics of a set as a mathcomp finset.
  • : The empty set.
  • full: The full set of elements of the type universe.t s.
  • singleton a: The set containing the single element a.
  • union and big.union: The union of two sets and the associated "big" operator
  • intersection and big.intersection: The intersection of two sets and the associated "big" operator.
  • inhabited: Check whether a set is inhabited.

Finite subset types


Definition t (s : sort) := (s ~> bool)%con.
Definition union {s} : t s t s t s := function.zipWith orb.
Definition intersection {s} : t s t s t s := function.zipWith andb.
Definition disjoint_union {s1 s2} : t s1 t s2 t (s1 s2) := function.concat.

Definition empty {s} : t s := function.constant false.
Definition full {s} : t s := function.constant true.

Definition inhabited {s} : t s bool := function.fold orb.


Definition injl {s1 s2} (u : t s1) : t (s1 s2) := u .
Definition injr {s1 s2} (u : t s2) : t (s1 s2) := u.

Fixpoint singleton {s} : typeOf s t s :=
  match s with
  | 𝟙fun _full
  | s1 s2fun umatch u with
                    | inl uLinjl (singleton uL)
                    | inr uRinjr (singleton uR)
                    end
  end.

Lemma union_empty_r {s}(a : t s) : a = a.
  apply function.extensionalityi.
  by rewrite /union zip_pointwise /empty constantE orbF.
Qed.

Lemma union_empty_l {s}(a : t s) : a = a.
  apply function.extensionalityi.
  by rewrite /union zip_pointwise /empty constantE orFb.
Qed.

Semantics


Definition denote {s} (a : t s) : {set universe.denote s} := finset (function.denote a).


Lemma denoteE {s}(a : t s) : i, i \in denote a = a i.
  movei; by rewrite /denote /function.denote in_set ffunE.
Qed.

Lemma disjULE {s1 s2}{a : t s1}{b : t s2} x : x \in denote a = (inl x \in denote (a b)).
  apply/idP/idP.
  - by rewrite denoteEh; rewrite (denoteE (a b)) /disjoint_union //=.
  - by rewrite (denoteE (a b)) //= -denoteE.
Qed.

Lemma disjURE {s1 s2}{a : t s1}{b : t s2} x : x \in denote b = (inr x \in denote (a b)).
  apply/idP/idP.
  - by rewrite denoteEh; rewrite (denoteE (a b)) /disjoint_union //=.
  - by rewrite (denoteE (a b)) //= -denoteE.
Qed.

Lemma union_spec {s}(a b : t s) : denote (a b) = denote a :|: denote b.
  apply/setPx; by rewrite in_setU ?denoteE /union zip_pointwise.
Qed.


Lemma intersection_spec {s}(a b : t s) : denote (a b) = denote a :&: denote b.
  apply/setPx; by rewrite in_setI ?denoteE /intersection zip_pointwise.
Qed.

Lemma empty_spec {s} : denote (@empty s) = set0.
  apply/setPx; by rewrite /empty ?denoteE constantE in_set0.
Qed.

Lemma full_spec {s} : denote (@full s) = setT.
  apply/setPx; by rewrite /empty ?denoteE constantE in_setT.
Qed.

Lemma inl_inj {A B : Type} : (injective (inl : A A + B)).
  movex y Hyp; by inversion Hyp.
Qed.

Lemma inr_inj {A B : Type} : (injective (inr : B A + B)).
  movex y Hyp; by inversion Hyp.
Qed.

Lemma injlinv_spec {s1 s2} (a : t s1) : inl @^-1: denote (injl (s2:=s2) a) = denote a.
  apply/setPx; by rewrite ?denoteE ?in_set function.denoteE //=.
Qed.

Lemma injl_spec {s1 s2}(a : t s1) : denote (injl (s2:=s2) a) = inl @: denote a.
  rewrite /injl /disjoint_union -setPx; case xu.
  - rewrite (mem_imset _ _ (inl_inj)) ?in_set ?function.denoteE //=.
  - rewrite ?in_set ?function.denoteE /empty //= ?function.constantE //=.
    apply/idP/imsetP.
    + done.
    + casey h1 h2; inversion h2.
Qed.

Lemma setUnit : [set: unit] = [set tt].
  apply/setP; by case; rewrite ?in_set in_set1 //=.
Qed.

Lemma injrinv_spec {s1 s2} (a : t s2) : inr @^-1: denote (injr (s1:=s1) a) = denote a.
  apply/setPx; by rewrite ?denoteE ?in_set function.denoteE //=.
Qed.

Lemma injr_spec {s1 s2}(a : t s2) : denote (injr (s1:=s1) a) = inr @: denote a.
  rewrite /injr /disjoint_union -setPx; case xu.
  - rewrite ?in_set ?function.denoteE /empty //= ?function.constantE //=.
    apply/idP/imsetP.
    + done.
    + casey h1 h2; inversion h2.
  - rewrite (mem_imset _ _ (inr_inj)) ?in_set ?function.denoteE //=.
Qed.

Lemma singleton_spec {s} : (a : typeOf s), denote (singleton a) = set1 a.
  movea; apply/setPx; rewrite ?denoteE ?in_set.
  induction s.
  - rewrite //=; case x; rewrite ?in_set1 //=.
  - destruct a; destruct x; rewrite //= ?IHs1 ?IHs2 ?in_set1 /empty //= ?constantE ?in_set1 //=.
Qed.

Lemma disUUU {s1 s2}(a1 a2 : t s1)(b1 b2 : t s2) : (a1 a2) (b1 b2) = (a1 b1) (a2 b2).
  rewrite /disjoint_union /union; apply function.extensionality; casex; rewrite //=.
Qed.

Lemma injDU {s1 s2}(a : t s1)(b : t s2) : a b = injl a injr b.
  by rewrite /injl /injr -/disjoint_union -disUUU union_empty_l union_empty_r.
Qed.

Lemma inhabitedP {s} (A : t s) : reflect ( x, x \in denote A) (inhabited A).
  rewrite /inhabited.
  induction A.
  - case: a.
    + by apply ReflectT; tt; rewrite denoteE //=.
    + apply ReflectF; casex; rewrite denoteE constantE //=.
  - rewrite /fold -/fold; apply /(iffP idP).
    + case/orP.
      × by case/IHA1x1 h1; (inl x1); rewrite -disjULE.
      × by case/IHA2x2 h2; (inr x2); rewrite -disjURE.
    + casex; case: xa; rewrite -?disjULE -?disjUREh; apply/orP.
      × by left; apply/IHA1; a.
      × by right; apply/IHA2; a.
Qed.

Lemma inhabited_spec {s} (A : t s) : inhabited A = abstract.utils.inhabited (denote A).
  by apply /inhabitedP/existsP.
Qed.

Module big.

  Section Cxt.
    Context {idx s : sort}(F : idx ~> t s).

    Definition union (iset : t idx) : t s :=
      function.fold (@subset.union s) (function.zipWith (fun b Sif b then S else ) iset F).

    Definition intersection (iset : t idx)
      := function.fold (@subset.intersection s) (function.zipWith (fun b Sif b then S else full) iset F).

  End Cxt.

  Lemma bigcup_sum {idx1 idx2 s}(F1 : idx1 ~> t s) (F2 : idx2 ~> t s)(iset1 : t idx1) (iset2 : t idx2) :
    \bigcup_(i in denote (iset1 ++ iset2)) denote ((F1 ++ F2) i) =
      \bigcup_(i in denote iset1) denote (F1 i) :|: \bigcup_(i in denote iset2) denote (F2 i).
    apply /setPx; rewrite in_setU; apply/bigcupP/orP.
    - casei; case iidx; rewrite -?disjULE -?disjURE //= ⇒ h1 h2.
      + by left; apply /bigcupP ; idx.
      + by right; apply /bigcupP; idx.
    - case; case /bigcupPi h1 h2.
      + by (inl i); rewrite -?disjULE //=.
      + by (inr i); rewrite -?disjURE //=.
  Qed.

  Lemma bigcap_sum {idx1 idx2 s}(F1 : idx1 ~> t s) (F2 : idx2 ~> t s)(iset1 : t idx1) (iset2 : t idx2) :
    \bigcap_(i in denote (iset1 ++ iset2)) denote ((F1 ++ F2) i) =
      \bigcap_(i in denote iset1) denote (F1 i) :&: \bigcap_(i in denote iset2) denote (F2 i).
    apply/setPx; rewrite in_setI. apply/bigcapP/andP.
    - moveh. apply conj; apply /bigcapPi.
      + by rewrite (disjULE(b:=iset2)); apply (h (inl i)).
      + by rewrite (disjURE(a:=iset1)); apply (h (inr i)).
    - case; move/bigcapPh1; move /bigcapPh2 i; case iidx; rewrite -?disjULE -?disjUREh.
      + rewrite (disjULE (b:=iset2)) //= -?disjULE; intuition.
      + rewrite (disjURE (a:=iset2)) //= -?disjURE; intuition.
  Qed.

  Lemma union_spec {idx s}(F : idx ~> t s)(iset : t idx) :
    denote (big.union F iset) = \bigcup_ (i in denote iset) denote (F i).
    induction idx; dependent destruction iset; dependent destruction F.
    - case: b.
      × by rewrite full_spec setUnit big_set1E setU0.
      × by rewrite ?empty_spec big_set0.
    - by rewrite bigcup_sum -IHidx1 -IHidx2 -subset.union_spec.
  Qed.

  Lemma intersection_spec {idx s}(F : idx ~> t s)(iset : t idx) :
    denote (big.intersection F iset) = \bigcap_ (i in denote iset) denote (F i).
    induction idx; dependent destruction iset; dependent destruction F.
    - case: b.
      × by rewrite full_spec setUnit big_set1E setIT.
      × by rewrite empty_spec big_set0 full_spec.
    - by rewrite bigcap_sum -IHidx1 -IHidx2 -subset.intersection_spec.
  Qed.

End big.