# Antidiagonal with values in general types #

We define a type class Finset.HasAntidiagonal A which contains a function antidiagonal : A → Finset (A × A) such that antidiagonal n is the finset of all pairs adding to n, as witnessed by mem_antidiagonal.

When A is a canonically ordered add monoid with locally finite order this typeclass can be instantiated with Finset.antidiagonalOfLocallyFinite. This applies in particular when A is ℕ, more generally or σ →₀ ℕ, or even ι →₀ A under the additional assumption OrderedSub A that make it a canonically ordered add monoid. (In fact, we would just need an AddMonoid with a compatible order, finite Iic, such that if a + b = n, then a, b ≤ n, and any finiteness condition would be OK.)

For computational reasons it is better to manually provide instances for ℕ and σ →₀ ℕ, to avoid quadratic runtime performance. These instances are provided as Finset.Nat.instHasAntidiagonal and Finsupp.instHasAntidiagonal. This is why Finset.antidiagonalOfLocallyFinite is an abbrev and not an instance.

This definition does not exactly match with that of Multiset.antidiagonal defined in Mathlib.Data.Multiset.Antidiagonal, because of the multiplicities. Indeed, by counting multiplicities, Multiset α is equivalent to α →₀ ℕ, but Finset.antidiagonal and Multiset.antidiagonal will return different objects. For example, for s : Multiset ℕ := {0,0,0}, Multiset.antidiagonal s has 8 elements but Finset.antidiagonal s has only 4.

def s : Multiset ℕ := {0, 0, 0}
#eval (Finset.antidiagonal s).card -- 4
#eval Multiset.card (Multiset.antidiagonal s) -- 8


## TODO #

• Define HasMulAntidiagonal (for monoids). For PNat, we will recover the set of divisors of a strictly positive integer.
class Finset.HasAntidiagonal (A : Type u_1) [] :
Type u_1

The class of additive monoids with an antidiagonal

• antidiagonal : AFinset (A × A)

The antidiagonal of an element n is the finset of pairs (i, j) such that i + j = n.

• mem_antidiagonal : ∀ {n : A} {a : A × A}, a.1 + a.2 = n

A pair belongs to antidiagonal n iff the sum of its components is equal to n.

Instances
@[simp]
theorem Finset.HasAntidiagonal.mem_antidiagonal {A : Type u_1} [] [self : ] {n : A} {a : A × A} :
a.1 + a.2 = n

A pair belongs to antidiagonal n iff the sum of its components is equal to n.

All HasAntidiagonal instances are equal

Equations
• =
theorem Finset.hasAntidiagonal_congr (A : Type u_2) [] [H1 : ] [H2 : ] :
Finset.antidiagonal = Finset.antidiagonal
theorem Finset.swap_mem_antidiagonal {A : Type u_1} [] {n : A} {xy : A × A} :
xy.swap
@[simp]
theorem Finset.map_prodComm_antidiagonal {A : Type u_1} [] {n : A} :
Finset.map ().toEmbedding =
@[simp]
theorem Finset.map_swap_antidiagonal {A : Type u_1} [] {n : A} :
Finset.map { toFun := Prod.swap, inj' := } =

See also Finset.map_prodComm_antidiagonal.

theorem Finset.antidiagonal_congr {A : Type u_1} [] {p : A × A} {q : A × A} {n : A} (hp : ) (hq : ) :
p = q p.1 = q.1

A point in the antidiagonal is determined by its first coordinate.

See also Finset.antidiagonal_congr'.

theorem Finset.antidiagonal_subtype_ext {A : Type u_1} [] {n : A} {p : { x : A × A // }} {q : { x : A × A // }} (h : (p).1 = (q).1) :
p = q

A point in the antidiagonal is determined by its first co-ordinate (subtype version of Finset.antidiagonal_congr). This lemma is used by the ext tactic.

theorem Finset.antidiagonal_congr' {A : Type u_1} {p : A × A} {q : A × A} {n : A} (hp : ) (hq : ) :
p = q p.2 = q.2

A point in the antidiagonal is determined by its second coordinate.

See also Finset.antidiagonal_congr.

@[simp]
theorem Finset.antidiagonal_zero {A : Type u_1} :
= {(0, 0)}
theorem Finset.antidiagonal.fst_le {A : Type u_1} {n : A} {kl : A × A} (hlk : ) :
kl.1 n
theorem Finset.antidiagonal.snd_le {A : Type u_1} {n : A} {kl : A × A} (hlk : ) :
kl.2 n
theorem Finset.filter_fst_eq_antidiagonal {A : Type u_1} [Sub A] [] [ContravariantClass A A (fun (x x_1 : A) => x + x_1) fun (x x_1 : A) => x x_1] (n : A) (m : A) [DecidablePred fun (x : A) => x = m] [Decidable (m n)] :
Finset.filter (fun (x : A × A) => x.1 = m) = if m n then {(m, n - m)} else
theorem Finset.filter_snd_eq_antidiagonal {A : Type u_1} [Sub A] [] [ContravariantClass A A (fun (x x_1 : A) => x + x_1) fun (x x_1 : A) => x x_1] (n : A) (m : A) [DecidablePred fun (x : A) => x = m] [Decidable (m n)] :
Finset.filter (fun (x : A × A) => x.2 = m) = if m n then {(n - m, m)} else
@[simp]
theorem Finset.sigmaAntidiagonalEquivProd_symm_apply_fst {A : Type u_1} [] (x : A × A) :
(Finset.sigmaAntidiagonalEquivProd.symm x).fst = x.1 + x.2
@[simp]
theorem Finset.sigmaAntidiagonalEquivProd_symm_apply_snd_coe {A : Type u_1} [] (x : A × A) :
(Finset.sigmaAntidiagonalEquivProd.symm x).snd = x
@[simp]
theorem Finset.sigmaAntidiagonalEquivProd_apply {A : Type u_1} [] (x : (n : A) × { x : A × A // }) :
Finset.sigmaAntidiagonalEquivProd x = x.snd
def Finset.sigmaAntidiagonalEquivProd {A : Type u_1} [] :
(n : A) × { x : A × A // } A × A

The disjoint union of antidiagonals Σ (n : A), antidiagonal n is equivalent to the product A × A. This is such an equivalence, obtained by mapping (n, (k, l)) to (k, l).

Equations
• One or more equations did not get rendered due to their size.
Instances For
@[reducible, inline]

In a canonically ordered add monoid, the antidiagonal can be construct by filtering.

Note that this is not an instance, as for some times a more efficient algorithm is available.

Equations
• One or more equations did not get rendered due to their size.
Instances For