├── .editorconfig ├── .gitattributes ├── .github ├── pull_request_template.md └── workflows │ ├── build.yml │ └── preview.yml ├── .gitignore ├── 1lab.agda-lib ├── CITATION.bib ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── _typos.toml ├── cabal.project ├── default.nix ├── package-lock.json ├── package.json ├── src ├── 1Lab │ ├── Classical.lagda.md │ ├── Counterexamples │ │ ├── GlobalChoice.lagda.md │ │ ├── IsIso.lagda.md │ │ ├── Isovalence.lagda.md │ │ ├── Russell.lagda.md │ │ └── Sigma.lagda.md │ ├── Equiv.lagda.md │ ├── Equiv │ │ ├── Biinv.lagda.md │ │ ├── Fibrewise.lagda.md │ │ ├── FromPath.lagda.md │ │ └── HalfAdjoint.lagda.md │ ├── Extensionality.agda │ ├── Function │ │ ├── Embedding.lagda.md │ │ ├── Reasoning.lagda.md │ │ └── Surjection.lagda.md │ ├── HIT │ │ └── Truncation.lagda.md │ ├── HLevel.lagda.md │ ├── HLevel │ │ ├── Closure.lagda.md │ │ └── Universe.lagda.md │ ├── Inductive.agda │ ├── Membership.agda │ ├── Path.lagda.md │ ├── Path │ │ ├── Cartesian.lagda.md │ │ ├── Groupoid.lagda.md │ │ ├── IdentitySystem.lagda.md │ │ ├── IdentitySystem │ │ │ ├── Interface.agda │ │ │ └── Strict.lagda.md │ │ └── Reasoning.lagda.md │ ├── Prelude.agda │ ├── Reflection.lagda.md │ ├── Reflection │ │ ├── Copattern.agda │ │ ├── Deriving │ │ │ └── Show.agda │ │ ├── HLevel.agda │ │ ├── Induction.agda │ │ ├── Induction │ │ │ └── Examples.agda │ │ ├── Marker.agda │ │ ├── Record.agda │ │ ├── Regularity.agda │ │ ├── Signature.agda │ │ ├── Solver.agda │ │ ├── Subst.agda │ │ ├── Univalence.agda │ │ └── Variables.agda │ ├── Resizing.lagda.md │ ├── Type.lagda.md │ ├── Type │ │ ├── Pi.lagda.md │ │ ├── Pointed.lagda.md │ │ └── Sigma.lagda.md │ ├── Underlying.agda │ ├── Univalence.lagda.md │ ├── Univalence │ │ ├── Fibrewise.lagda.md │ │ ├── SIP.lagda.md │ │ └── SIP │ │ │ └── Auto.agda │ └── intro.lagda.md ├── Algebra │ ├── Group.lagda.md │ ├── Group │ │ ├── Ab.lagda.md │ │ ├── Ab │ │ │ ├── Abelianisation.lagda.md │ │ │ ├── Free.lagda.md │ │ │ ├── Hom.lagda.md │ │ │ ├── Sum.lagda.md │ │ │ └── Tensor.lagda.md │ │ ├── Action.lagda.md │ │ ├── Cat │ │ │ ├── Base.lagda.md │ │ │ ├── FinitelyComplete.lagda.md │ │ │ └── Monadic.lagda.md │ │ ├── Cayley.lagda.md │ │ ├── Concrete.lagda.md │ │ ├── Concrete │ │ │ ├── Abelian.lagda.md │ │ │ ├── FinitelyComplete.lagda.md │ │ │ └── Semidirect.lagda.md │ │ ├── Free.lagda.md │ │ ├── Free │ │ │ └── Product.lagda.md │ │ ├── Homotopy.lagda.md │ │ ├── Homotopy │ │ │ └── BAut.lagda.md │ │ ├── Instances │ │ │ ├── Cyclic.lagda.md │ │ │ ├── Dihedral.lagda.md │ │ │ ├── Integers.lagda.md │ │ │ └── Symmetric.lagda.md │ │ ├── NAry.lagda.md │ │ ├── Notation.agda │ │ ├── Semidirect.lagda.md │ │ ├── Solver.agda │ │ └── Subgroup.lagda.md │ ├── Magma.lagda.md │ ├── Magma │ │ ├── Unital.lagda.md │ │ └── Unital │ │ │ └── EckmannHilton.lagda.md │ ├── Monoid.lagda.md │ ├── Monoid │ │ ├── Category.lagda.md │ │ └── Reasoning.lagda.md │ ├── Quasigroup.lagda.md │ ├── Quasigroup │ │ └── Instances │ │ │ ├── Group.lagda.md │ │ │ └── Initial.lagda.md │ ├── Ring.lagda.md │ ├── Ring │ │ ├── Cat │ │ │ └── Initial.lagda.md │ │ ├── Commutative.lagda.md │ │ ├── Ideal.lagda.md │ │ ├── Localisation.lagda.md │ │ ├── Module.lagda.md │ │ ├── Module │ │ │ ├── Action.lagda.md │ │ │ ├── Category.lagda.md │ │ │ ├── Free.lagda.md │ │ │ ├── Multilinear.lagda.md │ │ │ ├── Notation.agda │ │ │ └── Vec.lagda.md │ │ ├── Quotient.lagda.md │ │ ├── Reasoning.lagda.md │ │ └── Solver.agda │ └── Semigroup.lagda.md ├── Authors.lagda.md ├── Borceux.lagda.md ├── Cat │ ├── Abelian │ │ ├── Base.lagda.md │ │ ├── Endo.lagda.md │ │ ├── Functor.lagda.md │ │ ├── Images.lagda.md │ │ ├── Instances │ │ │ ├── Ab.lagda.md │ │ │ └── Functor.lagda.md │ │ ├── Limits.lagda.md │ │ └── NAry.lagda.md │ ├── Allegory │ │ ├── Base.lagda.md │ │ ├── Instances │ │ │ └── Mat.lagda.md │ │ ├── Maps.lagda.md │ │ ├── Morphism.lagda.md │ │ └── Reasoning.lagda.md │ ├── Base.lagda.md │ ├── Bi │ │ ├── Base.lagda.md │ │ ├── Diagram │ │ │ ├── Adjunction.lagda.md │ │ │ ├── Monad.lagda.md │ │ │ └── Monad │ │ │ │ └── Spans.lagda.md │ │ └── Instances │ │ │ ├── Discrete.lagda.md │ │ │ ├── Displayed.lagda.md │ │ │ ├── InternalCats.lagda.md │ │ │ ├── Relations.lagda.md │ │ │ ├── Spans.lagda.md │ │ │ └── Terminal.lagda.md │ ├── CartesianClosed │ │ ├── Lambda.lagda.md │ │ └── Locally.lagda.md │ ├── Connected.lagda.md │ ├── Diagram │ │ ├── Biproduct.lagda.md │ │ ├── Coend.lagda.md │ │ ├── Coend │ │ │ ├── Formula.lagda.md │ │ │ └── Sets.lagda.md │ │ ├── Coequaliser.lagda.md │ │ ├── Coequaliser │ │ │ └── RegularEpi.lagda.md │ │ ├── Colimit │ │ │ ├── Base.lagda.md │ │ │ ├── Cocone.lagda.md │ │ │ ├── Coequaliser.lagda.md │ │ │ ├── Coproduct.lagda.md │ │ │ ├── Finite.lagda.md │ │ │ ├── Initial.lagda.md │ │ │ ├── Representable.lagda.md │ │ │ └── Universal.lagda.md │ │ ├── Comonad.lagda.md │ │ ├── Comonad │ │ │ └── Writer.lagda.md │ │ ├── Congruence.lagda.md │ │ ├── Coproduct.lagda.md │ │ ├── Coproduct │ │ │ ├── Copower.lagda.md │ │ │ └── Indexed.lagda.md │ │ ├── Duals.lagda.md │ │ ├── Equaliser.lagda.md │ │ ├── Equaliser │ │ │ ├── Joint.lagda.md │ │ │ ├── Kernel.lagda.md │ │ │ └── RegularMono.lagda.md │ │ ├── Exponential.lagda.md │ │ ├── Idempotent.lagda.md │ │ ├── Image.lagda.md │ │ ├── Initial.lagda.md │ │ ├── Initial │ │ │ └── Weak.lagda.md │ │ ├── Limit │ │ │ ├── Base.lagda.md │ │ │ ├── Cone.lagda.md │ │ │ ├── Equaliser.lagda.md │ │ │ ├── Finite.lagda.md │ │ │ ├── Initial.lagda.md │ │ │ ├── Product.lagda.md │ │ │ ├── Pullback.lagda.md │ │ │ └── Terminal.lagda.md │ │ ├── Monad.lagda.md │ │ ├── Monad │ │ │ ├── Codensity.lagda.md │ │ │ ├── Extension.lagda.md │ │ │ ├── Idempotent.lagda.md │ │ │ ├── Kleisli.lagda.md │ │ │ ├── Relative.lagda.md │ │ │ └── Solver.agda │ │ ├── Omega.lagda.md │ │ ├── Product.lagda.md │ │ ├── Product │ │ │ ├── Finite.lagda.md │ │ │ ├── Indexed.lagda.md │ │ │ └── Solver.lagda.md │ │ ├── Projective.lagda.md │ │ ├── Projective │ │ │ └── Strong.lagda.md │ │ ├── Pullback.lagda.md │ │ ├── Pullback │ │ │ ├── Along.lagda.md │ │ │ └── Properties.lagda.md │ │ ├── Pushout.lagda.md │ │ ├── Pushout │ │ │ └── Properties.lagda.md │ │ ├── Separator.lagda.md │ │ ├── Separator │ │ │ ├── Regular.lagda.md │ │ │ └── Strong.lagda.md │ │ ├── Sieve.lagda.md │ │ ├── Terminal.lagda.md │ │ └── Zero.lagda.md │ ├── Displayed │ │ ├── Adjoint.lagda.md │ │ ├── Base.lagda.md │ │ ├── BeckChevalley.lagda.md │ │ ├── Bifibration.lagda.md │ │ ├── Cartesian.lagda.md │ │ ├── Cartesian │ │ │ ├── Discrete.lagda.md │ │ │ ├── Identity.lagda.md │ │ │ ├── Indexing.lagda.md │ │ │ ├── Joint.lagda.md │ │ │ ├── Right.lagda.md │ │ │ ├── Street.lagda.md │ │ │ └── Weak.lagda.md │ │ ├── Cocartesian.lagda.md │ │ ├── Cocartesian │ │ │ ├── Discrete.lagda.md │ │ │ ├── Indexing.lagda.md │ │ │ └── Weak.lagda.md │ │ ├── Composition.lagda.md │ │ ├── Comprehension.lagda.md │ │ ├── Comprehension │ │ │ ├── Coproduct.lagda.md │ │ │ └── Coproduct │ │ │ │ ├── Strong.lagda.md │ │ │ │ └── VeryStrong.lagda.md │ │ ├── Diagram │ │ │ └── Total │ │ │ │ └── Product.lagda.md │ │ ├── Doctrine.lagda.md │ │ ├── Doctrine │ │ │ ├── Frame.lagda.md │ │ │ └── Logic.lagda.md │ │ ├── Fibre.lagda.md │ │ ├── Fibre │ │ │ └── Reasoning.lagda.md │ │ ├── Functor.lagda.md │ │ ├── GenericObject.lagda.md │ │ ├── Instances │ │ │ ├── CT-Structure.lagda.md │ │ │ ├── Chaotic.lagda.md │ │ │ ├── Comma.lagda.md │ │ │ ├── Diagrams.lagda.md │ │ │ ├── DisplayedFamilies.lagda.md │ │ │ ├── Elements.lagda.md │ │ │ ├── Externalisation.lagda.md │ │ │ ├── Family.lagda.md │ │ │ ├── Family │ │ │ │ └── Properties.lagda.md │ │ │ ├── Identity.lagda.md │ │ │ ├── Lifting.lagda.md │ │ │ ├── Objects.lagda.md │ │ │ ├── Opposite.lagda.md │ │ │ ├── Pullback.lagda.md │ │ │ ├── Scone.lagda.md │ │ │ ├── Simple.lagda.md │ │ │ ├── Simple │ │ │ │ └── Properties.lagda.md │ │ │ ├── Slice.lagda.md │ │ │ ├── Slice │ │ │ │ └── Properties.lagda.md │ │ │ ├── Subobjects.lagda.md │ │ │ ├── Subobjects │ │ │ │ └── Reasoning.lagda.md │ │ │ ├── TotalProduct.lagda.md │ │ │ └── Trivial.lagda.md │ │ ├── InternalSum.lagda.md │ │ ├── Morphism.lagda.md │ │ ├── Morphism │ │ │ └── Duality.lagda.md │ │ ├── Path.lagda.md │ │ ├── Reasoning.lagda.md │ │ ├── Solver.agda │ │ ├── Total.lagda.md │ │ ├── Total │ │ │ └── Op.lagda.md │ │ ├── TwoSided.lagda.md │ │ ├── TwoSided │ │ │ └── Discrete.lagda.md │ │ ├── Univalence.lagda.md │ │ └── Univalence │ │ │ ├── Reasoning.lagda.md │ │ │ └── Thin.lagda.md │ ├── Finite.lagda.md │ ├── Functor │ │ ├── Adjoint.lagda.md │ │ ├── Adjoint │ │ │ ├── AFT.lagda.md │ │ │ ├── Comonad.lagda.md │ │ │ ├── Comonadic.lagda.md │ │ │ ├── Compose.lagda.md │ │ │ ├── Conservative.lagda.md │ │ │ ├── Continuous.lagda.md │ │ │ ├── Epireflective.lagda.md │ │ │ ├── Hom.lagda.md │ │ │ ├── Kan.lagda.md │ │ │ ├── Mate.lagda.md │ │ │ ├── Monad.lagda.md │ │ │ ├── Monadic.lagda.md │ │ │ ├── Properties.lagda.md │ │ │ ├── Reflective.lagda.md │ │ │ ├── Representable.lagda.md │ │ │ └── Unique.lagda.md │ │ ├── Algebra.lagda.md │ │ ├── Algebra │ │ │ ├── KnasterTarski.lagda.md │ │ │ └── Limits.lagda.md │ │ ├── Amnestic.lagda.md │ │ ├── Base.lagda.md │ │ ├── Bifunctor.lagda.md │ │ ├── Closed.lagda.md │ │ ├── Coherence.agda │ │ ├── Compose.lagda.md │ │ ├── Conservative.lagda.md │ │ ├── Constant.lagda.md │ │ ├── Dense.lagda.md │ │ ├── Equivalence.lagda.md │ │ ├── Equivalence │ │ │ ├── Complete.lagda.md │ │ │ └── Path.lagda.md │ │ ├── Final.lagda.md │ │ ├── FullSubcategory.lagda.md │ │ ├── Hom.lagda.md │ │ ├── Hom │ │ │ ├── Cocompletion.lagda.md │ │ │ ├── Coyoneda.lagda.md │ │ │ ├── Displayed.lagda.md │ │ │ ├── Duality.lagda.md │ │ │ ├── Properties.lagda.md │ │ │ ├── Representable.lagda.md │ │ │ └── Yoneda.lagda.md │ │ ├── Joint.lagda.md │ │ ├── Kan │ │ │ ├── Adjoint.lagda.md │ │ │ ├── Base.lagda.md │ │ │ ├── Duality.lagda.md │ │ │ ├── Global.lagda.md │ │ │ ├── Nerve.lagda.md │ │ │ ├── Pointwise.lagda.md │ │ │ ├── Reflection.agda │ │ │ ├── Representable.lagda.md │ │ │ └── Unique.lagda.md │ │ ├── Monadic │ │ │ ├── Beck.lagda.md │ │ │ └── Crude.lagda.md │ │ ├── Morphism.lagda.md │ │ ├── Naturality.lagda.md │ │ ├── Naturality │ │ │ └── Reflection.agda │ │ ├── Properties.lagda.md │ │ ├── Properties │ │ │ └── FullyFaithful.lagda.md │ │ ├── Pullback.lagda.md │ │ ├── Reasoning.lagda.md │ │ ├── Reasoning │ │ │ ├── FullyFaithful.lagda.md │ │ │ └── Presheaf.agda │ │ ├── Slice.lagda.md │ │ ├── Solver.agda │ │ ├── Subcategory.lagda.md │ │ ├── Univalence.lagda.md │ │ └── WideSubcategory.lagda.md │ ├── Gaunt.lagda.md │ ├── Groupoid.lagda.md │ ├── Instances │ │ ├── Algebras │ │ │ └── Limits.lagda.md │ │ ├── Coalgebras.lagda.md │ │ ├── Coalgebras │ │ │ ├── Cartesian.lagda.md │ │ │ └── Limits.lagda.md │ │ ├── Comma.lagda.md │ │ ├── Comma │ │ │ ├── Limits.lagda.md │ │ │ └── Univalent.lagda.md │ │ ├── Congruence.lagda.md │ │ ├── Core.lagda.md │ │ ├── Delooping.lagda.md │ │ ├── Discrete.lagda.md │ │ ├── Elements.lagda.md │ │ ├── Elements │ │ │ └── Covariant.lagda.md │ │ ├── FinSets.lagda.md │ │ ├── FinSets │ │ │ └── Omega.lagda.md │ │ ├── Free.lagda.md │ │ ├── Functor.lagda.md │ │ ├── Functor │ │ │ ├── Duality.lagda.md │ │ │ └── Limits.lagda.md │ │ ├── Graphs.lagda.md │ │ ├── InternalFunctor.lagda.md │ │ ├── InternalFunctor │ │ │ └── Compose.lagda.md │ │ ├── Karoubi.lagda.md │ │ ├── Lift.lagda.md │ │ ├── Localisation.lagda.md │ │ ├── MarkedGraphs.lagda.md │ │ ├── Monads.lagda.md │ │ ├── OFE.lagda.md │ │ ├── OFE │ │ │ ├── Closed.lagda.md │ │ │ ├── Complete.lagda.md │ │ │ ├── Coproduct.lagda.md │ │ │ ├── Discrete.lagda.md │ │ │ ├── Later.lagda.md │ │ │ └── Product.lagda.md │ │ ├── OuterFunctor.lagda.md │ │ ├── Poly.lagda.md │ │ ├── Presheaf │ │ │ ├── Colimits.lagda.md │ │ │ ├── Exponentials.lagda.md │ │ │ ├── Limits.lagda.md │ │ │ └── Omega.lagda.md │ │ ├── Product.lagda.md │ │ ├── Sets.lagda.md │ │ ├── Sets │ │ │ ├── CartesianClosed.lagda.md │ │ │ ├── Cocomplete.lagda.md │ │ │ ├── Complete.lagda.md │ │ │ ├── Congruences.lagda.md │ │ │ └── Counterexamples │ │ │ │ └── SelfDual.lagda.md │ │ ├── Shape │ │ │ ├── Cospan.lagda.md │ │ │ ├── Initial.lagda.md │ │ │ ├── Interval.lagda.md │ │ │ ├── Involution.lagda.md │ │ │ ├── Isomorphism.lagda.md │ │ │ ├── Join.lagda.md │ │ │ ├── Parallel.lagda.md │ │ │ ├── Terminal.lagda.md │ │ │ ├── Terminal │ │ │ │ └── Properties.lagda.md │ │ │ └── Two.lagda.md │ │ ├── Sheaf │ │ │ ├── Exponentials.lagda.md │ │ │ ├── Limits.lagda.md │ │ │ ├── Limits │ │ │ │ └── Finite.lagda.md │ │ │ └── Omega.lagda.md │ │ ├── Sheaves.lagda.md │ │ ├── Simplex.lagda.md │ │ ├── Slice.lagda.md │ │ ├── Slice │ │ │ ├── Colimit.lagda.md │ │ │ ├── Limit.lagda.md │ │ │ ├── Presheaf.lagda.md │ │ │ └── Twice.lagda.md │ │ ├── StrictCat.lagda.md │ │ ├── StrictCat │ │ │ └── Cohesive.lagda.md │ │ └── Twisted.lagda.md │ ├── Internal │ │ ├── Base.lagda.md │ │ ├── Functor │ │ │ └── Outer.lagda.md │ │ ├── Instances │ │ │ ├── Congruence.lagda.md │ │ │ └── Discrete.lagda.md │ │ ├── Morphism.lagda.md │ │ ├── Opposite.lagda.md │ │ ├── Reasoning.lagda.md │ │ └── Sets.lagda.md │ ├── Monoidal │ │ ├── Base.lagda.md │ │ ├── Braided.lagda.md │ │ ├── Diagonals.lagda.md │ │ ├── Diagram │ │ │ ├── Monoid.lagda.md │ │ │ └── Monoid │ │ │ │ └── Representable.lagda.md │ │ ├── Functor.lagda.md │ │ ├── Instances │ │ │ ├── Cartesian.lagda.md │ │ │ └── Day.lagda.md │ │ ├── Monad.lagda.md │ │ ├── Reverse.lagda.md │ │ ├── Strength.lagda.md │ │ └── Strength │ │ │ └── Monad.lagda.md │ ├── Morphism.lagda.md │ ├── Morphism │ │ ├── Duality.lagda.md │ │ ├── Factorisation.lagda.md │ │ ├── Instances.agda │ │ ├── Joint │ │ │ └── Mono.lagda.md │ │ ├── Orthogonal.lagda.md │ │ └── Strong │ │ │ ├── Epi.lagda.md │ │ │ └── Mono.lagda.md │ ├── Natural │ │ └── Reasoning.lagda.md │ ├── Prelude.agda │ ├── Reasoning.lagda.md │ ├── Regular.lagda.md │ ├── Regular │ │ ├── Image.lagda.md │ │ ├── Instances │ │ │ └── Sets.lagda.md │ │ └── Slice.lagda.md │ ├── Restriction │ │ ├── Base.lagda.md │ │ ├── Functor.lagda.md │ │ ├── Instances │ │ │ └── Allegory.lagda.md │ │ ├── Reasoning.lagda.md │ │ └── Total.lagda.md │ ├── Site │ │ ├── Base.lagda.md │ │ ├── Closure.lagda.md │ │ ├── Constructions.lagda.md │ │ ├── Grothendieck.lagda.md │ │ ├── Instances │ │ │ ├── Atomic.lagda.md │ │ │ ├── Canonical.lagda.md │ │ │ └── Frame.lagda.md │ │ └── Sheafification.lagda.md │ ├── Skeletal.lagda.md │ ├── Solver.lagda.md │ ├── Strict.lagda.md │ ├── Strict │ │ └── Reasoning.lagda.md │ ├── Univalent.lagda.md │ └── Univalent │ │ ├── Instances │ │ └── Opposite.lagda.md │ │ ├── Rezk.lagda.md │ │ └── Rezk │ │ └── Universal.lagda.md ├── Data │ ├── Bool.lagda.md │ ├── Bool │ │ └── Base.lagda.md │ ├── Char │ │ └── Base.lagda.md │ ├── Dec.lagda.md │ ├── Dec │ │ ├── Base.lagda.md │ │ └── Path.lagda.md │ ├── Fin.lagda.md │ ├── Fin │ │ ├── Base.lagda.md │ │ ├── Closure.lagda.md │ │ ├── Finite.lagda.md │ │ ├── Indexed.lagda.md │ │ ├── Product.lagda.md │ │ └── Properties.lagda.md │ ├── Finset │ │ ├── Base.lagda.md │ │ └── Properties.agda │ ├── Float │ │ └── Base.lagda.md │ ├── Id │ │ ├── Base.lagda.md │ │ └── Properties.agda │ ├── Image.lagda.md │ ├── Int.lagda.md │ ├── Int │ │ ├── Base.lagda.md │ │ ├── DivMod.lagda.md │ │ ├── Divisible.lagda.md │ │ ├── HIT.lagda.md │ │ ├── Order.lagda.md │ │ ├── Properties.lagda.md │ │ └── Universal.lagda.md │ ├── Irr.lagda.md │ ├── List.lagda.md │ ├── List │ │ ├── Base.lagda.md │ │ ├── Membership.lagda.md │ │ ├── Pi.agda │ │ ├── Properties.lagda.md │ │ ├── Quantifiers.lagda.md │ │ └── Sigma.agda │ ├── Maybe.lagda.md │ ├── Maybe │ │ ├── Base.lagda.md │ │ └── Properties.lagda.md │ ├── Nat.lagda.md │ ├── Nat │ │ ├── Base.lagda.md │ │ ├── DivMod.lagda.md │ │ ├── Divisible.lagda.md │ │ ├── Divisible │ │ │ └── GCD.lagda.md │ │ ├── Order.lagda.md │ │ ├── Prime.lagda.md │ │ ├── Properties.lagda.md │ │ └── Solver.lagda.md │ ├── Partial │ │ ├── Base.lagda.md │ │ └── Properties.lagda.md │ ├── Power.lagda.md │ ├── Power │ │ └── Complemented.lagda.md │ ├── Product │ │ └── NAry.lagda.md │ ├── Rational │ │ ├── Base.lagda.md │ │ ├── Order.lagda.md │ │ ├── Properties.lagda.md │ │ ├── Reflection.agda │ │ └── Solver.agda │ ├── Reflection │ │ ├── Abs.agda │ │ ├── Argument.agda │ │ ├── Error.agda │ │ ├── Fixity.agda │ │ ├── Literal.agda │ │ ├── Meta.agda │ │ ├── Name.agda │ │ └── Term.agda │ ├── Set │ │ ├── Coequaliser.lagda.md │ │ ├── Coequaliser │ │ │ └── Split.lagda.md │ │ ├── Material.lagda.md │ │ ├── Projective.lagda.md │ │ ├── Pushout.lagda.md │ │ ├── Surjection.lagda.md │ │ └── Truncation.lagda.md │ ├── String │ │ ├── Base.lagda.md │ │ └── Show.lagda.md │ ├── Sum.lagda.md │ ├── Sum │ │ ├── Base.lagda.md │ │ └── Properties.lagda.md │ ├── Vec │ │ ├── Base.lagda.md │ │ └── Properties.lagda.md │ ├── Wellfounded │ │ ├── Base.lagda.md │ │ ├── Properties.lagda.md │ │ └── W.lagda.md │ └── Word │ │ └── Base.lagda.md ├── Elephant.lagda.md ├── HoTT.lagda.md ├── Homotopy │ ├── Base.lagda.md │ ├── Conjugation.lagda.md │ ├── Connectedness.lagda.md │ ├── Connectedness │ │ └── Automation.lagda.md │ ├── Pushout.lagda.md │ ├── Space │ │ ├── Circle.lagda.md │ │ ├── Delooping.lagda.md │ │ ├── Sinfty.lagda.md │ │ ├── Sphere.lagda.md │ │ ├── Suspension.lagda.md │ │ ├── Suspension │ │ │ └── Properties.lagda.md │ │ └── Torus.lagda.md │ ├── Truncation.lagda.md │ └── Wedge.lagda.md ├── Logic │ └── Propositional │ │ ├── Classical.lagda.md │ │ └── Classical │ │ ├── CNF.lagda.md │ │ ├── Compactness.lagda.md │ │ └── SAT.lagda.md ├── Meta │ ├── Alt.lagda.md │ ├── Append.lagda.md │ ├── Bind.lagda.md │ ├── Brackets.lagda.md │ ├── Foldable.lagda.md │ ├── Idiom.lagda.md │ ├── Invariant.lagda.md │ └── Traversable.lagda.md ├── Order │ ├── Base.lagda.md │ ├── Cat.lagda.md │ ├── DCPO.lagda.md │ ├── DCPO │ │ ├── Free.lagda.md │ │ └── Pointed.lagda.md │ ├── Diagram │ │ ├── Bottom.lagda.md │ │ ├── Fixpoint.lagda.md │ │ ├── Glb.lagda.md │ │ ├── Glb │ │ │ └── Reasoning.lagda.md │ │ ├── Join.lagda.md │ │ ├── Join │ │ │ └── Reasoning.lagda.md │ │ ├── Lub.lagda.md │ │ ├── Lub │ │ │ ├── Reasoning.lagda.md │ │ │ └── Subset.lagda.md │ │ ├── Meet.lagda.md │ │ ├── Meet │ │ │ └── Reasoning.lagda.md │ │ └── Top.lagda.md │ ├── Displayed.lagda.md │ ├── Frame.lagda.md │ ├── Frame │ │ ├── Free.lagda.md │ │ └── Reasoning.lagda.md │ ├── Heyting.lagda.md │ ├── Instances │ │ ├── Coproduct.lagda.md │ │ ├── Discrete.lagda.md │ │ ├── Disjoint.lagda.md │ │ ├── Int.lagda.md │ │ ├── LexicalSum.lagda.md │ │ ├── Lift.lagda.md │ │ ├── Lower.lagda.md │ │ ├── Lower │ │ │ └── Cocompletion.lagda.md │ │ ├── Nat.lagda.md │ │ ├── Pointwise.lagda.md │ │ ├── Pointwise │ │ │ └── Diagrams.lagda.md │ │ ├── Product.lagda.md │ │ └── Props.lagda.md │ ├── Lattice.lagda.md │ ├── Lattice │ │ ├── Distributive.lagda.md │ │ └── Reasoning.lagda.md │ ├── Morphism.lagda.md │ ├── Reasoning.lagda.md │ ├── Semilattice │ │ ├── Free.lagda.md │ │ ├── Join.lagda.md │ │ ├── Join │ │ │ ├── NAry.lagda.md │ │ │ ├── Reasoning.lagda.md │ │ │ └── Subsemilattice.lagda.md │ │ ├── Meet.lagda.md │ │ └── Meet │ │ │ ├── NAry.lagda.md │ │ │ └── Reasoning.lagda.md │ ├── Subposet.lagda.md │ ├── Total.lagda.md │ └── Univalent.lagda.md ├── Prim │ ├── Data │ │ ├── Bool.lagda.md │ │ ├── Nat.lagda.md │ │ └── Sigma.lagda.md │ ├── Extension.lagda.md │ ├── HCompU.lagda.md │ ├── Interval.lagda.md │ ├── Kan.lagda.md │ ├── Literals.lagda.md │ └── Type.lagda.md ├── Talks │ └── Topos2024.lagda.md ├── Topoi │ ├── Base.lagda.md │ ├── Classifying │ │ └── Diaconescu.lagda.md │ └── Reasoning.lagda.md ├── bibliography.bibtex ├── index.lagda.md └── preamble.tex ├── support ├── check.sh ├── diagram.tex ├── everything.sh ├── favicon.ico ├── make-site.sh ├── nix │ ├── build-shake.nix │ ├── dep │ │ ├── Agda │ │ │ ├── default.nix │ │ │ ├── github.json │ │ │ └── thunk.nix │ │ └── nix-thunk │ │ │ ├── default.nix │ │ │ ├── github.json │ │ │ └── thunk.nix │ ├── haskell-packages.nix │ ├── nixpkgs.nix │ └── node │ │ ├── node-dependencies.nix │ │ └── node-env.nix ├── shake │ ├── .gitignore │ ├── 1lab-shake.cabal │ ├── CHANGELOG.md │ ├── LICENSE.agda │ ├── README.md │ └── app │ │ ├── Agda.hs │ │ ├── Definitions.hs │ │ ├── HTML │ │ ├── Backend.hs │ │ ├── Base.hs │ │ ├── Emit.hs │ │ └── Render.hs │ │ ├── Macros.hs │ │ ├── Main.hs │ │ ├── Shake │ │ ├── AgdaCompile.hs │ │ ├── Diagram.hs │ │ ├── Digest.hs │ │ ├── Git.hs │ │ ├── Highlights.hs │ │ ├── KaTeX.hs │ │ ├── LinkGraph.hs │ │ ├── LinkReferences.hs │ │ ├── Markdown.hs │ │ ├── Markdown.hs-boot │ │ ├── Modules.hs │ │ ├── Options.hs │ │ ├── Recent.hs │ │ ├── SearchData.hs │ │ └── Utils.hs │ │ └── Timer.hs ├── sort-imports.hs ├── static │ ├── cube-128x.png │ ├── cube-32x.png │ ├── cube-512x.png │ ├── cube-72x.png │ ├── icons │ │ ├── all-pages.svg │ │ ├── github.svg │ │ ├── home.svg │ │ ├── justified.svg │ │ ├── raggedleft.svg │ │ ├── raggedright.svg │ │ ├── serif.svg │ │ ├── star.svg │ │ └── view-controls.svg │ ├── licenses │ │ ├── LICENSE.EBGaramond.txt │ │ ├── LICENSE.InriaSans.txt │ │ ├── LICENSE.JuliaMono.txt │ │ ├── LICENSE.KaTeX.txt │ │ ├── LICENSE.Noto.txt │ │ ├── LICENSE.Octicons.txt │ │ └── LICENSE.fast-fuzzy.txt │ ├── lies-over-dark.svg │ ├── lies-over-light.svg │ └── pfps │ │ ├── amelia.png │ │ └── astra.png └── web │ ├── css │ ├── code.scss │ ├── colors.scss │ ├── components │ │ ├── commit.scss │ │ ├── controls.scss │ │ ├── modal.scss │ │ ├── popup.scss │ │ ├── profile.scss │ │ ├── search.scss │ │ ├── sidenotes.scss │ │ └── toc.scss │ ├── default.scss │ ├── mixins.scss │ ├── talk.scss │ ├── theme.scss │ └── vars.scss │ ├── highlights │ ├── note.svg │ ├── source.svg │ ├── terminology.svg │ └── warning.svg │ ├── js │ ├── code-only.ts │ ├── depgraph.tsx │ ├── equations.ts │ ├── highlight-hover.ts │ ├── lib │ │ ├── external.d.ts │ │ ├── hover.ts │ │ ├── jsx.ts │ │ ├── settings.tsx │ │ └── timeout.ts │ ├── main.ts │ ├── prompt.tsx │ ├── prompt │ │ ├── items.tsx │ │ └── sections.tsx │ ├── search.tsx │ ├── sidebar.tsx │ ├── sidenotes.tsx │ ├── start.ts │ └── theme.tsx │ ├── template.html │ └── template.reveal.html └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.lagda.md text diff=agda linguist-language=agda 2 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | _Please include a quick description of your changes here._ 4 | 5 | ## Checklist 6 | 7 | Before submitting a merge request, please check the items below: 8 | 9 | - [ ] I've read [the contributing guidelines](https://github.com/plt-amy/1lab/blob/main/CONTRIBUTING.md). 10 | - [ ] The imports of new modules have been sorted with `support/sort-imports.hs` (or `nix run --experimental-features nix-command -f . sort-imports`). 11 | - [ ] All new code blocks have "agda" as their language. 12 | 13 | If your change affects many files without adding substantial content, and 14 | you don't want your name to appear on those pages (for example, treewide 15 | refactorings or reformattings), start the commit message and PR title with `chore:`. 16 | -------------------------------------------------------------------------------- /.github/workflows/preview.yml: -------------------------------------------------------------------------------- 1 | name: PR Preview 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - reopened 8 | - synchronize 9 | 10 | jobs: 11 | pr-preview: 12 | runs-on: ubuntu-latest 13 | 14 | env: 15 | mailmap: ${{ secrets.MAILMAP }} 16 | 17 | steps: 18 | - name: Checkout ⬇️ 19 | uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 # we need the commit history for authors 22 | 23 | - name: Install Nix ❄️ 24 | uses: cachix/install-nix-action@v26 25 | 26 | - name: Set up Cachix ♻️ 27 | uses: cachix/cachix-action@v14 28 | with: 29 | name: 1lab 30 | skipPush: true 31 | 32 | - name: Build the Shakefile 🧰 33 | run: | 34 | hash=$(nix-build -A shakefile --no-out-link) 35 | hash=${hash#/nix/store/} hash=${hash%%-*} 36 | echo "shake_version=$hash" >> "$GITHUB_ENV" 37 | 38 | - name: Cache _build ♻️ 39 | uses: actions/cache@v4 40 | with: 41 | path: _build 42 | key: prose-4-${{ env.shake_version }}-${{ github.run_id }} 43 | restore-keys: prose-4-${{ env.shake_version }}- 44 | 45 | - name: Build the prose ✍️ 46 | run: | 47 | echo "$mailmap" > .mailmap 48 | nix-shell --arg interactive false --run "$build_command" 49 | env: 50 | NIX_BUILD_SHELL: bash 51 | build_command: | 52 | set -eu 53 | 1lab-shake -j all --skip-agda -b "https://preview.1lab.dev/${{ github.event.number }}/" 54 | eval "$installPhase" 55 | echo "${{ github.event.number }}" > _build/site/.pr-number 56 | # cp -rv _build/site pr-${{ github.event.number }} 57 | 58 | - name: Archive 📦 59 | uses: actions/upload-artifact@v4 60 | with: 61 | name: pr-preview 62 | path: _build/site 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | 4 | # Canonical location for work-in-progress stuff 5 | src/wip/ 6 | 7 | # Developer configuration 8 | /Makefile 9 | /.vscode 10 | /.envrc 11 | /.direnv 12 | .ghci 13 | hie.yaml 14 | /*.sh 15 | 16 | # Build output 17 | /html 18 | /_build 19 | /result* 20 | /node_modules 21 | /dist-newstyle 22 | /stack.yaml.lock 23 | /.stack-work 24 | .shake 25 | *.agdai 26 | *.hi 27 | *.o 28 | *.hi-boot 29 | *.o-boot 30 | /rubtmp* 31 | 32 | # LaTeX stuff that occasionally gets generated 33 | *.log 34 | *.synctex.gz 35 | *.aux 36 | *.fls 37 | *.pdf 38 | *.fdb_latexmk 39 | -------------------------------------------------------------------------------- /1lab.agda-lib: -------------------------------------------------------------------------------- 1 | name: 1lab 2 | include: 3 | src 4 | wip 5 | _build 6 | . 7 | flags: 8 | --cubical 9 | --no-load-primitives 10 | --postfix-projections 11 | --rewriting 12 | --guardedness 13 | --two-level 14 | -W noUnsupportedIndexedMatch 15 | -------------------------------------------------------------------------------- /CITATION.bib: -------------------------------------------------------------------------------- 1 | @online{1lab, 2 | author = {The {1Lab Development Team}}, 3 | title = {{The 1Lab}}, 4 | url = {https://1lab.dev}, 5 | year = 2024, 6 | } 7 | -------------------------------------------------------------------------------- /_typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = ["support", "*.scss", "*.bibtex"] 3 | 4 | [default.extend-words] 5 | identicals = "identicals" 6 | intensional = "intensional" 7 | operad = "operad" 8 | projectives = "projectives" 9 | raison = "raison" 10 | substituters = "substituters" 11 | 12 | # parts of identifiers 13 | ba = "ba" 14 | cancell = "cancell" 15 | DNE = "DNE" 16 | fo = "fo" 17 | Iy = "Iy" 18 | hom = "hom" 19 | lits = "lits" 20 | ment = "ment" 21 | mor = "mor" 22 | nam = "nam" 23 | nto = "nto" 24 | padd = "padd" 25 | pn = "pn" 26 | Singl = "Singl" 27 | SinglP = "SinglP" 28 | som = "som" 29 | toi = "toi" 30 | ue = "ue" 31 | unitl = "unitl" 32 | -------------------------------------------------------------------------------- /cabal.project: -------------------------------------------------------------------------------- 1 | packages: support/shake/1lab-shake.cabal 2 | 3 | source-repository-package 4 | type: git 5 | location: https://github.com/agda/agda.git 6 | tag: 632954bf442192276ca9c84ca95991d1ffc7a410 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "1lab", 3 | "version": "1.0.0", 4 | "description": " A formalised, cross-linked reference resource for mathematics done in Homotopy Type Theory ", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/the1lab/1lab.git" 12 | }, 13 | "author": "Amélia Liao et. al.", 14 | "license": "AGPL-3.0", 15 | "bugs": { 16 | "url": "https://github.com/the1lab/1lab/issues" 17 | }, 18 | "homepage": "https://github.com/the1lab/1lab#readme", 19 | "devDependencies": { 20 | "@types/d3": "^7.1.0", 21 | "d3": "^7.4.4", 22 | "esbuild": "^0.14.38", 23 | "typescript": "^4.6.4", 24 | "katex": "^0.15.3" 25 | }, 26 | "dependencies": { 27 | "fast-fuzzy": "^1.11.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/1Lab/Function/Reasoning.lagda.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ```agda 9 | module 1Lab.Function.Reasoning where 10 | ``` 11 | 12 | # Reasoning combinators for functions 13 | 14 | Unlike for [paths] and [categories], reasoning about functions is often easy 15 | because composition of functions is *strict*, i.e. definitionally unital 16 | and associative. 17 | 18 | [paths]: 1Lab.Path.Reasoning.html 19 | [categories]: Cat.Reasoning.html 20 | 21 | 29 | 30 | ## Notation 31 | 32 | When doing equational reasoning, it's often somewhat clumsy to have to write 33 | `ap (f ∘_) p` when proving that `f ∘ g ≡ f ∘ h`. To fix this, we steal 34 | some cute mixfix notation from `agda-categories` which allows us to write 35 | `≡⟨ refl⟩∘⟨ p ⟩` instead, which is much more aesthetically pleasing! 36 | 37 | As unification is sometimes fiddly when functions are involved, we also 38 | provide a way to write `≡⟨ f ∘⟨ p ⟩` instead. 39 | 40 | ```agda 41 | _⟩∘⟨_ : f ≡ h → g ≡ i → f ∘ g ≡ h ∘ i 42 | _⟩∘⟨_ = ap₂ (λ x y → x ∘ y) 43 | 44 | refl⟩∘⟨_ : g ≡ h → f ∘ g ≡ f ∘ h 45 | refl⟩∘⟨_ {f = f} p = ap (f ∘_) p 46 | 47 | _⟩∘⟨refl : f ≡ h → f ∘ g ≡ h ∘ g 48 | _⟩∘⟨refl {g = g} p = ap (_∘ g) p 49 | 50 | _∘⟨_ : (f : A → B) → g ≡ h → f ∘ g ≡ f ∘ h 51 | f ∘⟨ p = ap (f ∘_) p 52 | 53 | _⟩∘_ : f ≡ h → (g : A → B) → f ∘ g ≡ h ∘ g 54 | p ⟩∘ g = ap (_∘ g) p 55 | 56 | infixr 39 _⟩∘⟨_ _∘⟨_ _⟩∘_ 57 | ``` 58 | -------------------------------------------------------------------------------- /src/1Lab/Path/IdentitySystem/Interface.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.HLevel 2 | open import 1Lab.Equiv 3 | open import 1Lab.Type 4 | 5 | module 1Lab.Path.IdentitySystem.Interface where 6 | 7 | open import 1Lab.Path.IdentitySystem 8 | hiding (to-path-refl) 9 | open import 1Lab.Path using (_≡_) 10 | 11 | module 12 | Ids {ℓ ℓ'} {A : Type ℓ} {R : A → A → Type ℓ'} {refl : ∀ a → R a a} 13 | (rr : is-identity-system R refl) 14 | where 15 | 16 | J : ∀ {ℓ a} (P : (b : A) → R a b → Type ℓ) → P a (refl a) → {b : A} (s : R a b) → P b s 17 | J = IdsJ rr 18 | 19 | J-refl 20 | : ∀ {ℓ a} (P : ∀ b → R a b → Type ℓ) → (x : P a (refl a)) 21 | → J P x (refl a) ≡ x 22 | J-refl = IdsJ-refl rr 23 | 24 | module _ {a b} where open Equiv (identity-system-gives-path rr {a} {b}) public 25 | 26 | to-refl : ∀ {a} → to-path rr (refl a) ≡ λ _ → a 27 | to-refl = 1Lab.Path.IdentitySystem.to-path-refl rr 28 | 29 | from-refl : ∀ {a} → from (λ _ → a) ≡ refl a 30 | from-refl = 1Lab.Path.transport-refl (refl _) 31 | 32 | hlevel : ∀ n → (∀ x y → is-hlevel (R x y) n) → is-hlevel A (suc n) 33 | hlevel n = identity-system→hlevel n rr 34 | -------------------------------------------------------------------------------- /src/1Lab/Prelude.agda: -------------------------------------------------------------------------------- 1 | -- This module doesn't have any text! That's because it's simply a bunch 2 | -- of convenient re-exports for working outside of the 1Lab namespace. 3 | 4 | module 1Lab.Prelude where 5 | 6 | open import 1Lab.Type 7 | hiding (Σ-syntax ; case_of_ ; case_return_of_) 8 | public 9 | 10 | open import 1Lab.Path public 11 | open import 1Lab.Path.Groupoid public 12 | 13 | open import 1Lab.Path.IdentitySystem public 14 | open import 1Lab.Path.IdentitySystem.Interface public 15 | 16 | open import Meta.Brackets public 17 | open import Meta.Append public 18 | open import Meta.Idiom public 19 | open import Meta.Bind public 20 | open import Meta.Alt public 21 | 22 | open import 1Lab.HLevel public 23 | open import 1Lab.HLevel.Closure public 24 | open import 1Lab.HLevel.Universe public 25 | 26 | open import 1Lab.Equiv public 27 | open import 1Lab.Equiv.FromPath public 28 | open import 1Lab.Equiv.Fibrewise public 29 | open import 1Lab.Function.Embedding public 30 | open import 1Lab.Function.Reasoning public 31 | open import 1Lab.Equiv.HalfAdjoint public 32 | 33 | open import 1Lab.Function.Surjection public 34 | 35 | open import 1Lab.Univalence public 36 | 37 | open import 1Lab.Univalence.SIP 38 | renaming (_≃[_]_ to _≃[_]s_) 39 | public 40 | 41 | open import 1Lab.Type.Pi public 42 | open import 1Lab.Type.Sigma public 43 | open import 1Lab.Type.Pointed public 44 | 45 | open import 1Lab.HIT.Truncation 46 | hiding (∃-syntax) 47 | public 48 | 49 | open import 1Lab.Reflection.Marker public 50 | open import 1Lab.Reflection.Record 51 | using (declare-record-iso) 52 | public 53 | open import 1Lab.Reflection.HLevel public 54 | open import 1Lab.Reflection.Regularity public 55 | open import 1Lab.Reflection.Univalence public 56 | 57 | open import 1Lab.Resizing public 58 | 59 | open import 1Lab.Underlying public 60 | open import 1Lab.Membership public 61 | open import 1Lab.Extensionality public 62 | open import 1Lab.Inductive public 63 | 64 | open import Data.Id.Base public 65 | -------------------------------------------------------------------------------- /src/1Lab/Reflection/Induction/Examples.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Reflection.Induction 2 | open import 1Lab.HLevel 3 | open import 1Lab.Path hiding (J) 4 | open import 1Lab.Type 5 | 6 | open import Data.Set.Truncation hiding (∥-∥₀-elim) 7 | open import Data.Wellfounded.W hiding (W-elim) 8 | open import Data.Fin.Base hiding (Fin-elim) 9 | open import Data.Id.Base 10 | 11 | open import Homotopy.Space.Circle hiding (S¹-elim) 12 | 13 | module 1Lab.Reflection.Induction.Examples where 14 | 15 | unquoteDecl J = make-elim-with default-elim-visible J (quote _≡ᵢ_) 16 | 17 | _ : {ℓ : Level} {A : Type ℓ} {x : A} {ℓ₁ : Level} 18 | (P : (z : A) (z₁ : x ≡ᵢ z) → Type ℓ₁) 19 | (Prefl : P x reflᵢ) 20 | (y : A) (p : x ≡ᵢ y) → P y p 21 | _ = J 22 | 23 | unquoteDecl W-elim = make-elim W-elim (quote W) 24 | 25 | _ : {ℓ ℓ' : Level} {A : Type ℓ} {B : (z : A) → Type ℓ'} 26 | {ℓ₁ : Level} {P : (w : W A B) → Type ℓ₁} 27 | (Psup : (x : A) (f : (z : B x) → W A B) (Pf : (z : B x) → P (f z)) → P (sup x f)) 28 | (w : W A B) → P w 29 | _ = W-elim 30 | 31 | unquoteDecl S¹-elim = make-elim S¹-elim (quote S¹) 32 | unquoteDecl S¹-elim-prop = make-elim-n 1 S¹-elim-prop (quote S¹) 33 | 34 | _ : {ℓ : Level} {P : (s : S¹) → Type ℓ} 35 | (Pbase : P base) 36 | (Ploop : PathP (λ i → P (loop i)) Pbase Pbase) 37 | (s : S¹) → P s 38 | _ = S¹-elim 39 | 40 | _ : {ℓ : Level} {P : (s : S¹) → Type ℓ} 41 | → (∀ s → is-prop (P s)) 42 | → P base → ∀ s → P s 43 | _ = S¹-elim-prop 44 | 45 | unquoteDecl ∥-∥₀-elim = make-elim-n 2 ∥-∥₀-elim (quote ∥_∥₀) 46 | 47 | _ : {ℓ : Level} {A : Type ℓ} {ℓ₁ : Level} {P : (z : ∥ A ∥₀) → Type ℓ₁} 48 | (h : (z : ∥ A ∥₀) → is-hlevel (P z) 2) 49 | (Pinc : (z : A) → P (inc z)) 50 | (x : ∥ A ∥₀) → P x 51 | _ = ∥-∥₀-elim 52 | 53 | -- Test case: this should not generate unsolved metavariables. 54 | unquoteDecl Nat-rec = make-elim-with (record default-rec { hide-cons-args = true }) Nat-rec (quote Nat) 55 | 56 | _ : {ℓ : Level} {P : Type ℓ} 57 | → P 58 | → ({n : Nat} → P → P) 59 | → Nat → P 60 | _ = Nat-rec 61 | -------------------------------------------------------------------------------- /src/1Lab/Reflection/Univalence.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Reflection 2 | open import 1Lab.Univalence 3 | open import 1Lab.Type 4 | 5 | open import Prim.Extension 6 | open import Prim.HCompU 7 | open import Prim.Kan 8 | 9 | import 1Lab.Univalence as U 10 | 11 | module 1Lab.Reflection.Univalence where 12 | 13 | name-of-glue : Name 14 | unquoteDef name-of-glue = do 15 | nm ← resetting do 16 | def nm _ ← reduce (def (quote Glue) (unknown v∷ unknown v∷ [])) 17 | where anything → typeError ("insane: Glue did not reduce to a defined type?\n" ∷ termErr anything ∷ []) 18 | pure nm 19 | 20 | define-function name-of-glue (clause [] [] (lit (name nm)) ∷ []) 21 | 22 | macro 23 | -- Simple helper macro to shadow the 'unglue' function with something 24 | -- that can actually infer the φ argument. 25 | 26 | unglue : Term → Term → TC ⊤ 27 | unglue x goal = do 28 | let 29 | fail : Term → TC ⊤ 30 | fail ty = typeError 31 | [ "unglue: the argument " , termErr x , " does not have a Glue type. instead, it is\n" 32 | , " " , termErr ty 33 | ] 34 | 35 | ty ← wait-for-type =<< reduce =<< infer-type x 36 | case ty of λ where 37 | (def (quote primHComp) (ℓ h∷ _ h∷ φ h∷ s v∷ b v∷ [])) → unify goal 38 | (def (quote prim^unglueU) 39 | (unknown h∷ φ h∷ s h∷ def (quote inS) (b v∷ []) h∷ x v∷ [])) 40 | 41 | ty@(def a (_ h∷ _ h∷ _ v∷ φ h∷ _)) → case a ≡? name-of-glue of λ where 42 | (yes _) → do 43 | wait-for-type φ 44 | unify goal (def (quote U.unattach) (φ v∷ x v∷ [])) 45 | (no _) → fail ty 46 | ty → fail ty 47 | 48 | {-# DISPLAY unattach _ x = unglue x #-} 49 | -------------------------------------------------------------------------------- /src/1Lab/Type/Pointed.lagda.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ```agda 9 | module 1Lab.Type.Pointed where 10 | ``` 11 | 12 | ## Pointed types {defines="pointed pointed-type pointed-map pointed-homotopy"} 13 | 14 | A **pointed type** is a type $A$ equipped with a choice of base point $\point{A}$. 15 | 16 | ```agda 17 | Type∙ : ∀ ℓ → Type (lsuc ℓ) 18 | Type∙ ℓ = Σ (Type ℓ) (λ A → A) 19 | ``` 20 | 21 | 28 | 29 | If we have pointed types $(A, a)$ and $(B, b)$, the most natural notion 30 | of function between them is not simply the type of functions $A \to B$, 31 | but rather those functions $A \to B$ which _preserve the basepoint_, 32 | i.e. the functions $f : A \to B$ equipped with paths $f(a) \equiv b$. 33 | Those are called **pointed maps**. 34 | 35 | ```agda 36 | _→∙_ : Type∙ ℓ → Type∙ ℓ' → Type _ 37 | (A , a) →∙ (B , b) = Σ[ f ∈ (A → B) ] (f a ≡ b) 38 | 39 | infixr 0 _→∙_ 40 | ``` 41 | 42 | Pointed maps compose in a straightforward way. 43 | 44 | ```agda 45 | id∙ : A →∙ A 46 | id∙ = id , refl 47 | 48 | _∘∙_ : (B →∙ C) → (A →∙ B) → A →∙ C 49 | (f , ptf) ∘∙ (g , ptg) = f ∘ g , ap f ptg ∙ ptf 50 | 51 | infixr 40 _∘∙_ 52 | ``` 53 | 54 | Paths between pointed maps are characterised as **pointed homotopies**: 55 | 56 | ```agda 57 | funext∙ : {f g : A →∙ B} 58 | → (h : ∀ x → f .fst x ≡ g .fst x) 59 | → Square (h (A .snd)) (f .snd) (g .snd) refl 60 | → f ≡ g 61 | funext∙ h pth i = funext h i , pth i 62 | ``` 63 | 64 | The product of two pointed types is again a pointed type. 65 | 66 | ```agda 67 | _×∙_ : Type∙ ℓ → Type∙ ℓ' → Type∙ (ℓ ⊔ ℓ') 68 | (A , a) ×∙ (B , b) = A × B , a , b 69 | 70 | infixr 5 _×∙_ 71 | 72 | fst∙ : A ×∙ B →∙ A 73 | fst∙ = fst , refl 74 | 75 | snd∙ : A ×∙ B →∙ B 76 | snd∙ = snd , refl 77 | ``` 78 | -------------------------------------------------------------------------------- /src/1Lab/Univalence/SIP/Auto.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Univalence.SIP 2 | open import 1Lab.Reflection 3 | open import 1Lab.Type.Sigma 4 | open import 1Lab.Univalence 5 | open import 1Lab.Equiv 6 | open import 1Lab.Path 7 | open import 1Lab.Type 8 | 9 | open import Data.List.Base 10 | 11 | module 1Lab.Univalence.SIP.Auto where 12 | 13 | makeAutoStr-term : Nat → Term → TC ⊤ 14 | makeAutoStr-term zero t = typeError (strErr "autoDesc ran out of fuel" ∷ []) 15 | makeAutoStr-term (suc n) t = 16 | tryPoint 17 | <|> tryBin (quote _s→_) 18 | <|> tryBin (quote _s×_) 19 | <|> useConst 20 | where 21 | tryPoint = do 22 | unify t (con (quote s∙) []) 23 | 24 | tryBin : Name → TC ⊤ 25 | tryBin namen = do 26 | h1 ← new-meta unknown 27 | h2 ← new-meta unknown 28 | tt ← unify (con namen (h1 v∷ h2 v∷ [])) t 29 | tt ← makeAutoStr-term n h1 30 | makeAutoStr-term n h2 31 | 32 | useConst = do 33 | unify t (con (quote s-const) (unknown v∷ [])) 34 | 35 | macro 36 | auto-str-term : Term → TC ⊤ 37 | auto-str-term = makeAutoStr-term 100 38 | -------------------------------------------------------------------------------- /src/Algebra/Group/Ab/Free.lagda.md: -------------------------------------------------------------------------------- 1 | 14 | 15 | ```agda 16 | module Algebra.Group.Ab.Free where 17 | ``` 18 | 19 | # Free abelian groups 20 | 21 | We have already constructed the [[free group|free group construction]] 22 | on a [[set]] and the [[free abelian group on a group|abelianisation]]; 23 | [[Composing these adjunctions|adjunctions compose]], we obtain the free 24 | [[abelian group]] on a set. 25 | 26 | [free group on a set]: Algebra.Group.Free.html 27 | [free abelian group on a group]: Algebra.Group.Ab.Abelianisation.html 28 | 29 | ```agda 30 | Free-abelian : ∀ {ℓ} → Type ℓ → Abelian-group ℓ 31 | Free-abelian T = Abelianise (Free-Group T) 32 | ``` 33 | 34 | 41 | 42 | ```agda 43 | Free-abelian⊣Forget 44 | : ∀ {ℓ} → Free-abelian-functor {ℓ} ⊣ Ab↪Sets 45 | Free-abelian⊣Forget = LF⊣GR 46 | (free-objects→left-adjoint make-free-group) 47 | (free-objects→left-adjoint make-free-abelian) 48 | ``` 49 | 50 | 72 | -------------------------------------------------------------------------------- /src/Algebra/Group/Cayley.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Algebra.Group.Cayley {ℓ} (G : Group ℓ) where 13 | 14 | open Group-on (G .snd) renaming (underlying-set to G-set) 15 | ``` 16 | 17 | # Cayley's theorem {defines="cayleys-theorem"} 18 | 19 | Cayley's theorem says that any group $G$ admits a representation as a 20 | subgroup of a [[symmetric group]], specifically the symmetric group acting 21 | on the underlying set of $G$. 22 | 23 | First, recall that we get a family of equivalences $G \simeq G$ by multiplication 24 | on the left, the [[principal action]] of $G$ on itself: 25 | 26 | ```agda 27 | Cayley : ⌞ G ⌟ → ⌞ G ⌟ ≃ ⌞ G ⌟ 28 | Cayley x = (λ y → x ⋆ y) , ⋆-equivl x 29 | ``` 30 | 31 | We then show that this map is a group homomorphism from $G$ to 32 | $\rm{Sym}(G)$: 33 | 34 | ```agda 35 | Cayley-is-hom : is-group-hom (G .snd) (Sym G-set) Cayley 36 | Cayley-is-hom .is-group-hom.pres-⋆ x y = ext λ e → sym associative 37 | ``` 38 | 39 | Finally, we show that this map is injective; Thus, $G$ embeds as a 40 | subgroup of $\rm{Sym}(G)$ (the image of `Cayley`{.Agda}). 41 | 42 | ```agda 43 | Cayley-injective : injective Cayley 44 | Cayley-injective {x} {y} eqvs-equal = 45 | x ≡⟨ sym idr ⟩ 46 | x ⋆ unit ≡⟨⟩ 47 | Cayley x .fst unit ≡⟨ happly (ap fst eqvs-equal) unit ⟩ 48 | Cayley y .fst unit ≡⟨⟩ 49 | y ⋆ unit ≡⟨ idr ⟩ 50 | y ∎ 51 | ``` 52 | -------------------------------------------------------------------------------- /src/Algebra/Group/Instances/Symmetric.lagda.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ```agda 13 | module Algebra.Group.Instances.Symmetric where 14 | ``` 15 | 16 | # Symmetric groups {defines="symmetric-group"} 17 | 18 | If $X$ is a set, then the type of all bijections $X \simeq X$ is also a 19 | set, and it forms the carrier for a [[group]]: The _symmetric group_ on $X$. 20 | 21 | ```agda 22 | Sym : ∀ {ℓ} (X : Set ℓ) → Group-on (∣ X ∣ ≃ ∣ X ∣) 23 | Sym X = to-group-on group-str where 24 | open make-group 25 | group-str : make-group (∣ X ∣ ≃ ∣ X ∣) 26 | group-str .mul g f = f ∙e g 27 | ``` 28 | 29 | The group operation is `composition of equivalences`{.Agda ident=∙e}; 30 | The identity element is `the identity equivalence`{.Agda ident=id-equiv}. 31 | 32 | ```agda 33 | group-str .unit = id , id-equiv 34 | ``` 35 | 36 | This type is a set because $X \to X$ is a set (because $X$ is a set by 37 | assumption), and `being an equivalence is a proposition`{.Agdaa 38 | ident=is-equiv-is-prop}. 39 | 40 | ```agda 41 | group-str .group-is-set = hlevel 2 42 | ``` 43 | 44 | The associativity and identity laws hold definitionally. 45 | 46 | ```agda 47 | group-str .assoc _ _ _ = trivial! 48 | group-str .idl _ = trivial! 49 | ``` 50 | 51 | The inverse is given by `the inverse equivalence`{.Agda ident=_e⁻¹}, and 52 | the inverse equations hold by the fact that the inverse of an 53 | equivalence is both a section and a retraction. 54 | 55 | ```agda 56 | group-str .inv = _e⁻¹ 57 | group-str .invl (f , eqv) = ext (equiv→unit eqv) 58 | ``` 59 | 60 | We write $S_n$ for the symmetric group on the [[standard finite set]] 61 | with $n$ elements. 62 | 63 | ```agda 64 | S : Nat → Group lzero 65 | S n = el! (Fin n ≃ Fin n) , Sym (el! (Fin n)) 66 | ``` 67 | -------------------------------------------------------------------------------- /src/Algebra/Group/Notation.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Prelude hiding (_+_ ; _*_) 2 | 3 | open import Algebra.Group.Ab 4 | open import Algebra.Group 5 | 6 | module Algebra.Group.Notation where 7 | 8 | module Additive-notation = Group-on renaming 9 | ( _⋆_ to infixl 20 _+_ 10 | ; _⁻¹ to infixr 30 -_ 11 | ; unit to 0g 12 | ; associative to +-assoc 13 | ; inverser to +-invr 14 | ; inversel to +-invl 15 | ; idl to +-idl 16 | ; idr to +-idr 17 | ; inv-inv to neg-neg 18 | ; inv-comm to neg-comm 19 | ; inv-unit to neg-0 20 | ) 21 | hiding (magma-hlevel) 22 | 23 | module Multiplicative-notation = Group-on renaming 24 | ( _⋆_ to infixl 20 _*_ 25 | ; _⁻¹ to infixl 30 _⁻¹ 26 | ; unit to 1g 27 | ; associative to *-assoc 28 | ; inverser to *-invr 29 | ; inversel to *-invl 30 | ; idl to *-idl 31 | ; idr to *-idr 32 | ; inv-unit to inv-1 33 | ) 34 | hiding (magma-hlevel) 35 | 36 | instance 37 | Abelian-group-on→Group-on 38 | : ∀ {ℓ} {T : Type ℓ} ⦃ A : Abelian-group-on T ⦄ 39 | → Group-on T 40 | Abelian-group-on→Group-on ⦃ A ⦄ = record { 41 | has-is-group = is-abelian-group.has-is-group (A .Abelian-group-on.has-is-ab) } 42 | -------------------------------------------------------------------------------- /src/Algebra/Monoid/Reasoning.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Algebra.Monoid.Reasoning {ℓ} (M : Monoid ℓ) where 11 | ``` 12 | 13 | # Reasoning combinators for monoids 14 | 15 | 23 | 24 | ```agda 25 | id-comm : a * 1m ≡ 1m * a 26 | id-comm = idr ∙ sym idl 27 | 28 | id-comm-sym : 1m * a ≡ a * 1m 29 | id-comm-sym = idl ∙ sym idr 30 | 31 | module _ (p : x ≡ 1m) where 32 | eliml : x * a ≡ a 33 | eliml = ap₂ _*_ p refl ∙ idl 34 | 35 | elimr : a * x ≡ a 36 | elimr = ap₂ _*_ refl p ∙ idr 37 | 38 | introl : a ≡ x * a 39 | introl = sym eliml 40 | 41 | intror : a ≡ a * x 42 | intror = sym elimr 43 | 44 | module _ (p : x * y ≡ z) where 45 | pulll : x * (y * a) ≡ z * a 46 | pulll = associative ∙ ap₂ _*_ p refl 47 | 48 | pullr : (a * x) * y ≡ a * z 49 | pullr = sym associative ∙ ap₂ _*_ refl p 50 | 51 | module _ (p : z ≡ x * y) where 52 | pushl : z * a ≡ x * (y * a) 53 | pushl = sym (pulll (sym p)) 54 | 55 | pushr : a * z ≡ (a * x) * y 56 | pushr = sym (pullr (sym p)) 57 | 58 | module _ (p : w * x ≡ y * z) where 59 | extendl : w * (x * a) ≡ y * (z * a) 60 | extendl = pulll refl ∙ ap₂ _*_ p refl ∙ pullr refl 61 | 62 | extendr : (a * w) * x ≡ (a * y) * z 63 | extendr = pullr refl ∙ ap₂ _*_ refl p ∙ pulll refl 64 | 65 | module _ (p : x * y ≡ 1m) where 66 | cancell : x * (y * a) ≡ a 67 | cancell = pulll p ∙ idl 68 | 69 | cancelr : (a * x) * y ≡ a 70 | cancelr = pullr p ∙ idr 71 | 72 | insertl : a ≡ x * (y * a) 73 | insertl = sym cancell 74 | 75 | insertr : a ≡ (a * x) * y 76 | insertr = sym cancelr 77 | 78 | lswizzle : g ≡ h * i → f * h ≡ 1m → f * g ≡ i 79 | lswizzle p q = ap₂ _*_ refl p ∙ cancell q 80 | 81 | rswizzle : g ≡ i * h → h * f ≡ 1m → g * f ≡ i 82 | rswizzle p q = ap₂ _*_ p refl ∙ cancelr q 83 | 84 | swizzle : f * g ≡ h * i → g * g' ≡ 1m → h' * h ≡ 1m → h' * f ≡ i * g' 85 | swizzle p q r = lswizzle (sym (associative ∙ rswizzle (sym p) q)) r 86 | ``` 87 | -------------------------------------------------------------------------------- /src/Algebra/Quasigroup/Instances/Initial.lagda.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | The initial quasigroup. 4 | --- 5 | 14 | 15 | ```agda 16 | module Algebra.Quasigroup.Instances.Initial where 17 | ``` 18 | 19 | # The initial quasigroup {defines="initial-quasigroup empty-quasigroup"} 20 | 21 | The empty type trivially forms a [[quasigroup]]. 22 | 23 | 31 | 32 | ```agda 33 | Empty-quasigroup : ∀ {ℓ} → Quasigroup ℓ 34 | Empty-quasigroup = to-quasigroup ⊥-quasigroup where 35 | open make-quasigroup 36 | 37 | ⊥-quasigroup : make-quasigroup (Lift _ ⊥) 38 | ⊥-quasigroup .quasigroup-is-set = hlevel 2 39 | ⊥-quasigroup ._⋆_ () 40 | ⊥-quasigroup ._⧵_ () 41 | ⊥-quasigroup ._/_ () 42 | ⊥-quasigroup ./-invl () 43 | ⊥-quasigroup ./-invr () 44 | ⊥-quasigroup .⧵-invr () 45 | ⊥-quasigroup .⧵-invl () 46 | ``` 47 | 48 | Moreover, the empty quasigroup is an [[initial object]] in the category 49 | of quasigroups, as there is a unique function out of the empty type. 50 | 51 | ```agda 52 | Empty-quasigroup-is-initial : is-initial (Quasigroups ℓ) Empty-quasigroup 53 | Empty-quasigroup-is-initial A .centre .hom () 54 | Empty-quasigroup-is-initial A .centre .preserves .is-quasigroup-hom.pres-⋆ () 55 | Empty-quasigroup-is-initial A .paths f = ext λ () 56 | 57 | Initial-quasigroup : Initial (Quasigroups ℓ) 58 | Initial-quasigroup .Initial.bot = Empty-quasigroup 59 | Initial-quasigroup .Initial.has⊥ = Empty-quasigroup-is-initial 60 | ``` 61 | 62 | In fact, the empty quasigroup is a [[strict initial object]]. 63 | 64 | ```agda 65 | Initial-quasigroup-is-strict 66 | : is-strict-initial (Quasigroups ℓ) Initial-quasigroup 67 | Initial-quasigroup-is-strict = 68 | make-is-strict-initial (Quasigroups _) Initial-quasigroup $ λ A f → ext λ a → 69 | absurd (Lift.lower (f · a)) 70 | ``` 71 | 72 | 81 | -------------------------------------------------------------------------------- /src/Algebra/Ring/Commutative.lagda.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | ```agda 18 | module Algebra.Ring.Commutative where 19 | ``` 20 | 21 | 26 | 27 | 28 | # Commutative rings 29 | 30 | This module is not very mathematically interesting: All it exists to do 31 | is to package commutative rings together into one datum. 32 | 33 | ```agda 34 | record CRing-on {ℓ} (R : Type ℓ) : Type ℓ where 35 | field 36 | has-ring-on : Ring-on R 37 | *-commutes : ∀ {x y} → has-ring-on ._*_ x y ≡ has-ring-on ._*_ y x 38 | open Ring-on has-ring-on public 39 | 40 | 41 | CRing-structure : ∀ ℓ → Thin-structure ℓ CRing-on 42 | CRing-structure ℓ = Full-substructure ℓ CRing-on Ring-on emb (Ring-structure ℓ) where 43 | open CRing-on 44 | emb : ∀ X → CRing-on X ↪ Ring-on X 45 | emb X .fst = has-ring-on 46 | emb X .snd y (r , p) (s , q) = 47 | Σ-pathp (λ i → 48 | record { has-ring-on = (p ∙ sym q) i 49 | ; *-commutes = λ {x} {y} j → 50 | is-set→squarep (λ i j → CRing-on.has-is-set r) 51 | (λ i → (p ∙ sym q) i ._*_ x y) 52 | (r .*-commutes) 53 | (s .*-commutes) 54 | (λ i → (p ∙ sym q) i ._*_ y x) 55 | i j 56 | }) 57 | (commutes→square (∙-cancelr p q ∙ sym (∙-idr p))) 58 | 59 | CRings : ∀ ℓ → Precategory (lsuc ℓ) ℓ 60 | CRings ℓ = Structured-objects (CRing-structure ℓ) 61 | 62 | CRing : ∀ ℓ → Type (lsuc ℓ) 63 | CRing ℓ = CRings ℓ .Precategory.Ob 64 | 65 | module CRing {ℓ} (R : CRing ℓ) where 66 | ring : Ring ℓ 67 | ring .fst = R .fst 68 | ring .snd = record { CRing-on (R .snd) } 69 | 70 | open CRing-on (R .snd) using (*-commutes ; _+_ ; _*_ ; -_ ; _-_ ; 1r ; 0r) public 71 | open Kit ring hiding (_+_ ; _*_ ; -_ ; _-_ ; 1r ; 0r) public 72 | 73 | is-commutative-ring : ∀ {ℓ} (R : Ring ℓ) → Type _ 74 | is-commutative-ring R = ∀ {x y} → x R.* y ≡ y R.* x where 75 | module R = Ring-on (R .snd) 76 | 77 | ℤ-comm : CRing lzero 78 | ℤ-comm = record { fst = el! Int ; snd = record { has-ring-on = ℤ .snd ; *-commutes = λ {x y} → *ℤ-commutative x y } } 79 | ``` 80 | -------------------------------------------------------------------------------- /src/Algebra/Ring/Module/Notation.agda: -------------------------------------------------------------------------------- 1 | open import Algebra.Group.Notation 2 | open import Algebra.Ring.Module 3 | open import Algebra.Group.Ab 4 | open import Algebra.Group 5 | open import Algebra.Ring 6 | 7 | open import Cat.Prelude hiding (_+_ ; _*_) 8 | 9 | module Algebra.Ring.Module.Notation where 10 | 11 | record Module-notation {ℓ ℓm} (R : Ring ℓ) (T : Type ℓm) : Type (ℓ ⊔ ℓm) where 12 | private module R = Ring-on (R .snd) 13 | 14 | field 15 | instance additive-group : Abelian-group-on T 16 | 17 | private 18 | _+_ : T → T → T 19 | _+_ = Abelian-group-on._*_ additive-group 20 | 21 | field 22 | +-comm : (a b : T) → a + b ≡ b + a 23 | 24 | _⋆_ : ⌞ R ⌟ → T → T 25 | ⋆-distribl : ∀ r x y → r ⋆ (x + y) ≡ (r ⋆ x) + (r ⋆ y) 26 | ⋆-distribr : ∀ r s x → (r R.+ s) ⋆ x ≡ (r ⋆ x) + (s ⋆ x) 27 | ⋆-assoc : ∀ r s x → r ⋆ (s ⋆ x) ≡ (r R.* s) ⋆ x 28 | ⋆-id : ∀ x → R.1r ⋆ x ≡ x 29 | 30 | infixr 25 _⋆_ 31 | 32 | module-notation : ∀ {ℓ ℓm} {R : Ring ℓ} (M : Module R ℓm) → Module-notation R ⌞ M ⌟ 33 | module-notation M .Module-notation.additive-group = Module-on→Abelian-group-on (M .snd) 34 | module-notation M .Module-notation.+-comm a b = Module-on.+-comm (M .snd) 35 | module-notation M .Module-notation._⋆_ = Module-on._⋆_ (M .snd) 36 | module-notation M .Module-notation.⋆-distribl = Module-on.⋆-distribl (M .snd) 37 | module-notation M .Module-notation.⋆-distribr = Module-on.⋆-distribr (M .snd) 38 | module-notation M .Module-notation.⋆-assoc = Module-on.⋆-assoc (M .snd) 39 | module-notation M .Module-notation.⋆-id = Module-on.⋆-id (M .snd) 40 | -------------------------------------------------------------------------------- /src/Algebra/Ring/Reasoning.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Algebra.Ring.Reasoning {ℓ} (R : Ring ℓ) where 12 | ``` 13 | 14 | # Reasoning combinators for rings 15 | 16 | 24 | 25 | ```agda 26 | *-zerol : 0r * x ≡ 0r 27 | *-zerol {x} = 28 | 0r * x ≡⟨ a.introl a.inversel ⟩ 29 | (- 0r * x) + 0r * x + 0r * x ≡⟨ a.pullr (sym *-distribr) ⟩ 30 | (- 0r * x) + (0r + 0r) * x ≡⟨ ap₂ _+_ refl (ap (_* x) a.idl) ⟩ 31 | (- 0r * x) + 0r * x ≡⟨ a.inversel ⟩ 32 | 0r ∎ 33 | 34 | *-zeror : x * 0r ≡ 0r 35 | *-zeror {x} = 36 | x * 0r ≡⟨ a.intror a.inverser ⟩ 37 | x * 0r + (x * 0r - x * 0r) ≡⟨ a.pulll (sym *-distribl) ⟩ 38 | x * (0r + 0r) - x * 0r ≡⟨ ap₂ _-_ (ap (x *_) a.idl) refl ⟩ 39 | x * 0r - x * 0r ≡⟨ a.inverser ⟩ 40 | 0r ∎ 41 | 42 | *-negatel : (- x) * y ≡ - (x * y) 43 | *-negatel {x} {y} = monoid-inverse-unique a.has-is-monoid (x * y) ((- x) * y) (- (x * y)) 44 | (sym *-distribr ∙∙ ap (_* y) a.inversel ∙∙ *-zerol) 45 | a.inverser 46 | 47 | *-negater : x * (- y) ≡ - (x * y) 48 | *-negater {x} {y} = monoid-inverse-unique a.has-is-monoid (x * y) (x * (- y)) (- (x * y)) 49 | (sym *-distribl ∙∙ ap (x *_) a.inversel ∙∙ *-zeror) 50 | a.inverser 51 | ``` 52 | -------------------------------------------------------------------------------- /src/Cat/Abelian/Endo.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Cat.Abelian.Endo {o ℓ} {C : Precategory o ℓ} (A : Ab-category C) where 12 | ``` 13 | 14 | 19 | 20 | # Endomorphism rings {defines="endomorphism-ring"} 21 | 22 | Fix an [$\Ab$-category] $\cA$: It can be the category of [[abelian 23 | groups]] $\Ab$ itself, for example, or $R$-Mod for your favourite 24 | ring^[We tacitly assume the reader has a favourite ring.]. Because 25 | composition in $\cA$ distributes over addition, the collection of 26 | endomorphisms of any particular object $x : \cA$ is not only a monoid, 27 | but a _ring_: the **endomorphism ring** of $x$. 28 | 29 | [$\Ab$-category]: Cat.Abelian.Base.html#ab-enriched-categories 30 | 31 | ```agda 32 | Endo : A.Ob → Ring ℓ 33 | Endo x = to-ring mr where 34 | open make-ring 35 | mr : make-ring (A.Hom x x) 36 | mr .ring-is-set = A.Hom-set x x 37 | mr .0R = A.0m 38 | mr .1R = A.id 39 | mr .make-ring._+_ = A._+_ 40 | mr .make-ring.-_ = A.Hom.inverse 41 | mr .make-ring._*_ = A._∘_ 42 | mr .+-idl _ = A.Hom.idl 43 | mr .+-invr _ = A.Hom.inverser 44 | mr .+-assoc _ _ _ = A.Hom.associative 45 | mr .+-comm _ _ = A.Hom.commutes 46 | mr .*-idl _ = A.idl _ 47 | mr .*-idr _ = A.idr _ 48 | mr .*-assoc _ _ _ = A.assoc _ _ _ 49 | mr .*-distribl _ _ _ = sym (A.∘-linear-r _ _ _) 50 | mr .*-distribr _ _ _ = sym (A.∘-linear-l _ _ _) 51 | ``` 52 | 53 | This is a fantastic source of non-commutative rings, and indeed the 54 | justification for allowing them at all. Even for the relatively simple 55 | case of $\cA = \Ab$, it is an open problem to characterise the 56 | abelian groups with commutative endomorphism rings. 57 | -------------------------------------------------------------------------------- /src/Cat/Abelian/Instances/Ab.lagda.md: -------------------------------------------------------------------------------- 1 | 17 | 18 | ```agda 19 | module Cat.Abelian.Instances.Ab {ℓ} where 20 | ``` 21 | 22 | 31 | 32 | # The category of abelian groups 33 | 34 | The prototypal --- representative, even --- example of an 35 | [$\Ab$-enriched], and an [abelian] category at that, is the category of 36 | [[abelian groups]], $\Ab$. For abstractly-nonsensical reasons, we could 37 | say $\Ab$ is $\Ab$-enriched by virtue of being monoidal closed, but we 38 | have a concrete construction at hand: `Ab-ab-category`{.Agda} 39 | 40 | [$\Ab$-enriched]: Cat.Abelian.Base.html#ab-enriched-categories 41 | [abelian]: Cat.Abelian.Base.html#pre-abelian-abelian-categories 42 | 43 | Let us show it is additive. The terminal group is given by the terminal 44 | set, equipped with its unique group structure, and we have already 45 | computed [[products|direct sum abelian groups]] --- they are given by 46 | direct sums. 47 | 48 | ```agda 49 | Ab-is-additive : is-additive (Ab ℓ) 50 | Ab-is-additive .has-ab = Ab-ab-category 51 | Ab-is-additive .has-terminal .top = from-commutative-group (Zero-group {ℓ}) (λ x y → refl) 52 | Ab-is-additive .has-terminal .has⊤ x = 53 | contr (total-hom (λ _ → lift tt) (record { pres-⋆ = λ x y i → lift tt })) 54 | λ x → trivial! 55 | 56 | Ab-is-additive .has-prods A B .apex = A ⊕ B 57 | Ab-is-additive .has-prods A B .π₁ = _ 58 | Ab-is-additive .has-prods A B .π₂ = _ 59 | Ab-is-additive .has-prods A B .has-is-product = Direct-sum-is-product 60 | ``` 61 | -------------------------------------------------------------------------------- /src/Cat/Abelian/NAry.lagda.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | ```agda 15 | module Cat.Abelian.NAry {o ℓ} {C : Precategory o ℓ} (A : Ab-category C) where 16 | ``` 17 | 18 | # n-Ary operations on Hom-groups 19 | 20 | We instantiate the theory of n-ary sums in a group to the special case 21 | of the $\hom$ [[abelian groups]] of an $\Ab$-enriched category. In 22 | particular, we show that the linearity of function composition extends 23 | to distribution over arbitrary sums. 24 | 25 | ```agda 26 | private module A = Ab-category A 27 | 28 | ∑ₕ : ∀ {x y} n → (Fin n → A.Hom x y) → A.Hom x y 29 | ∑ₕ n f = ∑ {n = n} (Abelian→Group-on (A.Abelian-group-on-hom _ _)) f 30 | 31 | ∑-∘-left : ∀ {j} {A B C} (f : Fin j → A.Hom A B) {g : A.Hom B C} 32 | → g A.∘ ∑ₕ j f 33 | ≡ ∑ₕ j (λ i → g A.∘ f i) 34 | ∑-∘-left {zero} f = A.∘-zero-r 35 | ∑-∘-left {suc j} f {g = g} = 36 | g A.∘ (f 0 A.+ ∑ₕ j (λ i → f (fsuc i))) ≡˘⟨ A.∘-linear-r _ _ _ ⟩ 37 | g A.∘ f 0 A.+ ⌜ g A.∘ ∑ₕ j (λ i → f (fsuc i)) ⌝ ≡⟨ ap! (∑-∘-left {j} _) ⟩ 38 | g A.∘ f 0 A.+ ∑ₕ j (λ i → g A.∘ f (fsuc i)) ∎ 39 | 40 | ∑-∘-right : ∀ {j} {A B C} (f : Fin j → A.Hom B C) {g : A.Hom A B} 41 | → ∑ₕ j f A.∘ g 42 | ≡ ∑ₕ j (λ i → f i A.∘ g) 43 | ∑-∘-right {zero} f = A.∘-zero-l 44 | ∑-∘-right {suc j} f {g} = 45 | (f 0 A.+ ∑ₕ j (λ i → f (fsuc i))) A.∘ g ≡˘⟨ A.∘-linear-l _ _ _ ⟩ 46 | f 0 A.∘ g A.+ ⌜ ∑ₕ j (λ i → f (fsuc i)) A.∘ g ⌝ ≡⟨ ap! (∑-∘-right {j} _) ⟩ 47 | (f 0 A.∘ g A.+ ∑ₕ j (λ i → f (fsuc i) A.∘ g)) ∎ 48 | ``` 49 | -------------------------------------------------------------------------------- /src/Cat/Bi/Instances/Discrete.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Cat.Bi.Instances.Discrete {o ℓ} (C : Precategory o ℓ) where 15 | ``` 16 | 17 | 24 | 25 | # Locally discrete bicategories {defines="locally-discrete-bicategory"} 26 | 27 | Let $\cC$ be a precategory. We can define a prebicategory $\bf{C}$ by 28 | letting the hom-1-categories of $\bf{C}$ be the [discrete categories] on 29 | the Hom-sets of $\cC$. 30 | 31 | [discrete categories]: Cat.Instances.Discrete.html 32 | 33 | ```agda 34 | {-# TERMINATING #-} 35 | Locally-discrete : Prebicategory o ℓ ℓ 36 | Locally-discrete .Ob = C.Ob 37 | Locally-discrete .Hom x y = Disc' (el (C.Hom x y) (C.Hom-set x y)) 38 | Locally-discrete .id = C.id 39 | Locally-discrete .compose .F₀ (f , g) = f C.∘ g 40 | Locally-discrete .compose .F₁ (p , q) = ap₂ C._∘_ p q 41 | Locally-discrete .compose .F-id = refl 42 | Locally-discrete .compose .F-∘ f g = C.Hom-set _ _ _ _ _ _ 43 | Locally-discrete .unitor-l = to-natural-iso ni where 44 | ni : make-natural-iso _ _ 45 | ni .make-natural-iso.eta x = sym (C.idl x) 46 | ni .make-natural-iso.inv x = C.idl x 47 | ni .make-natural-iso.eta∘inv x = ∙-invr (C.idl x) 48 | ni .make-natural-iso.inv∘eta x = ∙-invl (C.idl x) 49 | ni .make-natural-iso.natural x y f = C.Hom-set _ _ _ _ _ _ 50 | Locally-discrete .unitor-r = to-natural-iso ni where 51 | ni : make-natural-iso _ _ 52 | ni .make-natural-iso.eta x = sym (C.idr x) 53 | ni .make-natural-iso.inv x = C.idr x 54 | ni .make-natural-iso.eta∘inv x = ∙-invr (C.idr x) 55 | ni .make-natural-iso.inv∘eta x = ∙-invl (C.idr x) 56 | ni .make-natural-iso.natural x y f = C.Hom-set _ _ _ _ _ _ 57 | Locally-discrete .associator = to-natural-iso ni where 58 | ni : make-natural-iso _ _ 59 | ni .make-natural-iso.eta x = sym (C.assoc _ _ _) 60 | ni .make-natural-iso.inv x = C.assoc _ _ _ 61 | ni .make-natural-iso.eta∘inv x = ∙-invr (C.assoc _ _ _) 62 | ni .make-natural-iso.inv∘eta x = ∙-invl (C.assoc _ _ _) 63 | ni .make-natural-iso.natural x y f = C.Hom-set _ _ _ _ _ _ 64 | Locally-discrete .triangle f g = C.Hom-set _ _ _ _ _ _ 65 | Locally-discrete .pentagon f g h i = C.Hom-set _ _ _ _ _ _ 66 | ``` 67 | -------------------------------------------------------------------------------- /src/Cat/Bi/Instances/Terminal.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Cat.Bi.Instances.Terminal where 15 | ``` 16 | 17 | # The terminal bicategory {defines="terminal-bicategory"} 18 | 19 | The **terminal bicategory** is the [[bicategory]] with a single object, and a trivial 20 | category of morphisms. 21 | 22 | ```agda 23 | open Prebicategory 24 | 25 | ⊤Bicat : Prebicategory lzero lzero lzero 26 | ⊤Bicat .Ob = ⊤ 27 | ⊤Bicat .Hom _ _ = ⊤Cat 28 | ⊤Bicat .Prebicategory.id = tt 29 | ⊤Bicat .compose = !F 30 | ⊤Bicat .unitor-l = path→iso !F-unique₂ 31 | ⊤Bicat .unitor-r = path→iso !F-unique₂ 32 | ⊤Bicat .associator = path→iso !F-unique₂ 33 | ⊤Bicat .triangle _ _ = refl 34 | ⊤Bicat .pentagon _ _ _ _ = refl 35 | ``` 36 | -------------------------------------------------------------------------------- /src/Cat/Diagram/Colimit/Initial.lagda.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | A correspondence is established between initial objects 4 | and colimits of empty diagrams. 5 | --- 6 | 7 | 16 | 17 | ```agda 18 | module Cat.Diagram.Colimit.Initial {o h} (C : Precategory o h) where 19 | ``` 20 | 21 | 30 | 31 | # Initial objects are colimits 32 | 33 | An [[initial object]] is equivalently defined as a colimit of the empty diagram. 34 | 35 | ```agda 36 | is-colimit→is-initial 37 | : ∀ {T : Ob} {eta : ¡F => Const T} 38 | → is-colimit {C = C} ¡F T eta 39 | → is-initial C T 40 | is-colimit→is-initial colim Y = contr (colim.universal (λ ()) (λ ())) 41 | (λ _ → sym (colim.unique _ _ _ λ ())) 42 | where module colim = is-colimit colim 43 | 44 | is-initial→is-colimit : ∀ {T : Ob} {F : Functor ⊥Cat C} → is-initial C T → is-colimit {C = C} F T ¡nt 45 | is-initial→is-colimit {T} {F} init = to-is-colimitp mc λ {} where 46 | open make-is-colimit 47 | mc : make-is-colimit F T 48 | mc .ψ () 49 | mc .commutes () 50 | mc .universal _ _ = init _ .centre 51 | mc .factors {} 52 | mc .unique _ _ _ _ = sym (init _ .paths _) 53 | 54 | Colimit→Initial : Colimit {C = C} ¡F → Initial C 55 | Colimit→Initial colim .bot = Colimit.coapex colim 56 | Colimit→Initial colim .has⊥ = is-colimit→is-initial (Colimit.has-colimit colim) 57 | 58 | Initial→Colimit : ∀ {F : Functor ⊥Cat C} → Initial C → Colimit {C = C} F 59 | Initial→Colimit init = to-colimit (is-initial→is-colimit (init .has⊥)) 60 | ``` 61 | -------------------------------------------------------------------------------- /src/Cat/Diagram/Comonad.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Diagram.Comonad where 13 | ``` 14 | 15 | 24 | 25 | # Comonads {defines="comonad"} 26 | 27 | A **comonad on a category** $\cC$ is dual to a [[monad]] on $\cC$; instead 28 | of a unit $\Id \To M$ and multiplication $(M \circ M) \To M$, we have a 29 | counit $W \To \Id$ and comultiplication $W \To (W \circ W)$. More 30 | generally, we can define what it means to equip a *fixed* functor $W$ 31 | with the structure of a comonad. 32 | 33 | ```agda 34 | record Comonad-on (W : Functor C C) : Type (o ⊔ ℓ) where 35 | field 36 | counit : W => Id 37 | comult : W => (W F∘ W) 38 | ``` 39 | 40 | 50 | 51 | We also have equations governing the counit and comultiplication. 52 | Unsurprisingly, these are dual to the equations of a monad. 53 | 54 | ```agda 55 | field 56 | δ-unitl : ∀ {x} → W₁ (ε x) ∘ δ x ≡ id 57 | δ-unitr : ∀ {x} → ε (W₀ x) ∘ δ x ≡ id 58 | δ-assoc : ∀ {x} → W₁ (δ x) ∘ δ x ≡ δ (W₀ x) ∘ δ x 59 | ``` 60 | 61 | 79 | -------------------------------------------------------------------------------- /src/Cat/Diagram/Limit/Initial.lagda.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | ```agda 15 | module Cat.Diagram.Limit.Initial where 16 | ``` 17 | 18 | # Initial objects as limits 19 | 20 | This module provides a characterisation of [[initial objects]] as 21 | [[*limits*]], rather than as [[colimits]]. Namely, while an initial 22 | object is the *co*limit of the empty diagram, it is the *limit* of the 23 | identity functor, considered as a diagram. 24 | 25 | Since the identity functor on $\cC$ has $\cC$ itself as a domain, 26 | computing its limit by general means is usually infeasible. However, 27 | *if* we have such a limit handy, then we know that $\cC$ has an initial 28 | object. Conversely, if $\cC$ has an initial object, then, as a 29 | triviality, we can say that it admits at least one "large" limit. 30 | 31 | 39 | 40 | ```agda 41 | rem₁ : L.ψ L.apex ≡ id 42 | rem₁ = L.unique₂ (λ j → L.ψ j) (λ f → L.commutes f) (λ j → L.commutes _) (λ j → idr _) 43 | 44 | Id-limit→Initial : Initial C 45 | Id-limit→Initial .bot = L.apex 46 | Id-limit→Initial .has⊥ x = λ where 47 | .centre → L.ψ x 48 | .paths h → sym (intror rem₁ ∙ L.commutes h) 49 | ``` 50 | 51 | 59 | 60 | ```agda 61 | Initial→Id-limit : Limit (Id {C = C}) 62 | Initial→Id-limit = to-limit (to-is-limit mk) where 63 | mk : make-is-limit Id L.bot 64 | mk .ψ j = L.¡ 65 | mk .commutes f = L.¡-unique₂ _ _ 66 | mk .universal eps x = eps L.bot 67 | mk .factors eps p = p _ 68 | mk .unique eps p other x = introl (L.¡-unique₂ _ _) ∙ x L.bot 69 | ``` 70 | -------------------------------------------------------------------------------- /src/Cat/Diagram/Limit/Terminal.lagda.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | A correspondence is established between terminal objects 4 | and limits of empty diagrams. 5 | --- 6 | 7 | 17 | 18 | ```agda 19 | module Cat.Diagram.Limit.Terminal {o h} (C : Precategory o h) where 20 | ``` 21 | 22 | 31 | 32 | # Terminal objects are limits 33 | 34 | A [[terminal object]] is equivalently defined as a limit of the empty diagram. 35 | 36 | ```agda 37 | is-limit→is-terminal 38 | : ∀ {T : Ob} {eps : Const T => ¡F} 39 | → is-limit {C = C} ¡F T eps 40 | → is-terminal C T 41 | is-limit→is-terminal lim Y = contr (lim.universal (λ ()) (λ ())) 42 | (λ _ → sym (lim.unique _ _ _ λ ())) 43 | where module lim = is-limit lim 44 | 45 | is-terminal→is-limit : ∀ {T : Ob} {F : Functor ⊥Cat C} → is-terminal C T → is-limit {C = C} F T ¡nt 46 | is-terminal→is-limit {T} {F} term = to-is-limitp ml λ {} where 47 | open make-is-limit 48 | ml : make-is-limit F T 49 | ml .ψ () 50 | ml .commutes () 51 | ml .universal _ _ = term _ .centre 52 | ml .factors {} 53 | ml .unique _ _ _ _ = sym (term _ .paths _) 54 | 55 | Limit→Terminal : Limit {C = C} ¡F → Terminal C 56 | Limit→Terminal lim .top = Limit.apex lim 57 | Limit→Terminal lim .has⊤ = is-limit→is-terminal (Limit.has-limit lim) 58 | 59 | Terminal→Limit : ∀ {F : Functor ⊥Cat C} → Terminal C → Limit {C = C} F 60 | Terminal→Limit term = to-limit (is-terminal→is-limit (term .has⊤)) 61 | ``` 62 | -------------------------------------------------------------------------------- /src/Cat/Diagram/Pushout/Properties.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Cat.Diagram.Pushout.Properties where 12 | ``` 13 | 14 | 22 | 23 | ## Epimorphisms 24 | 25 | $f : A \to B$ is an epimorphism iff. the square below is a pushout 26 | 27 | ~~~{.quiver} 28 | \[\begin{tikzcd} 29 | a && b \\ 30 | \\ 31 | b && b 32 | \arrow["{\mathrm{id}}", from=1-3, to=3-3] 33 | \arrow["{\mathrm{id}}"', from=3-1, to=3-3] 34 | \arrow["f", from=1-1, to=1-3] 35 | \arrow["f"', from=1-1, to=3-1] 36 | \end{tikzcd}\] 37 | ~~~ 38 | 39 | ```agda 40 | module _ {a b} {f : Hom a b} where 41 | is-epic→is-pushout : is-epic f → is-pushout C f id f id 42 | is-epic→is-pushout epi .square = refl 43 | is-epic→is-pushout epi .universal {i₁' = i₁'} p = i₁' 44 | is-epic→is-pushout epi .universal∘i₁ = idr _ 45 | is-epic→is-pushout epi .universal∘i₂ {p = p} = idr _ ∙ epi _ _ p 46 | is-epic→is-pushout epi .unique p q = intror refl ∙ p 47 | 48 | is-pushout→is-epic : is-pushout C f id f id → is-epic f 49 | is-pushout→is-epic pb g h p = sym (pb .universal∘i₁ {p = p}) ∙ pb .universal∘i₂ 50 | ``` 51 | 52 | Pushout additionally preserve epimorphisms, as shown below: 53 | 54 | ```agda 55 | is-epic→pushout-is-epic 56 | : ∀ {x y z} {f : Hom x y} {g : Hom x z} {p} {i₁ : Hom y p} {i₂ : Hom z p} 57 | → is-epic f 58 | → is-pushout C f i₁ g i₂ 59 | → is-epic i₂ 60 | is-epic→pushout-is-epic {f = f} {g} {i₁ = i₁} {i₂} epi pb h j p = eq 61 | where 62 | module pb = is-pushout pb 63 | 64 | q : (h ∘ i₁) ∘ f ≡ (j ∘ i₁) ∘ f 65 | q = 66 | (h ∘ i₁) ∘ f ≡⟨ extendr pb.square ⟩ 67 | (h ∘ i₂) ∘ g ≡⟨ ap (_∘ g) p ⟩ 68 | (j ∘ i₂) ∘ g ≡˘⟨ extendr pb.square ⟩ 69 | (j ∘ i₁) ∘ f ∎ 70 | 71 | r : h ∘ i₁ ≡ j ∘ i₁ 72 | r = epi _ _ q 73 | 74 | eq : h ≡ j 75 | eq = pb.unique₂ {p = extendr pb.square} r p refl refl 76 | ``` 77 | -------------------------------------------------------------------------------- /src/Cat/Displayed/Cocartesian/Indexing.lagda.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ```agda 13 | module Cat.Displayed.Cocartesian.Indexing 14 | {o ℓ o' ℓ'} {ℬ : Precategory o ℓ} 15 | (ℰ : Displayed ℬ o' ℓ') 16 | (opfibration : Cocartesian-fibration ℰ) 17 | where 18 | ``` 19 | 20 | 29 | 30 | # Opreindexing for cocartesian fibrations {defines="cobase-change"} 31 | 32 | [Opfibrations] are dual to [fibrations], so they inherit the ability 33 | to [reindex along morphisms in the base]. However, this reindexing is 34 | *covariant* for opfibrations, whereas it is *contravariant* for 35 | fibrations. 36 | 37 | [Opfibrations]: Cat.Displayed.Cocartesian.html 38 | [fibrations]: Cat.Displayed.Cartesian.html 39 | [reindex along morphisms in the base]: Cat.Displayed.Cartesian.Indexing.html 40 | 41 | This difference in variance gives opfibrations a distinct character. 42 | Reindexing in fibrations can be thought of a sort of restriction map. 43 | This can be seen clearly with [[canonical self-indexing]], where the 44 | reindexing functors are given by [[pullbacks]]. On the other hand, 45 | opreindexing can be thought of as an extension map. We can again use the 46 | the canonical self-indexing as our example: opreindexing is given by 47 | postcomposition, which extends families over $X$ to families over $Y$ by 48 | adding in empty fibres. 49 | 50 | [pullbacks]: Cat.Diagram.Pullback.html 51 | 52 | ```agda 53 | cobase-change : ∀ {x y} (f : Hom x y) → Functor (Fibre ℰ x) (Fibre ℰ y) 54 | cobase-change f .F₀ ob = f ^! ob 55 | cobase-change f .F₁ vert = rebase f vert 56 | ``` 57 | 58 | 74 | -------------------------------------------------------------------------------- /src/Cat/Displayed/Instances/Elements.lagda.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | We define the displayed category of elements. 4 | --- 5 | 11 | 12 | ```agda 13 | module Cat.Displayed.Instances.Elements {o ℓ s} (B : Precategory o ℓ) 14 | (P : Functor (B ^op) (Sets s)) where 15 | ``` 16 | 17 | 26 | 27 | # The displayed category of elements 28 | 29 | It is useful to view the [category of elements] of a presheaf 30 | `P`{.Agda} as a [[displayed category]]. Instead of considering pairs of 31 | objects $X$ and sections $s$, we instead think of the set of sections as 32 | displayed _over_ $X$. The story is similar for morphisms; instead of 33 | taking pairs of morphisms $f$ and fragments of data that $P(f)(x) = y$, 34 | we place those fragments over the morphism $f$. 35 | 36 | [category of elements]: Cat.Instances.Elements.html 37 | 38 | In a sense, this is the more natural presentation of the category of 39 | elements, as we obtain the more traditional definition by taking the 40 | [[total category]] of `∫`{.Agda}. 41 | 42 | ```agda 43 | ∫ : Displayed B s s 44 | ∫ .Displayed.Ob[_] X = P ʻ X 45 | ∫ .Displayed.Hom[_] f P[X] P[Y] = P.₁ f P[Y] ≡ P[X] 46 | ∫ .Displayed.Hom[_]-set _ _ _ = hlevel 2 47 | ∫ .Displayed.id' = happly P.F-id _ 48 | ∫ .Displayed._∘'_ {x = x} {y} {z} {f} {g} p q = pf where abstract 49 | pf : P.₁ (f ∘ g) z ≡ x 50 | pf = 51 | P.₁ (f ∘ g) z ≡⟨ happly (P.F-∘ g f) z ⟩ 52 | P.₁ g (P.₁ f z) ≡⟨ ap (P.₁ g) p ⟩ 53 | P.₁ g y ≡⟨ q ⟩ 54 | x ∎ 55 | ∫ .Displayed.idr' _ = prop! 56 | ∫ .Displayed.idl' _ = prop! 57 | ∫ .Displayed.assoc' _ _ _ = prop! 58 | ``` 59 | -------------------------------------------------------------------------------- /src/Cat/Displayed/Instances/Simple/Properties.lagda.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Properties of simple fibrations. 4 | --- 5 | 16 | ```agda 17 | module Cat.Displayed.Instances.Simple.Properties 18 | {o ℓ} (B : Precategory o ℓ) 19 | (has-prods : ∀ X Y → Product B X Y) 20 | where 21 | ``` 22 | 23 | 31 | 32 | # Properties of simple fibrations 33 | 34 | This module collects some useful properties of [[simple fibrations]]. 35 | 36 | ## Total products in simple fibrations 37 | 38 | Every simple fibration has all [[total products]]. 39 | 40 | ```agda 41 | simple-total-product 42 | : ∀ {Γ Δ A B : Ob} 43 | → Total-product Simple[B] (has-prods Γ Δ) A B 44 | ``` 45 | 46 | ```agda 47 | simple-total-product {Γ} {Δ} {A} {B} = total-prod where 48 | open is-total-product 49 | open Total-product 50 | 51 | total-prod : Total-product Simple[B] (has-prods Γ Δ) A B 52 | ``` 53 | 54 | The apex of the total product is simply given by a product in $\cB$. 55 | We can obtain the projections $(\Gamma \times \Delta) \times (A \times B) \to A$ 56 | and $(\Gamma \times \Delta) \times (A \times B) \to B$ by composing projections. 57 | 58 | ```agda 59 | total-prod .apex' = A ⊗₀ B 60 | total-prod .π₁' = π₁ ∘ π₂ 61 | total-prod .π₂' = π₂ ∘ π₂ 62 | ``` 63 | 64 | The universal property follows from some straightforward algebra. 65 | 66 | ```agda 67 | total-prod .has-is-total-product .⟨_,_⟩' f g = ⟨ f , g ⟩ 68 | total-prod .has-is-total-product .π₁∘⟨⟩' = 69 | pullr π₂∘⟨⟩ ∙ π₁∘⟨⟩ 70 | total-prod .has-is-total-product .π₂∘⟨⟩' = 71 | pullr π₂∘⟨⟩ ∙ π₂∘⟨⟩ 72 | total-prod .has-is-total-product .unique' p q = 73 | ⟨⟩-unique (pushr (sym π₂∘⟨⟩) ∙ p) (pushr (sym π₂∘⟨⟩) ∙ q) 74 | ``` 75 | -------------------------------------------------------------------------------- /src/Cat/Displayed/Instances/Slice/Properties.lagda.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | 4 | --- 5 | 17 | ```agda 18 | module Cat.Displayed.Instances.Slice.Properties where 19 | ``` 20 | 21 | # Properties of slice categories 22 | 23 | This module gathers together some useful properties of [[slice categories]]. 24 | 25 | 36 | 37 | ## Total products in slice categories 38 | 39 | A [[total product]] in a slice category is given by a [[product]] of 40 | the domains of the slices. 41 | 42 | ```agda 43 | slice-total-product 44 | : ∀ {I J X Y} {f : Hom X I} {g : Hom Y J} 45 | → (X×Y : Product B X Y) 46 | → (I×J : Product B I J) 47 | → Total-product (Slices B) I×J (cut f) (cut g) 48 | slice-total-product {f = f} {g = g} X×Y I×J = total-prod where 49 | open is-total-product 50 | open Total-product 51 | 52 | module X×Y = Product X×Y 53 | module I×J = Product I×J 54 | 55 | total-prod : Total-product (Slices B) I×J (cut f) (cut g) 56 | total-prod .apex' .domain = X×Y.apex 57 | total-prod .apex' .map = I×J.⟨ f ∘ X×Y.π₁ , g ∘ X×Y.π₂ ⟩ 58 | total-prod .π₁' .to = X×Y.π₁ 59 | total-prod .π₁' .commute = I×J.π₁∘⟨⟩ 60 | total-prod .π₂' .to = X×Y.π₂ 61 | total-prod .π₂' .commute = I×J.π₂∘⟨⟩ 62 | ``` 63 | 64 | The universal property follows from a bit of routine algebra involving 65 | products. 66 | 67 | ```agda 68 | total-prod .has-is-total-product .⟨_,_⟩' f g .to = X×Y.⟨ f. to , g .to ⟩ 69 | total-prod .has-is-total-product .⟨_,_⟩' f g .commute = 70 | I×J.unique₂ 71 | (pulll I×J.π₁∘⟨⟩ ∙ f .commute) 72 | (pulll I×J.π₂∘⟨⟩ ∙ g .commute) 73 | (pulll I×J.π₁∘⟨⟩ ∙ pullr X×Y.π₁∘⟨⟩) 74 | (pulll I×J.π₂∘⟨⟩ ∙ pullr X×Y.π₂∘⟨⟩) 75 | total-prod .has-is-total-product .π₁∘⟨⟩' = 76 | Slice-pathp B _ X×Y.π₁∘⟨⟩ 77 | total-prod .has-is-total-product .π₂∘⟨⟩' = 78 | Slice-pathp B _ X×Y.π₂∘⟨⟩ 79 | total-prod .has-is-total-product .unique' p q = 80 | Slice-pathp B _ (X×Y.unique (λ i → p i .to) λ i → q i .to) 81 | ``` 82 | -------------------------------------------------------------------------------- /src/Cat/Displayed/Instances/TotalProduct.lagda.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | ```agda 18 | module Cat.Displayed.Instances.TotalProduct 19 | {o₁ ℓ₁ o₂ ℓ₂ o₃ ℓ₃ o₄ ℓ₄} 20 | (C : Precategory o₁ ℓ₁) 21 | (D : Precategory o₂ ℓ₂) 22 | (EC : Displayed C o₃ ℓ₃) (ED : Displayed D o₄ ℓ₄) where 23 | private module EC = Displayed EC 24 | private module ED = Displayed ED 25 | ``` 26 | # The total product of displayed categories 27 | 28 | If $\cE\to \cB$ and $q :\cD \to \cC$ are 29 | displayed categories, then we can define their **total product** 30 | $\cE\times \cD\to \cB\times \cC$, 31 | which is again a displayed category. 32 | 33 | ```agda 34 | _×ᵀᴰ_ : Displayed (C ×ᶜ D) (o₃ ⊔ o₄) (ℓ₃ ⊔ ℓ₄) 35 | ``` 36 | If displayed categories are regarded as functors, then the product of 37 | displayed categories can be regarded as the usual product of functors. 38 | ```agda 39 | _×ᵀᴰ_ .Displayed.Ob[_] (p₁ , p₂) = 40 | EC.Ob[ p₁ ] × ED.Ob[ p₂ ] 41 | _×ᵀᴰ_ .Displayed.Hom[_] (f₁ , f₂) (c₁ , c₂) (d₁ , d₂) = 42 | EC.Hom[ f₁ ] c₁ d₁ × 43 | ED.Hom[ f₂ ] c₂ d₂ 44 | _×ᵀᴰ_ .Displayed.id' = (EC.id' , ED.id') 45 | ``` 46 | 47 | We establish that the hom sets of the product fibration are actually 48 | sets. 49 | 50 | If $x, y : \operatorname{Ob}[C \times D]$ 51 | (so $x = (x_C, x_D), y = (y_C, y_D)$) and 52 | $f : x \to y$ (so $f$ is $(f_C, f_D)$) 53 | then for any two morphisms $f_1,f_2$ lying over $f$, 54 | and any $p, q : f_1 = f_2$, $p=q$. 55 | 56 | ```agda 57 | _×ᵀᴰ_ .Displayed.Hom[_]-set _ _ _ = hlevel 2 58 | ``` 59 | Composition is pairwise. 60 | ```agda 61 | _×ᵀᴰ_ .Displayed._∘'_ (f₁ , f₂) (g₁ , g₂) = 62 | EC._∘'_ f₁ g₁ , ED._∘'_ f₂ g₂ 63 | ``` 64 | 65 | Associativity and left/right identity laws hold because 66 | they hold for the components of the ordered pairs. 67 | 68 | ```agda 69 | _×ᵀᴰ_ .Displayed.idr' (f₁ , f₂) = EC.idr' f₁ ,ₚ ED.idr' f₂ 70 | _×ᵀᴰ_ .Displayed.idl' (f₁ , f₂) = EC.idl' f₁ ,ₚ ED.idl' f₂ 71 | _×ᵀᴰ_ .Displayed.assoc' (f₁ , f₂) (g₁ , g₂) (h₁ , h₂) = 72 | EC.assoc' f₁ g₁ h₁ ,ₚ ED.assoc' f₂ g₂ h₂ 73 | ``` 74 | -------------------------------------------------------------------------------- /src/Cat/Displayed/InternalSum.lagda.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ```agda 13 | module Cat.Displayed.InternalSum 14 | {o ℓ o' ℓ'} {B : Precategory o ℓ} (E : Displayed B o' ℓ') where 15 | ``` 16 | 17 | 22 | 23 | # Internal sums 24 | 25 | As has been noted before, fibrations are an excellent setting for studying 26 | logical and type-theoretic phenomena. Internal sums are an example of this; 27 | serving as the categorical analog of Sigma types. 28 | 29 | To begin our definition, we first need a notion of a family internal to 30 | a fibration: this is handled by the [fibration of displayed families]. 31 | We say that a fibration $\cE$ has **internal sums** if the constant 32 | displayed family functor has a [[fibred left adjoint]]. 33 | 34 | [fibration of displayed families]: Cat.Displayed.Instances.DisplayedFamilies.html 35 | 36 | ```agda 37 | record Internal-sum : Type (o ⊔ ℓ ⊔ o' ⊔ ℓ') 38 | where 39 | no-eta-equality 40 | field 41 | ∐F : Vertical-functor (Disp-family E) E 42 | ∐F-fibred : is-fibred-functor ∐F 43 | ∐F⊣ConstFam : ∐F ⊣↓ ConstDispFam E 44 | ``` 45 | -------------------------------------------------------------------------------- /src/Cat/Finite.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Cat.Finite where 15 | ``` 16 | 17 | # Finite precategories {defines="finite-precategory finite-category"} 18 | 19 | A precategory is **finite** if both its type of objects and its total space of 20 | morphisms are [[finite]]. 21 | 22 | ```agda 23 | record is-finite-precategory {o ℓ} (D : Precategory o ℓ) : Type (o ⊔ ℓ) where 24 | constructor finite-cat 25 | field 26 | ⦃ has-finite-Ob ⦄ : Finite (Ob D) 27 | ⦃ has-finite-Arrows ⦄ : Finite (Arrows D) 28 | 29 | open is-finite-precategory 30 | ``` 31 | 32 | 38 | 39 | Conveniently, because finite types are `closed`{.Agda ident=Finite-Σ} under 40 | `Σ`{.Agda}, it suffices that each `Hom`{.Agda} set be finite: 41 | 42 | ```agda 43 | finite-cat-hom 44 | : ∀ {o ℓ} {D : Precategory o ℓ} 45 | → ⦃ Finite (Ob D) ⦄ 46 | → (∀ a b → Finite (Hom D a b)) 47 | → is-finite-precategory D 48 | finite-cat-hom {D = D} f = finite-cat where 49 | instance 50 | finite-Hom : ∀ {a b} → Finite (Hom D a b) 51 | finite-Hom {a} {b} = f a b 52 | ``` 53 | 54 | Thanks to even more instance magic (`path types of a finite type are 55 | finite`{.Agda ident=Finite-PathP}), the [[discrete category]] on a 56 | finite set is finite: 57 | 58 | ```agda 59 | Disc-finite : ∀ {ℓ} {A : Type ℓ} {isg : is-groupoid A} → ⦃ Finite A ⦄ 60 | → is-finite-precategory (Disc A isg) 61 | Disc-finite = finite-cat 62 | ``` 63 | -------------------------------------------------------------------------------- /src/Cat/Functor/Equivalence/Complete.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Functor.Equivalence.Complete where 13 | ``` 14 | 15 | # Completeness respects equivalences 16 | 17 | Let $\cC$ be a category admitting limits for $\cJ$-shaped 18 | diagrams, and $F : \cC \cong \cD$ an equivalence. Then $\cD$ 19 | also admits limits for $\cJ$-shaped diagrams; In particular, if 20 | $\cC$ is complete, then so is $\cD$. 21 | 22 | ```agda 23 | module 24 | _ {o ℓ o' ℓ'} {C : Precategory o ℓ} {D : Precategory o' ℓ'} 25 | {F : Functor C D} (eqv : is-equivalence F) 26 | where 27 | 28 | open is-equivalence eqv 29 | ``` 30 | 31 | This is a very short theorem: If $\cC$ admits $\cJ$-shaped limits, then 32 | for any diagram $K : \cJ \to \cD$, the composite $F\inv K$ has a limit. 33 | But since equivalences are [[right adjoints]], $F$ preserves this limit, 34 | so $FF\inv K$ has a limit in $\cD$; But that composite is naturally 35 | isomorphic to $K$, so $K$ also has a limit. 36 | 37 | ```agda 38 | equivalence→complete : ∀ {co cℓ} → is-complete co cℓ C → is-complete co cℓ D 39 | equivalence→complete ccomp K = 40 | natural-iso→limit (F∘-iso-id-l F∘F⁻¹≅Id) 41 | (subst Limit F∘-assoc (right-adjoint-limit F⁻¹⊣F (ccomp (F⁻¹ F∘ K)))) 42 | ``` 43 | -------------------------------------------------------------------------------- /src/Cat/Functor/Hom/Displayed.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Cat.Functor.Hom.Displayed 15 | {o ℓ o' ℓ'} {ℬ : Precategory o ℓ} (ℰ : Displayed ℬ o' ℓ') 16 | where 17 | ``` 18 | 19 | 27 | 28 | # Displayed Hom functors 29 | 30 | Let $\cE$ be a [[displayed category]] over $\cB$. For every $u : x \to y$ 31 | in the base, we can obtain a bifunctor from $\cE_{x}\op \times \cE_{y}$ 32 | to $\Sets$, where $\cE_{x}$ denotes the [[fibre category]] of $\cE$ at $x$. 33 | The action of $(f, h)$ on $g$ is given by $h \circ g \circ f$, just as 34 | in the [non-displayed case]. 35 | 36 | [bifunctor]: Cat.Functor.Bifunctor.html 37 | [non-displayed case]: Cat.Functor.Hom.html 38 | 39 | ```agda 40 | Hom-over : ∀ {x y} → Hom x y → Functor (Fibre ℰ x ^op ×ᶜ Fibre ℰ y) (Sets ℓ') 41 | Hom-over u .F₀ (a , b) = el (Hom[ u ] a b) (Hom[ u ]-set a b) 42 | Hom-over u .F₁ (f , h) g = hom[ idl _ ∙ idr _ ] (h ∘' g ∘' f) 43 | Hom-over u .F-id = funext λ f → 44 | apr' {q = idl _} (idr' f) ∙ idl[] 45 | Hom-over u .F-∘ (f , h) (f' , h') = funext λ g → 46 | hom[] (hom[] (h ∘' h') ∘' g ∘' hom[] (f' ∘' f)) ≡⟨ disp! ℰ ⟩ 47 | hom[] (h ∘' hom[] (h' ∘' g ∘' f') ∘' f) ∎ 48 | ``` 49 | 50 | We can also define partially applied versions of this functor. 51 | 52 | ```agda 53 | Hom-over-from : ∀ {x y} → Hom x y → Ob[ x ] → Functor (Fibre ℰ y) (Sets ℓ') 54 | Hom-over-from u x' .F₀ y' = el (Hom[ u ] x' y') (Hom[ u ]-set x' y') 55 | Hom-over-from u x' .F₁ f g = hom[ idl u ] (f ∘' g) 56 | Hom-over-from u x' .F-id = funext λ f → idl[] 57 | Hom-over-from u x' .F-∘ f g = funext λ h → 58 | smashl _ _ ∙ sym assoc[] ∙ sym (smashr _ _) 59 | 60 | Hom-over-into : ∀ {x y} → Hom x y → Ob[ y ] → Functor (Fibre ℰ x ^op) (Sets ℓ') 61 | Hom-over-into u y' .F₀ x' = el (Hom[ u ] x' y') (Hom[ u ]-set x' y') 62 | Hom-over-into u y' .F₁ f g = hom[ idr u ] (g ∘' f) 63 | Hom-over-into u y' .F-id = funext λ f → idr[] 64 | Hom-over-into u y' .F-∘ f g = funext λ h → 65 | smashr _ _ ∙ assoc[] ∙ (sym $ smashl _ _ ) 66 | ``` 67 | -------------------------------------------------------------------------------- /src/Cat/Functor/Hom/Duality.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Functor.Hom.Duality where 13 | ``` 14 | 15 | # Duality of Hom functors 16 | 17 | We prove the obvious dualities between $\hom$ functors of opposite categories, and 18 | between representable and corepresentable functors. 19 | 20 | 30 | 31 | ```agda 32 | Hom-from-op : ∀ c → Hom-from (C ^op) c ≡ Hom-into C c 33 | Hom-from-op c = Functor-path (λ _ → refl) (λ _ → refl) 34 | 35 | Hom-into-op : ∀ c → Hom-into (C ^op) c ≡ Hom-from C c 36 | Hom-into-op c = Functor-path (λ _ → refl) (λ _ → refl) 37 | 38 | corepresentable→co-representable 39 | : ∀ {F : Functor C (Sets ℓ)} 40 | → Corepresentation F → Representation {C = C ^op} F 41 | corepresentable→co-representable F-corep .rep = F-corep .corep 42 | corepresentable→co-representable F-corep .represents = 43 | path→iso (sym (Hom-into-op _)) ∘ni F-corep .corepresents 44 | 45 | co-representable→corepresentable 46 | : ∀ {F : Functor (C ^op) (Sets ℓ)} 47 | → Representation {C = C} F → Corepresentation F 48 | co-representable→corepresentable F-rep .corep = F-rep .rep 49 | co-representable→corepresentable F-rep .corepresents = 50 | path→iso (sym (Hom-from-op _)) ∘ni F-rep .represents 51 | ``` 52 | -------------------------------------------------------------------------------- /src/Cat/Functor/Naturality/Reflection.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Reflection.Subst 2 | open import 1Lab.Reflection 3 | 4 | open import Cat.Instances.Shape.Terminal 5 | open import Cat.Functor.Naturality 6 | open import Cat.Reasoning 7 | open import Cat.Prelude 8 | 9 | module Cat.Functor.Naturality.Reflection where 10 | 11 | module _ {o ℓ o' ℓ'} {C : Precategory o ℓ} {D : Precategory o' ℓ'} where 12 | 13 | -- Tactic worker for filling in trivial natural isomorphisms F ≅ⁿ G. 14 | -- 15 | -- The assumptions are: 16 | -- 1. ∀ x, F .F₀ x is definitionally equal to G .F₀ x 17 | -- 2. ∀ f, F .F₁ f is extensionally equal (by `trivial!`) to G .F₁ f 18 | -- OR C = ⊤Cat 19 | -- 20 | -- The functor arguments are only used for type inference. 21 | trivial-isoⁿ : (F G : Functor C D) → Term → TC ⊤ 22 | trivial-isoⁿ _ _ hole = do 23 | `C ← quoteTC C 24 | `D ← quoteTC D 25 | wait-just-a-bit `C >>= unify hole ⊙ λ where 26 | (def₀ (quote ⊤Cat)) → def₀ (quote !const-isoⁿ) 27 | ##ₙ (def₀ (quote id-iso) ##ₙ `D) 28 | _ → def₀ (quote iso→isoⁿ) 29 | ##ₙ vlam "" (def₀ (quote id-iso) ##ₙ raise 1 `D) 30 | ##ₙ vlam "" 31 | (def₀ (quote _∙∙_∙∙_) 32 | ##ₙ (def₀ (quote idr) ##ₙ raise 1 `D ##ₙ unknown) 33 | ##ₙ def₀ (quote trivial!) 34 | ##ₙ (def₀ (quote sym) 35 | ##ₙ (def₀ (quote idl) ##ₙ raise 1 `D ##ₙ unknown))) 36 | 37 | trivial-isoⁿ! 38 | : ∀ {F G : Functor C D} 39 | → {@(tactic trivial-isoⁿ F G) is : F ≅ⁿ G} 40 | → F ≅ⁿ G 41 | trivial-isoⁿ! {is = is} = is 42 | 43 | -- Tests 44 | 45 | module _ {o ℓ} {C : Precategory o ℓ} where 46 | 47 | _ : ∀ {F : Functor C C} → F ≅ⁿ F 48 | _ = trivial-isoⁿ! 49 | 50 | _ : ∀ {K : Functor ⊤Cat C} → !Const (K .Functor.F₀ _) ≅ⁿ K 51 | _ = trivial-isoⁿ! 52 | -------------------------------------------------------------------------------- /src/Cat/Functor/Reasoning/Presheaf.agda: -------------------------------------------------------------------------------- 1 | open import Cat.Prelude hiding (ap ; ap₂) 2 | 3 | import Cat.Functor.Reasoning as Func 4 | import Cat.Reasoning as Cat 5 | 6 | module Cat.Functor.Reasoning.Presheaf 7 | {o ℓ s} {C : Precategory o ℓ} (P : Functor C (Sets s)) 8 | where 9 | 10 | private 11 | module C = Cat C 12 | module Pf = Func P 13 | open Precategory C 14 | 15 | open Functor P using (F₀ ; F₁ ; ₀ ; ₁) public 16 | 17 | private variable 18 | U V W : ⌞ C ⌟ 19 | f g h i f' g' h' i' : C.Hom U V 20 | x y z : ∣ F₀ U ∣ 21 | 22 | F-id : ∀ {U : ⌞ C ⌟} {x} → F₁ {U} id x ≡ x 23 | F-id = happly Pf.F-id _ 24 | 25 | F-∘ 26 | : ∀ {U V W} (f : Hom V U) (g : Hom W V) {x} 27 | → F₁ (f ∘ g) x ≡ F₁ f (F₁ g x) 28 | F-∘ f g = happly (Pf.F-∘ f g) _ 29 | 30 | elim : f ≡ id → F₁ f x ≡ x 31 | elim p = happly (Pf.elim p) _ 32 | 33 | intro : id ≡ f → x ≡ F₁ f x 34 | intro p = sym (elim (sym p)) 35 | 36 | collapse : f ∘ g ≡ h → F₁ f (F₁ g x) ≡ F₁ h x 37 | collapse p = happly (Pf.collapse p) _ 38 | 39 | expand : h ≡ f ∘ g → F₁ h x ≡ F₁ f (F₁ g x) 40 | expand p = happly (Pf.expand p) _ 41 | 42 | weave : f ∘ g ≡ h ∘ i → F₁ f (F₁ g x) ≡ F₁ h (F₁ i x) 43 | weave p = happly (Pf.weave p) _ 44 | 45 | annihilate : f ∘ g ≡ id → F₁ f (F₁ g x) ≡ x 46 | annihilate p = happly (Pf.annihilate p) _ 47 | 48 | conjure : id ≡ f ∘ g → x ≡ F₁ f (F₁ g x) 49 | conjure p = sym (annihilate (sym p)) 50 | 51 | ap : x ≡ y → F₁ f x ≡ F₁ f y 52 | ap {f = f} p i = F₁ f (p i) 53 | 54 | ap₂ : f ≡ g → x ≡ y → F₁ f x ≡ F₁ g y 55 | ap₂ p q i = F₁ (p i) (q i) 56 | -------------------------------------------------------------------------------- /src/Cat/Groupoid.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Cat.Groupoid where 11 | ``` 12 | 13 | # Groupoids {defines="pregroupoid"} 14 | 15 | A category $\cC$ is a (pre)**groupoid** if every morphism of $\cC$ is 16 | invertible. 17 | 18 | ```agda 19 | is-pregroupoid : ∀ {o ℓ} → Precategory o ℓ → Type (o ⊔ ℓ) 20 | is-pregroupoid C = ∀ {x y} (f : Hom x y) → is-invertible f 21 | where open Cat.Reasoning C 22 | ``` 23 | -------------------------------------------------------------------------------- /src/Cat/Instances/Congruence.lagda.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | ```agda 15 | module Cat.Instances.Congruence where 16 | ``` 17 | 18 | # Congruences as groupoids {defines="congruences-as-groupoids"} 19 | 20 | Just as [[posets]] can be seen [[as *thin* categories|posets as categories]], 21 | [[congruences]] can be seen as thin *[[groupoids|pregroupoid]]*: categories 22 | in which every morphism is invertible and any two parallel morphisms are equal. 23 | 24 | ```agda 25 | module _ {ℓ ℓ'} {A : Type ℓ} (R : Congruence A ℓ') where 26 | open Congruence R 27 | 28 | congruence→category : Precategory _ _ 29 | congruence→category .Ob = A 30 | congruence→category .Hom = _∼_ 31 | congruence→category .Hom-set _ _ = is-prop→is-set (has-is-prop _ _) 32 | congruence→category .id = reflᶜ 33 | congruence→category ._∘_ f g = g ∙ᶜ f 34 | congruence→category .idr _ = has-is-prop _ _ _ _ 35 | congruence→category .idl _ = has-is-prop _ _ _ _ 36 | congruence→category .assoc _ _ _ = has-is-prop _ _ _ _ 37 | 38 | congruence→thin : is-thin congruence→category 39 | congruence→thin = has-is-prop 40 | 41 | congruence→groupoid : is-pregroupoid congruence→category 42 | congruence→groupoid f = make-invertible _ (symᶜ f) 43 | (has-is-prop _ _ _ _) (has-is-prop _ _ _ _) 44 | ``` 45 | 46 | To give a [[functor]] into a congruence *qua* category, it suffices to give a 47 | function into $A$ such that the source and target of every morphism have 48 | related images. 49 | 50 | ```agda 51 | congruence-functor 52 | : ∀ {o ℓ} {C : Precategory o ℓ} 53 | → (f : C .Ob → A) 54 | → (∀ {x y} → C .Hom x y → f x ∼ f y) 55 | → Functor C congruence→category 56 | congruence-functor = thin-functor congruence→thin 57 | ``` 58 | -------------------------------------------------------------------------------- /src/Cat/Instances/Delooping.lagda.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | ```agda 15 | module Cat.Instances.Delooping where 16 | ``` 17 | 18 | # The delooping of a monoid {defines="delooping-category delooping-of-a-monoid"} 19 | 20 | 26 | 27 | Given a monoid $M$, we build a pointed, [[connected|connected category]] 28 | precategory $\B{M}$, where the endomorphism monoid of the point recovers $M$. 29 | 30 | ```agda 31 | module _ {ℓ} {M : Type ℓ} (mm : Monoid-on M) where 32 | module mm = Monoid-on mm 33 | 34 | B : Precategory lzero ℓ 35 | B .Ob = ⊤ 36 | B .Hom _ _ = M 37 | B .Hom-set _ _ = mm.has-is-set 38 | B .Precategory.id = mm.identity 39 | B .Precategory._∘_ = mm._⋆_ 40 | B .idr _ = mm.idr 41 | B .idl _ = mm.idl 42 | B .assoc _ _ _ = mm.associative 43 | 44 | B-is-connected : is-connected-cat B 45 | B-is-connected .point = inc tt 46 | B-is-connected .zigzag _ _ = inc [] 47 | ``` 48 | -------------------------------------------------------------------------------- /src/Cat/Instances/Functor/Duality.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Instances.Functor.Duality where 13 | ``` 14 | 15 | # Duality of functor categories 16 | 17 | The duality involution $\cC\op$ on categories extends to a "duality 18 | involution" $F\op$ on _functors_. However, since this changes the type 19 | of the functor --- the dual of $F : \cC \to \cD$ is $F\op : \cC 20 | \to \cD$ --- it does not represent an involution on functor 21 | categories; Rather, it is an equivalence $(-)\op : [\cC,\cD]\op 22 | \cong [\cC\op,\cD\op]$. 23 | 24 | 34 | 35 | ```agda 36 | op-functor→ : Functor (Cat[ C , D ] ^op) Cat[ C ^op , D ^op ] 37 | op-functor→ .F₀ = Functor.op 38 | op-functor→ .F₁ nt .η = nt .η 39 | op-functor→ .F₁ nt .is-natural x y f = sym (nt .is-natural y x f) 40 | op-functor→ .F-id = trivial! 41 | op-functor→ .F-∘ f g = trivial! 42 | 43 | op-functor-is-iso : is-precat-iso (op-functor→ {C = C} {D = D}) 44 | op-functor-is-iso = isom where 45 | open is-precat-iso 46 | open is-iso 47 | 48 | isom : is-precat-iso _ 49 | isom .has-is-ff = is-iso→is-equiv ff where 50 | ff : is-iso (F₁ op-functor→) 51 | ff .from nt .η = nt .η 52 | ff .from nt .is-natural x y f = sym (nt .is-natural y x f) 53 | ff .rinv x = trivial! 54 | ff .linv x = trivial! 55 | isom .has-is-iso = is-iso→is-equiv (iso Functor.op 56 | (λ x → Functor-path (λ x → refl) (λ x → refl)) (λ x → F^op^op≡F)) 57 | ``` 58 | 59 | This means, in particular, that it is an adjoint equivalence: 60 | 61 | ```agda 62 | op-functor-is-equiv : is-equivalence (op-functor→ {C = C} {D = D}) 63 | op-functor-is-equiv = is-precat-iso→is-equivalence op-functor-is-iso 64 | 65 | op-functor← : Functor Cat[ C ^op , D ^op ] (Cat[ C , D ] ^op) 66 | op-functor← = is-equivalence.F⁻¹ op-functor-is-equiv 67 | 68 | op-functor←→ : op-functor← {C = C} {D = D} F∘ op-functor→ ≡ Id 69 | op-functor←→ {C = C} {D = D} = Functor-path (λ _ → refl) λ f → ext λ x → 70 | Regularity.precise! ((D.id D.∘ f .η x) D.∘ D.id ≡⟨ cat! D ⟩ f .η x ∎) 71 | where 72 | module D = Cat.Reasoning D 73 | ``` 74 | -------------------------------------------------------------------------------- /src/Cat/Instances/Lift.lagda.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ```agda 8 | module Cat.Instances.Lift where 9 | ``` 10 | 11 | # Lifting categories across universes 12 | 13 | Suppose you have a category $\cC$ with objects in $o$ and homs in 14 | $\ell$, but you really need it to have objects in some larger universe 15 | $o \sqcup o'$ and homs in $\ell \sqcup \ell'$. Fortunately you can 16 | uniformly lift the precategory $\cC$ to this bigger universe. 17 | 18 | ```agda 19 | Lift-cat : ∀ {o ℓ} o' ℓ' → Precategory o ℓ → Precategory (o ⊔ o') (ℓ ⊔ ℓ') 20 | Lift-cat o' ℓ' C = liftc where 21 | open Precategory C 22 | liftc : Precategory _ _ 23 | liftc .Precategory.Ob = Lift o' Ob 24 | liftc .Precategory.Hom (lift x) (lift y) = Lift ℓ' (Hom x y) 25 | liftc .Precategory.Hom-set x y = hlevel 2 26 | liftc .Precategory.id = lift id 27 | liftc .Precategory._∘_ (lift f) (lift g) = lift (f ∘ g) 28 | liftc .Precategory.idr (lift f) = ap lift (idr f) 29 | liftc .Precategory.idl (lift f) = ap lift (idl f) 30 | liftc .Precategory.assoc (lift f) (lift g) (lift h) = ap lift (assoc f g h) 31 | 32 | Lift-functor-l 33 | : ∀ {so sℓ} bo bℓ {o ℓ} {C : Precategory so sℓ} {D : Precategory o ℓ} 34 | → Functor C D 35 | → Functor (Lift-cat bo bℓ C) D 36 | Lift-functor-l bo bℓ G = F where 37 | open Functor 38 | F : Functor _ _ 39 | F .F₀ (lift x) = G .F₀ x 40 | F .F₁ (lift f) = G .F₁ f 41 | F .F-id = G .F-id 42 | F .F-∘ (lift f) (lift g) = G .F-∘ f g 43 | 44 | Lift-functor-r 45 | : ∀ {so sℓ} bo bℓ {o ℓ} {C : Precategory so sℓ} {D : Precategory o ℓ} 46 | → Functor C D 47 | → Functor C (Lift-cat bo bℓ D) 48 | Lift-functor-r bo bℓ G = F where 49 | open Functor 50 | F : Functor _ _ 51 | F .F₀ x = lift $ G .F₀ x 52 | F .F₁ f = lift $ G .F₁ f 53 | F .F-id = ap lift $ G .F-id 54 | F .F-∘ f g = ap lift $ G .F-∘ f g 55 | ``` 56 | -------------------------------------------------------------------------------- /src/Cat/Instances/OFE/Closed.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Cat.Instances.OFE.Closed where 12 | ``` 13 | 14 | # Function OFEs 15 | 16 | If $A$ and $B$ are [OFEs], then so is the space of non-expansive 17 | functions $A \overset{ne}{\to} B$: this makes the category OFE into a 18 | Cartesian closed category. 19 | 20 | [OFEs]: Cat.Instances.OFE.html 21 | 22 | 36 | 37 | ```agda 38 | Function-OFE : OFE-on (ℓa ⊔ ℓb') (O →ⁿᵉ P) 39 | Function-OFE .within n f g = ∀ x → f .map x ≈[ n ] g .map x 40 | Function-OFE .has-is-ofe .has-is-prop n x y = hlevel 1 41 | Function-OFE .has-is-ofe .≈-refl n x = P.≈-refl n 42 | Function-OFE .has-is-ofe .≈-sym n p x = P.≈-sym n (p x) 43 | Function-OFE .has-is-ofe .≈-trans n p q x = P.≈-trans n (p x) (q x) 44 | Function-OFE .has-is-ofe .bounded f g x = P.bounded (f .map x) (g .map x) 45 | Function-OFE .has-is-ofe .step n f g α x = P.step n (f .map x) (g .map x) (α x) 46 | Function-OFE .has-is-ofe .limit f g α = Nonexp-ext λ x → 47 | P.limit (f .map x) (g .map x) (λ n → α n x) 48 | ``` 49 | -------------------------------------------------------------------------------- /src/Cat/Instances/OFE/Discrete.lagda.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ```agda 9 | module Cat.Instances.OFE.Discrete where 10 | ``` 11 | 12 | # Discrete OFEs 13 | 14 | Given a set $X$, we can make it into a **discrete [OFE]** by equipping 15 | it with the relation that _takes one step_ to approximate equality: $x 16 | \within{0} y$ is trivial, but $x \within{1 + n} y$ is defined to be $x = 17 | y$, no matter what $n$ is. 18 | 19 | [OFE]: Cat.Instances.OFE.html 20 | 21 | ```agda 22 | Discrete-OFE : ∀ {ℓ} (A : Type ℓ) → is-set A → OFE-on ℓ A 23 | Discrete-OFE A A-set .within zero x y = Lift _ ⊤ 24 | Discrete-OFE A A-set .within (suc n) x y = x ≡ y 25 | Discrete-OFE A A-set .has-is-ofe .has-is-prop zero _ _ _ _ _ = _ 26 | Discrete-OFE A A-set .has-is-ofe .has-is-prop (suc n) = A-set 27 | 28 | Discrete-OFE A A-set .has-is-ofe .≈-refl zero = _ 29 | Discrete-OFE A A-set .has-is-ofe .≈-refl (suc n) = refl 30 | 31 | Discrete-OFE A A-set .has-is-ofe .≈-sym zero = _ 32 | Discrete-OFE A A-set .has-is-ofe .≈-sym (suc n) p = sym p 33 | 34 | Discrete-OFE A A-set .has-is-ofe .≈-trans zero = _ 35 | Discrete-OFE A A-set .has-is-ofe .≈-trans (suc n) p q = q ∙ p 36 | 37 | Discrete-OFE A A-set .has-is-ofe .bounded = _ 38 | Discrete-OFE A A-set .has-is-ofe .step zero = _ 39 | Discrete-OFE A A-set .has-is-ofe .step (suc n) x y p = p 40 | Discrete-OFE A A-set .has-is-ofe .limit x y α = α 1 41 | ``` 42 | -------------------------------------------------------------------------------- /src/Cat/Instances/Shape/Initial.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Cat.Instances.Shape.Initial where 11 | ``` 12 | 13 | 18 | 19 | :::{.definition #initial-category} 20 | The **initial category** is the category with no objects. 21 | ::: 22 | 23 | ```agda 24 | ⊥Cat : Precategory lzero lzero 25 | ⊥Cat .Ob = ⊥ 26 | ⊥Cat .Hom _ _ = ⊥ 27 | ``` 28 | 29 | This category is notable for the existence of a unique functor from 30 | it to any other category. 31 | 32 | ```agda 33 | module _ {o h} {A : Precategory o h} where 34 | private module A = Precategory A 35 | open Functor 36 | 37 | 38 | ¡F : Functor ⊥Cat A 39 | ¡F .F₀ () 40 | 41 | ¡F-unique : ∀ (F G : Functor ⊥Cat A) → F ≡ G 42 | ¡F-unique F G i .F₀ () 43 | 44 | ¡nt : ∀ {F G : Functor ⊥Cat A} → F => G 45 | ¡nt ._=>_.η () 46 | ¡nt ._=>_.is-natural () 47 | ``` 48 | -------------------------------------------------------------------------------- /src/Cat/Instances/Shape/Terminal/Properties.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Instances.Shape.Terminal.Properties where 13 | ``` 14 | 15 | # Properties 16 | 17 | We note that the [[terminal category]] is a unit to the categorical product. 18 | 19 | ```agda 20 | ⊤Cat-unit : ∀ {o h} {C : Precategory o h} → ⊤Cat ×ᶜ C ≡ C 21 | ⊤Cat-unit = sym $ Precategory-path Cat⟨ !F , Id ⟩ Cat⟨!F,Id⟩-is-iso where 22 | open is-precat-iso 23 | open is-iso 24 | Cat⟨!F,Id⟩-is-iso : is-precat-iso Cat⟨ !F , Id ⟩ 25 | Cat⟨!F,Id⟩-is-iso .has-is-ff .is-eqv (tt , f) .centre = f , refl 26 | Cat⟨!F,Id⟩-is-iso .has-is-iso .is-eqv (tt , a) .centre = a , refl 27 | Cat⟨!F,Id⟩-is-iso .has-is-ff .is-eqv (tt , f) .paths (g , p) i = p (~ i) .snd , λ j → p (~ i ∨ j) 28 | Cat⟨!F,Id⟩-is-iso .has-is-iso .is-eqv (tt , a) .paths (b , p) i = p (~ i) .snd , λ j → p (~ i ∨ j) 29 | ``` 30 | -------------------------------------------------------------------------------- /src/Cat/Instances/Shape/Two.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Cat.Instances.Shape.Two where 15 | ``` 16 | 17 | # The two-object category {defines="two-object-category"} 18 | 19 | We define the [[discrete category]] $\twocat$ on two objects, which is 20 | useful for expressing binary [[products]] and [[coproducts]] as 21 | [[limits]] and [[colimits]], respectively. 22 | 23 | ```agda 24 | 2-object-category : Precategory _ _ 25 | 2-object-category = Disc' (el! Bool) 26 | ``` 27 | 28 | A diagram of shape $\twocat$ in $\cC$ simply consists of two objects of 29 | $\cC$. 30 | 31 | ```agda 32 | module _ {o h} {C : Precategory o h} where 33 | open Precategory C 34 | 35 | 2-object-diagram : Ob → Ob → Functor 2-object-category C 36 | 2-object-diagram a b = Disc-diagram λ where 37 | true → a 38 | false → b 39 | ``` 40 | 41 | Similarly, a natural transformation between two such diagrams consists 42 | of two morphisms in $\cC$. 43 | 44 | ```agda 45 | 2-object-nat-trans 46 | : ∀ {F G : Functor 2-object-category C} 47 | → Hom (F · true) (G · true) → Hom (F · false) (G · false) 48 | → F => G 49 | 2-object-nat-trans f g = Disc-natural λ where 50 | true → f 51 | false → g 52 | ``` 53 | 54 | We note that _any_ functor $F : \twocat \to \cC$ is 55 | canonically _equal_, not just naturally isomorphic, to the one we 56 | defined above. 57 | 58 | ```agda 59 | canonical-functors 60 | : ∀ (F : Functor 2-object-category C) 61 | → F ≡ 2-object-diagram (F · true) (F · false) 62 | canonical-functors F = Functor-path p q where 63 | p : ∀ x → _ 64 | p false = refl 65 | p true = refl 66 | 67 | q : ∀ {x y} (f : x ≡ y) → _ 68 | q {false} {false} p = 69 | F .F₁ p ≡⟨ ap (F .F₁) prop! ⟩ 70 | F .F₁ refl ≡⟨ F .F-id ⟩ 71 | id ∎ 72 | q {true} {true} p = 73 | F .F₁ p ≡⟨ ap (F .F₁) prop! ⟩ 74 | F .F₁ refl ≡⟨ F .F-id ⟩ 75 | id ∎ 76 | q {false} {true} p = absurd (true≠false (sym p)) 77 | q {true} {false} p = absurd (true≠false p) 78 | ``` 79 | -------------------------------------------------------------------------------- /src/Cat/Instances/Simplex.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Instances.Simplex where 13 | ``` 14 | 15 | 20 | 21 | # The simplex category 22 | 23 | The simplex category, $\Delta$, is generally introduced as the category 24 | of non-empty finite ordinals and order-preserving maps. We will, for 25 | convenience reasons, define it _skeletally_: Rather than taking actual 26 | finite ordinals as objects, we will use the natural numbers as ordinals, 27 | each natural standing for the isomorphism class of ordinals of that 28 | cardinality. 29 | 30 | ```agda 31 | record Δ-map (n m : Nat) : Type where 32 | field 33 | map : Fin (suc n) → Fin (suc m) 34 | ascending : (x y : Fin (suc n)) → x ≤ y → map x ≤ map y 35 | ``` 36 | 37 | 53 | 54 | ```agda 55 | Δ : Precategory lzero lzero 56 | Δ .Ob = Nat 57 | Δ .Hom n m = Δ-map n m 58 | Δ .Hom-set _ _ = hlevel 2 59 | 60 | Δ .id .map x = x 61 | Δ .id .ascending x y p = p 62 | 63 | Δ ._∘_ f g .map x = f .map (g .map x) 64 | Δ ._∘_ f g .ascending x y p = f .ascending _ _ (g .ascending _ _ p) 65 | 66 | Δ .idr f = Δ-map-path λ x → refl 67 | Δ .idl f = Δ-map-path λ x → refl 68 | Δ .assoc f g h = Δ-map-path λ x → refl 69 | ``` 70 | -------------------------------------------------------------------------------- /src/Cat/Internal/Morphism.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Internal.Morphism 13 | {o ℓ} {C : Precategory o ℓ} 14 | (ℂ : Internal-cat C) 15 | where 16 | ``` 17 | 18 | 29 | 30 | # Morphisms in internal categories 31 | 32 | This module defines the internal versions of monomorphisms, 33 | epimorphisms, and isomorphisms. These definitions mirror [their 34 | 1-categorical counterparts], so we do not comment on them further. 35 | 36 | [their 1-categorical counterparts]: Cat.Morphism.html 37 | 38 | ## Monos 39 | 40 | ```agda 41 | is-monici : Homi x y → Type _ 42 | is-monici {x = x} f = ∀ {w} → (g h : Homi w x) → f ∘i g ≡ f ∘i g → g ≡ h 43 | 44 | is-monici-is-prop : ∀ (f : Homi x y) → is-prop (is-monici f) 45 | is-monici-is-prop f x y i {w} g h p = Internal-hom-set g h (x g h p) (y g h p) i 46 | 47 | record _↪i_ (x y : Hom Γ C₀) : Type ℓ where 48 | field 49 | mori : Homi x y 50 | monici : is-monici mori 51 | ``` 52 | 53 | ## Epis 54 | 55 | ```agda 56 | is-epici : Homi x y → Type _ 57 | is-epici {y = y} f = ∀ {z} → (g h : Homi y z) → g ∘i f ≡ h ∘i f → g ≡ h 58 | 59 | is-epici-is-prop : ∀ (f : Homi x y) → is-prop (is-epici f) 60 | is-epici-is-prop f x y i {z} g h p = Internal-hom-set g h (x g h p) (y g h p) i 61 | 62 | record _↠i_ (x y : Hom Γ C₀) : Type ℓ where 63 | field 64 | mori : Homi x y 65 | epici : is-epici mori 66 | ``` 67 | 68 | ## Isomorphisms 69 | 70 | ```agda 71 | record Inversesi (f : Homi x y) (g : Homi y x) : Type ℓ where 72 | field 73 | invli : f ∘i g ≡ idi y 74 | invri : g ∘i f ≡ idi x 75 | 76 | record is-invertiblei (f : Homi x y) : Type ℓ where 77 | field 78 | invi : Homi y x 79 | inversesi : Inversesi f invi 80 | 81 | open Inversesi inversesi public 82 | 83 | record _≅i_ (x y : Hom Γ C₀) : Type ℓ where 84 | field 85 | toi : Homi x y 86 | fromi : Homi y x 87 | inversesi : Inversesi toi fromi 88 | 89 | open Inversesi inversesi public 90 | 91 | open _≅i_ public 92 | ``` 93 | -------------------------------------------------------------------------------- /src/Cat/Monoidal/Diagonals.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Cat.Monoidal.Diagonals {o ℓ} 13 | {C : Precategory o ℓ} (Cᵐ : Monoidal-category C) 14 | where 15 | ``` 16 | 17 | # Monoidal categories with diagonals {defines="monoidal-category-with-diagonals"} 18 | 19 | 27 | 28 | A [[monoidal category]] can be equipped with a system of *diagonal 29 | morphisms* $\delta_A : A \to A \otimes A$. Of course, such a system 30 | should be natural in $A$; another sensible thing to require is that the 31 | diagonal $1 \to 1 \otimes 1$ agree with the left (`hence`{.Agda ident=λ≡ρ} 32 | also right) unitor. 33 | 34 | We call the resulting structure a **monoidal category with diagonals**. 35 | 36 | ```agda 37 | record Diagonals : Type (o ⊔ ℓ) where 38 | field 39 | diagonals : Id => -⊗- F∘ Cat⟨ Id , Id ⟩ 40 | 41 | module δ = _=>_ diagonals 42 | 43 | δ : ∀ {A} → Hom A (A ⊗ A) 44 | δ = δ.η _ 45 | 46 | field 47 | diagonal-λ→ : δ {Unit} ≡ λ→ {Unit} 48 | ``` 49 | 50 | The prototypical examples of monoidal categories with diagonals are 51 | [[cartesian monoidal categories]]. 52 | -------------------------------------------------------------------------------- /src/Cat/Monoidal/Reverse.lagda.md: -------------------------------------------------------------------------------- 1 | 15 | 16 | ```agda 17 | module Cat.Monoidal.Reverse {o ℓ} 18 | {C : Precategory o ℓ} (Cᵐ : Monoidal-category C) 19 | where 20 | ``` 21 | 22 | 29 | 30 | # Reverse monoidal categories {defines="reverse-monoidal-category"} 31 | 32 | Given a [[monoidal category]] $\cC$ with tensor product $\otimes : 33 | \cC \times \cC \to \cC$, we can define the **reverse** monoidal category 34 | $\cC^\rm{rev}$ with the same unit and the tensor product flipped 35 | around: $A \otimes^\rm{rev} B = B \otimes A$. 36 | 37 | ```agda 38 | _^rev : Monoidal-category C 39 | _^rev .-⊗- = Flip C.-⊗- 40 | _^rev .Unit = C.Unit 41 | ``` 42 | 43 | The coherence isomorphisms are straightforward to obtain from those of 44 | $\cC$: the left and right unitors are swapped, and the associator is 45 | reversed and has its arguments swapped. 46 | 47 | ```agda 48 | _^rev .unitor-l = iso→isoⁿ (isoⁿ→iso C.unitor-r) 49 | λ f → sym (C.unitor-r .Isoⁿ.to .is-natural _ _ f) 50 | _^rev .unitor-r = iso→isoⁿ (isoⁿ→iso C.unitor-l) 51 | λ f → sym (C.unitor-l .Isoⁿ.to .is-natural _ _ f) 52 | _^rev .associator = iso→isoⁿ 53 | (λ (a , b , c) → isoⁿ→iso (C.associator ni⁻¹) (c , b , a)) 54 | λ (f , g , h) → sym (C.associator .Isoⁿ.from .is-natural _ _ (h , g , f)) 55 | _^rev .triangle = C.triangle-α→ 56 | _^rev .pentagon = C.pentagon-α→ 57 | ``` 58 | 59 | 64 | 65 | Thinking of monoidal categories as one-object [[bicategories]] (via the 66 | `Deloop`{.Agda}ing construction), the $-^\rm{rev}$ operation corresponds to 67 | flipping the 1-cells of a bicategory, leaving the 2-cells unchanged. 68 | -------------------------------------------------------------------------------- /src/Cat/Morphism/Instances.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Prelude hiding (_∘_ ; id ; _↪_ ; _↠_) 2 | 3 | open import Cat.Morphism 4 | open import Cat.Base 5 | 6 | open Precategory 7 | 8 | module Cat.Morphism.Instances where 9 | 10 | abstract 11 | instance 12 | H-Level-is-invertible 13 | : ∀ {o ℓ} {C : Precategory o ℓ} {a b} {f : C .Hom a b} {n} → H-Level (is-invertible C f) (suc n) 14 | H-Level-is-invertible {C = C} = prop-instance (is-invertible-is-prop C) 15 | 16 | unquoteDecl H-Level-↪ = declare-record-hlevel 2 H-Level-↪ (quote _↪_) 17 | unquoteDecl H-Level-↠ = declare-record-hlevel 2 H-Level-↠ (quote _↠_) 18 | unquoteDecl H-Level-Inverses = declare-record-hlevel 2 H-Level-Inverses (quote Inverses) 19 | unquoteDecl H-Level-≅ = declare-record-hlevel 2 H-Level-≅ (quote _≅_) 20 | unquoteDecl 21 | H-Level-has-section = declare-record-hlevel 2 H-Level-has-section (quote has-section) 22 | unquoteDecl 23 | H-Level-has-retract = declare-record-hlevel 2 H-Level-has-retract (quote has-retract) 24 | 25 | module _ {o ℓ} {C : Precategory o ℓ} where instance 26 | Extensional-↪ : ∀ {a b ℓr} ⦃ _ : Extensional (C .Hom a b) ℓr ⦄ → Extensional (_↪_ C a b) ℓr 27 | Extensional-↪ ⦃ sa ⦄ = injection→extensional! (↪-pathp C) sa 28 | 29 | Extensional-↠ : ∀ {a b ℓr} ⦃ _ : Extensional (C .Hom a b) ℓr ⦄ → Extensional (_↠_ C a b) ℓr 30 | Extensional-↠ ⦃ sa ⦄ = injection→extensional! (↠-pathp C) sa 31 | 32 | Extensional-≅ : ∀ {a b ℓr} ⦃ _ : Extensional (C .Hom a b) ℓr ⦄ → Extensional (_≅_ C a b) ℓr 33 | Extensional-≅ ⦃ sa ⦄ = injection→extensional! (≅-pathp C refl refl) sa 34 | 35 | Funlike-≅ 36 | : ∀ {ℓ' ℓ''} {A : Type ℓ'} {B : A → Type ℓ''} 37 | → ∀ {a b} ⦃ i : Funlike (Hom C a b) A B ⦄ 38 | → Funlike (_≅_ C a b) A B 39 | Funlike-≅ .Funlike._·_ f x = f .to · x 40 | -------------------------------------------------------------------------------- /src/Cat/Prelude.agda: -------------------------------------------------------------------------------- 1 | -- This module doesn't have any text! That's because it's simply a bunch 2 | -- of convenient re-exports for working in the Cat namespace. 3 | 4 | module Cat.Prelude where 5 | 6 | open import 1Lab.Prelude 7 | renaming ( _↪_ to _↣_ 8 | ; _∘_ to _⊙_ -- \o. 9 | ; _⟩∘⟨_ to _⟩⊙⟨_ 10 | ; refl⟩∘⟨_ to refl⟩⊙⟨_ 11 | ; _⟩∘⟨refl to _⟩⊙⟨refl 12 | ; _∘⟨_ to _⊙⟨_ 13 | ; _⟩∘_ to _⟩⊙_ 14 | ) 15 | hiding (id ; map ; _↠_ ; ⟨_,_⟩) 16 | public 17 | 18 | open import Data.Set.Truncation public 19 | open import Data.Set.Coequaliser public 20 | 21 | open import Cat.Base public 22 | open import Cat.Solver hiding (module NbE; module Reflection) public 23 | open import Cat.Univalent 24 | using ( is-category ; path→iso ; Hom-pathp 25 | ; Hom-transport ; Hom-pathp-refll ; Hom-pathp-reflr 26 | ; module Univalent ) 27 | public 28 | 29 | open import Cat.Morphism.Instances public 30 | -------------------------------------------------------------------------------- /src/Cat/Restriction/Total.lagda.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | ```agda 13 | module Cat.Restriction.Total where 14 | ``` 15 | 16 | # The subcategory of total maps 17 | 18 | Let $\cC$ be a restriction category. We can construct a 19 | [wide subcategory] of $\cC$ containing only the [total maps] of $\cC$, 20 | denoted $\thecat{Total}(\cC)$. 21 | 22 | [wide subcategory]: Cat.Functor.WideSubcategory.html 23 | [total maps]: Cat.Restriction.Reasoning.html#total-morphisms 24 | 25 | 31 | 32 | ```agda 33 | Total-wide-subcat : Wide-subcat C ℓ 34 | Total-wide-subcat .Wide-subcat.P = is-total 35 | Total-wide-subcat .Wide-subcat.P-prop = is-total-is-prop 36 | Total-wide-subcat .Wide-subcat.P-id = id-total 37 | Total-wide-subcat .Wide-subcat.P-∘ = total-∘ 38 | 39 | Total-maps : Precategory o ℓ 40 | Total-maps = Wide Total-wide-subcat 41 | ``` 42 | 43 | 49 | 50 | Furthermore, the injection from $\thecat{Total}(\cC)$ into $\cC$ is 51 | [pseudomonic], as all isomorphisms in $\cC$ are total. 52 | 53 | [pseudomonic]: Cat.Functor.Properties.html#pseudomonic-functors 54 | 55 | ```agda 56 | 57 | Forget-total : Functor (Total-maps C↓) C 58 | Forget-total = Forget-wide-subcat 59 | 60 | Forget-total-pseudomonic : is-pseudomonic Forget-total 61 | Forget-total-pseudomonic = 62 | is-pseudomonic-Forget-wide-subcat invertible→total 63 | ``` 64 | -------------------------------------------------------------------------------- /src/Cat/Strict.lagda.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ```agda 8 | module Cat.Strict where 9 | ``` 10 | 11 | # Strict precategories {defines="strict-category strict-categories"} 12 | 13 | We call a precategory **strict** if its type of objects is a `Set`{.Agda 14 | ident=is-set}. 15 | 16 | ```agda 17 | is-strict : ∀ {o ℓ} → Precategory o ℓ → Type o 18 | is-strict C = is-set ⌞ C ⌟ 19 | ``` 20 | 21 | Strictness is a very strong condition to impose on categories, since it 22 | classifies the "categories-as-algebras", or _petit_, view on categories, 23 | which regards categories _themselves_ as set-level structures, which 24 | could be compared to [monoids] or [groups]. For example, the [path 25 | category] on a directed graph is naturally regarded as strict. Moreover, 26 | [[strict categories form a precategory|category of strict categories]]. 27 | 28 | [strcat]: Cat.Instances.StrictCat.html 29 | [path category]: Cat.Instances.Free.html 30 | [monoids]: Algebra.Monoid.html 31 | [groups]: Algebra.Group.html 32 | 33 | This is in contrast with the "categories-as-universes", or _gros_, view 34 | on categories. From this perspective, categories serve to organise 35 | objects at the set-level, like [$\thecat{Mon}$] or [$\Grp$]. These 36 | categories tend to be [[univalent|univalent category]], with a proper 37 | underlying _groupoid_ of objects. 38 | 39 | [$\thecat{Mon}$]: Algebra.Monoid.Category.html 40 | [$\Grp$]: Algebra.Group.Cat.Base.html 41 | -------------------------------------------------------------------------------- /src/Cat/Univalent/Instances/Opposite.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Cat.Univalent.Instances.Opposite 11 | {o ℓ} {C : Precategory o ℓ} 12 | where 13 | ``` 14 | 15 | 22 | 23 | # Opposites of univalent categories 24 | 25 | A simple case of closure of [[univalence|univalent categories]] is the 26 | duality involution: Since isomorphisms in $\cC\op$ are the same as 27 | isomorphisms in $\cC$, the former is univalent iff the latter is. 28 | 29 | ```agda 30 | opposite-is-category : is-category C → is-category (C ^op) 31 | opposite-is-category x .to-path i = x .to-path $ 32 | C.make-iso (i .Cop.from) (i .Cop.to) (i .Cop.invl) (i .Cop.invr) 33 | opposite-is-category x .to-path-over p = 34 | Cop.≅-pathp refl _ $ Univalent.Hom-pathp-refll-iso x (C.idl _) 35 | ``` 36 | -------------------------------------------------------------------------------- /src/Data/Char/Base.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Data.Char.Base where 13 | ``` 14 | 15 | # The type of characters 16 | 17 | ```agda 18 | postulate Char : Type 19 | {-# BUILTIN CHAR Char #-} 20 | 21 | private module P where primitive 22 | primIsLower primIsDigit primIsAlpha primIsSpace primIsAscii 23 | primIsLatin1 primIsPrint primIsHexDigit : Char → Bool 24 | 25 | primToUpper primToLower : Char → Char 26 | primCharToNat : Char → Nat 27 | primNatToChar : Nat → Char 28 | 29 | primCharToNatInjective : ∀ a b → primCharToNat a ≡ᵢ primCharToNat b → a ≡ᵢ b 30 | 31 | open P public renaming 32 | ( primIsLower to is-lower? 33 | ; primIsDigit to is-digit? 34 | ; primIsAlpha to is-alpha? 35 | ; primIsSpace to is-space? 36 | ; primIsAscii to is-ascii? 37 | ; primIsLatin1 to is-latin1? 38 | ; primIsPrint to is-printable? 39 | ; primIsHexDigit to is-hex-digit? 40 | 41 | ; primToUpper to to-upper 42 | ; primToLower to to-lower 43 | ; primNatToChar to nat→char 44 | ; primCharToNat to char→nat 45 | ) 46 | 47 | instance 48 | Discrete-Char : Discrete Char 49 | Discrete-Char = Discrete-inj' _ (primCharToNatInjective _ _) 50 | -------------------------------------------------------------------------------- /src/Data/Dec.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Data.Dec where 3 | ``` 4 | 5 | # Decisions 6 | 7 | ```agda 8 | open import Data.Dec.Base public 9 | open import Data.Dec.Path public 10 | ``` 11 | -------------------------------------------------------------------------------- /src/Data/Dec/Path.lagda.md: -------------------------------------------------------------------------------- 1 | 14 | 15 | ```agda 16 | module Data.Dec.Path where 17 | ``` 18 | 19 | ```agda 20 | module Dec-path {ℓ} {A : Type ℓ} where 21 | Code : Dec A → Dec A → Type ℓ 22 | Code (yes x) (yes y) = x ≡ y 23 | Code (yes x) (no ¬x) = absurd (¬x x) 24 | Code (no ¬x) (yes x) = absurd (¬x x) 25 | Code (no ¬x) (no ¬y) = Lift _ ⊤ 26 | 27 | Code-refl : ∀ x → Code x x 28 | Code-refl (yes x) = refl 29 | Code-refl (no x) = lift tt 30 | 31 | decode : ∀ x y → Code x y → x ≡ y 32 | decode (yes x) (yes y) p = ap yes p 33 | decode (yes x) (no ¬x) p = absurd (¬x x) 34 | decode (no ¬x) (yes x) p = absurd (¬x x) 35 | decode (no ¬x) (no ¬y) p = ap no (funext λ x → absurd (¬x x)) 36 | 37 | Code-ids : is-identity-system Code Code-refl 38 | Code-ids .to-path = decode _ _ 39 | Code-ids .to-path-over {yes x} {yes y} p = λ i j → p (i ∧ j) 40 | Code-ids .to-path-over {yes x} {no ¬x} p = absurd (¬x x) 41 | Code-ids .to-path-over {no ¬x} {yes x} p = absurd (¬x x) 42 | Code-ids .to-path-over {no ¬x} {no ¬y} p = refl 43 | 44 | Code-hlevel : ∀ {n} → is-hlevel A (suc n) → ∀ x y → is-hlevel (Code x y) n 45 | Code-hlevel a-hl (yes x) (yes y) = Path-is-hlevel' _ a-hl x y 46 | Code-hlevel a-hl (yes x) (no ¬x) = absurd (¬x x) 47 | Code-hlevel a-hl (no ¬x) (yes x) = absurd (¬x x) 48 | 49 | Code-hlevel {zero} a-hl (no ¬x) (no ¬y) = 50 | contr (lift tt) (λ x i → lift tt) 51 | Code-hlevel {suc n} a-hl (no ¬x) (no ¬y) = 52 | is-prop→is-hlevel-suc (λ x y i → lift tt) 53 | 54 | Dec-is-hlevel : ∀ {ℓ} n {A : Type ℓ} → is-hlevel A n → is-hlevel (Dec A) n 55 | Dec-is-hlevel 0 ahl = contr (yes (ahl .centre)) λ where 56 | (yes a) → ap yes (ahl .paths a) 57 | (no ¬a) → absurd (¬a (ahl .centre)) 58 | Dec-is-hlevel (suc n) ahl = 59 | identity-system→hlevel n Dec-path.Code-ids $ 60 | Dec-path.Code-hlevel ahl 61 | 62 | instance 63 | H-Level-Dec : ∀ {n} {ℓ} {A : Type ℓ} ⦃ hl : H-Level A n ⦄ 64 | → H-Level (Dec A) n 65 | H-Level-Dec {n} = hlevel-instance (Dec-is-hlevel n (hlevel n)) 66 | ``` 67 | -------------------------------------------------------------------------------- /src/Data/Fin.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Data.Fin where 3 | 4 | open import Data.Fin.Properties public 5 | open import Data.Fin.Finite public 6 | open import Data.Fin.Base public 7 | ``` 8 | 9 | # Finite sets - index 10 | 11 | The natural numbers are constructed in the module 12 | [`Data.Fin.Base`]. Their arithmetical properties are proved in 13 | [`Data.Fin.Properties`]. 14 | 15 | [`Data.Fin.Base`]: Data.Fin.Base.html 16 | [`Data.Fin.Properties`]: Data.Fin.Properties.html 17 | -------------------------------------------------------------------------------- /src/Data/Id/Properties.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Path 2 | open import 1Lab.Type 3 | 4 | open import Data.Id.Base 5 | 6 | module Data.Id.Properties where 7 | 8 | private variable 9 | ℓ ℓ' ℓ'' : Level 10 | A B C : Type ℓ 11 | P Q R : A → Type ℓ 12 | x y z : A 13 | 14 | symᵢ-symᵢ : ∀ {ℓ} {A : Type ℓ} {x y : A} (p : x ≡ᵢ y) → symᵢ (symᵢ p) ≡ p 15 | symᵢ-symᵢ reflᵢ = refl 16 | 17 | symᵢ-from : ∀ {ℓ} {A : Type ℓ} {x y : A} (p : x ≡ y) → symᵢ (Id≃path.from p) ≡ Id≃path.from (sym p) 18 | symᵢ-from = J (λ y p → symᵢ (Id≃path.from p) ≡ Id≃path.from (sym p)) (ap symᵢ (transport-refl reflᵢ) ∙ sym (transport-refl reflᵢ)) 19 | 20 | 21 | apᵢ-from : (f : A → B) {x y : A} (p : x ≡ y) → apᵢ f (Id≃path.from p) ≡ Id≃path.from (ap f p) 22 | apᵢ-from f = J (λ y p → apᵢ f (Id≃path.from p) ≡ Id≃path.from (ap f p)) (ap (apᵢ f) (transport-refl reflᵢ) ∙ sym (transport-refl reflᵢ)) 23 | 24 | apᵢ-symᵢ : (f : A → B) (p : x ≡ᵢ y) → apᵢ f (symᵢ p) ≡ᵢ symᵢ (apᵢ f p) 25 | apᵢ-symᵢ f reflᵢ = reflᵢ 26 | 27 | symPᵢ : {a b : A} {x : P a} {y : P b} (p : a ≡ᵢ b) → Id-over P p x y → Id-over P (symᵢ p) y x 28 | symPᵢ reflᵢ reflᵢ = reflᵢ 29 | 30 | symPᵢ⁻ : {a b : A} {x : P a} {y : P b} (p : a ≡ᵢ b) → Id-over P (symᵢ p) y x → Id-over P p x y 31 | symPᵢ⁻ reflᵢ reflᵢ = reflᵢ 32 | -------------------------------------------------------------------------------- /src/Data/Int.lagda.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | ```agda 7 | module Data.Int where 8 | ``` 9 | 10 | # The integers - index 11 | 12 | ```agda 13 | open import Data.Int.Properties public 14 | open import Data.Int.Order public 15 | open import Data.Int.Base public 16 | ``` 17 | -------------------------------------------------------------------------------- /src/Data/Int/Divisible.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Data.Int.Divisible where 12 | ``` 13 | 14 | # Divisibility of integers {defines="divisibility-of-integers"} 15 | 16 | We define what it means for an [[integer]] to be [[divisible]] by a 17 | natural number, as a straightforward generalisation of the case for 18 | natural numbers. 19 | 20 | ```agda 21 | _∣ℤ_ : Nat → Int → Type 22 | zero ∣ℤ y = y ≡ 0 23 | suc x ∣ℤ y = fibre (_*ℤ possuc x) y 24 | 25 | infix 7 _∣ℤ_ 26 | 27 | ∣ℤ-is-prop : ∀ x y → is-prop (x ∣ℤ y) 28 | ∣ℤ-is-prop zero y n k = prop! 29 | ∣ℤ-is-prop (suc x) y (n , p) (n' , q) = Σ-prop-path! (*ℤ-injectiver-possuc x n n' (p ∙ sym q)) 30 | 31 | ∣ℤ-is-truncation : ∀ {x y} → (x ∣ℤ y) ≃ ∥ fibre (_*ℤ pos x) y ∥ 32 | ∣ℤ-is-truncation {zero} {y} = 33 | prop-ext! 34 | (λ p → inc (y , *ℤ-zeror y ∙ sym p)) 35 | (rec! λ x p → sym p ∙ *ℤ-zeror x ) 36 | ∣ℤ-is-truncation {suc x} {y} = Equiv.to is-prop≃equiv∥-∥ (∣ℤ-is-prop (suc x) y) 37 | 38 | ∣ℤ→fibre : ∀ {x y} → x ∣ℤ y → fibre (_*ℤ pos x) y 39 | ∣ℤ→fibre {zero} wit = 0 , sym wit 40 | ∣ℤ→fibre {suc x} wit = wit 41 | 42 | fibre→∣ℤ : ∀ {x y} → fibre (_*ℤ pos x) y → x ∣ℤ y 43 | fibre→∣ℤ f = Equiv.from ∣ℤ-is-truncation (inc f) 44 | 45 | dividesℤ : ∀ {x y} (q : Int) → q *ℤ pos x ≡ y → x ∣ℤ y 46 | dividesℤ x p = fibre→∣ℤ (x , p) 47 | 48 | ∣ℤ-zero : ∀ {x} → x ∣ℤ 0 49 | ∣ℤ-zero = dividesℤ 0 refl 50 | 51 | ∣ℤ-one : ∀ {x} → 1 ∣ℤ x 52 | ∣ℤ-one {x} = dividesℤ x (*ℤ-oner x) 53 | 54 | m∣ℤsn→m≤sn : ∀ {x y} → ¬ (y ≡ 0) → x ∣ℤ y → x Nat.≤ abs y 55 | m∣ℤsn→m≤sn {x} {y} nz p with ∣ℤ→fibre p 56 | ... | posz , p = absurd (nz (sym p)) 57 | ... | possuc k , p = difference→≤ (k * x) 58 | (ap abs (sym (assign-pos (x + k * x))) ∙ ap abs p) 59 | ... | negsuc k , p = difference→≤ (k * x) 60 | (sym (abs-negℤ (pos (x + k * x))) ∙ ap abs (sym (assign-neg (x + k * x))) ∙ ap abs p) 61 | 62 | ∣ℤ-+ : ∀ {k n m} → k ∣ℤ n → k ∣ℤ m → k ∣ℤ (n +ℤ m) 63 | ∣ℤ-+ {zero} {n} {m} p q = ap₂ _+ℤ_ p q 64 | ∣ℤ-+ {suc k} (x , p) (y , q) = x +ℤ y , *ℤ-distribr (possuc k) x y ∙ ap₂ _+ℤ_ p q 65 | 66 | ∣ℤ-negℤ : ∀ {k n} → k ∣ℤ n → k ∣ℤ negℤ n 67 | ∣ℤ-negℤ {zero} d = ap negℤ d 68 | ∣ℤ-negℤ {suc k} (x , p) = negℤ x , *ℤ-negl x _ ∙ ap negℤ p 69 | ``` 70 | -------------------------------------------------------------------------------- /src/Data/Irr.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Data.Irr where 13 | ``` 14 | 15 | # Strict propositional truncations 16 | 17 | 24 | 25 | In Agda, it's possible to turn any type into one that *definitionally* 26 | has at most one inhabitant. We do this using a record containing an 27 | irrelevant field. 28 | 29 | ```agda 30 | record Irr {ℓ} (A : Type ℓ) : Type ℓ where 31 | constructor forget 32 | field 33 | .lower : A 34 | ``` 35 | 36 | The most important property of this type is that, given any $x, y$ in 37 | $\operatorname{Irr}(A)$, the constant path `refl`{.Agda} checks at type 38 | $x \is y$. 39 | 40 | ```agda 41 | instance 42 | H-Level-Irr : ∀ {n} → H-Level (Irr A) (suc n) 43 | H-Level-Irr {n} = prop-instance λ _ _ → refl 44 | ``` 45 | 46 | 57 | -------------------------------------------------------------------------------- /src/Data/List.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Data.List where 3 | ``` 4 | 5 | # Lists - index 6 | 7 | ```agda 8 | open import Data.List.Base public 9 | open import Data.List.Properties public 10 | open import Data.List.Membership public 11 | ``` 12 | -------------------------------------------------------------------------------- /src/Data/List/Pi.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Prelude 2 | 3 | open import Data.List.Membership 4 | open import Data.Fin.Product 5 | open import Data.List.Sigma 6 | open import Data.List.Base 7 | open import Data.Fin.Base 8 | 9 | module Data.List.Pi where 10 | 11 | private variable 12 | ℓ ℓ' : Level 13 | A B C : Type ℓ 14 | P Q : A → Type ℓ 15 | 16 | Pi : (xs : List A) → (A → Type ℓ') → Type _ 17 | Pi {ℓ' = ℓ'} xs P = Πᶠ {length xs} {λ _ → ℓ'} (λ i → P (xs ! i)) 18 | 19 | pi : (xs : List A) (ys : ∀ a → List (P a)) → List (Pi xs P) 20 | pi [] ys = tt ∷ [] 21 | pi (x ∷ xs) ys = sigma (ys x) (λ _ → pi xs ys) 22 | 23 | Pi' : (xs : List A) → (A → Type ℓ') → Type _ 24 | Pi' xs P = ∀ a → a ∈ₗ xs → P a 25 | 26 | module _ {A : Type ℓ} (P : A → Type ℓ') where 27 | to-pi' : ∀ {xs} → Pi xs P → Pi' xs P 28 | to-pi' (x , xs) a (here p) = substᵢ P (symᵢ p) x 29 | to-pi' (x , xs) a (there h) = to-pi' xs a h 30 | 31 | from-pi' : ∀ {xs} → Pi' xs P → Pi xs P 32 | from-pi' {[]} x = tt 33 | from-pi' {x₁ ∷ xs} x = x _ (here reflᵢ) , from-pi' {xs} (λ _ h → x _ (there h)) 34 | 35 | to-from-pi' : ∀ {xs} (p : Pi xs P) → from-pi' (to-pi' p) ≡ p 36 | to-from-pi' {[]} p = refl 37 | to-from-pi' {x ∷ xs} p = refl ,ₚ to-from-pi' {xs} (p .snd) 38 | 39 | from-to-pi' : ∀ {xs} (p : Pi' xs P) → to-pi' (from-pi' p) ≡ p 40 | from-to-pi' p i a (here reflᵢ) = p a (here reflᵢ) 41 | from-to-pi' p i a (there x) = from-to-pi' (λ a h → p a (there h)) i a x 42 | 43 | pi-member' 44 | : {A : Type ℓ} {P : A → Type ℓ'} (xs : List A) (ys : ∀ a → List (P a)) {e : Pi xs P} 45 | → (∀ h → indexₚ e h ∈ₗ ys (xs ! h)) → e ∈ₗ pi xs ys 46 | pi-member' [] ys {tt} p = here reflᵢ 47 | pi-member' (x ∷ xs) ys {p , ps} q = sigma-member {xs = ys x} {ys = λ _ → pi xs ys} (q fzero) (pi-member' xs ys (q ∘ fsuc)) 48 | 49 | member-pi' 50 | : {A : Type ℓ} {P : A → Type ℓ'} (xs : List A) (ys : ∀ a → List (P a)) {e : Pi xs P} 51 | → (α : e ∈ₗ pi xs ys) → fibre (pi-member' xs ys) α 52 | member-pi' [] ys (here p) = (λ h → absurd (Fin-absurd h)) , ap here (is-set→is-setᵢ (hlevel 2) _ _ reflᵢ p) 53 | member-pi' (x ∷ xs) ys elt = 54 | let 55 | α = member-sigmaₗ (ys x) (λ _ → pi xs ys) elt 56 | β = member-sigmaᵣ (ys x) (λ _ → pi xs ys) elt 57 | 58 | (f , coh) = member-pi' xs ys β 59 | 60 | g = Fin-cases α λ h → member-pi' xs ys β .fst h 61 | in g , ap (sigma-member α) coh ∙ member-sigma-view (ys x) (λ _ → pi xs ys) elt .snd 62 | -------------------------------------------------------------------------------- /src/Data/Maybe.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Data.Maybe where 3 | 4 | open import Data.Maybe.Base public 5 | open import Data.Maybe.Properties public 6 | ``` 7 | -------------------------------------------------------------------------------- /src/Data/Nat.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Data.Nat where 3 | 4 | open import Data.Nat.Properties public 5 | open import Data.Nat.Order public 6 | open import Data.Nat.Base public 7 | open import Data.Nat.Divisible public 8 | open import Data.Nat.Divisible.GCD public 9 | open import Data.Nat.DivMod public 10 | open import Prim.Data.Nat 11 | using (Nat ; _+_ ; _-_) public 12 | ``` 13 | 14 | # Natural numbers - index 15 | 16 | The natural numbers are constructed in the module 17 | [`Data.Nat.Base`]. Their arithmetical properties are proved in 18 | [`Data.Nat.Properties`]. 19 | 20 | [`Data.Nat.Base`]: Data.Nat.Base.html 21 | [`Data.Nat.Properties`]: Data.Nat.Properties.html 22 | -------------------------------------------------------------------------------- /src/Data/Product/NAry.lagda.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ```agda 9 | module Data.Product.NAry where 10 | ``` 11 | 12 | # n-Ary products 13 | 14 | This is an alternative definition of the type of n-ary products, which, 15 | unlike [`Vec`](Data.Vec.Base.html), is defined by _recursion_ on the 16 | length. 17 | 18 | ```agda 19 | Vecₓ : ∀ {ℓ} → Type ℓ → Nat → Type ℓ 20 | Vecₓ A 0 = Lift _ ⊤ 21 | Vecₓ A 1 = A 22 | Vecₓ A (suc (suc n)) = A × Vecₓ A (suc n) 23 | ``` 24 | 25 | The point of having the type `Vecₓ`{.Agda} around is that its 26 | inhabitants can be written using the usual tuple syntax, so that we can 27 | define a `From-product`{.Agda} "type class" for those type constructors 28 | (possibly indexed by the length) which can be built as a sequence of 29 | arguments. 30 | 31 | ```agda 32 | _ : Vecₓ Nat 3 33 | _ = 1 , 2 , 3 34 | 35 | record From-product {ℓ} (A : Type ℓ) (T : Nat → Type ℓ) : Type ℓ where 36 | field from-prod : ∀ n → Vecₓ A n → T n 37 | ``` 38 | 39 | Shuffling the arguments to `from-prod`{.Agda} slightly, we arrive at the 40 | "list syntax" construction: 41 | 42 | ```agda 43 | [_] : ∀ {ℓ} {A : Type ℓ} {T : Nat → Type ℓ} {n} ⦃ fp : From-product A T ⦄ 44 | → Vecₓ A n → T n 45 | [_] ⦃ fp = fp ⦄ = fp .From-product.from-prod _ 46 | ``` 47 | -------------------------------------------------------------------------------- /src/Data/Rational/Reflection.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Reflection hiding ([_]) 2 | open import 1Lab.Prelude 3 | 4 | open import Data.Rational.Base hiding (_/_) 5 | 6 | module Data.Rational.Reflection where 7 | 8 | open 1Lab.Reflection using (Bind-TC) public 9 | 10 | {- 11 | 12 | Simple macro that automates wrapping ℚ-elim-propⁿ so the first n ℚ 13 | arguments are implicit. 14 | 15 | foo : ∀ {x y z} → P 16 | unquoteDef foo = by-elim-ℚ foo ?body 17 | 18 | is equivalent to 19 | 20 | foo {x} {y} {z} = ℚ-elim-propⁿ {P} ?body 21 | 22 | The number of arguments to induct over is the number of implicit pis 23 | with ℚ domain at the head of the type. The function being defined must 24 | have a type signature with no metas. 25 | -} 26 | 27 | private 28 | strip-leading-impl-ℚs : Term → Telescope × Term 29 | strip-leading-impl-ℚs it@(pi (arg i ty) (abs nm b)) = go (i .ArgInfo.arg-vis) ty module spi where 30 | go : Visibility → Term → Telescope × Term 31 | go hidden (def₀ (quote ℚ)) with (etel , tm') ← strip-leading-impl-ℚs b = 32 | (nm , arg (set-visibility visible i) ty) ∷ etel , tm' 33 | go _ ty = [] , it 34 | strip-leading-impl-ℚs tm = [] , tm 35 | 36 | by-elim-ℚ : ∀ {ℓ} (n : Name) {ty : Type ℓ} → ty → TC ⊤ 37 | by-elim-ℚ nm body = do 38 | ty ← get-type nm >>= wait-for-type 39 | 40 | let 41 | (tel , motive) = strip-leading-impl-ℚs ty 42 | motive = tel→lam tel motive 43 | 44 | patel = set-visibility hidden tel 45 | 46 | body ← quoteTC body 47 | let 48 | body = def (quote ℚ-elim-propⁿ) $ 49 | argN (lit (nat (length tel))) ∷ 50 | argH unknown ∷ -- level 51 | argH motive ∷ 52 | argN body ∷ 53 | tel→args 0 tel 54 | 55 | define-function nm (clause patel (tel→pats 0 patel) body ∷ []) 56 | -------------------------------------------------------------------------------- /src/Data/Reflection/Abs.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Path.IdentitySystem 2 | open import 1Lab.Path 3 | open import 1Lab.Type 4 | 5 | open import Data.String.Base 6 | open import Data.Dec.Base 7 | open import Data.Id.Base 8 | 9 | module Data.Reflection.Abs where 10 | 11 | record Abs {a} (A : Type a) : Type a where 12 | constructor abs 13 | field 14 | abs-name : String 15 | abs-binder : A 16 | 17 | {-# BUILTIN ABS Abs #-} 18 | {-# BUILTIN ABSABS abs #-} 19 | 20 | instance 21 | Discrete-Abs : ∀ {ℓ} {A : Type ℓ} ⦃ _ : Discrete A ⦄ → Discrete (Abs A) 22 | Discrete-Abs = Discrete-inj (λ (abs n b) → n , b) (λ p → ap₂ abs (ap fst p) (ap snd p)) auto 23 | -------------------------------------------------------------------------------- /src/Data/Reflection/Error.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Type 2 | 3 | open import Data.Reflection.Name 4 | open import Data.Reflection.Term 5 | open import Data.String.Base 6 | open import Data.List.Base 7 | 8 | open import Meta.Append 9 | 10 | module Data.Reflection.Error where 11 | 12 | data ErrorPart : Type where 13 | strErr : String → ErrorPart 14 | termErr : Term → ErrorPart 15 | pattErr : Pattern → ErrorPart 16 | nameErr : Name → ErrorPart 17 | 18 | {-# BUILTIN AGDAERRORPART ErrorPart #-} 19 | {-# BUILTIN AGDAERRORPARTSTRING strErr #-} 20 | {-# BUILTIN AGDAERRORPARTTERM termErr #-} 21 | {-# BUILTIN AGDAERRORPARTPATT pattErr #-} 22 | {-# BUILTIN AGDAERRORPARTNAME nameErr #-} 23 | 24 | instance 25 | From-string-ErrorPart : From-string ErrorPart 26 | From-string-ErrorPart .From-string.Constraint _ = ⊤ 27 | From-string-ErrorPart .from-string s = strErr s 28 | 29 | instance 30 | From-string-error : From-string (List ErrorPart) 31 | From-string-error .From-string.Constraint _ = ⊤ 32 | From-string-error .from-string s = strErr s ∷ [] 33 | -------------------------------------------------------------------------------- /src/Data/Reflection/Meta.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Path 2 | open import 1Lab.Type 3 | 4 | open import Data.String.Base 5 | open import Data.String.Show 6 | open import Data.List.Base 7 | open import Data.Dec.Base 8 | open import Data.Nat.Base 9 | open import Data.Id.Base 10 | open import Data.Bool 11 | 12 | module Data.Reflection.Meta where 13 | 14 | postulate Meta : Type 15 | {-# BUILTIN AGDAMETA Meta #-} 16 | 17 | private module P where primitive 18 | primMetaEquality : Meta → Meta → Bool 19 | primMetaLess : Meta → Meta → Bool 20 | primShowMeta : Meta → String 21 | primMetaToNat : Meta → Nat 22 | primMetaToNatInjective : ∀ x y → primMetaToNat x ≡ᵢ primMetaToNat y → x ≡ᵢ y 23 | 24 | instance 25 | Discrete-Meta : Discrete Meta 26 | Discrete-Meta = Discrete-inj' _ (P.primMetaToNatInjective _ _) 27 | 28 | Show-Meta : Show Meta 29 | Show-Meta = default-show P.primShowMeta 30 | 31 | data Blocker : Type where 32 | blocker-any : List Blocker → Blocker 33 | blocker-all : List Blocker → Blocker 34 | blocker-meta : Meta → Blocker 35 | 36 | {-# BUILTIN AGDABLOCKER Blocker #-} 37 | {-# BUILTIN AGDABLOCKERANY blocker-any #-} 38 | {-# BUILTIN AGDABLOCKERALL blocker-all #-} 39 | {-# BUILTIN AGDABLOCKERMETA blocker-meta #-} 40 | -------------------------------------------------------------------------------- /src/Data/Reflection/Name.agda: -------------------------------------------------------------------------------- 1 | open import 1Lab.Path.IdentitySystem 2 | open import 1Lab.Path 3 | open import 1Lab.Type 4 | 5 | open import Data.Reflection.Fixity 6 | open import Data.String.Base 7 | open import Data.String.Show 8 | open import Data.Word.Base 9 | open import Data.Dec.Base 10 | open import Data.Id.Base 11 | 12 | module Data.Reflection.Name where 13 | 14 | postulate Name : Type 15 | {-# BUILTIN QNAME Name #-} 16 | 17 | private module P where primitive 18 | primQNameEquality : Name → Name → Bool 19 | primQNameLess : Name → Name → Bool 20 | primShowQName : Name → String 21 | primQNameToWord64s : Name → Σ Word64 (λ _ → Word64) 22 | primQNameToWord64sInjective : ∀ x y → primQNameToWord64s x ≡ᵢ primQNameToWord64s y → x ≡ᵢ y 23 | primQNameFixity : Name → Fixity 24 | 25 | open P 26 | renaming (primQNameFixity to name→fixity) 27 | using () 28 | public 29 | 30 | instance 31 | Discrete-Name : Discrete Name 32 | Discrete-Name = Discrete-inj' _ (P.primQNameToWord64sInjective _ _) 33 | 34 | Show-Name : Show Name 35 | Show-Name = default-show P.primShowQName 36 | -------------------------------------------------------------------------------- /src/Data/String/Base.lagda.md: -------------------------------------------------------------------------------- 1 | 14 | 15 | ```agda 16 | module Data.String.Base where 17 | ``` 18 | 19 | # Primitive: Characters and strings 20 | 21 | We bind the big list of Agda primitives for interacting with characters 22 | and strings. 23 | 24 | ```agda 25 | postulate String : Type 26 | {-# BUILTIN STRING String #-} 27 | 28 | private module P where primitive 29 | primStringUncons : String → Maybe (Char × String) 30 | primStringToList : String → List Char 31 | primStringFromList : List Char → String 32 | primStringAppend : String → String → String 33 | primStringToListInjective : ∀ a b → primStringToList a ≡ᵢ primStringToList b → a ≡ᵢ b 34 | ``` 35 | 36 | ```agda 37 | open P public renaming 38 | ( primStringUncons to uncons-string 39 | ; primStringToList to string→list 40 | ; primStringFromList to list→string 41 | ) 42 | hiding ( primStringAppend ; primStringToListInjective ) 43 | ``` 44 | 45 | ```agda 46 | record From-string {a} (A : Type a) : Type (lsuc a) where 47 | field 48 | Constraint : String → Type a 49 | from-string : (s : String) {{_ : Constraint s}} → A 50 | 51 | open From-string {{...}} public using (from-string) 52 | 53 | {-# DISPLAY From-string.from-string _ s = from-string s #-} 54 | {-# BUILTIN FROMSTRING from-string #-} 55 | 56 | instance 57 | From-string-String : From-string String 58 | From-string-String .From-string.Constraint _ = ⊤ 59 | From-string-String .from-string s = s 60 | 61 | Append-String : Append String 62 | Append-String ._<>_ = P.primStringAppend 63 | Append-String .mempty = "" 64 | 65 | {-# DISPLAY P.primStringAppend x y = x <> y #-} 66 | 67 | instance 68 | Discrete-String : Discrete String 69 | Discrete-String = Discrete-inj' _ (P.primStringToListInjective _ _) 70 | ``` 71 | -------------------------------------------------------------------------------- /src/Data/String/Show.lagda.md: -------------------------------------------------------------------------------- 1 | 15 | 16 | ```agda 17 | module Data.String.Show where 18 | ``` 19 | 20 | # The Show class 21 | 22 | ```agda 23 | record ShowS : Type where 24 | constructor showS 25 | field 26 | unshowS : String → String 27 | 28 | instance 29 | From-string-ShowS : From-string ShowS 30 | From-string-ShowS .From-string.Constraint _ = ⊤ 31 | From-string-ShowS .from-string s = showS (s <>_) 32 | 33 | Append-ShowS : Append ShowS 34 | Append-ShowS .Append.mempty = showS id 35 | Append-ShowS .Append._<>_ (showS k1) (showS k2) = showS (k1 ∘ k2) 36 | 37 | record Show {ℓ} (A : Type ℓ) : Type ℓ where 38 | field 39 | -- Convert a value into a difference-string, using the given 40 | -- precedence to determine whether or not parentheses are necessary. 41 | shows-prec : Precedence → A → ShowS 42 | 43 | -- Convert a value into a string suitable for printing. 44 | show : A → String 45 | 46 | open Show ⦃ ... ⦄ public 47 | 48 | default-show : ∀ {ℓ} {A : Type ℓ} → (A → String) → Show A 49 | default-show s = record 50 | { shows-prec = λ _ x → from-string (s x) 51 | ; show = s 52 | } 53 | 54 | show-parens : Bool → ShowS → ShowS 55 | show-parens true x = "(" <> x <> ")" 56 | show-parens false x = x 57 | 58 | private module P where primitive 59 | primShowChar : Char → String 60 | primShowString : String → String 61 | primShowNat : Nat → String 62 | primShowFloat : Float → String 63 | 64 | instance 65 | Show-Word64 : Show Word64 66 | Show-Word64 = default-show λ x → P.primShowNat (word64→nat x) 67 | 68 | Show-Nat : Show Nat 69 | Show-Nat = default-show P.primShowNat 70 | 71 | Show-String : Show String 72 | Show-String = default-show P.primShowString 73 | 74 | Show-Char : Show Char 75 | Show-Char = default-show P.primShowChar 76 | 77 | Show-Float : Show Float 78 | Show-Float = default-show P.primShowFloat 79 | ``` 80 | -------------------------------------------------------------------------------- /src/Data/Sum.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Data.Sum where 3 | ``` 4 | 5 | # Sum types 6 | 7 | ```agda 8 | open import Data.Sum.Properties public 9 | open import Data.Sum.Base public 10 | ``` 11 | -------------------------------------------------------------------------------- /src/Data/Vec/Properties.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Data.Vec.Properties where 15 | ``` 16 | 17 | 26 | 27 | # Properties of vectors 28 | 29 | ```agda 30 | tabulate-lookup : (xs : Vec A n) → tabulate (lookup xs) ≡ xs 31 | tabulate-lookup [] = refl 32 | tabulate-lookup (x ∷ xs) = ap (x ∷_) (tabulate-lookup xs) 33 | 34 | lookup-tabulate : (xs : Fin n → A) (i : Fin n) → lookup (tabulate xs) i ≡ xs i 35 | lookup-tabulate xs i with fin-view i 36 | ... | zero = refl 37 | ... | suc i = lookup-tabulate (xs ∘ fsuc) i 38 | 39 | lookup-is-equiv : is-equiv (lookup {A = A} {n}) 40 | lookup-is-equiv = is-iso→is-equiv $ 41 | iso tabulate (λ x → funext (lookup-tabulate x)) tabulate-lookup 42 | 43 | module Lookup {ℓ} {A : Type ℓ} {n : Nat} = Equiv (lookup {A = A} {n} , lookup-is-equiv) 44 | 45 | map-lookup : ∀ (f : A → B) (xs : Vec A n) i → lookup (Vec.map f xs) i ≡ f (lookup xs i) 46 | map-lookup _ _ i with fin-view i 47 | map-lookup f (x ∷ xs) _ | zero = refl 48 | map-lookup f (x ∷ xs) _ | suc i = map-lookup f xs i 49 | 50 | map-id : (xs : Vec A n) → Vec.map (λ x → x) xs ≡ xs 51 | map-id xs = Lookup.injective₂ (funext λ i → map-lookup _ xs i) refl 52 | 53 | map-comp 54 | : (xs : Vec A n) (f : A → B) (g : B → C) 55 | → Vec.map (λ x → g (f x)) xs ≡ Vec.map g (Vec.map f xs) 56 | map-comp xs f g = Lookup.injective $ funext λ i → 57 | lookup (Vec.map (λ x → g (f x)) xs) i ≡⟨ map-lookup (λ x → g (f x)) xs i ⟩ 58 | g (f (lookup xs i)) ≡˘⟨ ap g (map-lookup f xs i) ⟩ 59 | g (lookup (Vec.map f xs) i) ≡˘⟨ map-lookup g (Vec.map f xs) i ⟩ 60 | lookup (Vec.map g (Vec.map f xs)) i ∎ 61 | ``` 62 | -------------------------------------------------------------------------------- /src/Data/Wellfounded/Base.lagda.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ```agda 9 | module Data.Wellfounded.Base where 10 | ``` 11 | 12 | # Well-founded relations 13 | 14 | Well-founded relations are, in essence, orders over which _induction_ is 15 | acceptable. A relation is well-founded if all of its chains have bounded 16 | length, which we can summarize with the following inductive definition 17 | of **accessibility**: 18 | 19 | 24 | 25 | ```agda 26 | data Acc (x : A) : Type (ℓ ⊔ ℓ') where 27 | acc : (∀ y → y < x → Acc y) → Acc x 28 | ``` 29 | 30 | That is, an element $x : A$ is accessible if every element $y < x$ under 31 | it (by the relation $<$) is also accessible. Paraphrasing the HoTT book, 32 | it may seem like such a definition can never get started, but the "base 33 | case" is when there are _no_ elements $y < x$ --- for example, taking 34 | $<$ to be the usual $<$ on the natural numbers, there are no numbers $y 35 | < 0$, so $0$ is accessible. 36 | 37 | A relation is **well-founded** if every $x : A$ is accessible. 38 | 39 | ```agda 40 | Wf : Type _ 41 | Wf = ∀ x → Acc x 42 | ``` 43 | 44 | Being well-founded implies that we support induction, and conversely, 45 | any relation supporting induction is well-founded, by taking the motive 46 | $P$ to be the proposition "$x$ is accessible". 47 | 48 | ```agda 49 | Wf-induction' 50 | : ∀ {ℓ'} (P : A → Type ℓ') 51 | → (∀ x → (∀ y → y < x → P y) → P x) 52 | → ∀ x → Acc x → P x 53 | Wf-induction' P work = go where 54 | go : ∀ x → Acc x → P x 55 | go x (acc w) = work x (λ y y 10 | 11 | ```agda 12 | module Data.Wellfounded.Properties where 13 | ``` 14 | 15 | It was mentioned in the definition of `Acc`{.Agda} that being accessible 16 | is a proposition, but this has not yet been established. We can do so 17 | using, as usual, induction: 18 | 19 | 27 | 28 | ```agda 29 | Acc-is-prop : ∀ x → is-prop (Acc R x) 30 | Acc-is-prop x (acc s) (acc t) = 31 | ap acc (ext λ y y 10 | 11 | ```agda 12 | module Data.Word.Base where 13 | ``` 14 | 15 | # Machine words 16 | 17 | ```agda 18 | postulate Word64 : Type 19 | 20 | {-# BUILTIN WORD64 Word64 #-} 21 | 22 | private module P where primitive 23 | primWord64ToNat : Word64 → Nat 24 | primWord64FromNat : Nat → Word64 25 | primWord64ToNatInjective : ∀ a b → primWord64ToNat a ≡ᵢ primWord64ToNat b → a ≡ᵢ b 26 | 27 | open P public renaming 28 | ( primWord64FromNat to nat→word64 29 | ; primWord64ToNat to word64→nat 30 | ) 31 | using () 32 | 33 | instance 34 | Discrete-Word64 : Discrete Word64 35 | Discrete-Word64 = Discrete-inj' _ (P.primWord64ToNatInjective _ _) 36 | ``` 37 | -------------------------------------------------------------------------------- /src/Meta/Alt.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Meta.Alt where 12 | ``` 13 | 14 | ```agda 15 | record Alt (M : Effect) : Typeω where 16 | private module M = Effect M 17 | field 18 | fail : ∀ {ℓ} {A : Type ℓ} → M.₀ A 19 | _<|>_ : ∀ {ℓ} {A : Type ℓ} → M.₀ A → M.₀ A → M.₀ A 20 | 21 | infixl 3 _<|>_ 22 | 23 | open Alt ⦃ ... ⦄ public 24 | 25 | guard 26 | : ∀ {M : Effect} (let module M = Effect M) ⦃ appl : Idiom M ⦄ ⦃ alt : Alt M ⦄ 27 | → Bool → M.₀ ⊤ 28 | guard true = pure tt 29 | guard false = fail 30 | 31 | guardM 32 | : ∀ {M : Effect} (let module M = Effect M) ⦃ mon : Bind M ⦄ ⦃ alt : Alt M ⦄ 33 | → M.₀ Bool → M.₀ ⊤ 34 | guardM M = M >>= guard 35 | ``` 36 | -------------------------------------------------------------------------------- /src/Meta/Append.lagda.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ```agda 8 | module Meta.Append where 9 | ``` 10 | 11 | # Types with concatenation 12 | 13 | ```agda 14 | record Append {ℓ} (A : Type ℓ) : Type ℓ where 15 | infixr 8 _<>_ 16 | 17 | field 18 | mempty : A 19 | _<>_ : A → A → A 20 | 21 | open Append ⦃ ... ⦄ public 22 | ``` 23 | -------------------------------------------------------------------------------- /src/Meta/Bind.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Meta.Bind where 11 | ``` 12 | 13 | # Primitive: `do` syntax 14 | 15 | ```agda 16 | record Bind (M : Effect) : Typeω where 17 | private module M = Effect M 18 | field 19 | _>>=_ : ∀ {ℓ ℓ'} {A : Type ℓ} {B : Type ℓ'} → M.₀ A → (A → M.₀ B) → M.₀ B 20 | ⦃ Idiom-bind ⦄ : Idiom M 21 | 22 | _>>_ : ∀ {ℓ ℓ'} {A : Type ℓ} {B : Type ℓ'} → M.₀ A → M.₀ B → M.₀ B 23 | _>>_ f g = f >>= λ _ → g 24 | 25 | infixl 1 _>>=_ 26 | 27 | _=<<_ : ∀ {ℓ ℓ'} {A : Type ℓ} {B : Type ℓ'} → (A → M.₀ B) → M.₀ A → M.₀ B 28 | _=<<_ f x = x >>= f 29 | 30 | infixr 1 _=<<_ 31 | 32 | open Bind ⦃ ... ⦄ public 33 | ``` 34 | -------------------------------------------------------------------------------- /src/Meta/Brackets.lagda.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ```agda 8 | module Meta.Brackets where 9 | ``` 10 | 11 | # Semantic bracket notation 12 | 13 | In many of our developments (primarily, but not limited to, those in 14 | logic), we have a notion of a type $T$ being a *syntactic presentation* 15 | for some other, *semantic*, type $S$. In keeping with convention, we 16 | want to overload the notation $\sem{e}$ to mean "the semantic value of 17 | $e$." This can be achieved with a simple notation class: 18 | 19 | ```agda 20 | record ⟦⟧-notation {ℓ} (A : Type ℓ) : Typeω where 21 | constructor brackets 22 | field 23 | {lvl} : Level 24 | Sem : Type lvl 25 | ⟦_⟧ : A → Sem 26 | 27 | open ⟦⟧-notation ⦃...⦄ using (⟦_⟧) public 28 | {-# DISPLAY ⟦⟧-notation.⟦_⟧ _ x = ⟦ x ⟧ #-} 29 | ``` 30 | -------------------------------------------------------------------------------- /src/Meta/Foldable.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Meta.Foldable where 12 | ``` 13 | 14 | # Meta: Foldable effects 15 | 16 | ```agda 17 | record Foldable (F : Effect) : Typeω where 18 | private module F = Effect F 19 | field 20 | foldr : ∀ {ℓ ℓ'} {a : Type ℓ} {b : Type ℓ'} → (a → b → b) → b → F.₀ a → b 21 | 22 | open Foldable ⦃ ... ⦄ public 23 | 24 | asum 25 | : ∀ {F M : Effect} ⦃ f : Foldable F ⦄ ⦃ a : Alt M ⦄ {ℓ} {A : Type ℓ} 26 | (let module F = Effect F) (let module M = Effect M) 27 | → F.₀ (M.₀ A) → M.₀ A 28 | asum = foldr _<|>_ fail 29 | 30 | nondet 31 | : ∀ (F : Effect) {M} ⦃ f : Foldable F ⦄ ⦃ t : Map F ⦄ 32 | ⦃ a : Alt M ⦄ ⦃ i : Idiom M ⦄ 33 | {ℓ ℓ'} {A : Type ℓ} {B : Type ℓ'} 34 | → (let module F = Effect F) 35 | → (let module M = Effect M) 36 | → F.₀ A → (A → M.₀ B) → M.₀ B 37 | nondet F ⦃ f = f ⦄ xs k = asum ⦃ f = f ⦄ (k <$> xs) 38 | ``` 39 | -------------------------------------------------------------------------------- /src/Meta/Traversable.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Meta.Traversable where 12 | ``` 13 | 14 | # Meta: Traversable 15 | 16 | The `Traverse`{.Agda} class captures the idea that some containers 17 | "commute with effects", where an effect is anything implementing 18 | `Idiom`{.Agda}: 19 | 20 | ```agda 21 | record Traversable (F : Effect) : Typeω where 22 | private module F = Effect F 23 | field 24 | traverse 25 | : ∀ {ℓ₀ ℓ₁} {M : Effect} ⦃ i : Idiom M ⦄ (let module M = Effect M) 26 | {a : Type ℓ₀} {b : Type ℓ₁} 27 | → (a → M.₀ b) → F.₀ a → M.₀ (F.₀ b) 28 | 29 | for 30 | : ∀ {ℓ₀ ℓ₁} {M : Effect} ⦃ i : Idiom M ⦄ (let module M = Effect M) 31 | {a : Type ℓ₀} {b : Type ℓ₁} 32 | → F.₀ a → (a → M.₀ b) → M.₀ (F.₀ b) 33 | for x f = traverse f x 34 | 35 | open Traversable ⦃ ... ⦄ public 36 | 37 | sequence 38 | : ∀ {M F : Effect} ⦃ _ : Idiom M ⦄ ⦃ _ : Traversable F ⦄ 39 | (let module M = Effect M ; module F = Effect F) {ℓ} 40 | {a : Type ℓ} 41 | → F.₀ (M.₀ a) → M.₀ (F.₀ a) 42 | sequence = traverse id 43 | -------------------------------------------------------------------------------- /src/Order/Diagram/Lub/Subset.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Order.Diagram.Lub.Subset where 15 | ``` 16 | 17 | # Joins of subsets 18 | 19 | Imagine you have a [[poset]] $A$ whose carrier has size $\kappa$, which 20 | furthermore has [[least upper bounds]] for $\kappa$-small families of 21 | elements. But imagine that you have a second universe $\lambda$, and you 22 | have a $\lambda$-small predicate $P : \bb{P}_{\lambda}(A)$. Normally, 23 | you'd be out of luck: there is no reason for $A$ to admit $(\kappa 24 | \sqcup \lambda)$-sized joins. 25 | 26 | But since we've assumed [[propositional resizing]], we can resize 27 | (pointwise) $P$ to be valued in the universe $\kappa$; That way we can 28 | turn the total space $\int P$ into a $\kappa$-small type! By projecting 29 | the first component, we have a $\kappa$-small family of elements, which 30 | has a join. This is a good definition for the **join of the subset 31 | $P$**. 32 | 33 | 45 | 46 | ```agda 47 | opaque 48 | ⋃ˢ : ∀ (P : ⌞ F ⌟ → Ω) → ⌞ F ⌟ 49 | ⋃ˢ P = ⋃ {I = Σ[ t ∈ F ] □ (t ∈ P)} fst 50 | 51 | ⋃ˢ-inj 52 | : ∀ {P : ⌞ F ⌟ → Ω} {x} 53 | → x ∈ P → x ≤ ⋃ˢ P 54 | ⋃ˢ-inj x = P.⋃-inj (_ , (inc x)) 55 | 56 | ⋃ˢ-universal 57 | : ∀ {P : ⌞ F ⌟ → Ω} {x} 58 | → (∀ i → i ∈ P → i ≤ x) 59 | → ⋃ˢ P ≤ x 60 | ⋃ˢ-universal f = P.⋃-universal _ λ (i , w) → f i (□-out! w) 61 | ``` 62 | -------------------------------------------------------------------------------- /src/Order/Instances/Int.lagda.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ```agda 14 | module Order.Instances.Int where 15 | ``` 16 | 17 | 22 | 23 | # The usual ordering on the integers 24 | 25 | This module deals with noting down facts about the usual ordering on the 26 | set of integers. Most of the proofs are in the module 27 | [`Data.Int.Order`](Data.Int.Order.html). 28 | 29 | ```agda 30 | Int-poset : Poset lzero lzero 31 | Int-poset .P.Ob = Int 32 | Int-poset .P._≤_ = _≤_ 33 | Int-poset .P.≤-thin = hlevel 1 34 | Int-poset .P.≤-refl = ≤-refl 35 | Int-poset .P.≤-trans = ≤-trans 36 | Int-poset .P.≤-antisym = ≤-antisym 37 | ``` 38 | 39 | It's worth pointing out that the ordering on integers is a [[decidable 40 | total order]], essentially because the ordering on naturals also is. 41 | 42 | ```agda 43 | Int-is-dec-total : is-decidable-total-order Int-poset 44 | Int-is-dec-total = from-weakly-total (≤-is-weakly-total _ _) 45 | ``` 46 | -------------------------------------------------------------------------------- /src/Order/Instances/Lift.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Order.Instances.Lift where 11 | ``` 12 | 13 | # Lifting posets across universes 14 | 15 | Suppose you have a poset whose elements are in $o$ and relation in 16 | $r$, but you really need it to have elements or relationships 17 | in some larger universe $o \sqcup o'$ and homs in $r \sqcup r'$. 18 | Fortunately you can uniformly lift the poset to this bigger universe. 19 | 20 | ```agda 21 | Liftᵖ : ∀ {o r} o′ r′ → Poset o r → Poset (o ⊔ o′) (r ⊔ r′) 22 | Liftᵖ o' r' X .Poset.Ob = Lift o' ⌞ X ⌟ 23 | Liftᵖ o' r' X .Poset._≤_ x y = Lift r' $ (X .Poset._≤_) (lower x) (lower y) 24 | Liftᵖ o' r' X .Poset.≤-thin = Lift-is-hlevel 1 $ X .Poset.≤-thin 25 | Liftᵖ o' r' X .Poset.≤-refl = lift $ X .Poset.≤-refl 26 | Liftᵖ o' r' X .Poset.≤-trans (lift p) (lift q) = lift (X .Poset.≤-trans p q) 27 | Liftᵖ o' r' X .Poset.≤-antisym (lift p) (lift q) = ap lift (X .Poset.≤-antisym p q) 28 | 29 | Lift-monotone-l 30 | : ∀ {so sr} bo br {o r} {X : Poset so sr} {Y : Poset o r} 31 | → Monotone X Y 32 | → Monotone (Liftᵖ bo br X) Y 33 | Lift-monotone-l bo br G = F where 34 | open Monotone 35 | F : Monotone _ _ 36 | F .hom (lift x) = G .hom x 37 | F .pres-≤ (lift α) = G .pres-≤ α 38 | 39 | Lift-monotone-r 40 | : ∀ {so sr} bo br {o r} {X : Poset so sr} {Y : Poset o r} 41 | → Monotone X Y 42 | → Monotone X (Liftᵖ bo br Y) 43 | Lift-monotone-r bo br G = F where 44 | open Monotone 45 | F : Monotone _ _ 46 | F .hom x = lift $ G .hom x 47 | F .pres-≤ α = lift $ G .pres-≤ α 48 | ``` 49 | -------------------------------------------------------------------------------- /src/Order/Reasoning.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Order.Reasoning {ℓ ℓ'} (P : Poset ℓ ℓ') where 11 | ``` 12 | 13 | # Partial order syntax 14 | 15 | This module defines a syntax for reasoning with transitivity in a 16 | [[partial order]]. Simply speaking, it lets us write chains like 17 | 18 | $$ 19 | a \le b \le c 20 | $$ 21 | 22 | to mean something like "$a \le c$ through the intermediate step $b$". In 23 | the syntax, we intersperse the justification for _why_ $a \le b$ and $b 24 | \le c$. We also allow equality steps, so chains like $a \le b = b' \le 25 | c$ are supported, too. 26 | 27 | ```agda 28 | open Poset P public 29 | 30 | private variable 31 | a b c d : ⌞ P ⌟ 32 | 33 | _≤⟨_⟩_ : (a : ⌞ P ⌟) → a ≤ b → b ≤ c → a ≤ c 34 | _=⟨_⟩_ : (a : ⌞ P ⌟) → a ≡ b → b ≤ c → a ≤ c 35 | _=˘⟨_⟩_ : (a : ⌞ P ⌟) → b ≡ a → b ≤ c → a ≤ c 36 | _≤∎ : (a : ⌞ P ⌟) → a ≤ a 37 | 38 | f ≤⟨ p ⟩ q = ≤-trans p q 39 | f =⟨ p ⟩ q = subst (_≤ _) (sym p) q 40 | f =˘⟨ p ⟩ q = subst (_≤ _) p q 41 | f ≤∎ = ≤-refl 42 | 43 | infixr 2 _=⟨_⟩_ _=˘⟨_⟩_ _≤⟨_⟩_ 44 | infix 3 _≤∎ 45 | ``` 46 | -------------------------------------------------------------------------------- /src/Order/Semilattice/Join/Reasoning.lagda.md: -------------------------------------------------------------------------------- 1 | 18 | 19 | ```agda 20 | module Order.Semilattice.Join.Reasoning 21 | {o ℓ} {P : Poset o ℓ} (slat : is-join-semilattice P) 22 | where 23 | ``` 24 | 25 | # Reasoning about join semilattices 26 | 27 | This module proves some basic facts about [[join semilattices]], and 28 | exposes reasoning combinators for working with them. 29 | 30 | ```agda 31 | open is-join-semilattice slat public 32 | open Order.Reasoning P public 33 | ``` 34 | 35 | The bottom element of a join semilattice is both a left and right 36 | identity element with respect to joins. 37 | 38 | ```agda 39 | ∪-idl : ∀ {x} → bot ∪ x ≡ x 40 | ∪-idl = ≤-antisym (∪-universal _ ¡ ≤-refl) r≤∪ 41 | 42 | ∪-idr : ∀ {x} → x ∪ bot ≡ x 43 | ∪-idr = ≤-antisym (∪-universal _ ≤-refl ¡) l≤∪ 44 | ``` 45 | 46 | Therefore, every join semilattice is a monoid. 47 | 48 | ```agda 49 | ∪-is-monoid : is-monoid bot _∪_ 50 | ∪-is-monoid .has-is-semigroup = ∪-is-semigroup 51 | ∪-is-monoid .idl = ∪-idl 52 | ∪-is-monoid .idr = ∪-idr 53 | 54 | ∪-monoid : Monoid-on ⌞ P ⌟ 55 | ∪-monoid .Monoid-on.identity = bot 56 | ∪-monoid .Monoid-on._⋆_ = _∪_ 57 | ∪-monoid .Monoid-on.has-is-monoid = ∪-is-monoid 58 | 59 | module ∪ = Cat.Reasoning (B ∪-monoid) hiding (Ob) 60 | ``` 61 | -------------------------------------------------------------------------------- /src/Order/Semilattice/Join/Subsemilattice.lagda.md: -------------------------------------------------------------------------------- 1 | 14 | 15 | ```agda 16 | module Order.Semilattice.Join.Subsemilattice where 17 | ``` 18 | 19 | # Subsets of Join Semilattices 20 | 21 | Let $P : A \to \prop$ be a predicate on a [[join semilattice]] $A$. 22 | If $P$ is closed under joins and the bottom element of $A$, then the 23 | [[subposet]] induced by $P$ is also a join semilattice. 24 | 25 | ```agda 26 | module _ {o ℓ} {A : Poset o ℓ} (A-slat : is-join-semilattice A) where 27 | module A = Order.Semilattice.Join.Reasoning A-slat 28 | open is-join-semilattice 29 | open Join 30 | 31 | Subposet-is-join-semilattice 32 | : ∀ {ℓ'} {P : A.Ob → Prop ℓ'} 33 | → (∀ {x y} → x ∈ P → y ∈ P → (x A.∪ y) ∈ P) 34 | → A.bot ∈ P 35 | → is-join-semilattice (Subposet A P) 36 | Subposet-is-join-semilattice {P = P} ∪∈P bot∈P ._∪_ (x , x∈P) (y , y∈P) = record 37 | { fst = x A.∪ y 38 | ; snd = ∪∈P x∈P y∈P 39 | } 40 | Subposet-is-join-semilattice {P = P} ∪∈P bot∈P .∪-joins (x , x∈P) (y , y∈P) = 41 | subposet-has-join _ _ _ (A.∪-joins x y) 42 | Subposet-is-join-semilattice {P = P} ∪∈P bot∈P .has-bottom = 43 | subposet-bottom A.has-bottom bot∈P 44 | ``` 45 | -------------------------------------------------------------------------------- /src/Order/Semilattice/Meet/Reasoning.lagda.md: -------------------------------------------------------------------------------- 1 | 18 | 19 | ```agda 20 | module Order.Semilattice.Meet.Reasoning 21 | {o ℓ} {P : Poset o ℓ} (slat : is-meet-semilattice P) 22 | where 23 | ``` 24 | 25 | # Reasoning about meet semilattices 26 | 27 | This module proves some basic facts about [[meet semilattices]], and 28 | exposes reasoning combinators for working with them. 29 | 30 | ```agda 31 | open Order.Reasoning P public 32 | open is-meet-semilattice slat public 33 | ``` 34 | 35 | The top element of a meet semilattice is both a left and right 36 | identity element with respect to meets. 37 | 38 | ```agda 39 | ∩-idl : ∀ {x} → top ∩ x ≡ x 40 | ∩-idl = ≤-antisym ∩≤r (∩-universal _ ! ≤-refl) 41 | 42 | ∩-idr : ∀ {x} → x ∩ top ≡ x 43 | ∩-idr = ≤-antisym ∩≤l (∩-universal _ ≤-refl !) 44 | ``` 45 | 46 | Therefore, every meet semilattice is a monoid. 47 | 48 | ```agda 49 | ∩-is-monoid : is-monoid top _∩_ 50 | ∩-is-monoid .has-is-semigroup = ∩-is-semigroup 51 | ∩-is-monoid .idl = ∩-idl 52 | ∩-is-monoid .idr = ∩-idr 53 | 54 | ∩-monoid : Monoid-on ⌞ P ⌟ 55 | ∩-monoid .Monoid-on.identity = top 56 | ∩-monoid .Monoid-on._⋆_ = _∩_ 57 | ∩-monoid .Monoid-on.has-is-monoid = ∩-is-monoid 58 | 59 | module ∩ = Cat.Reasoning (B ∩-monoid) hiding (Ob) 60 | ``` 61 | -------------------------------------------------------------------------------- /src/Prim/Data/Bool.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Prim.Data.Bool where 12 | ``` 13 | 14 | # Primitive: Booleans 15 | 16 | The [booleans](Data.Bool.html) are the h-initial type with two inhabitants. 17 | 18 | ```agda 19 | data Bool : Type where 20 | true false : Bool 21 | {-# BUILTIN BOOL Bool #-} 22 | 23 | {-# BUILTIN FALSE false #-} 24 | {-# BUILTIN TRUE true #-} 25 | ``` 26 | -------------------------------------------------------------------------------- /src/Prim/Data/Nat.lagda.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ```agda 12 | module Prim.Data.Nat where 13 | ``` 14 | 15 | # Primitive: Natural numbers 16 | 17 | The [natural numbers](Data.Nat.html) are the h-initial type generated by 18 | a point and an endomorphism. 19 | 20 | ```agda 21 | data Nat : Type where 22 | zero : Nat 23 | suc : Nat → Nat 24 | {-# BUILTIN NATURAL Nat #-} 25 | ``` 26 | 27 | ## Optimised functions on Nat 28 | 29 | Agda lets us define the following functions on natural numbers, which 30 | are computed more efficiently when bound as `BUILTIN`s. 31 | 32 | ```agda 33 | infix 4 _==_ _<_ 34 | infixl 8 _+_ _-_ 35 | infixl 9 _*_ 36 | 37 | _+_ : Nat → Nat → Nat 38 | zero + m = m 39 | suc n + m = suc (n + m) 40 | 41 | {-# BUILTIN NATPLUS _+_ #-} 42 | 43 | _-_ : Nat → Nat → Nat 44 | n - zero = n 45 | zero - suc m = zero 46 | suc n - suc m = n - m 47 | 48 | {-# BUILTIN NATMINUS _-_ #-} 49 | 50 | _*_ : Nat → Nat → Nat 51 | zero * m = zero 52 | suc n * m = m + n * m 53 | 54 | {-# BUILTIN NATTIMES _*_ #-} 55 | 56 | _==_ : Nat → Nat → Bool 57 | zero == zero = true 58 | suc n == suc m = n == m 59 | _ == _ = false 60 | 61 | {-# BUILTIN NATEQUALS _==_ #-} 62 | 63 | _<_ : Nat → Nat → Bool 64 | _ < zero = false 65 | zero < suc _ = true 66 | suc n < suc m = n < m 67 | 68 | {-# BUILTIN NATLESS _<_ #-} 69 | ``` 70 | -------------------------------------------------------------------------------- /src/Prim/Data/Sigma.lagda.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | ```agda 11 | module Prim.Data.Sigma where 12 | ``` 13 | 14 | # Primitives: Sigma types 15 | 16 | The dependent sum type, total space, or type of dependent pairs, is 17 | defined as a record, so that it enjoys definitional η. 18 | 19 | ```agda 20 | record Σ {ℓ ℓ'} (A : Type ℓ) (B : A → Type ℓ') : Type (ℓ ⊔ ℓ') where 21 | constructor _,_ 22 | field 23 | fst : A 24 | snd : B fst 25 | 26 | open Σ public 27 | 28 | {-# BUILTIN SIGMA Σ #-} 29 | 30 | infixr 4 _,_ 31 | ``` 32 | 33 | 46 | 47 | Similarly, for the unit type: 48 | 49 | ```agda 50 | record ⊤ : Type where 51 | instance constructor tt 52 | {-# BUILTIN UNIT ⊤ #-} 53 | ``` 54 | -------------------------------------------------------------------------------- /src/Prim/Extension.lagda.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ```agda 9 | module Prim.Extension where 10 | ``` 11 | 12 | # Primitives: Extension types 13 | 14 | Using the type of `Partial`{.Agda} elements lets us specify maps from 15 | some sub-object of a power of the interval to a type $A$. The _cubical 16 | subtypes_, or extension types, give us the ability to encode that such a 17 | partial element $p$ fits into a commutative diagram 18 | 19 | ~~~{.quiver} 20 | \[\begin{tikzcd} 21 | {\sqcup^n_\varphi} && A \\ 22 | \\ 23 | {\square^n} 24 | \arrow[dashed, from=1-1, to=3-1] 25 | \arrow["p", from=1-1, to=1-3] 26 | \arrow["e", from=3-1, to=1-3] 27 | \end{tikzcd}\] 28 | ~~~ 29 | 30 | where $e$ is an ordinary element of $A$ (with $n$ dimension variables). 31 | Commutativity means that, where $p$ is defined, $e$ agrees with it 32 | definitionally. 33 | 34 | ```agda 35 | {-# BUILTIN SUB _[_↦_] #-} 36 | 37 | postulate 38 | inS : ∀ {ℓ} {A : Type ℓ} {φ} (x : A) → A [ φ ↦ (λ _ → x) ] 39 | 40 | {-# BUILTIN SUBIN inS #-} 41 | 42 | private module X where primitive 43 | primSubOut : ∀ {ℓ} {A : Type ℓ} {φ : I} {u : Partial φ A} → A [ φ ↦ u ] → A 44 | 45 | open X renaming (primSubOut to outS) public 46 | ``` 47 | 48 | Using extension types, we can represent the accurate type of 49 | `primPOr`{.Agda}, where the two partial elements `u` and `v` must agree 50 | on the intersection `i ∧ j`. 51 | 52 | ```agda 53 | partial-pushout 54 | : ∀ {ℓ} (i j : I) {A : Partial (i ∨ j) (Type ℓ)} 55 | {ai : PartialP {a = ℓ} (i ∧ j) (λ { (j ∧ i = i1) → A 1=1 }) } 56 | → (.(z : IsOne i) → A (leftIs1 i j z) [ (i ∧ j) ↦ (λ { (i ∧ j = i1) → ai 1=1 }) ]) 57 | → (.(z : IsOne j) → A (rightIs1 i j z) [ (i ∧ j) ↦ (λ { (i ∧ j = i1) → ai 1=1 }) ]) 58 | → PartialP (i ∨ j) A 59 | partial-pushout i j u v = primPOr i j (λ z → outS (u z)) (λ z → outS (v z)) 60 | ``` 61 | -------------------------------------------------------------------------------- /src/Prim/HCompU.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Prim.HCompU where 11 | ``` 12 | 13 | # Primitive: Composition for universes 14 | 15 | This module binds the operations `prim^glueU`{.Agda} and 16 | `prim^unglueU`{.Agda}, which expose the fibrancy structure of the 17 | universe as being a `Glue`{.Agda}-like type former. Additionally, we 18 | prove `extend-transp-fibre`{.Agda}, which is used internally for 19 | composition in the universe. 20 | 21 | ```agda 22 | primitive 23 | prim^glueU 24 | : {ℓ : Level} {φ : I} {T : I → Partial φ (Type ℓ)} 25 | {A : Type ℓ [ φ ↦ T i0 ]} 26 | → PartialP φ (T i1) → outS A → primHComp T (outS A) 27 | 28 | prim^unglueU 29 | : {ℓ : Level} {φ : I} {T : I → Partial φ (Type ℓ)} 30 | {A : Type ℓ [ φ ↦ T i0 ]} 31 | → primHComp T (outS A) → outS A 32 | 33 | -- Needed for transp. 34 | primFaceForall : (I → I) → I 35 | 36 | extend-transp-fibre 37 | : ∀ {l} (e : I → Type l) (φ : I) 38 | (a : Partial φ (e i0)) 39 | (b : e i1 [ φ ↦ (λ o → transp e i0 (a o)) ]) 40 | → fibre (transp e i0) (outS b) 41 | extend-transp-fibre e φ a b = _ , λ j → 42 | comp e (φ ∨ ∂ j) λ where 43 | i (φ = i1) → coe0→i e i (a 1=1) 44 | i (j = i0) → coe0→i e i (g i1) 45 | i (j = i1) → g (~ i) 46 | i (i = i0) → g i1 47 | where 48 | g : ∀ i → e (~ i) 49 | g k = fill (λ i → e (~ i)) (∂ φ) k λ where 50 | i (φ = i1) → coe0→i e (~ i) (a 1=1) 51 | i (φ = i0) → coe1→i e (~ i) (outS b) 52 | i (i = i0) → outS b 53 | 54 | {-# BUILTIN TRANSPPROOF extend-transp-fibre #-} 55 | ``` 56 | -------------------------------------------------------------------------------- /src/Prim/Kan.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Prim.Kan where 11 | ``` 12 | 13 | # Primitive: Kan operations 14 | 15 | Using the machinery from the other `Prim` modules, we can define the Kan 16 | operations: [transport] and [composition]. 17 | 18 | [transport]: 1Lab.Path.html#transport 19 | [composition]: 1Lab.Path.html#composition 20 | 21 | ```agda 22 | private module X where primitive 23 | primTransp : ∀ {ℓ} (A : (i : I) → Type (ℓ i)) (φ : I) (a : A i0) → A i1 24 | primHComp : ∀ {ℓ} {A : Type ℓ} {φ : I} (u : ∀ i → Partial φ A) (a : A) → A 25 | primComp : ∀ {ℓ} (A : (i : I) → Type (ℓ i)) {φ : I} (u : ∀ i → Partial φ (A i)) (a : A i0) → A i1 26 | 27 | open X public renaming (primTransp to transp) 28 | 29 | hcomp 30 | : ∀ {ℓ} {A : Type ℓ} (φ : I) 31 | → (u : (i : I) → Partial (φ ∨ ~ i) A) 32 | → A 33 | hcomp {A = A} φ u = X.primHComp sys (u i0 1=1) module hcomp-sys where 34 | sys : ∀ j → Partial φ A 35 | sys j (φ = i1) = u j 1=1 36 | 37 | ∂ : I → I 38 | ∂ i = i ∨ ~ i 39 | 40 | comp 41 | : ∀ {ℓ : I → Level} (A : (i : I) → Type (ℓ i)) (φ : I) 42 | → (u : (i : I) → Partial (φ ∨ ~ i) (A i)) 43 | → A i1 44 | comp A φ u = X.primHComp sys (transp (λ i → A i) i0 (u i0 1=1)) module comp-sys where 45 | sys : ∀ j → Partial φ (A i1) 46 | sys i (φ = i1) = transp (λ j → A (i ∨ j)) i (u i 1=1) 47 | ``` 48 | 49 | We also define the type of dependent paths, and of non-dependent paths. 50 | 51 | ```agda 52 | postulate 53 | PathP : ∀ {ℓ} (A : I → Type ℓ) → A i0 → A i1 → Type ℓ 54 | 55 | {-# BUILTIN PATHP PathP #-} 56 | 57 | infix 7 _≡_ 58 | 59 | _≡_ : ∀ {ℓ} {A : Type ℓ} → A → A → Type ℓ 60 | _≡_ {A = A} = PathP (λ i → A) 61 | 62 | {-# BUILTIN PATH _≡_ #-} 63 | ``` 64 | 65 | 82 | -------------------------------------------------------------------------------- /src/Prim/Literals.lagda.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ```agda 10 | module Prim.Literals where 11 | ``` 12 | 13 | # Primitive: Overloaded literals 14 | 15 | We define the records `Number`{.Agda}, `Negative`{.Agda} and 16 | `String`{.Agda} to allow overloading of the numeric literals. 17 | 18 | ```agda 19 | record Number {a} (A : Type a) : Type (lsuc a) where 20 | field 21 | Constraint : Nat → Type a 22 | fromNat : ∀ n → {{_ : Constraint n}} → A 23 | 24 | open Number {{...}} public using (fromNat) 25 | 26 | record Negative {a} (A : Type a) : Type (lsuc a) where 27 | field 28 | Constraint : Nat → Type a 29 | fromNeg : ∀ n → {{_ : Constraint n}} → A 30 | 31 | open Negative {{...}} public using (fromNeg) 32 | 33 | {-# BUILTIN FROMNAT fromNat #-} 34 | {-# DISPLAY Number.fromNat _ n = fromNat n #-} 35 | {-# BUILTIN FROMNEG fromNeg #-} 36 | {-# DISPLAY Negative.fromNeg _ n = fromNeg n #-} 37 | 38 | {-# DISPLAY Number.fromNat _ n = fromNat n #-} 39 | {-# DISPLAY Negative.fromNeg _ n = fromNeg n #-} 40 | 41 | instance 42 | Number-Nat : Number Nat 43 | Number-Nat .Number.Constraint _ = ⊤ 44 | Number-Nat .Number.fromNat n = n 45 | ``` 46 | -------------------------------------------------------------------------------- /src/Prim/Type.lagda.md: -------------------------------------------------------------------------------- 1 | ```agda 2 | module Prim.Type where 3 | ``` 4 | 5 | # Primitives: Sorts 6 | 7 | This module defines bindings for the primitive sorts in Agda. These are 8 | _very magic_ symbols since they bootstrap everything about the type 9 | system. For more details about the use of universes, see 10 | [`1Lab.Type`](1Lab.Type.html). 11 | 12 | ```agda 13 | {-# BUILTIN TYPE Type #-} 14 | {-# BUILTIN SETOMEGA Typeω #-} 15 | 16 | {-# BUILTIN PROP Prop #-} 17 | {-# BUILTIN PROPOMEGA Propω #-} 18 | 19 | {-# BUILTIN STRICTSET SSet #-} 20 | {-# BUILTIN STRICTSETOMEGA SSetω #-} 21 | ``` 22 | 23 | Additionally, we have the `Level` type, of _universe levels_. The 24 | universe levels are an algebra containing 0, closed under successor and 25 | maximum. The difference between this and e.g. the natural numbers is 26 | that `Level` isn't _initial_, i.e. you can't pattern-match on it. 27 | 28 | ```agda 29 | postulate 30 | Level : Type 31 | lzero : Level 32 | lsuc : Level → Level 33 | _⊔_ : Level → Level → Level 34 | infixl 6 _⊔_ 35 | 36 | {-# BUILTIN LEVELUNIV LevelUniv #-} 37 | {-# BUILTIN LEVEL Level #-} 38 | {-# BUILTIN LEVELZERO lzero #-} 39 | {-# BUILTIN LEVELSUC lsuc #-} 40 | {-# BUILTIN LEVELMAX _⊔_ #-} 41 | ``` 42 | -------------------------------------------------------------------------------- /support/check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eo pipefail 4 | 5 | # Slightly hacky script to generate _build/all-pages.agda and check it, 6 | # possibly with a specified version of Agda (use the AGDA environment 7 | # variable). 8 | 9 | unsorted="$(mktemp)" 10 | agda="${AGDA:-agda}" 11 | 12 | if ! type "${agda}" &>/dev/null; then 13 | echo "${agda} is not executable. Either add it to your path or set \$AGDA." 14 | exit 1 15 | else 16 | echo ">>> Checking with ${agda} ($(type "${agda}"))" 17 | fi 18 | 19 | add-module () { 20 | echo "$1" | \ 21 | # Remove the leading `src/`, and turn slashes into dots 22 | sed -re 's@^src/@@;s@/@.@g' | \ 23 | 24 | # Remove the trailing file extension 25 | sed -re 's@(\.lagda\.md|\.agda)$@@' | \ 26 | 27 | # Make this into an import 28 | sed -re 's@^@open import @' >> ${unsorted} 29 | } 30 | 31 | echo ">>> Building _build/all-pages.agda" 32 | 33 | git ls-files --full-name src/ | while IFS='' read file; do 34 | if echo "${file}" | egrep "l?agda(.md)?$" >/dev/null; then 35 | printf '.' 36 | add-module "${file}" 37 | fi 38 | done 39 | 40 | # Sort the all-pages file to mimic what we would get with a proper 41 | # build, call the provided executable. 42 | 43 | printf '\n>>> Checking %s modules\n' "$(wc -l "${unsorted}" | cut -d' ' -f1)" 44 | 45 | sort "${unsorted}" > _build/all-pages.agda 46 | rm "${unsorted}" 47 | 48 | ${AGDA:-agda} _build/all-pages.agda --trace-imports=3 ${AGDAFLAGS} 49 | -------------------------------------------------------------------------------- /support/everything.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "module $(echo "${1}" | sed "sa/a.ag").Everything where" > src/${1}/Everything.agda 4 | 5 | find src/${1} -type f -name '*.lagda.md' | \ 6 | grep -v "Everything" | sort | \ 7 | sed -re 's@src/@@g;s@.lagda.md@@g;s@/@.@g;s@^@open import @g;s@$@ public@g' \ 8 | >> src/${1}/Everything.agda -------------------------------------------------------------------------------- /support/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/favicon.ico -------------------------------------------------------------------------------- /support/make-site.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | rm -rf _build/site 4 | cp _build/html _build/site -rvf 5 | mkdir -p _build/site/static/ _build/site/css 6 | cp /root/static/* _build/site/static/ -rvf 7 | cp /root/css/* _build/site/css -rvf 8 | -------------------------------------------------------------------------------- /support/nix/dep/Agda/default.nix: -------------------------------------------------------------------------------- 1 | # DO NOT HAND-EDIT THIS FILE 2 | import (import ./thunk.nix) -------------------------------------------------------------------------------- /support/nix/dep/Agda/github.json: -------------------------------------------------------------------------------- 1 | { 2 | "owner": "agda", 3 | "repo": "agda", 4 | "branch": "master", 5 | "private": false, 6 | "rev": "3bcf0086b1ac20f6900ba270510b28f0b25406a9", 7 | "sha256": "191mr86zkd402spl66sjwsrq1f9k0l31zwjdw1f04sm61xs5kiwf" 8 | } 9 | -------------------------------------------------------------------------------- /support/nix/dep/Agda/thunk.nix: -------------------------------------------------------------------------------- 1 | # DO NOT HAND-EDIT THIS FILE 2 | let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }: 3 | if !fetchSubmodules && !private then builtins.fetchTarball { 4 | url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256; 5 | } else (import (builtins.fetchTarball { 6 | url = "https://github.com/NixOS/nixpkgs/archive/3aad50c30c826430b0270fcf8264c8c41b005403.tar.gz"; 7 | sha256 = "0xwqsf08sywd23x0xvw4c4ghq0l28w2ki22h0bdn766i16z9q2gr"; 8 | }) {}).fetchFromGitHub { 9 | inherit owner repo rev sha256 fetchSubmodules private; 10 | }; 11 | json = builtins.fromJSON (builtins.readFile ./github.json); 12 | in fetch json -------------------------------------------------------------------------------- /support/nix/dep/nix-thunk/default.nix: -------------------------------------------------------------------------------- 1 | # DO NOT HAND-EDIT THIS FILE 2 | import (import ./thunk.nix) -------------------------------------------------------------------------------- /support/nix/dep/nix-thunk/github.json: -------------------------------------------------------------------------------- 1 | { 2 | "owner": "obsidiansystems", 3 | "repo": "nix-thunk", 4 | "branch": "master", 5 | "private": false, 6 | "rev": "bd0de53129ca4ac5ce313a3e021edf3638a3a22c", 7 | "sha256": "0cn74ylcfr9v2w94jpga9v18jn6zafb9k996afszn59iqlcfi74q" 8 | } 9 | -------------------------------------------------------------------------------- /support/nix/dep/nix-thunk/thunk.nix: -------------------------------------------------------------------------------- 1 | # DO NOT HAND-EDIT THIS FILE 2 | let fetch = { private ? false, fetchSubmodules ? false, owner, repo, rev, sha256, ... }: 3 | if !fetchSubmodules && !private then builtins.fetchTarball { 4 | url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; inherit sha256; 5 | } else (import (builtins.fetchTarball { 6 | url = "https://github.com/NixOS/nixpkgs/archive/3aad50c30c826430b0270fcf8264c8c41b005403.tar.gz"; 7 | sha256 = "0xwqsf08sywd23x0xvw4c4ghq0l28w2ki22h0bdn766i16z9q2gr"; 8 | }) {}).fetchFromGitHub { 9 | inherit owner repo rev sha256 fetchSubmodules private; 10 | }; 11 | json = builtins.fromJSON (builtins.readFile ./github.json); 12 | in fetch json -------------------------------------------------------------------------------- /support/nix/haskell-packages.nix: -------------------------------------------------------------------------------- 1 | pkgs: super: 2 | let 3 | thunkSource = (import ./dep/nix-thunk { inherit pkgs; }).thunkSource; 4 | noJunk = x: pkgs.haskell.lib.overrideCabal x { 5 | doCheck = false; 6 | doHaddock = false; 7 | testHaskellDepends = []; 8 | }; 9 | noProfile = x: pkgs.haskell.lib.overrideCabal x { 10 | enableExecutableProfiling = false; 11 | enableLibraryProfiling = false; 12 | }; 13 | in 14 | { 15 | # Can't just override all Haskell packages because callCabal2nix 16 | # somehow depends on mime-types 17 | labHaskellPackages = super.haskell.packages.ghc946.override (old: { 18 | overrides = self: super: { 19 | Agda = noJunk (super.callCabal2nixWithOptions "Agda" (thunkSource ./dep/Agda) "-f optimise-heavily -f debug" {}); 20 | }; 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /support/nix/nixpkgs.nix: -------------------------------------------------------------------------------- 1 | args: import (builtins.fetchTarball { 2 | name = "1lab-nixpkgs"; 3 | url = "https://github.com/nixos/nixpkgs/archive/6cfbf89825dae72c64188bb218fd4ceca1b6a9e3.tar.gz"; 4 | sha256 = "sha256:17m78fn3y2x44zgdm428k3l6xamyw6vnz2vd68nj5kxlkbfqnynr"; 5 | }) ({ 6 | overlays = [ (import ./haskell-packages.nix) ]; 7 | } // args) 8 | -------------------------------------------------------------------------------- /support/shake/.gitignore: -------------------------------------------------------------------------------- 1 | *.hi 2 | *.o 3 | dist-* 4 | .stack-work 5 | -------------------------------------------------------------------------------- /support/shake/1lab-shake.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: 1lab-shake 3 | version: 0.1.0.0 4 | author: Amélia Liao 5 | maintainer: me@amelia.how 6 | 7 | -- A copyright notice. 8 | -- copyright: 9 | -- category: 10 | extra-source-files: CHANGELOG.md 11 | 12 | common common 13 | build-depends: 14 | base >=4.14.3.0, 15 | aeson, 16 | Agda, 17 | blaze-html, 18 | bytestring, 19 | containers, 20 | deepseq, 21 | directory, 22 | filepath, 23 | mtl, 24 | SHA, 25 | split, 26 | text, 27 | transformers, 28 | unicode-collation, 29 | unordered-containers, 30 | uri-encode, 31 | hashable, 32 | binary, 33 | parsec, 34 | syb, 35 | other-modules: 36 | Agda, 37 | HTML.Backend, 38 | HTML.Base, 39 | HTML.Emit, 40 | Shake.AgdaCompile, 41 | Shake.Git, 42 | Shake.KaTeX, 43 | Shake.LinkGraph, 44 | Shake.LinkReferences, 45 | Shake.Markdown, 46 | Shake.Modules, 47 | Shake.Options, 48 | Shake.SearchData, 49 | Shake.Highlights, 50 | Shake.Utils, 51 | Agda, 52 | Macros, 53 | Timer, 54 | Definitions 55 | default-language: GHC2021 56 | ghc-options: -Wextra -Wall -Wno-name-shadowing -Wno-implicit-prelude 57 | default-extensions: BlockArguments, LambdaCase 58 | 59 | executable shake 60 | import: common 61 | -- putting hs-source-dirs in common confuses hie-bios 62 | hs-source-dirs: app 63 | main-is: Main.hs 64 | build-depends: 65 | citeproc, 66 | doctemplates, 67 | extra, 68 | fsnotify >= 0.4 && < 0.5, 69 | network-uri, 70 | pandoc, 71 | pandoc-types, 72 | process, 73 | shake, 74 | stm, 75 | tagsoup, 76 | other-modules: 77 | HTML.Emit 78 | , Shake.AgdaCompile 79 | , Shake.Diagram 80 | , Shake.Digest 81 | , Shake.Git 82 | , Shake.KaTeX 83 | , Shake.LinkGraph 84 | , Shake.LinkReferences 85 | , Shake.Markdown 86 | , Shake.Modules 87 | , Shake.Options 88 | , Shake.SearchData 89 | , Shake.Utils 90 | , Timer 91 | ghc-options: -j -threaded -with-rtsopts -A128M -rtsopts 92 | -------------------------------------------------------------------------------- /support/shake/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Revision history for shake 2 | 3 | ## 0.1.0.0 -- YYYY-mm-dd 4 | 5 | * First version. Released on an unsuspecting world. 6 | -------------------------------------------------------------------------------- /support/shake/README.md: -------------------------------------------------------------------------------- 1 | # 1lab-shake 2 | 3 | Haskell commands used for building the 1Lab. 4 | 5 | **1lab-shake**: Our Shakefile. (main-is: `Main.hs`) 6 | 7 | -------------------------------------------------------------------------------- /support/shake/app/Agda.hs: -------------------------------------------------------------------------------- 1 | module Agda where 2 | 3 | import Agda.Interaction.Options 4 | import Agda.TypeChecking.Monad 5 | import Control.Monad.IO.Class 6 | import Agda.Utils.FileName 7 | 8 | import System.FilePath 9 | 10 | runAgda :: CommandLineOptions -> (String -> TCMT IO a) -> IO a 11 | runAgda opts k = do 12 | e <- runTCMTop $ do 13 | p <- setupTCM opts 14 | k p 15 | case e of 16 | Left s -> error (show s) 17 | Right x -> pure x 18 | 19 | setupTCM :: CommandLineOptions -> TCMT IO String 20 | setupTCM options = do 21 | file <- case optInputFile options of 22 | Nothing -> error "No input files." 23 | Just x -> liftIO . absolute $ takeDirectory x 24 | 25 | setCommandLineOptions' file options 26 | pure (filePath file) 27 | -------------------------------------------------------------------------------- /support/shake/app/HTML/Emit.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | module HTML.Emit 3 | ( renderHTML5 4 | , overHTML 5 | , checkMarkup 6 | ) where 7 | 8 | import qualified Data.Text as Text 9 | import Data.Text (Text) 10 | import Text.HTML.TagSoup 11 | 12 | import Development.Shake 13 | 14 | -- | Write a HTML file, correctly handling the closing of some tags. 15 | renderHTML5 :: [Tag Text] -> Text 16 | renderHTML5 = renderTagsOptions renderOptions{ optMinimize = min } where 17 | min = flip elem ["br", "meta", "link", "img", "hr"] 18 | 19 | overHTML :: ([Tag Text] -> [Tag Text]) -> Text -> Text 20 | overHTML f = renderHTML5 . f . parseTags 21 | 22 | -- | Check HTML markup is well-formed. 23 | checkMarkup :: FilePath -> Tag Text -> Action () 24 | checkMarkup file (TagText txt) 25 | | "" `Text.isInfixOf` txt || "–>" `Text.isInfixOf` txt 27 | = fail $ "[WARN] " ++ file ++ " contains misplaced " 28 | checkMarkup _ _ = pure () 29 | -------------------------------------------------------------------------------- /support/shake/app/Shake/Digest.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE BlockArguments, GeneralizedNewtypeDeriving, TypeFamilies #-} 2 | 3 | -- | Compute a truncated hash of a file, useful for computing cache-busters 4 | -- (or other unique ids) for a file. 5 | module Shake.Digest (digestRules, getFileDigest) where 6 | 7 | import qualified Data.ByteString.Lazy as LazyBS 8 | import Data.Digest.Pure.SHA 9 | import Data.Typeable 10 | 11 | import Development.Shake.Classes (Hashable, Binary, NFData) 12 | import Development.Shake 13 | 14 | newtype FileDigest = FileDigest FilePath 15 | deriving (Show, Typeable, Eq, Hashable, Binary, NFData) 16 | 17 | type instance RuleResult FileDigest = String 18 | 19 | -- | Shake rules required for computing file digest. 20 | digestRules :: Rules () 21 | digestRules = versioned 1 do 22 | _ <- addOracle \(FileDigest f) -> do 23 | need [f] 24 | take 8 . showDigest . sha256 <$> liftIO (LazyBS.readFile f) 25 | pure () 26 | 27 | -- | Compute a short digest of a file. 28 | getFileDigest :: FilePath -> Action String 29 | getFileDigest = askOracle . FileDigest 30 | -------------------------------------------------------------------------------- /support/shake/app/Shake/Markdown.hs-boot: -------------------------------------------------------------------------------- 1 | module Shake.Markdown where 2 | 3 | import Control.Monad.IO.Class (MonadIO) 4 | import Text.Pandoc.Definition (Pandoc) 5 | 6 | readLabMarkdown :: MonadIO m => FilePath -> m Pandoc 7 | -------------------------------------------------------------------------------- /support/shake/app/Shake/SearchData.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} 2 | 3 | -- | Read and write data for site-wide search. 4 | module Shake.SearchData where 5 | 6 | import Data.Text (Text) 7 | import Data.Aeson 8 | import GHC.Generics (Generic) 9 | 10 | -- | Data about a searchable term. This is designed to be compatible with the 11 | -- type information written by our Agda HTML backend. 12 | data SearchTerm = SearchTerm 13 | { idIdent :: Text 14 | , idAnchor :: Text 15 | , idType :: Maybe Text 16 | , idDefines :: Maybe [Text] 17 | } 18 | deriving (Eq, Show, Ord, Generic, ToJSON, FromJSON) 19 | -------------------------------------------------------------------------------- /support/shake/app/Shake/Utils.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | module Shake.Utils 3 | ( nodeCommand 4 | , readJSONFile 5 | ) where 6 | 7 | import Data.Aeson 8 | 9 | import Development.Shake 10 | 11 | -- | Invoke a Node command. On Nix builds (more generally, if the 12 | -- @NODE_BIN_PATH@ preprocessor macro is set while compiling), this will 13 | -- look for the command in a statically-known path. Otherwise, it'll try 14 | -- from @node_modules/.bin@ or your @PATH@. 15 | nodeCommand :: CmdResult r => [CmdOption] -> String -> [String] -> Action r 16 | #ifdef NODE_BIN_PATH 17 | 18 | nodeCommand opts path = command opts ( NODE_BIN_PATH ++ "/" ++ path ) 19 | 20 | #else 21 | 22 | nodeCommand opts = command (opts ++ [AddPath [] ["node_modules/.bin"]]) 23 | 24 | #endif 25 | 26 | -- | Read and decode JSON from a file, tracking it as a dependency. 27 | readJSONFile :: FromJSON b => FilePath -> Action b 28 | readJSONFile path = need [path] >> liftIO (eitherDecodeFileStrict' path) >>= either fail pure 29 | -------------------------------------------------------------------------------- /support/shake/app/Timer.hs: -------------------------------------------------------------------------------- 1 | -- | A basic profiling library, for timing how long it takes to evaluate an 2 | -- expression. 3 | -- 4 | -- This works a little like Haskell's SCC (Set Cost Center): one uses `timed' or 5 | -- `timedM' to give an expression a label. That expression is then timed and 6 | -- added to the total time for each label. 7 | {-# LANGUAGE BlockArguments #-} 8 | module Timer 9 | ( timedM 10 | , timed 11 | , reportTimes 12 | ) where 13 | 14 | import qualified Data.Map.Strict as Map 15 | import Data.Foldable 16 | import Data.Maybe 17 | import Data.IORef 18 | import Data.Text (Text) 19 | 20 | import Control.Monad.IO.Class 21 | import Control.DeepSeq 22 | import Control.Monad 23 | 24 | import System.IO.Unsafe (unsafePerformIO) 25 | import System.CPUTime 26 | 27 | import Text.Printf 28 | 29 | totalTimers :: IORef (Map.Map Text Integer) 30 | totalTimers = unsafePerformIO (newIORef mempty) 31 | {-# NOINLINE totalTimers #-} 32 | 33 | 34 | -- | Time how long a computation takes to run, forcing the returned expression. 35 | timedM :: (MonadIO m, NFData a) => Text -> m a -> m a 36 | timedM label val = do 37 | start <- liftIO getCPUTime 38 | val <- val 39 | val `deepseq` pure () 40 | end <- liftIO getCPUTime 41 | 42 | let duration = end - start 43 | liftIO $ atomicModifyIORef totalTimers \timers -> 44 | let total = duration + fromMaybe 0 (Map.lookup label timers) 45 | in (Map.insert label total timers, ()) 46 | 47 | pure val 48 | 49 | -- | Time how long an expression takes to fully evaluate. 50 | timed :: NFData a => Text -> a -> a 51 | timed label val = unsafePerformIO (timedM label (pure val)) 52 | {-# NOINLINE timed #-} 53 | 54 | 55 | -- | Print a table of all timings. 56 | reportTimes :: MonadIO m => m () 57 | reportTimes = liftIO do 58 | times <- readIORef totalTimers 59 | unless (Map.null times) (reportTimes times) 60 | 61 | where 62 | formatPico :: Integer -> Float 63 | formatPico x = fromIntegral x * 1e-12 64 | 65 | reportTimes :: Map.Map Text Integer -> IO () 66 | reportTimes times = do 67 | printf "%30s | %10s\n" "Label" "Time (s)" 68 | printf "%30s | %10s\n" (replicate 30 '=') (replicate 10 '=') 69 | 70 | for_ (Map.toList times) \(label, time) -> 71 | printf "%30s | %10.2f\n" label (formatPico time) 72 | -------------------------------------------------------------------------------- /support/static/cube-128x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/static/cube-128x.png -------------------------------------------------------------------------------- /support/static/cube-32x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/static/cube-32x.png -------------------------------------------------------------------------------- /support/static/cube-512x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/static/cube-512x.png -------------------------------------------------------------------------------- /support/static/cube-72x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/static/cube-72x.png -------------------------------------------------------------------------------- /support/static/icons/all-pages.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /support/static/icons/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /support/static/icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /support/static/icons/justified.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /support/static/icons/raggedleft.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /support/static/icons/raggedright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /support/static/icons/serif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /support/static/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /support/static/icons/view-controls.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /support/static/licenses/LICENSE.KaTeX.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2018 Khan Academy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /support/static/licenses/LICENSE.Octicons.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 GitHub Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /support/static/licenses/LICENSE.fast-fuzzy.txt: -------------------------------------------------------------------------------- 1 | Copyright Ethan Rutherford 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /support/static/pfps/amelia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/static/pfps/amelia.png -------------------------------------------------------------------------------- /support/static/pfps/astra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/the1lab/1lab/aafcd46dd4d4cff3bfff260a2decb067d61531ad/support/static/pfps/astra.png -------------------------------------------------------------------------------- /support/web/css/components/commit.scss: -------------------------------------------------------------------------------- 1 | div#recent-additions { 2 | margin-block: 1em; 3 | 4 | :first-child { padding-block-start: 0; } 5 | :last-child { 6 | border-block-end: 0; 7 | padding-block-end: 0; 8 | } 9 | } 10 | 11 | div.commit { 12 | border-inline-start: $left-border-width solid theme(--commit-bg); 13 | padding-inline-start: $left-border-distance; 14 | 15 | display: flex; 16 | flex-direction: column; 17 | gap: 0.5ex; 18 | 19 | margin-block: 0.75em; 20 | 21 | .commit-subject { 22 | font-weight: bold; 23 | width: fit-content; 24 | 25 | &, &:visited, &.hover-highlight { 26 | color: theme(--text-fg); 27 | background-color: theme(--text-bg); 28 | } 29 | } 30 | 31 | .commit-author-date { 32 | font-style: italic; 33 | font-size: 0.8em; 34 | margin-block-start: -0.75ex; 35 | 36 | span { 37 | font-weight: bold; 38 | font-style: normal; 39 | } 40 | } 41 | 42 | .commit-changes { 43 | font-size: 0.8em; 44 | --code-font-size: 0.9em; 45 | hyphenate-character: ''; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /support/web/css/components/modal.scss: -------------------------------------------------------------------------------- 1 | @import "../mixins.scss"; 2 | 3 | $modal-width: 820px; 4 | 5 | .modal { 6 | position: fixed; 7 | width: 100vw; 8 | height: 100vh; 9 | opacity: 0; 10 | transition: all 0.3s ease; 11 | 12 | top: 0; 13 | left: 0; 14 | 15 | display: none; 16 | align-items: center; 17 | justify-content: center; 18 | 19 | z-index: 2; 20 | 21 | &.open { 22 | display: flex; 23 | opacity: 1; 24 | transition-delay: 0s; 25 | background-color: theme(--modal-bg); 26 | backdrop-filter: blur(5px); 27 | } 28 | 29 | &-contents { 30 | width: $modal-width; 31 | height: calc($modal-width * 9 / 16); 32 | max-width: 80%; 33 | 34 | background-color: theme(--text-bg); 35 | padding: 0em; 36 | box-shadow: 2px 2px 6px theme(--shadow); 37 | 38 | text-align: center; 39 | display: flex; 40 | flex-direction: column; 41 | align-items: center; 42 | 43 | > svg { 44 | font-family: 'Inria Sans'; 45 | font-size: 14pt; 46 | width: 100%; 47 | height: 100%; 48 | } 49 | 50 | > h3 { 51 | margin: 0; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /support/web/css/components/popup.scss: -------------------------------------------------------------------------------- 1 | div.hover-popup, div.hover-popup.sourceCode { 2 | &.popup-hidden { display: none; } 3 | @include widescreen { display: block; } 4 | 5 | position: absolute; 6 | z-index: 100; 7 | 8 | color: theme(--code-fg); 9 | background: theme(--code-bg); 10 | 11 | --font-size: 1.125rem; 12 | --code-font-size: 1rem; 13 | 14 | box-shadow: 2px 2px 6px theme(--shadow); 15 | 16 | >:first-child { margin-block-start: 0; } 17 | >:last-child { margin-block-end: 0; } 18 | 19 | padding: 0.3em; 20 | border: 0; 21 | margin: 0; 22 | 23 | &:before { 24 | display: none; 25 | } 26 | } 27 | 28 | .text-popup { 29 | min-width: 22em; 30 | max-width: 26em; 31 | width: min-content; 32 | 33 | margin-left: 1.25em; 34 | } 35 | 36 | 37 | @mixin keyframes-for($dir, $dy) { 38 | @keyframes popup-fade-in-#{$dir} { 39 | 0% { 40 | opacity: 0; 41 | transform: translate(0, $dy); 42 | } 43 | 100% { 44 | opacity: 1; 45 | transform: translate(0, 0); 46 | } 47 | } 48 | 49 | @keyframes popup-fade-out-#{$dir} { 50 | 0% { 51 | opacity: 1; 52 | transform: translate(0, 0); 53 | } 54 | 100% { 55 | opacity: 0; 56 | transform: translate(0, $dy); 57 | } 58 | } 59 | 60 | .popup-fade-in-#{$dir} { animation: 0.3s popup-fade-in-#{$dir}; } 61 | .popup-fade-out-#{$dir} { animation: 0.3s popup-fade-out-#{$dir}; } 62 | } 63 | 64 | @include keyframes-for(up, 10px); 65 | @include keyframes-for(down, -10px); 66 | -------------------------------------------------------------------------------- /support/web/css/components/profile.scss: -------------------------------------------------------------------------------- 1 | div.profile { 2 | display: grid; 3 | grid-template-rows: 1fr; 4 | gap: 1em; 5 | 6 | &.pfp-left { 7 | grid-template-columns: calc(128px + 2em) 1fr; 8 | grid-template-areas: "pfp profile"; 9 | } 10 | &.pfp-right { 11 | grid-template-columns: 1fr calc(128px + 2em); 12 | grid-template-areas: "profile pfp"; 13 | } 14 | 15 | border-top: 2px solid #444; 16 | 17 | padding-top: 0.5em; 18 | padding-bottom: 0.5em; 19 | 20 | .profile-pfp { 21 | grid-column: pfp; 22 | width: 100%; 23 | display: flex; 24 | flex-flow: column nowrap; 25 | align-items: center; 26 | justify-content: center; 27 | } 28 | 29 | .profile-profile { 30 | grid-column: profile; 31 | grid-row: 1; 32 | } 33 | 34 | .profile-pfp p { 35 | display: flex; 36 | flex-flow: column nowrap; 37 | align-items: center; 38 | justify-content: center; 39 | width: 20%; 40 | 41 | img { 42 | width: 128px; 43 | height: 128px; 44 | clip-path: url(#squircle); 45 | margin-bottom: 0.25em; 46 | } 47 | 48 | p { 49 | margin: 0; 50 | } 51 | 52 | .profile-name { 53 | font-size: 19pt; 54 | } 55 | .profile-pronouns { 56 | font-style: italic; 57 | } 58 | } 59 | } 60 | 61 | .author-list { 62 | margin-top: 0.5em; 63 | white-space: initial; 64 | font-size: 0.8em; 65 | font-style: italic; 66 | text-align: center; 67 | } 68 | -------------------------------------------------------------------------------- /support/web/css/components/sidenotes.scss: -------------------------------------------------------------------------------- 1 | span.sidenote-baseline-mark { 2 | width: 0px; 3 | vertical-align: baseline; 4 | display: inline-block; 5 | } 6 | 7 | div.sidenote { 8 | position: absolute; 9 | right: 0; 10 | 11 | :nth-child(2) { margin-block-start: 0; } 12 | :last-child { margin-block-end: 0; } 13 | 14 | font-size: smaller; 15 | --code-font-size: 0.85em; 16 | 17 | width: 100%; 18 | text-align: justify; 19 | hyphens: auto; 20 | 21 | > span.sidenote-number { 22 | position: absolute; 23 | top: -1.5em; 24 | 25 | text-align: right; 26 | width: 100%; 27 | 28 | border-bottom: 1px dotted black; 29 | } 30 | 31 | a.footnote-back { display: none; } 32 | 33 | div.diagram-container img.diagram { 34 | height: calc(0.66 * var(--height)); 35 | } 36 | } 37 | 38 | section.footnotes { 39 | @include widescreen { display: none; } 40 | display: block; 41 | } 42 | 43 | aside#sidenote-container { 44 | @include widescreen { display: block; } 45 | 46 | display: none; 47 | 48 | position: relative; 49 | } 50 | -------------------------------------------------------------------------------- /support/web/css/components/toc.scss: -------------------------------------------------------------------------------- 1 | aside#toc { 2 | @include widescreen { display: flex; } 3 | display: none; 4 | 5 | grid-column: sidebar; 6 | h3 { @include centered-contents; } 7 | 8 | font-family: var(--sans-serif); 9 | --font-size: 1.3rem; 10 | --code-font-size: calc(0.92 * var(--font-size)); 11 | 12 | position: sticky; 13 | 14 | box-sizing: border-box; 15 | top: $page-padding; 16 | 17 | height: calc(100vh - (2 * #{$page-padding})); 18 | 19 | flex-direction: column; 20 | gap: 0.5rem; 21 | max-width: 30ch; 22 | margin-inline-start: auto; 23 | 24 | z-index: 1; 25 | 26 | div#toc-container { 27 | box-sizing: border-box; 28 | overflow-y: auto; 29 | max-height: 80vh; 30 | 31 | display: flex; 32 | flex-direction: column; 33 | gap: 0.5rem; 34 | width: 100%; 35 | } 36 | 37 | a[href]#logo.hover-highlight { 38 | background-color: unset; 39 | } 40 | 41 | a[href].header-link { 42 | &, &:visited { 43 | color: theme(--primary) 44 | }; 45 | 46 | &.current-heading { 47 | font-weight: bold; 48 | color: theme(--text-fg); 49 | } 50 | 51 | .header-link-emoji { display: none; } 52 | } 53 | 54 | hr { 55 | width: 90%; 56 | } 57 | 58 | > svg { 59 | font-family: 'Inria Sans'; 60 | min-height: 150px; 61 | aspect-ratio: 1 / 1; 62 | font-size: 14pt; 63 | } 64 | 65 | ul { 66 | border-left: $ruler-size solid theme(--ruler); 67 | 68 | list-style-type: none; 69 | padding-left: 0.75em; 70 | margin-top: 0; 71 | margin-bottom: 0; 72 | 73 | a { 74 | text-decoration: none; 75 | } 76 | 77 | a:hover { 78 | text-decoration: underline; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /support/web/css/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin left-bordered($bg) { 2 | border-inline-start: $left-border-width solid $bg; 3 | padding-inline-start: $left-border-distance; 4 | 5 | @include widescreen { 6 | position: relative; 7 | 8 | border-inline-start: unset; 9 | padding-inline-start: unset; 10 | 11 | &:before { 12 | content: " "; 13 | background-color: $bg; 14 | 15 | height: 100%; 16 | width: $left-border-width; 17 | 18 | position: absolute; 19 | left: calc(-1 * #{$left-border-distance} - #{$left-border-width}); 20 | } 21 | } 22 | 23 | @at-root div.hover-popup & { 24 | border-inline-start: 0; 25 | padding-inline-start: 0; 26 | 27 | &:before { 28 | display: none; 29 | } 30 | } 31 | } 32 | 33 | @mixin material($bg) { 34 | @include left-bordered($bg); 35 | box-sizing: border-box; 36 | 37 | >:nth-child(1) { margin-block-start: 0; } 38 | >:nth-last-child(1) { margin-block-end: 0; } 39 | 40 | margin-block: 1em; 41 | } 42 | 43 | @mixin highlight($name, $bg, $icon) { 44 | div.#{$name}, span.#{$name}, details.#{$name} { 45 | .highlight-icon { 46 | fill: $icon; 47 | color: $icon; 48 | 49 | display: flex; 50 | gap: 0.5em; 51 | align-items: center; 52 | margin-bottom: 0.3em; 53 | } 54 | } 55 | 56 | div.#{$name}, details.#{$name} { 57 | @include material($bg); 58 | > :nth-child(2) { 59 | margin-block-start: 0.25em; 60 | } 61 | } 62 | } 63 | 64 | @mixin centered-contents { 65 | display: flex; 66 | flex-direction: column; 67 | align-items: center; 68 | } 69 | 70 | @mixin monospaced { 71 | font-family: 'Julia Mono', 'Iosevka', 'Fantasque Sans Mono', 'Roboto Mono', monospace; 72 | font-weight: 500; 73 | font-size: var(--code-font-size); 74 | 75 | font-variant-ligatures: none; 76 | } 77 | 78 | @mixin widescreen { 79 | @media only screen and (min-width: $desktop-layout-width) { 80 | @content; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /support/web/css/vars.scss: -------------------------------------------------------------------------------- 1 | $nav-height: 48px; 2 | $page-padding: 3rem; 3 | 4 | // "Desktop layout": navigation bar, content, sidenotes. 5 | $desktop-layout-width: 95rem; 6 | 7 | // Distance and width between a "left-bordered block" (think
) 8 | // and the actual border. 9 | $left-border-distance: 1em; 10 | $left-border-width: 5px; 11 | 12 | // Size of rulers (e.g.
, border of the navbar list) 13 | $ruler-size: 2px; 14 | -------------------------------------------------------------------------------- /support/web/highlights/note.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /support/web/highlights/source.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /support/web/highlights/terminology.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /support/web/highlights/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | \ 4 | 5 | -------------------------------------------------------------------------------- /support/web/js/code-only.ts: -------------------------------------------------------------------------------- 1 | // This file is included on pages which only have code (and so don't require the 2 | // more advanced features). 3 | 4 | import "./equations"; 5 | import "./highlight-hover"; 6 | import "./search"; 7 | import "./prompt"; 8 | -------------------------------------------------------------------------------- /support/web/js/lib/external.d.ts: -------------------------------------------------------------------------------- 1 | declare module JSX { 2 | type Element = HTMLElement; 3 | interface IntrinsicElements { 4 | [elemName: string]: any; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /support/web/js/lib/jsx.ts: -------------------------------------------------------------------------------- 1 | export type Content = HTMLElement | string | number | Content[] | undefined; 2 | 3 | const add = (element: Node, child: Content) => { 4 | if (typeof child === "string" || typeof child === "number") { 5 | element.appendChild(document.createTextNode(child.toString())); 6 | } else if (child instanceof Array) { 7 | child.forEach((x) => add(element, x)); 8 | } else if (child === undefined || child === null) { 9 | return; 10 | } else { 11 | element.appendChild(child); 12 | } 13 | }; 14 | 15 | type JSXName = string | ((props: T) => Node); 16 | type ElemProps = { [id: string]: string | boolean }; 17 | 18 | export class JSX { 19 | static createTextNode(t: string): Node { 20 | return document.createTextNode(t); 21 | } 22 | 23 | static createElement(fn: (props: T) => Node, props: T, ...content: Content[]): Node; 24 | static createElement(name: string, props: ElemProps, ...content: Content[]): Node; 25 | static createElement>( 26 | name: T, 27 | arg: T extends "string" ? ElemProps : P, 28 | ...content: Content[] 29 | ): Node { 30 | if (typeof name !== "string") { 31 | const elt = name(arg); 32 | for (const c of content) { 33 | add(elt, c); 34 | } 35 | return elt; 36 | } else { 37 | const element = document.createElement(name); 38 | const props = (arg as { [id: string]: string | boolean }) || {}; 39 | 40 | for (const name in props) { 41 | if (name && props.hasOwnProperty(name)) { 42 | let value = props[name]; 43 | if (value === true) { 44 | element.setAttribute(name, name); 45 | } else if (value !== false && value != null) { 46 | element.setAttribute(name, value.toString()); 47 | } 48 | } 49 | } 50 | 51 | for (const c of content) { 52 | add(element, c); 53 | } 54 | return element; 55 | } 56 | } 57 | } 58 | 59 | export default JSX; 60 | -------------------------------------------------------------------------------- /support/web/js/lib/timeout.ts: -------------------------------------------------------------------------------- 1 | class TimeoutCancelled { constructor(public name: string) { } }; 2 | 3 | export class Timeout { 4 | public cancelled: TimeoutCancelled; 5 | 6 | private token?: number; 7 | private reject?: (t: TimeoutCancelled) => void; 8 | public done: boolean = false; 9 | 10 | constructor(private duration: number, public name: string) { 11 | this.cancelled = new TimeoutCancelled(name); 12 | } 13 | 14 | private promise?: Promise 15 | public start(): Promise { 16 | if (this.duration === 0) { 17 | return new Promise((resolve) => resolve()); 18 | } 19 | 20 | if (this.promise) return this.promise; 21 | 22 | return this.promise = new Promise((resolve, reject) => { 23 | this.token = setTimeout(() => { 24 | this.done = true; 25 | resolve(); 26 | }, this.duration); 27 | this.reject = reject; 28 | }) 29 | } 30 | 31 | public cancel() { 32 | if (this.done) 33 | throw "Attempted to cancel a timeout that finished" 34 | 35 | clearTimeout(this.token) 36 | if (this.reject) this.reject(this.cancelled); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /support/web/js/main.ts: -------------------------------------------------------------------------------- 1 | import "./depgraph"; 2 | import "./equations"; 3 | import "./highlight-hover"; 4 | import "./search"; 5 | import "./sidebar"; 6 | import "./prompt"; 7 | import "./theme"; 8 | import "./sidenotes"; 9 | -------------------------------------------------------------------------------- /support/web/js/prompt/sections.tsx: -------------------------------------------------------------------------------- 1 | import { Section } from "./items"; 2 | import { JSX } from "../lib/jsx"; 3 | 4 | export const Miscellanea: Section = new Section(
  • Search results
  • ); 5 | export const InThisPage: Section = new Section(
  • In this page
  • ); 6 | export const Settings: Section = new Section(
  • Settings
  • ); 7 | 8 | export const allSections: Section[] = [ 9 | Settings, 10 | InThisPage, 11 | Miscellanea, 12 | ]; 13 | -------------------------------------------------------------------------------- /support/web/js/sidebar.tsx: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | const headers = Array.from(document.querySelectorAll("article a.header-link")) 3 | .map(x => x.parentElement) 4 | .filter((x): x is HTMLHeadingElement => !!x); 5 | 6 | const headerLinks = Array.from(document.querySelectorAll("aside#toc a.header-link")); 7 | 8 | const findHeader = () => { 9 | let closest = headers[0]; 10 | 11 | for (const header of headers) { 12 | let top = header.getBoundingClientRect().top; 13 | if (top >= 25) break; 14 | closest = header; 15 | }; 16 | 17 | for (const link of headerLinks) { 18 | if (link.getAttribute("href") === `#${closest.getAttribute("id")}`) { 19 | link.classList.add("current-heading"); 20 | } else { 21 | link.classList.remove("current-heading"); 22 | } 23 | } 24 | }; 25 | 26 | let waiting = false; 27 | 28 | document.addEventListener("scroll", () => { 29 | if (!waiting) { 30 | window.requestAnimationFrame(() => { 31 | findHeader(); 32 | waiting = false; 33 | }); 34 | waiting = true; 35 | } 36 | }); 37 | 38 | setTimeout(() => { findHeader() }, 200); 39 | }); 40 | export { }; 41 | -------------------------------------------------------------------------------- /support/web/js/start.ts: -------------------------------------------------------------------------------- 1 | // Much smaller entrypoint file that only knows how to apply the users' 2 | // settings from localStorage. This file compiles to ~1KiB of JS; it's 3 | // totally fine to block on, unlike the ever-growing main.js. 4 | 5 | import { firstLoad } from "./lib/settings"; 6 | 7 | firstLoad(); 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esNext", 4 | "moduleResolution": "node", 5 | "target": "es6", 6 | "lib": ["es2019", "dom"], 7 | "newLine": "LF", 8 | 9 | // Additional compile options 10 | // Ideally we'd set noEmitOnError, but this aborts the rolup build. 11 | "preserveWatchOutput": true, 12 | 13 | // Strict Type-Checking Options 14 | "strict": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "noImplicitReturns": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "verbatimModuleSyntax": true, 20 | "isolatedModules": true, 21 | 22 | "forceConsistentCasingInFileNames": true, 23 | "jsx": "react", 24 | "jsxFactory": "JSX.createElement", 25 | }, 26 | "include": [ 27 | "support/web/js/**/*.ts", "support/web/js/**/*.tsx" 28 | ] 29 | } 30 | --------------------------------------------------------------------------------