Deciding Multiset.Rel for a partial equivalence #
Multiset.Rel r s t holds when the elements of s and t can be matched one-to-one
along r. For a general decidable r this is a bipartite-matching problem, but when r
is symmetric and transitive on the elements involved, the greedy strategy — match each
element of s to the first r-related element of t and discard the pair — is complete.
This file implements the greedy matcher as a Boolean function on lists, proves it decides
Multiset.Rel, and packages the result as a Decidable instance. The matcher recurses
structurally, so the instance reduces in the kernel and concrete goals close by decide.
Main definitions #
List.isPermBy p l₁ l₂: greedy matching ofl₁againstl₂along the Boolean relationp— the algorithm ofList.isPerm, withpin place of==.
Main results #
Multiset.rel_coe_iff_exists:Rel r ↑l₁ ↑l₂iff some reordering ofl₂is componentwiser-related tol₁.List.isPermBy_iff_rel':isPermBy pdecidesMultiset.Rel (p · ·), given symmetry and transitivity ofpon a predicate covering both lists.Multiset.rel_symm_of_symm_on,Multiset.rel_trans_of_trans_on: symmetry and transitivity ofRel rfrom the corresponding properties ofron the members alone.Multiset.Rel.decidableRel:DecidableRel (Rel r)for decidable symmetric transitiver.
Implementation notes #
Core's List.isPerm_iff proves the greedy matcher correct only under LawfulBEq, which
forces p to coincide with equality. The lemmas here assume instead that p is
symmetric and transitive on a predicate P covering the lists' members — the form a
consumer needs when p is defined by recursion and its equivalence properties are only
available beneath a termination bound (see RootedTree/DecEq.lean). The unconditional
Std.Symm/IsTrans version is a corollary.
[UPSTREAM] candidate.
Rel r on coerced lists: some reordering of l₂ is componentwise r-related to
l₁. The list-level reading of Multiset.Rel.
Rel r is symmetric when r is symmetric on the members.
Rel r is transitive when r is transitive on the members.
Greedy matching of l₁ against l₂ along p: pair each element of l₁ with the
first p-related element of l₂, removing it. The algorithm of List.isPerm, with
p in place of ==. Complete for Multiset.Rel (p · ·) when p is symmetric and
transitive on the members (isPermBy_iff_rel').
Equations
- List.isPermBy p [] x✝ = x✝.isEmpty
- List.isPermBy p (a :: l₁) x✝ = match List.findIdx? (p a) x✝ with | some i => List.isPermBy p l₁ (x✝.eraseIdx i) | none => false
Instances For
Soundness of the greedy matcher against Multiset.Rel, hypothesis-free.
isPermBy p is reflexive when p is reflexive on the members.
Completeness of the greedy matcher against Multiset.Rel, given symmetry and
transitivity of p on a predicate P covering both lists.
The greedy matcher decides Multiset.Rel, given symmetry and transitivity of p on
a predicate P covering both lists.
The greedy matcher decides Multiset.Rel for an unconditionally symmetric and
transitive p.
Characterization of the greedy matcher for a symmetric transitive p, the analogue
of List.isPerm_iff: some reordering of l₂ is componentwise p-related to
l₁.
On a lawful BEq, the greedy matcher at (· == ·) decides permutation: isPermBy
generalizes core's List.isPerm (compare List.isPerm_iff).
Multiset.Rel r is decidable, and computably so, for a decidable symmetric
transitive r: decided by the greedy matcher on representatives, which reduces in
the kernel.
Equations
- Multiset.Rel.decidableRel s t = Quotient.recOnSubsingleton₂ s t fun (l₁ l₂ : List α) => decidable_of_iff (List.isPermBy (fun (a b : α) => decide (r a b)) l₁ l₂ = true) ⋯