File: Mathlib/Testing/SlimCheck/Functions.lean

full_name: SlimCheck.TotalFunction
code: /-- Data structure specifying a total function using a list of pairs
and a default value returned when the input is not in the domain of
the partial function.

`withDefault f y` encodes `x ↦ f x` when `x ∈ f` and `x ↦ y`
otherwise.

We use `Σ` to encode mappings instead of `×` because we
rely on the association list API defined in `Mathlib/Data/List/Sigma.lean`.
 -/
inductive TotalFunction (α : Type u) (β : Type v) : Type max u v
  | withDefault : List (Σ _ : α, β) → β → TotalFunction α β
goal: Type (max u v)

full_name: SlimCheck.TotalFunction.withDefault
code: /-- Data structure specifying a total function using a list of pairs
and a default value returned when the input is not in the domain of
the partial function.

`withDefault f y` encodes `x ↦ f x` when `x ∈ f` and `x ↦ y`
otherwise.

We use `Σ` to encode mappings instead of `×` because we
rely on the association list API defined in `Mathlib/Data/List/Sigma.lean`.
 -/
inductive TotalFunction (α : Type u) (β : Type v) : Type max u v
  | withDefault : List (Σ _ : α, β) → β → TotalFunction α β
goal: List ((_ : α) × β) → β → SlimCheck.TotalFunction α β

full_name: SlimCheck.TotalFunction.inhabited
code: instance TotalFunction.inhabited [Inhabited β] : Inhabited (TotalFunction α β) 
goal: Inhabited (SlimCheck.TotalFunction α β)

full_name: SlimCheck.TotalFunction.comp
code: /-- Compose a total function with a regular function on the left -/
def comp {γ : Type w} (f : β → γ) : TotalFunction α β → TotalFunction α γ
  
goal: SlimCheck.TotalFunction α β → SlimCheck.TotalFunction α γ

full_name: SlimCheck.TotalFunction.apply
code: /-- Apply a total function to an argument. -/
def apply [DecidableEq α] : TotalFunction α β → α → β
  
goal: SlimCheck.TotalFunction α β → α → β

full_name: SlimCheck.TotalFunction.reprAux
code: /-- Implementation of `Repr (TotalFunction α β)`.

Creates a string for a given `finmap` and output, `x₀ ↦ y₀, .. xₙ ↦ yₙ`
for each of the entries. The brackets are provided by the calling function.
-/
def reprAux [Repr α] [Repr β] (m : List (Σ _ : α, β)) : String 
goal: String

full_name: SlimCheck.TotalFunction.repr
code: /-- Produce a string for a given `TotalFunction`.
The output is of the form `[x₀ ↦ f x₀, .. xₙ ↦ f xₙ, _ ↦ y]`.
-/
protected def repr [Repr α] [Repr β] : TotalFunction α β → String
  
goal: SlimCheck.TotalFunction α β → String

full_name: SlimCheck.TotalFunction.instRepr
code: instance (α : Type u) (β : Type v) [Repr α] [Repr β] : Repr (TotalFunction α β) 
goal: Repr (SlimCheck.TotalFunction α β)

full_name: SlimCheck.TotalFunction.List.toFinmap'
code: /-- Create a `finmap` from a list of pairs. -/
def List.toFinmap' (xs : List (α × β)) : List (Σ _ : α, β) 
goal: List ((_ : α) × β)

full_name: SlimCheck.TotalFunction.shrink
code: /-- Shrink a total function by shrinking the lists that represent it. -/
def shrink {α β} [DecidableEq α] [Shrinkable α] [Shrinkable β] :
    TotalFunction α β → List (TotalFunction α β)
  
goal: SlimCheck.TotalFunction α β → List (SlimCheck.TotalFunction α β)

full_name: SlimCheck.TotalFunction.Pi.sampleableExt
code: instance Pi.sampleableExt : SampleableExt (α → β) 
goal: SlimCheck.SampleableExt (α → β)

full_name: SlimCheck.TotalFunction.zeroDefault
code: /-- Map a total_function to one whose default value is zero so that it represents a finsupp. -/
@[simp]
def zeroDefault : TotalFunction α β → TotalFunction α β
  
goal: SlimCheck.TotalFunction α β → SlimCheck.TotalFunction α β

full_name: SlimCheck.TotalFunction.zeroDefaultSupp
code: /-- The support of a zero default `TotalFunction`. -/
@[simp]
def zeroDefaultSupp : TotalFunction α β → Finset α
  
goal: SlimCheck.TotalFunction α β → Finset α

full_name: SlimCheck.TotalFunction.applyFinsupp
code: /-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β 
goal: α →₀ β

