| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Proarrow.Category.Enriched.Finitary.Sheaf
Description
Sheaves on a finite site, decided by enumeration.
A cover of a generates a Sieve (generatedSieve), and a matching family for that cover is
exactly a natural transformation out of the sieve -- which over finitary profunctors is a finite
thing you can list. So the sheaf condition becomes a comparison of two finite lists (sheafAt):
restrict each element at a to get one table per element, enumerate the matching families to get
the other list, and check the two agree as multisets. Comparing only their lengths is not
enough: Props.Sheaf's Collapse has as many elements as matching families and is still not a
sheaf.
The same coverage is a Lawvere–Tierney topology on the topos. closure sends a sieve to the pairs
(g, h) along which it pulls back to a covering one, and lawvereTierney packages that as an
arrow on Omega.
The topology also has a sheafification, Sheafify, with its unit and universal property --
computed rather than postulated, so it is one more thing that can be enumerated and compared.
Synopsis
- generatedSieve :: forall t {j} {k} (a :: k) (b :: j) c. (Site t k, LocallyFinite k, CategoryOf j, Ob a, Ob b) => Cover t k a c -> Sieve a b
- isMaximal :: forall {j} {k} (a :: k) (b :: j). (FiniteCat j, FiniteCat k) => Sieve a b -> Bool
- contains :: forall {j} {k} (a :: k) (b :: j). (FiniteCat j, FiniteCat k) => Sieve a b -> Sieve a b -> Bool
- isCovering :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => Sieve a b -> Bool
- coveringCover :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, CategoryOf j) => Sieve a b -> Maybe (SomeCover t k a)
- closure :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => Sieve a b -> Sieve a b
- lawvereTierney :: forall t j k. (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => (Omega :: PROD (FINITARY j k)) ~> (Omega :: PROD (FINITARY j k))
- isSheaf :: forall t {j} {k} (p :: j +-> k). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Bool
- sheafAt :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j) c. (Site t k, Finitary p, FiniteCat j, FiniteCat k, Ob a, Ob b) => Cover t k a c -> Bool
- withTabulatedSheaf :: forall t {j} {k} (p :: j +-> k) r. (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => (forall {lm :: [[[[Nat]]]]} {rm :: [[[[Nat]]]]} (tab :: j +-> k). (tab ~ (Tabulated t lm rm :: k -> j -> Type), KnownTables j k lm rm, Sheaf t tab) => (p :~> tab) -> (tab :~> p) -> r) -> r -> r
- withSieve :: forall {j} {k} (a :: k) (b :: j) r. (FiniteCat j, FiniteCat k) => Sieve a b -> (forall (q :: j +-> k). Finitary q => (q :~> Yo a ('OP b)) -> r) -> r
- data Plus t (p :: j +-> k) (a :: k) (b :: j) where
- support :: forall {k1} {k} t (p :: k1 +-> k) (a :: k) (b :: k1). Plus t p a b -> Sieve a b
- isDense :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => Sieve a b -> Bool
- leastDenseSieve :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k, Ob a, Ob b) => Sieve a b
- plusElements :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k, Ob a, Ob b) => [Plus t p a b]
- restrictTo :: forall {j} {k} (q :: k -> j -> Type) (a :: k) (b :: j) t (p :: j +-> k). (q :~> Yo a ('OP b)) -> Plus t p a b -> q :~> p
- plusTable :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Plus t p a b -> [Natural]
- samePlus :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Plus t p a b -> Plus t p a b -> Bool
- type Sheafify t (p :: j +-> k) = Plus t (Plus t p)
- unitPlus :: forall t {j} {k} (p :: j +-> k). Profunctor p => p :~> Plus t p
- unitSheafify :: forall t {j} {k} (p :: j +-> k). Profunctor p => p :~> Sheafify t p
- extendPlus :: forall t {j} {k} (p :: j +-> k) (q :: j +-> k). (HasFiniteCovers t k, Sheaf t q) => (p :~> q) -> Plus t p :~> q
- gluePlus :: forall t {j} {k} (q :: j +-> k) (a :: k) c (b :: j). (Site t k, LocallyFinite k, Ob a, Ob b) => Cover t k a c -> (forall (x :: k). Leg t k a c x -> Plus t q x b) -> Plus t q a b
- extendSheafify :: forall t {j} {k} (p :: j +-> k) (q :: j +-> k). (HasFiniteCovers t k, Sheaf t q) => (p :~> q) -> Sheafify t p :~> q
- type SHEAVES t j k = SUBCAT ((Finitary :: (j +-> k) -> Constraint) :&&: (Sheaf t :: (j +-> k) -> Constraint))
- type SHF t (p :: j +-> k) = 'SUB p :: SUBCAT ((Finitary :: (j +-> k) -> Constraint) :&&: (Sheaf t :: (j +-> k) -> Constraint))
Documentation
generatedSieve :: forall t {j} {k} (a :: k) (b :: j) c. (Site t k, LocallyFinite k, CategoryOf j, Ob a, Ob b) => Cover t k a c -> Sieve a b Source Github #
The sieve a cover generates at (a, b): the arrows into a that factor through a leg,
paired with every arrow out of b.
isMaximal :: forall {j} {k} (a :: k) (b :: j). (FiniteCat j, FiniteCat k) => Sieve a b -> Bool Source Github #
Whether a sieve is the maximal one -- every arrow of the category is in it.
contains :: forall {j} {k} (a :: k) (b :: j). (FiniteCat j, FiniteCat k) => Sieve a b -> Sieve a b -> Bool Source Github #
Whether every point of the second sieve is a point of the first.
isCovering :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => Sieve a b -> Bool Source Github #
Whether a sieve is covering: either it is the maximal sieve, or it contains the sieve that some
cover of its object generates -- which, a sieve being closed under composition, is to contain
that cover's legs (coveringCover).
That is the coverage taken at face value. It agrees with the Grothendieck topology the coverage
generates only when the covers are stable and compose. When they do not, closure stops being
idempotent, and testLawvereTierney is where that shows up.
coveringCover :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, CategoryOf j) => Sieve a b -> Maybe (SomeCover t k a) Source Github #
The first listed cover all of whose legs lie in the sieve, if there is one. This is the search
isCovering makes and the one extendPlus needs, and it needs no tabulation: whether a sieve
contains the legs at the identity decides whether it contains everything they generate.
So it trusts the closure Proarrow.Profunctor.Instance.Sieve does not enforce: on a hand-built predicate that is not a sieve it says yes where comparing the whole generated sieve says no.
closure :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => Sieve a b -> Sieve a b Source Github #
The Lawvere–Tierney closure of a sieve: the pairs (g, h) along which it pulls back to a
covering one. A sieve is covering exactly when its closure is the maximal sieve.
Note both components -- , not just dimap g h. A coverage constrains only the
contravariant side, but a sieve over lmap gj has two, which is why +-> kProps.Sheaf checks this
function's naturality at a non-trivial j.
lawvereTierney :: forall t j k. (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => (Omega :: PROD (FINITARY j k)) ~> (Omega :: PROD (FINITARY j k)) Source Github #
The coverage as a Lawvere–Tierney topology on the topos of finitary profunctors: closure, as
an arrow on the subobject classifier.
isSheaf :: forall t {j} {k} (p :: j +-> k). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Bool Source Github #
Whether a finitary profunctor is a sheaf for the coverage: at every pair of objects and every cover, restriction is a bijection from the elements at the covered object to the matching families on the sieve the cover generates.
sheafAt :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j) c. (Site t k, Finitary p, FiniteCat j, FiniteCat k, Ob a, Ob b) => Cover t k a c -> Bool Source Github #
The sheaf condition at one cover: the restrictions of the elements at the covered object are exactly the matching families on the sieve it generates, as multisets.
withTabulatedSheaf :: forall t {j} {k} (p :: j +-> k) r. (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => (forall {lm :: [[[[Nat]]]]} {rm :: [[[[Nat]]]]} (tab :: j +-> k). (tab ~ (Tabulated t lm rm :: k -> j -> Type), KnownTables j k lm rm, Sheaf t tab) => (p :~> tab) -> (tab :~> p) -> r) -> r -> r Source Github #
Present a finitary profunctor by its tables, as
withTabulated does, and tag the presentation with the
coverage -- which is to give it a Sheaf instance. What that instance asserts is decided here,
by isSheaf, so the assertion is backed by an enumeration and not by the caller's word; the
failure continuation is taken when the profunctor is no sheaf for t.
This is how a sheaf with no Sheaf instance of its own -- a representable, a sheafification --
becomes an object of SHEAVES. It is also the cheap way to be one: the condition is decided on
the tables rather than on p, where a Sheafify answers a single toIndex by re-running the
whole plus construction.
withSieve :: forall {j} {k} (a :: k) (b :: j) r. (FiniteCat j, FiniteCat k) => Sieve a b -> (forall (q :: j +-> k). Finitary q => (q :~> Yo a ('OP b)) -> r) -> r Source Github #
A sieve as a subobject of the representable, handed on with its inclusion: the natural
transformations out of that subobject are exactly the matching families on the sieve, with no
separate treatment of the points outside it and no argument about which naturality conditions
may be dropped. This is the one notion of matching family in the module; sheafAt and Plus
both go through it.
withSubobject checks the closure a sieve must have, and its failure branch is unreachable for
any coverage, lawful or not: generatedSieve's membership ignores its covariant argument and
is closed under precomposition, and leastDenseSieve is a meet of sieves. Reaching it would take
a Finitary instance on the hom-profunctor whose elements omits an arrow, which
testFinitary rules out.
Sheafification
data Plus t (p :: j +-> k) (a :: k) (b :: j) where Source Github #
One step of the plus construction for the topology t. An element at (a, b) is a matching
family on a dense sieve, taken up to agreement on a dense sieve; a Plus value holds one such
family, as a partial function whose support is its sieve -- the sieve is never stored separately
and so cannot disagree with the family. On a finite site whose coverage is a Grothendieck topology
the dense sieves have a least one, leastDenseSieve, and every element has exactly one family on
it: so the element a value stands for is its restriction to that sieve, plusTable, and that is
what Finitary numbers and Proarrow.Testing compares. Nothing has to be quotiented.
That is HasFiniteCovers's Composition law, and leastDenseSieve fails loudly rather than
compute where it does not hold.
The constructor checks none of: that the support is a sieve, that it is dense, that the
family is matching -- as Sieve's does not check closure. plusElements builds only lawful
values; one built by hand is its builder's responsibility.
Constructors
| Plus :: forall {k} {j} (a :: k) (b :: j) (p :: j +-> k) t. (Ob a, Ob b) => (forall (c :: k) (d :: j). (c ~> a) -> (b ~> d) -> Maybe (p c d)) -> Plus t p a b |
Instances
| (Site t k, LocallyFinite k, CategoryOf j) => Sheaf t (Sheafify t p :: k -> j -> Type) Source Github # | Sheafification lands in the sheaves. This is the theorem
|
| (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Finitary (Plus t p :: k -> j -> Type) Source Github # | Numbered by |
Defined in Proarrow.Category.Enriched.Finitary.Sheaf Methods size :: forall (a :: k) (b :: j). (Ob a, Ob b) => Natural Source Github # toIndex :: forall (a :: k) (b :: j). (Ob a, Ob b) => Plus t p a b -> Natural Source Github # fromIndex :: forall (a :: k) (b :: j). (Ob a, Ob b) => Natural -> Plus t p a b Source Github # elements :: forall (a :: k) (b :: j). (Ob a, Ob b) => [Plus t p a b] Source Github # | |
| (CategoryOf j, CategoryOf k) => Profunctor (Plus t p :: k -> j -> Type) Source Github # | |
Defined in Proarrow.Category.Enriched.Finitary.Sheaf Methods dimap :: forall (c :: k) (a :: k) (b :: j) (d :: j). (c ~> a) -> (b ~> d) -> Plus t p a b -> Plus t p c d Source Github # lmap :: forall (c :: k) (a :: k) (b :: j). (c ~> a) -> Plus t p a b -> Plus t p c b Source Github # rmap :: forall (b :: j) (d :: j) (a :: k). (b ~> d) -> Plus t p a b -> Plus t p a d Source Github # (\\) :: forall (a :: k) (b :: j) r. ((Ob a, Ob b) => r) -> Plus t p a b -> r Source Github # | |
support :: forall {k1} {k} t (p :: k1 +-> k) (a :: k) (b :: k1). Plus t p a b -> Sieve a b Source Github #
The sieve a value is defined on.
isDense :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k) => Sieve a b -> Bool Source Github #
Whether a sieve is dense for the topology: its closure is the maximal sieve. On a lawful
coverage this agrees with isCovering -- testDenseIsCovering checks
that -- but it is the stable notion, and Plus needs stability, since dimap pulls a support
back along arrows.
leastDenseSieve :: forall t {j} {k} (a :: k) (b :: j). (HasFiniteCovers t k, FiniteCat j, FiniteCat k, Ob a, Ob b) => Sieve a b Source Github #
The meet of all the dense sieves at a pair of objects, and so the least dense sieve -- when
the covers compose, since that is what makes closure preserve meets. Restriction to it is what
picks one matching family out of each element of Plus. On a coverage whose covers pull back but
do not compose the meet need not be dense, and this errors, naming the law that failed, rather
than let Plus compute on it: a poset w ≤ x ≤ a, w ≤ y ≤ a with a covered by x and by
y separately and each of those by w is the smallest example.
plusElements :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k, Ob a, Ob b) => [Plus t p a b] Source Github #
The elements of Plus at a pair of objects: the matching families on the least dense sieve, in
the order natElements lists them.
restrictTo :: forall {j} {k} (q :: k -> j -> Type) (a :: k) (b :: j) t (p :: j +-> k). (q :~> Yo a ('OP b)) -> Plus t p a b -> q :~> p Source Github #
A value restricted to a sieve reified as a subobject: the natural transformation out of it that the value's family is.
plusTable :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Plus t p a b -> [Natural] Source Github #
samePlus :: forall t {j} {k} (p :: j +-> k) (a :: k) (b :: j). (HasFiniteCovers t k, Finitary p, FiniteCat j, FiniteCat k) => Plus t p a b -> Plus t p a b -> Bool Source Github #
Whether two values stand for the same element: their restrictions to the least dense sieve
agree. One sieve for the pair, where two plusTables would each build their own -- which is what
Proarrow.Testing's equality on Plus wants, since it compares far more often than it shows.
type Sheafify t (p :: j +-> k) = Plus t (Plus t p) Source Github #
Sheafification: the plus construction twice. One Plus makes a profunctor separated -- two
elements with the same restrictions to a dense sieve are equal -- and the second makes it a
sheaf. The first alone need not: Props.Sheaf's constant presheaf on the two-point space has one
section over the empty set after one plus, but still two over the whole space where a sheaf needs
four. On a site whose covers have no overlaps, ByArrow say, one plus is
already a sheaf and the second changes nothing.
unitPlus :: forall t {j} {k} (p :: j +-> k). Profunctor p => p :~> Plus t p Source Github #
The unit of the plus construction: an element as the family of its own restrictions, on the maximal sieve.
unitSheafify :: forall t {j} {k} (p :: j +-> k). Profunctor p => p :~> Sheafify t p Source Github #
unitPlus twice: the unit of sheafification.
extendPlus :: forall t {j} {k} (p :: j +-> k) (q :: j +-> k). (HasFiniteCovers t k, Sheaf t q) => (p :~> q) -> Plus t p :~> q Source Github #
The universal property, one plus at a time: a map into a sheaf extends along unitPlus. A
dense support either is everything, and the family is read off at the identity, or contains the
legs of some listed cover -- that is what density at the identity says, and coveringCover finds
it -- and the family restricted to those legs glues. Which cover is found does not matter, q
being a sheaf; nor need q be Finitary -- gluing is all that is asked of it.
gluePlus :: forall t {j} {k} (q :: j +-> k) (a :: k) c (b :: j). (Site t k, LocallyFinite k, Ob a, Ob b) => Cover t k a c -> (forall (x :: k). Leg t k a c x -> Plus t q x b) -> Plus t q a b Source Github #
Gluing for the plus construction: a matching family over a cover, assembled into one family.
At (g, h) it takes the first leg that g factors through and whose family is defined at the
factor -- factorThrough gives that factor u, and the value is the leg's family at (u, h).
So the support of the result is what the legs generate from the legs' own supports, which is
dense by HasFiniteCovers's Composition law.
Well definedness -- that another leg, or another factorisation through the same leg, gives the
same value -- is exactly what matching says, and glue is unconstrained on families that are
not matching, so the first one found is as good as any.
extendSheafify :: forall t {j} {k} (p :: j +-> k) (q :: j +-> k). (HasFiniteCovers t k, Sheaf t q) => (p :~> q) -> Sheafify t p :~> q Source Github #
extendPlus twice: a map into a sheaf extends along unitSheafify.
The category of sheaves
type SHEAVES t j k = SUBCAT ((Finitary :: (j +-> k) -> Constraint) :&&: (Sheaf t :: (j +-> k) -> Constraint)) Source Github #
The full subcategory of on the sheaves for FINITARY j kt: the finitary profunctors that
have a Sheaf instance. Its finite limits are computed exactly as FINITARY's and are sheaves
by the closure instances -- TerminalProfunctor, :*:, and
Reindex for the equalizers. Its colimits are not
computed as FINITARY's: a quotient of sheaves is no sheaf, and they go through Sheafify.
Its hom-sets are finitary by the conjunction instance in Proarrow.Category.Enriched.Finitary.Topos.
type SHF t (p :: j +-> k) = 'SUB p :: SUBCAT ((Finitary :: (j +-> k) -> Constraint) :&&: (Sheaf t :: (j +-> k) -> Constraint)) Source Github #
Orphan instances
| (Site t k, CategoryOf j) => HasBinaryProducts (SHEAVES t j k) Source Github # | |||||
Methods withObProd :: forall (a :: SHEAVES t j k) (b :: SHEAVES t j k) r. (Ob a, Ob b) => (Ob (a && b) => r) -> r Source Github # fst :: forall (a :: SHEAVES t j k) (b :: SHEAVES t j k). (Ob a, Ob b) => (a && b) ~> a Source Github # snd :: forall (a :: SHEAVES t j k) (b :: SHEAVES t j k). (Ob a, Ob b) => (a && b) ~> b Source Github # (&&&) :: forall (a :: SHEAVES t j k) (x :: SHEAVES t j k) (y :: SHEAVES t j k). (a ~> x) -> (a ~> y) -> a ~> (x && y) Source Github # (***) :: forall (a :: SHEAVES t j k) (b :: SHEAVES t j k) (x :: SHEAVES t j k) (y :: SHEAVES t j k). (a ~> x) -> (b ~> y) -> (a && b) ~> (x && y) Source Github # | |||||
| (Site t k, Enumerable j, Enumerable k) => HasEqualizers (SHEAVES t j k) Source Github # | Equalizers as in | ||||
| (Site t k, Enumerable j, Enumerable k) => HasPullbacks (SHEAVES t j k) Source Github # | |||||
Methods pullback :: forall (o :: SHEAVES t j k) (a :: SHEAVES t j k) (b :: SHEAVES t j k) r. (a ~> o) -> (b ~> o) -> (forall (p :: SHEAVES t j k). (p ~> a) -> (p ~> b) -> r) -> r Source Github # factorPullback :: forall (a :: SHEAVES t j k) (b :: SHEAVES t j k) (p :: SHEAVES t j k) (q :: SHEAVES t j k). (p ~> a) -> (p ~> b) -> (q ~> a) -> (q ~> b) -> q ~> p Source Github # | |||||
| (Site t k, CategoryOf j) => HasTerminalObject (SHEAVES t j k) Source Github # | |||||
Associated Types
| |||||