1-- Monotone maps, Galois connections, and closure operators on bundled orders2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Lattice.OrderHom8import Monotone9import CompleteLattice1011-- Maps between bundled orders, as properties of the map and the two12-- ordered sets. A Galois connection is written with its lower adjoint13-- first: l : P → Q is left adjoint to u : Q → P.14predicate MonotoneMap (f P Q : Set) :=15 IsMonotoneMap(f, points(P), le(P), points(Q), le(Q))16predicate AntitoneMap (f P Q : Set) :=17 IsAntitoneMap(f, points(P), le(P), points(Q), le(Q))18predicate GaloisConnection (l u P Q : Set) :=19 IsGaloisConnection(l, points(P), le(P), u, points(Q), le(Q))20predicate ClosureOperator (c P : Set) := IsClosureOperator(c, points(P), le(P))21predicate OrderIso (f P Q : Set) :=22 OrderIsomorphism(f, points(P), le(P), points(Q), le(Q))2324-- A map hypothesis supplies the orders of both of its ordered sets; an25-- operand is placed by its membership in a points or as a value f(a).26notationinfix50"≤"=> Le(P, _, _) viahypothesis MonotoneMap(f, P, Q) for P.points27notationinfix50"≤"=> Le(Q, _, _) viahypothesis MonotoneMap(f, P, Q) for Q.points28notationinfix50"≤"=> Le(P, _, _) viahypothesis AntitoneMap(f, P, Q) for P.points29notationinfix50"≤"=> Le(Q, _, _) viahypothesis AntitoneMap(f, P, Q) for Q.points30notationinfix50"≤"=> Le(P, _, _) viahypothesis GaloisConnection(l, u, P, Q) for P.points31notationinfix50"≤"=> Le(Q, _, _) viahypothesis GaloisConnection(l, u, P, Q) for Q.points32notationinfix50"≤"=> Le(P, _, _) viahypothesis ClosureOperator(c, P) for P.points33notationinfix50"≤"=> Le(P, _, _) viahypothesis OrderIso(f, P, Q) for P.points34notationinfix50"≤"=> Le(Q, _, _) viahypothesis OrderIso(f, P, Q) for Q.points35notationinfixl68"⊔"=> call2(sup(P), _, _) viahypothesis MonotoneMap(f, P, Q) for P.points36notationinfixl68"⊔"=> call2(sup(Q), _, _) viahypothesis MonotoneMap(f, P, Q) for Q.points37notationinfixl69"⊓"=> call2(inf(P), _, _) viahypothesis MonotoneMap(f, P, Q) for P.points38notationinfixl69"⊓"=> call2(inf(Q), _, _) viahypothesis MonotoneMap(f, P, Q) for Q.points3940-- Bridges to the unbundled forms.41instance MonotoneMap.unbundled (f P Q : Set)42requires monotone : MonotoneMap(f, P, Q)43shows IsMonotoneMap(f, points(P), le(P), points(Q), le(Q))44proof45simp [MonotoneMap]4647instance AntitoneMap.unbundled (f P Q : Set)48requires antitone : AntitoneMap(f, P, Q)49shows IsAntitoneMap(f, points(P), le(P), points(Q), le(Q))50proof51simp [AntitoneMap]5253instance GaloisConnection.unbundled (l u P Q : Set)54requires gc : GaloisConnection(l, u, P, Q)55shows IsGaloisConnection(l, points(P), le(P), u, points(Q), le(Q))56proof57simp [GaloisConnection]5859instance ClosureOperator.unbundled (c P : Set)60requires closure : ClosureOperator(c, P)61shows IsClosureOperator(c, points(P), le(P))62proof63simp [ClosureOperator]6465instance OrderIso.unbundled (f P Q : Set)66requires iso : OrderIso(f, P, Q)67shows OrderIsomorphism(f, points(P), le(P), points(Q), le(Q))68proof69simp [OrderIso]7071theorem MonotoneMap.mk (f A r B s : Set)72requires monotone : IsMonotoneMap(f, A, r, B, s)73shows MonotoneMap(f, Order.mk(A, r), Order.mk(B, s))74proof75unfold MonotoneMap76rw [Order.mk.points, Order.mk.le, Order.mk.points, Order.mk.le]77exact monotone7879theorem AntitoneMap.mk (f A r B s : Set)80requires antitone : IsAntitoneMap(f, A, r, B, s)81shows AntitoneMap(f, Order.mk(A, r), Order.mk(B, s))82proof83unfold AntitoneMap84rw [Order.mk.points, Order.mk.le, Order.mk.points, Order.mk.le]85exact antitone8687theorem GaloisConnection.mk (l A r u B s : Set)88requires gc : IsGaloisConnection(l, A, r, u, B, s)89shows GaloisConnection(l, u, Order.mk(A, r), Order.mk(B, s))90proof91unfold GaloisConnection92rw [Order.mk.points, Order.mk.le, Order.mk.points, Order.mk.le]93exact gc9495theorem ClosureOperator.mk (c A r : Set)96requires closure : IsClosureOperator(c, A, r)97shows ClosureOperator(c, Order.mk(A, r))98proof99unfold ClosureOperator100rw [Order.mk.points, Order.mk.le]101exact closure102103theorem OrderIso.mk (f A r B s : Set)104requires iso : OrderIsomorphism(f, A, r, B, s)105shows OrderIso(f, Order.mk(A, r), Order.mk(B, s))106proof107unfold OrderIso108rw [Order.mk.points, Order.mk.le, Order.mk.points, Order.mk.le]109exact iso110111-- Monotone maps112113theorem IsMonotoneMap.function (f P Q : Set)114requires monotone : MonotoneMap(f, P, Q)115shows f : points(P) → points(Q)116proof117exact IsMonotoneMap.function with (MonotoneMap.unbundled with monotone)118119instance MonotoneMap.apply_mem (f P Q : Set) (a ∈ points(P))120requires monotone : MonotoneMap(f, P, Q)121shows f(a) ∈ points(Q)122proof123exact IsMonotoneMap.apply_member with (MonotoneMap.unbundled with monotone), *124125theorem IsAntitoneMap.function (f P Q : Set)126requires antitone : AntitoneMap(f, P, Q)127shows f : points(P) → points(Q)128proof129exact IsAntitoneMap.function with (AntitoneMap.unbundled with antitone)130131section MonotoneLaws132variable (f P Q : Set)133hypothesis monotone : MonotoneMap(f, P, Q)134135theorem MonotoneMap.map_le (a b ∈ points(P))136requires hab : a ≤ b137shows f(a) ≤ f(b)138proof139unfold Le140exact IsMonotoneMap.preserves with (MonotoneMap.unbundled with monotone),141 (Le.relates with hab), *142143theorem MonotoneMap.dual144shows MonotoneMap(f, dual(P), dual(Q))145proof146unfold MonotoneMap147rw [dual.points, dual.le, dual.points, dual.le]148exact IsMonotoneMap.converse with (MonotoneMap.unbundled with monotone)149150end MonotoneLaws151152section AntitoneLaws153variable (f P Q : Set)154hypothesis antitone : AntitoneMap(f, P, Q)155156theorem AntitoneMap.map_le (a b ∈ points(P))157requires hab : a ≤ b158shows f(b) ≤ f(a)159proof160unfold Le161exact IsAntitoneMap.reverses with (AntitoneMap.unbundled with antitone),162 (Le.relates with hab), *163164theorem AntitoneMap.monotone_dual165shows MonotoneMap(f, P, dual(Q))166proof167unfold MonotoneMap168rw [dual.points, dual.le]169exact IsAntitoneMap.monotone_converse with (AntitoneMap.unbundled with antitone)170171end AntitoneLaws172173theorem MonotoneMap.id (P : Set)174shows MonotoneMap(identity(points(P)), P, P)175proof176unfold MonotoneMap177exact IsMonotoneMap.identity at points(P), le(P)178179theorem MonotoneMap.comp (f g P Q R : Set)180requires hf : MonotoneMap(f, P, Q)181requires hg : MonotoneMap(g, Q, R)182shows MonotoneMap(compose(g, f, points(P), points(Q), points(R)), P, R)183proof184unfold MonotoneMap185exact IsMonotoneMap.compose with (MonotoneMap.unbundled with hf),186 (MonotoneMap.unbundled with hg)187188instance OrderIso.monotone_of (f P Q : Set)189requires iso : OrderIso(f, P, Q)190shows MonotoneMap(f, P, Q)191proof192unfold MonotoneMap193exact OrderIsomorphism.monotone with (OrderIso.unbundled with iso)194195-- A monotone map between lattices sends joins above the join of the images196-- and meets below the meet of the images.197section MonotoneLattice198variable (f P Q : Set)199hypothesis monotone : MonotoneMap(f, P, Q)200hypothesis source : Lattice(P)201hypothesis target : Lattice(Q)202203theorem MonotoneMap.map_sup_le (a b ∈ points(P))204shows f(a) ⊔ f(b) ≤ f(a ⊔ b)205proof206have faIn : f(a) ∈ points(Q) := MonotoneMap.apply_mem with*207have fbIn : f(b) ∈ points(Q) := MonotoneMap.apply_mem with*208unfold Le209rw [sup.join, sup.join]210exact IsMonotoneMap.join_le at f, points(P), le(P), points(Q), le(Q), a, b211with (MonotoneMap.unbundled with monotone), *212213theorem MonotoneMap.le_map_inf (a b ∈ points(P))214shows f(a ⊓ b) ≤ f(a) ⊓ f(b)215proof216have faIn : f(a) ∈ points(Q) := MonotoneMap.apply_mem with*217have fbIn : f(b) ∈ points(Q) := MonotoneMap.apply_mem with*218unfold Le219rw [inf.meet, inf.meet]220exact IsMonotoneMap.meet_ge at f, points(P), le(P), points(Q), le(Q), a, b221with (MonotoneMap.unbundled with monotone), *222223end MonotoneLattice224225-- Galois connections226227theorem GaloisConnection.l_function (l u P Q : Set)228requires gc : GaloisConnection(l, u, P, Q)229shows l : points(P) → points(Q)230proof231exact IsGaloisConnection.lower_function with (GaloisConnection.unbundled with gc)232233theorem GaloisConnection.u_function (l u P Q : Set)234requires gc : GaloisConnection(l, u, P, Q)235shows u : points(Q) → points(P)236proof237exact IsGaloisConnection.upper_function with (GaloisConnection.unbundled with gc)238239instance GaloisConnection.l_apply_mem (l u P Q : Set) (a ∈ points(P))240requires gc : GaloisConnection(l, u, P, Q)241shows l(a) ∈ points(Q)242proof243have function := GaloisConnection.l_function with gc244exact FunctionBetween.apply_closed with function, *245246instance GaloisConnection.u_apply_mem (l u P Q : Set) (b ∈ points(Q))247requires gc : GaloisConnection(l, u, P, Q)248shows u(b) ∈ points(P)249proof250have function := GaloisConnection.u_function with gc251exact FunctionBetween.apply_closed with function, *252253section GaloisLaws254variable (l u P Q : Set)255hypothesis gc : GaloisConnection(l, u, P, Q)256hypothesis source : PartialOrder(P)257hypothesis target : PartialOrder(Q)258259theorem GaloisConnection.le_iff_le (a ∈ points(P)) (b ∈ points(Q))260shows l(a) ≤ b ↔ a ≤ u(b)261proof262have adjoint := IsGaloisConnection.adjunction263with (GaloisConnection.unbundled with gc), *264constructor265 . intro h266exact Le.of_relates with (adjoint.forward with (Le.relates with h))267 . intro h268exact Le.of_relates with (adjoint.backward with (Le.relates with h))269270theorem GaloisConnection.le_u_l (a ∈ points(P))271shows a ≤ u(l(a))272proof273unfold Le274exact IsGaloisConnection.unit with (GaloisConnection.unbundled with gc),275 (PartialOrder.unbundled with target), *276277theorem GaloisConnection.l_u_le (b ∈ points(Q))278shows l(u(b)) ≤ b279proof280unfold Le281exact IsGaloisConnection.counit with (GaloisConnection.unbundled with gc),282 (PartialOrder.unbundled with source), *283284theorem GaloisConnection.monotone_l285shows MonotoneMap(l, P, Q)286proof287unfold MonotoneMap288exact IsGaloisConnection.lower_monotone with (GaloisConnection.unbundled with gc),289 (PartialOrder.unbundled with source), (PartialOrder.unbundled with target)290291theorem GaloisConnection.monotone_u292shows MonotoneMap(u, Q, P)293proof294unfold MonotoneMap295exact IsGaloisConnection.upper_monotone with (GaloisConnection.unbundled with gc),296 (PartialOrder.unbundled with source), (PartialOrder.unbundled with target)297298theorem GaloisConnection.l_u_l_eq_l (a ∈ points(P))299shows l(u(l(a))) = l(a)300proof301exact IsGaloisConnection.lower_upper_lower with (GaloisConnection.unbundled with gc),302 (PartialOrder.unbundled with source),303 (PartialOrder.unbundled with target), *304305theorem GaloisConnection.u_l_u_eq_u (b ∈ points(Q))306shows u(l(u(b))) = u(b)307proof308exact IsGaloisConnection.upper_lower_upper with (GaloisConnection.unbundled with gc),309 (PartialOrder.unbundled with source),310 (PartialOrder.unbundled with target), *311312theorem GaloisConnection.l_isLUB (S s : Set)313requires lub : IsLUB(P, S, s)314shows IsLUB(Q, functionImage(l, S, points(Q)), l(s))315proof316unfold IsLUB at lub317unfold IsLUB318exact IsGaloisConnection.lower_supremum with (GaloisConnection.unbundled with gc),319 (PartialOrder.unbundled with source),320 (PartialOrder.unbundled with target), lub321322theorem GaloisConnection.u_isGLB (T t : Set)323requires glb : IsGLB(Q, T, t)324shows IsGLB(P, functionImage(u, T, points(P)), u(t))325proof326unfold IsGLB at glb327unfold IsGLB328exact IsGaloisConnection.upper_infimum with (GaloisConnection.unbundled with gc),329 (PartialOrder.unbundled with source),330 (PartialOrder.unbundled with target), glb331332theorem IsGaloisConnection.closure333shows ClosureOperator(compose(u, l, points(P), points(Q), points(P)), P)334proof335unfold ClosureOperator336exact IsGaloisConnection.closure with (GaloisConnection.unbundled with gc),337 (PartialOrder.unbundled with source), (PartialOrder.unbundled with target)338339end GaloisLaws340341theorem GaloisConnection.id (P : Set)342shows GaloisConnection(identity(points(P)), identity(points(P)), P, P)343proof344unfold GaloisConnection345exact IsGaloisConnection.identity at points(P), le(P)346347theorem GaloisConnection.comp (l u k v P Q R : Set)348requires first : GaloisConnection(l, u, P, Q)349requires second : GaloisConnection(k, v, Q, R)350shows GaloisConnection(compose(k, l, points(P), points(Q), points(R)),351 compose(u, v, points(R), points(Q), points(P)), P, R)352proof353unfold GaloisConnection354exact IsGaloisConnection.compose with (GaloisConnection.unbundled with first),355 (GaloisConnection.unbundled with second)356357-- Closure operators358359theorem IsClosureOperator.function (c P : Set)360requires closure : ClosureOperator(c, P)361shows c : points(P) → points(P)362proof363exact IsClosureOperator.function with (ClosureOperator.unbundled with closure)364365instance ClosureOperator.apply_mem (c P : Set) (a ∈ points(P))366requires closure : ClosureOperator(c, P)367shows c(a) ∈ points(P)368proof369exact IsClosureOperator.apply_member with (ClosureOperator.unbundled with closure),370*371372instance ClosureOperator.monotone_of (c P : Set)373requires closure : ClosureOperator(c, P)374shows MonotoneMap(c, P, P)375proof376unfold MonotoneMap377exact IsClosureOperator.monotone with (ClosureOperator.unbundled with closure)378379section ClosureLaws380variable (c P : Set)381hypothesis closure : ClosureOperator(c, P)382383theorem ClosureOperator.le_closure (a ∈ points(P))384shows a ≤ c(a)385proof386unfold Le387exact IsClosureOperator.extensive with (ClosureOperator.unbundled with closure),388*389390theorem ClosureOperator.closure_closure (a ∈ points(P))391shows c(c(a)) = c(a)392proof393exact IsClosureOperator.idempotent with (ClosureOperator.unbundled with closure),394*395396theorem ClosureOperator.le_closure_iff (a b ∈ points(P))397requires order : PartialOrder(P)398shows a ≤ c(b) ↔ c(a) ≤ c(b)399proof400have characterization := IsClosureOperator.le_iff at c, points(P), le(P), a, b401with (ClosureOperator.unbundled with closure),402 (PartialOrder.unbundled with order), *403constructor404 . intro h405exact Le.of_relates with (characterization.forward with (Le.relates with h))406 . intro h407exact Le.of_relates with (characterization.backward with (Le.relates with h))408409end ClosureLaws410411theorem ClosureOperator.id (P : Set)412requires order : PartialOrder(P)413shows ClosureOperator(identity(points(P)), P)414proof415unfold ClosureOperator416exact IsClosureOperator.identity with (PartialOrder.unbundled with order)417