full_name: SlimCheck.TotalFunction.Finsupp.sampleableExt
code: instance Finsupp.sampleableExt : SampleableExt (α →₀ β) 
goal: SlimCheck.SampleableExt (α →₀ β)

full_name: SlimCheck.TotalFunction.DFinsupp.sampleableExt
code: instance DFinsupp.sampleableExt : SampleableExt (Π₀ _ : α, β) 
goal: SlimCheck.SampleableExt (Π₀ (x : α), β)

full_name: SlimCheck.TotalFunction.PiPred.sampleableExt
code: instance (priority := 2000) PiPred.sampleableExt [SampleableExt (α → Bool)] :
    SampleableExt.{u + 1} (α → Prop) 
goal: SlimCheck.SampleableExt (α → Prop)

full_name: SlimCheck.TotalFunction.PiUncurry.sampleableExt
code: instance (priority := 2000) PiUncurry.sampleableExt [SampleableExt (α × β → γ)] :
    SampleableExt.{imax (u + 1) (v + 1) w} (α → β → γ) 
goal: SlimCheck.SampleableExt (α → β → γ)

full_name: SlimCheck.InjectiveFunction.mapToSelf
code: /-- Data structure specifying a total function using a list of pairs
and a default value returned when the input is not in the domain of
the partial function.

`mapToSelf f` encodes `x ↦ f x` when `x ∈ f` and `x ↦ x`,
i.e. `x` to itself, otherwise.

We use `Σ` to encode mappings instead of `×` because we
rely on the association list API defined in `Mathlib/Data/List/Sigma.lean`.
-/
inductive InjectiveFunction (α : Type u) : Type u
  | mapToSelf (xs : List (Σ _ : α, α)) :
      xs.map Sigma.fst ~ xs.map Sigma.snd → List.Nodup (xs.map Sigma.snd) → InjectiveFunction α
goal: List.map Sigma.fst xs ~ List.map Sigma.snd xs → (List.map Sigma.snd xs).Nodup → SlimCheck.InjectiveFunction α

full_name: SlimCheck.InjectiveFunction
code: /-- Data structure specifying a total function using a list of pairs
and a default value returned when the input is not in the domain of
the partial function.

`mapToSelf f` encodes `x ↦ f x` when `x ∈ f` and `x ↦ x`,
i.e. `x` to itself, otherwise.

We use `Σ` to encode mappings instead of `×` because we
rely on the association list API defined in `Mathlib/Data/List/Sigma.lean`.
-/
inductive InjectiveFunction (α : Type u) : Type u
  | mapToSelf (xs : List (Σ _ : α, α)) :
      xs.map Sigma.fst ~ xs.map Sigma.snd → List.Nodup (xs.map Sigma.snd) → InjectiveFunction α
goal: Type u

full_name: SlimCheck.instInhabitedInjectiveFunction
code: instance : Inhabited (InjectiveFunction α) 
goal: Inhabited (SlimCheck.InjectiveFunction α)

full_name: SlimCheck.InjectiveFunction.apply
code: /-- Apply a total function to an argument. -/
def apply [DecidableEq α] : InjectiveFunction α → α → α
  
goal: SlimCheck.InjectiveFunction α → α → α

full_name: SlimCheck.InjectiveFunction.repr
code: /-- Produce a string for a given `InjectiveFunction`.
The output is of the form `[x₀ ↦ f x₀, .. xₙ ↦ f xₙ, x ↦ x]`.
Unlike for `TotalFunction`, the default value is not a constant
but the identity function.
-/
protected def repr [Repr α] : InjectiveFunction α → String
  
goal: SlimCheck.InjectiveFunction α → String

full_name: SlimCheck.InjectiveFunction.instRepr
code: instance (α : Type u) [Repr α] : Repr (InjectiveFunction α) 
goal: Repr (SlimCheck.InjectiveFunction α)

full_name: SlimCheck.InjectiveFunction.List.applyId
code: /-- Interpret a list of pairs as a total function, defaulting to
the identity function when no entries are found for a given function -/
def List.applyId [DecidableEq α] (xs : List (α × α)) (x : α) : α 
goal: α

full_name: SlimCheck.InjectiveFunction.List.applyId_cons
code: @[simp]
theorem List.applyId_cons [DecidableEq α] (xs : List (α × α)) (x y z : α) :
    List.applyId ((y, z)::xs) x = if y = x then z else List.applyId xs x 
goal: SlimCheck.InjectiveFunction.List.applyId ((y, z) :: xs) x =
  if y = x then z else SlimCheck.InjectiveFunction.List.applyId xs x

full_name: SlimCheck.InjectiveFunction.List.applyId_zip_eq
code: theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs[i]? = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys[i]? = some y 
goal: SlimCheck.InjectiveFunction.List.applyId (xs.zip ys) x = y ↔ ys[i]? = some y

