Partial unification #
PartialUnify α equips a partial order with a partial join: unify a b is the least upper
bound of {a, b} when the pair is bounded above, and ⊤ otherwise. This is the pairwise face of
bounded completeness, Carpenter's setting for unification domains, in which an inheritance
hierarchy is a finite bounded complete partial order and joins are unifications. Adjoining a top
element, the inconsistent description, makes the join total, as Aït-Kaci and Smolka do in
Carpenter's account: WithTop α is a join-semilattice whose join of two coerced elements is their
unification, and the laws of unification, idempotence, commutativity, associativity with failure
propagating, ⊥ as identity and monotonicity, are the semilattice laws read through the
coercion. A carrier supplies only unify and the two axioms. The semilattice is a scoped
instance, since a carrier that is already a semilattice would otherwise give WithTop α a second
join.
Main declarations #
PartialUnify: the class.PartialUnify.isLUB_unify:unify a bis the join of↑aand↑binWithTop α.PartialUnify.semilatticeSup: the scoped join-semilattice onWithTop α.PartialUnify.unify_eq_coe_iff_isLUB,PartialUnify.unify_eq_top_iff: success and failure, characterized.PartialUnify.unify_comm,PartialUnify.unify_assoc,PartialUnify.unify_self,PartialUnify.bot_unify,PartialUnify.unify_mono: the unification laws.Compat: the consistency relation, a common upper bound.- The Pi instance: pointwise unification over a
Fintypeindex.
Implementation notes #
mem_upperBounds_pair, WithTop.decidableEqTop, WithTop.isLUB_image_coe_iff and
WithTop.isLUB_image_coe_top_iff are rungs of mathlib's bounds and WithTop API that the class
needs and mathlib lacks. [UPSTREAM]
References #
Bounds of pairs and of coerced sets #
Whether an element of WithTop α is ⊤ is decidable without decidable equality on α.
Equations
- x.decidableEqTop = WithTop.recTopCoe (isTrue ⋯) (fun (x : α) => isFalse ⋯) x
A coerced element is the least upper bound of a set of coerced elements iff it is the least upper bound of the set.
⊤ is the least upper bound of a set of coerced elements iff the set is unbounded.
The class #
A partial join on a partial order, where unify a b is the least upper bound of {a, b}
when the pair is bounded above and ⊤ otherwise.
- unify : α → α → WithTop α
The partial join,
⊤on an unbounded pair. - isLUB_of_unify_eq_coe {a b c : α} : unify a b = ↑c → IsLUB {a, b} c
A successful unification is a least upper bound.
- unify_ne_top_of_bddAbove {a b : α} : BddAbove {a, b} → unify a b ≠ ⊤
Unification succeeds on bounded pairs.
Instances
unify a b is the join of ↑a and ↑b in WithTop α.
The join-semilattice with failure adjoined #
The join on WithTop α that unification computes, ⊤ absorbing.
Equations
- PartialUnify.sup (some a) (some b) = PartialUnify.unify a b
- PartialUnify.sup x✝¹ x✝ = ⊤
Instances For
Unification presents WithTop α as a join-semilattice with ⊤ as the failure of
unification. The instance is scoped: a carrier that is already a semilattice would otherwise
give WithTop α a second join.
Equations
- PartialUnify.semilatticeSup = SemilatticeSup.ofIsLUB PartialUnify.sup ⋯
Instances For
Unification is associative, with failure propagating.
Unification is monotone where defined, so shrinking both inputs preserves success and shrinks the output.
Pointwise unification on Pi types #
Unification is pointwise, so a bundle unifies when every coordinate does.
Equations
- One or more equations did not get rendered due to their size.
Compatibility #
The consistency relation of unification: two elements are compatible when they have a common upper bound, equivalently when they unify. On feature carriers this is the agreement relation of Carpenter and Shieber.
A common upper bound witnesses compatibility.
Compatibility persists downward.
⊥ is a wildcard, compatible with everything.
Where every element other than ⊥ is maximal, two elements are incompatible exactly when
both are present and distinct.
Equations
- instDecidableCompatOfPartialUnify a b = decidable_of_iff (PartialUnify.unify a b ≠ ⊤) ⋯