Built with Alectryon, running Coq+SerAPI v8.16.0+0.16.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
From Tealeaves Require Import
Classes.Categorical.ContainerFunctor
Backends.Common.Names
Functors.List.From Coq Require
MSets.MSets.Import List.ListNotations.Import ContainerFunctor.Notations.#[local] Open Scope list_scope.(** * Definition of <<AtomSet>> type *)(******************************************************************************)ModuleAtomSet <: Coq.MSets.MSetInterface.WSets :=
Coq.MSets.MSetWeakList.Make Name.ModuleAtomSetProperties :=
Coq.MSets.MSetProperties.WPropertiesOn Name AtomSet.(** ** Notations for operations on <<AtomSet>> *)(******************************************************************************)Declare Scope set_scope.Delimit Scope set_scope withset.Open Scope set_scope.ModuleNotations.Notation"x `∈@` S" := (AtomSet.In x S) (at level40) : set_scope.Notation"x `in` S" := (AtomSet.In x S) (at level40) : set_scope.Notation"x `notin` S" := (~ AtomSet.In x S) (at level40) : set_scope.Notation"s [=] t" := (AtomSet.Equal s t) (at level70, no associativity) : set_scope.Notation"s ⊆ t" := (AtomSet.Subset s t) (at level70, no associativity) : set_scope.Notation"s ∩ t" := (AtomSet.inter s t) (at level60, no associativity) : set_scope.Notation"s \\ t" := (AtomSet.diff s t) (at level60, no associativity) : set_scope.Notation"s ∪ t" := (AtomSet.union s t) (at level61, left associativity) : set_scope.Notation"'elements'" := (AtomSet.elements) (at level60, no associativity) : set_scope.Notation"∅" := (AtomSet.empty) : set_scope.Notation"{{ x }}" := (AtomSet.singleton x) : set_scope.Tactic Notation"fsetdec" := AtomSetProperties.Dec.fsetdec.EndNotations.Import Notations.#[global] InstanceMonoid_op_atoms: @Monoid_op AtomSet.t := AtomSet.union.#[global] InstanceMonoid_unit_atoms: @Monoid_unit AtomSet.t := AtomSet.empty.
Monoid AtomSet.t
Monoid AtomSet.t
x, y, z: AtomSet.t
x ∪ y ∪ z = x ∪ (y ∪ z)
x: AtomSet.t
x ∪ ∅ = x
x: AtomSet.t
∅ ∪ x = x
(* Can't use existing monoid typeclass because the laws only hold up to AtomSet.Equal, not propositional equality. *)Abort.(** ** The [atoms] operation *)(** <<atoms>> collects a list of atoms into an <<AtomSet>>. It is conceptually inverse to [AtomSet.elements], but there's no guarantee the operations won't disturb the order*)(******************************************************************************)Fixpointatoms (l : list atom) : AtomSet.t :=
match l with
| nil => ∅
| x :: xs => AtomSet.add x (atoms xs)
end.(** ** Rewriting rules *)(******************************************************************************)Create HintDb tea_rw_atoms.
a: atom l1: list atom IHl1: foralll2 : list atom,
atoms (l1 ++ l2) [=] atoms l1 ∪ atoms l2
foralll2 : list atom,
atoms ((a :: l1) ++ l2) [=] atoms (a :: l1) ∪ atoms l2
a: atom l1: list atom IHl1: foralll2 : list atom,
atoms (l1 ++ l2) [=] atoms l1 ∪ atoms l2
foralll2 : list atom,
AtomSet.add a (atoms (l1 ++ l2))
[=] AtomSet.add a (atoms l1) ∪ atoms l2
a: atom l1: list atom IHl1: foralll2 : list atom,
atoms (l1 ++ l2) [=] atoms l1 ∪ atoms l2 l2: list atom
AtomSet.add a (atoms (l1 ++ l2))
[=] AtomSet.add a (atoms l1) ∪ atoms l2
a: atom l1: list atom IHl1: foralll2 : list atom,
atoms (l1 ++ l2) [=] atoms l1 ∪ atoms l2 l2: list atom
AtomSet.add a (atoms l1 ∪ atoms l2)
[=] AtomSet.add a (atoms l1) ∪ atoms l2
fsetdec.Qed.#[export] Hint Rewrite atoms_nil atoms_cons atoms_one atoms_app : tea_rw_atoms.
forallx : AtomSet.elt, x `in` atoms [] <-> False
forallx : AtomSet.elt, x `in` atoms [] <-> False
forallx : AtomSet.elt, x `in` ∅ <-> False
fsetdec.Qed.
forall (yx : atom) (xs : list atom),
y `in` atoms (x :: xs) <-> y = x \/ y `in` atoms xs
forall (yx : atom) (xs : list atom),
y `in` atoms (x :: xs) <-> y = x \/ y `in` atoms xs
y, x: atom xs: list atom
y `in` atoms (x :: xs) <-> y = x \/ y `in` atoms xs
y, x: atom xs: list atom
y `in` ({{x}} ∪ atoms xs) <-> y = x \/ y `in` atoms xs
fsetdec.Qed.
forallyx : atom, y `in` atoms [x] <-> y = x
forallyx : atom, y `in` atoms [x] <-> y = x
y, x: atom
y `in` atoms [x] <-> y = x
y, x: atom
y `in` {{x}} <-> y = x
fsetdec.Qed.
forall (x : atom) (l1l2 : list atom),
x `in` atoms (l1 ++ l2) <->
x `in` atoms l1 \/ x `in` atoms l2
forall (x : atom) (l1l2 : list atom),
x `in` atoms (l1 ++ l2) <->
x `in` atoms l1 \/ x `in` atoms l2
x: atom l1, l2: list atom
x `in` atoms (l1 ++ l2) <->
x `in` atoms l1 \/ x `in` atoms l2
x: atom l1, l2: list atom
x `in` (atoms l1 ∪ atoms l2) <->
x `in` atoms l1 \/ x `in` atoms l2
fsetdec.Qed.#[export] Hint Rewrite in_atoms_nil in_atoms_cons in_atoms_one in_atoms_app : tea_rw_atoms.
forallxy : atom, y `in` {{x}} <-> y = x
forallxy : atom, y `in` {{x}} <-> y = x
x, y: atom
y `in` {{x}} <-> y = x
fsetdec.Qed.
forall (x : atom) (s1s2 : AtomSet.t),
x `in` (s1 ∪ s2) <-> x `in` s1 \/ x `in` s2
forall (x : atom) (s1s2 : AtomSet.t),
x `in` (s1 ∪ s2) <-> x `in` s1 \/ x `in` s2
x: atom s1, s2: AtomSet.t
x `in` (s1 ∪ s2) <-> x `in` s1 \/ x `in` s2
fsetdec.Qed.(** ** Relating <<AtomSet.t>> and <<list atom>> *)(******************************************************************************)
forall (s : AtomSet.t) (x : atom),
x `in` s <-> x ∈ (elements) s
forall (s : AtomSet.t) (x : atom),
x `in` s <-> x ∈ (elements) s
s: AtomSet.t x: atom
x `in` s <-> x ∈ (elements) s
s: AtomSet.t x: atom
SetoidList.InA eq x ((elements) s) <->
x ∈ (elements) s
s: AtomSet.t x: atom
SetoidList.InA eq x [] <-> x ∈ []
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l
SetoidList.InA eq x (a :: l) <-> x ∈ (a :: l)
s: AtomSet.t x: atom
SetoidList.InA eq x [] <-> x ∈ []
s: AtomSet.t x: atom
(SetoidList.InA eq x [] -> False) /\
(False -> SetoidList.InA eq x [])
split; intro H; inversion H.
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l
SetoidList.InA eq x (a :: l) <-> x ∈ (a :: l)
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l
SetoidList.InA eq x (a :: l) <-> a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: SetoidList.InA eq x (a :: l) y: atom l0: list atom H1: x = a H0: y = a H2: l0 = l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: SetoidList.InA eq x (a :: l) y: atom l0: list atom H1: SetoidList.InA eq x l H0: y = a H2: l0 = l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: a = x \/ List.In x l H0: a = x
SetoidList.InA eq x (a :: l)
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: a = x \/ List.In x l H0: List.In x l
SetoidList.InA eq x (a :: l)
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: SetoidList.InA eq x (a :: l) y: atom l0: list atom H1: x = a H0: y = a H2: l0 = l
a = x \/ List.In x l
s: AtomSet.t a: AtomSet.elt l: list AtomSet.elt H: SetoidList.InA eq a (a :: l) IHl: SetoidList.InA eq a l <-> a ∈ l
a = a \/ List.In a l
nowleft.
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: SetoidList.InA eq x (a :: l) y: atom l0: list atom H1: SetoidList.InA eq x l H0: y = a H2: l0 = l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: SetoidList.InA eq x (a :: l) H1: SetoidList.InA eq x l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l y: atom l0: list atom H: x = y H1: SetoidList.InA eq x l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l y: atom l0: list atom H: SetoidList.InA eq x l0 H1: SetoidList.InA eq x l
a = x \/ List.In x l
s: AtomSet.t a: AtomSet.elt l: list AtomSet.elt y: atom IHl: SetoidList.InA eq y l <-> y ∈ l l0: list atom H1: SetoidList.InA eq y l
a = y \/ List.In y l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l y: atom l0: list atom H: SetoidList.InA eq x l0 H1: SetoidList.InA eq x l
a = x \/ List.In x l
s: AtomSet.t a: AtomSet.elt l: list AtomSet.elt y: atom IHl: SetoidList.InA eq y l <-> y ∈ l l0: list atom H1: y ∈ l
a = y \/ List.In y l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l y: atom l0: list atom H: SetoidList.InA eq x l0 H1: SetoidList.InA eq x l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l y: atom l0: list atom H: SetoidList.InA eq x l0 H1: SetoidList.InA eq x l
a = x \/ List.In x l
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l y: atom l0: list atom H: SetoidList.InA eq x l0 H1: x ∈ l
a = x \/ List.In x l
nowright.
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: a = x \/ List.In x l H0: a = x
SetoidList.InA eq x (a :: l)
s: AtomSet.t x: atom l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: x = x \/ List.In x l
SetoidList.InA eq x (x :: l)
nowleft.
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: a = x \/ List.In x l H0: List.In x l
SetoidList.InA eq x (a :: l)
s: AtomSet.t x: atom a: AtomSet.elt l: list AtomSet.elt IHl: SetoidList.InA eq x l <-> x ∈ l H: a = x \/ List.In x l H0: List.In x l
SetoidList.InA eq x l
nowrewrite IHl.Qed.
forall (l : list atom) (x : atom),
x ∈ l <-> x `in` atoms l
forall (l : list atom) (x : atom),
x ∈ l <-> x `in` atoms l
l: list atom x: atom
x ∈ l <-> x `in` atoms l
x: atom
x ∈ [] <-> x `in` atoms []
a: atom l: list atom x: atom IHl: x ∈ l <-> x `in` atoms l
x ∈ (a :: l) <-> x `in` atoms (a :: l)
x: atom
x ∈ [] <-> x `in` atoms []
easy.
a: atom l: list atom x: atom IHl: x ∈ l <-> x `in` atoms l
x ∈ (a :: l) <-> x `in` atoms (a :: l)
a: atom l: list atom x: atom IHl: x ∈ l <-> x `in` atoms l