full_name: SlimCheck.InjectiveFunction.applyId_mem_iff
code: theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs 
goal: SlimCheck.InjectiveFunction.List.applyId (xs.zip ys) x ∈ ys ↔ x ∈ xs

full_name: SlimCheck.InjectiveFunction.List.applyId_eq_self
code: theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x 
goal: x ∉ xs → SlimCheck.InjectiveFunction.List.applyId (xs.zip ys) x = x

full_name: SlimCheck.InjectiveFunction.applyId_injective
code: theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) 
goal: Function.Injective (SlimCheck.InjectiveFunction.List.applyId (xs.zip ys))

full_name: SlimCheck.InjectiveFunction.Perm.slice
code: /-- Remove a slice of length `m` at index `n` in a list and a permutation, maintaining the property
that it is a permutation.
-/
def Perm.slice [DecidableEq α] (n m : ℕ) :
    (Σ' xs ys : List α, xs ~ ys ∧ ys.Nodup) → Σ' xs ys : List α, xs ~ ys ∧ ys.Nodup
  
goal: (xs : List α) ×' (ys : List α) ×' xs ~ ys ∧ ys.Nodup → (xs : List α) ×' (ys : List α) ×' xs ~ ys ∧ ys.Nodup

full_name: SlimCheck.InjectiveFunction.sliceSizes
code: /-- A list, in decreasing order, of sizes that should be
sliced off a list of length `n`
-/
def sliceSizes : ℕ → List ℕ+
  
goal: ℕ → List ℕ+

full_name: SlimCheck.InjectiveFunction.shrinkPerm
code: /-- Shrink a permutation of a list, slicing a segment in the middle.

The sizes of the slice being removed start at `n` (with `n` the length
of the list) and then `n / 2`, then `n / 4`, etc down to 1. The slices
will be taken at index `0`, `n / k`, `2n / k`, `3n / k`, etc.
-/
protected def shrinkPerm {α : Type} [DecidableEq α] :
    (Σ' xs ys : List α, xs ~ ys ∧ ys.Nodup) → List (Σ' xs ys : List α, xs ~ ys ∧ ys.Nodup)
  
goal: (xs : List α) ×' (ys : List α) ×' xs ~ ys ∧ ys.Nodup → List ((xs : List α) ×' (ys : List α) ×' xs ~ ys ∧ ys.Nodup)

full_name: SlimCheck.InjectiveFunction.shrink
code: /-- Shrink an injective function slicing a segment in the middle of the domain and removing
the corresponding elements in the codomain, hence maintaining the property that
one is a permutation of the other.
-/
protected def shrink {α : Type} [DecidableEq α] :
    InjectiveFunction α → List (InjectiveFunction α)
  
goal: SlimCheck.InjectiveFunction α → List (SlimCheck.InjectiveFunction α)

full_name: SlimCheck.InjectiveFunction.mk
code: /-- Create an injective function from one list and a permutation of that list. -/
protected def mk (xs ys : List α) (h : xs ~ ys) (h' : ys.Nodup) : InjectiveFunction α 
goal: SlimCheck.InjectiveFunction α

full_name: SlimCheck.InjectiveFunction.injective
code: protected theorem injective [DecidableEq α] (f : InjectiveFunction α) : Injective (apply f) 
goal: Function.Injective f.apply

full_name: SlimCheck.InjectiveFunction.PiInjective.sampleableExt
code: instance PiInjective.sampleableExt : SampleableExt { f : ℤ → ℤ // Function.Injective f } 
goal: SlimCheck.SampleableExt { f // Function.Injective f }

full_name: SlimCheck.Injective.testable
code: instance Injective.testable (f : α → β)
    [I : Testable (NamedBinder "x" <|
      ∀ x : α, NamedBinder "y" <| ∀ y : α, NamedBinder "H" <| f x = f y → x = y)] :
    Testable (Injective f) 
goal: SlimCheck.Testable (Function.Injective f)

full_name: SlimCheck.Monotone.testable
code: instance Monotone.testable [Preorder α] [Preorder β] (f : α → β)
    [I : Testable (NamedBinder "x" <|
      ∀ x : α, NamedBinder "y" <| ∀ y : α, NamedBinder "H" <| x ≤ y → f x ≤ f y)] :
    Testable (Monotone f) 
goal: SlimCheck.Testable (Monotone f)

full_name: SlimCheck.Antitone.testable
code: instance Antitone.testable [Preorder α] [Preorder β] (f : α → β)
    [I : Testable (NamedBinder "x" <|
      ∀ x : α, NamedBinder "y" <| ∀ y : α, NamedBinder "H" <| x ≤ y → f y ≤ f x)] :
    Testable (Antitone f) 
goal: SlimCheck.Testable (Antitone f)