The flat order #
Flat α is Option α with the flat order: ⊥ below everything, distinct
values incomparable. It is the lift of the discrete order on α — the order
of partial values under extension — and is mathlib's order on Part α
carried on its decidable twin Option (le_iff_ofOption_le), where it
supports DecidableEq, DecidableLE, #eval, and constructor
pattern-matching. "Flat domain" is the domain-theory name for this poset
([Win93]; the flat class of Isabelle/HOLCF).
The flat order is bounded-complete but not a lattice: meets are total
(SemilatticeInf), joins partial (PartialUnify). It is ω-complete
(OmegaCompletePartialOrder), every chain being eventually constant.
Linguistically it is one atomic feature slot, ordered by [Shi86]'s and
[Car92]'s subsumption; Flat Bool is the knowledge order of Kleene
three-valued logic. Feature bundles arise via the Pi PartialUnify
instance, with Compat as consistency.
The order skeleton follows the WithBot mold (Mathlib/Order/TypeTags.lean,
Mathlib/Order/WithBot.lean) and is an [UPSTREAM] candidate for
Mathlib/Order/Flat.lean, coexisting with the namespaced Module.Flat and
ConvexCone.Flat. The PartialUnify instance and compat_iff stay here.
Main declarations #
Flat— the order-carrying alias, with coercion↑ : α → Flat α, andPartialOrder,OrderBot,SemilatticeInf,OmegaCompletePartialOrder, andPartialUnifyinstancesFlat.coe_le_coe,Flat.not_coe_le_bot— the order, characterizedFlat.or— left-biased total merge, withle_or_left/or_leFlat.ωSup_mem_range— chains attain their supremum (the domain has height ≤ 2)Flat.ωScottContinuous_of_monotone— monotone maps out ofFlatare continuousFlat.liftEquiv— the free-domain universal property: functionsα → Dare exactly strict continuous mapsFlat α →𝒄 DFlat.compat_iff— slot compatibility (Compat), characterizedFlat.unify_distinct_eq_none— distinct atoms do not unify (the non-distributivity witness)
TODO #
The free-domain universal property is now liftEquiv (with its enabling lemma
ωScottContinuous_of_monotone). The remaining domain-theoretic program:
- Categorical freeness. Package
liftEquivas a free–forgetful adjunction betweenTypeand the pointedωCPOcategory —Flat ⊣ U(template: mathlib'slatToBddLatForgetAdjunction, the free bounded lattice viaWithBot). - Lifting monad. Give
Flat(=Option) its ω-CPO monad structure — the partiality/lifting monad — whose Kleisli arrowsα → Flat βare partial continuous functions;PartialUnify.unifyis one, which is why it composes throughOption.bind(unify_assoc). (mathlib has this forPart.) - Algebraicity / bounded-completeness. Every element of
Flat αis compact, making it an algebraic (finite-height) bounded-complete domain — the Scott-domain packaging of the partial joinPartialUnifyprovides. - Three-valued logic.
Flat Boolis the knowledge order of Kleene three-valued logic; the strong-Kleene connectives are exactly its continuous maps. Connects this substrate to the trivalence/presupposition layer. - An inductive
Flat.LTin theWithBot.LTmold, for upstreaming.
Equations
- Flat.inhabited = { default := ⊥ }
Equations
Equations
- Flat.instBEq = { beq := Flat.instBEq._aux_1 }
Equations
- Flat.instRepr = { reprPrec := fun (o : Flat α) (x : ℕ) => match o with | none => Std.Format.text "⊥" | some a => Std.Format.text "↑" ++ repr a }
Recursor for Flat using the preferred forms ⊥ and ↑a.
Equations
- Flat.recBotCoe bot coe none = bot
- Flat.recBotCoe bot coe (some a) = coe a
Instances For
The flat order #
The flat order on Flat α, defined by ⊥ ≤ x and ↑a ≤ ↑a. The
definition as an inductive predicate follows WithBot.LE; it cannot be
accidentally unfolded too far.
Equations
- Flat.instLE = { le := Flat.LE }
Equations
- Flat.instOrderBot = { toBot := Flat.bot, bot_le := ⋯ }
Equations
- Flat.instPartialOrder = { toLE := Flat.instLE, lt := fun (a b : Flat α) => a ≤ b ∧ ¬b ≤ a, le_refl := ⋯, le_trans := ⋯, lt_iff_le_not_ge := ⋯, le_antisymm := ⋯ }
Equations
- Flat.instDecidableLEOfDecidableEq none x✝ = isTrue ⋯
- Flat.instDecidableLEOfDecidableEq (some a) none = isFalse ⋯
- Flat.instDecidableLEOfDecidableEq (some a) (some b) = decidable_of_iff' (a = b) ⋯
Left-biased merge #
Meets #
Equations
- Flat.instSemilatticeInfOfDecidableEq = { toPartialOrder := Flat.instPartialOrder, inf := Flat.inf, inf_le_left := ⋯, inf_le_right := ⋯, le_inf := ⋯ }
The flat domain is ω-complete #
A monotone chain in the flat order is eventually constant — ⊥ until it
(optionally) commits to a single value, then constant — so it has a
supremum. This is the flat domain, the canonical nontrivial example of an
OmegaCompletePartialOrder.
The flat domain is an OmegaCompletePartialOrder: chains are eventually
constant, so their suprema are the eventual value (or ⊥).
Equations
- Flat.instOmegaCompletePartialOrder = { toPartialOrder := Flat.instPartialOrder, ωSup := Flat.ωSupImpl✝, le_ωSup := ⋯, ωSup_le := ⋯ }
Chains in the flat domain attain their supremum — ωSup c is some c i:
the domain has height ≤ 2.
Every monotone map out of the flat domain is ωScottContinuous: chains
attain their suprema (ωSup_mem_range), so continuity is automatic. This is
the key fact behind the universal property liftEquiv.
The flat domain is free: functions α → D into a pointed domain are
exactly the strict continuous maps Flat α →𝒄 D. The forward map extends by
⊥ ↦ ⊥, continuous by ωScottContinuous_of_monotone; the inverse
precomposes with ↑.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Unification #
Unification of two slots merges equal commitments, treats ⊥ as
identity, and fails on distinct commitments.
Equations
- Flat.unify none y = some y
- Flat.unify (some a) none = some ↑a
- Flat.unify (some a) (some b) = if a = b then some ↑a else none
Instances For
Equations
- Flat.instPartialUnifyOfDecidableEq = { unify := Flat.unify, isLUB_of_unify_eq_some := ⋯, isSome_unify_of_bddAbove := ⋯ }
Two slots are compatible exactly when their committed values coincide; an uncommitted slot is a wildcard.
On compatible slots, unification is the priority union: agreeing
commitments collapse and ⊥ defers, so the biased and unbiased merges
coincide.
Non-distributivity #
The flat order is not distributive: three distinct atoms (with a top
adjoined) form the diamond M₃ — [Car92] takes subsumption orders
to be neither distributive nor modular in general. Flat carries only the
partial join (PartialUnify), so the distributive law cannot even be
stated on it directly; unify_distinct_eq_none is the witness — distinct
atoms have no upper bound, so the join the law would require is undefined.