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). 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,SemilatticeInfandPartialUnifyinstancesFlat.coe_le_coe,Flat.not_coe_le_bot— the order, characterizedFlat.covBy_iff— the covers, from⊥to a committed value: the order has height oneFlat.coe_inf_coe,Flat.disjoint_coe_coe,Flat.compat_coe_coe— the meet, disjointness and compatibility of committed slotsFlat.unbotD— the value, or a default at⊥, asWithBot.unbotDFlat.or— left-biased total merge, withle_or_left/or_leFlat.compat_iff— slot compatibility (Compat), characterizedFlat.unify_eq_top_of_ne— distinct atoms do not unify (the non-distributivity witness)
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 value of an element, or the default d at ⊥, as WithBot.unbotD.
Equations
- Flat.unbotD d x = Flat.recBotCoe d id x
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 := ⋯ }
A value is maximal: nothing lies above it but itself.
Every value other than ⊥ is maximal.
Equations
- Flat.instDecidableLEOfDecidableEq none x✝ = isTrue ⋯
- Flat.instDecidableLEOfDecidableEq (some a) none = isFalse ⋯
- Flat.instDecidableLEOfDecidableEq (some a) (some b) = decidable_of_iff' (a = b) ⋯
A flat inequality with no definedness gain is an equality.
Covering #
The flat order has height one: its covers are the steps from ⊥ to a committed value.
The flat order is Part's order, along Part.ofOption.
Left-biased merge #
Meets #
Equations
- Flat.instSemilatticeInfOfDecidableEq = { toPartialOrder := Flat.instPartialOrder, inf := Flat.inf, inf_le_left := ⋯, inf_le_right := ⋯, le_inf := ⋯ }
Two committed slots are disjoint exactly when they disagree.
Two committed slots are compatible exactly when they agree.
Equations
- Flat.instDecidableDisjointOfDecidableEq = decidable_of_iff (x ⊓ y = ⊥) ⋯
Unification #
Unification of two slots merges equal commitments, treats ⊥ as
identity, and fails on distinct commitments.
Equations
- Flat.unify none x✝ = ↑x✝
- Flat.unify (some a) none = ↑↑a
- Flat.unify (some a) (some b) = if a = b then ↑↑a else ⊤
Instances For
Equations
- Flat.instPartialUnifyOfDecidableEq = { unify := Flat.unify, isLUB_of_unify_eq_coe := ⋯, unify_ne_top_of_bddAbove := ⋯ }
Two slots are compatible exactly when their committed values coincide; an uncommitted slot is a wildcard.
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_eq_top_of_ne is the witness — distinct
atoms have no upper bound, so the join the law would require is undefined.