Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".
Project: Xena
Views: 18536License: APACHE
/- Copyright (c) 2019 Yury Kudryashov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov -/ import order.filter.basic logic.relator tactic.alias /-! # Minimum and maximum w.r.t. a filter and on a aet ## Main Definitions This file defines six predicates of the form `is_A_B`, where `A` is `min`, `max`, or `extr`, and `B` is `filter` or `on`. * `is_min_filter f l a` means that `f a ≤ f x` in some `l`-neighborhood of `a`; * `is_max_filter f l a` means that `f x ≤ f a` in some `l`-neighborhood of `a`; * `is_extr_filter f l a` means `is_min_filter f l a` or `is_max_filter f l a`. Similar predicates with `_on` suffix are particular cases for `l = principal s`. ## Main statements ### Change of the filter (set) argument * `is_*_filter.filter_mono` : replace the filter with a smaller one; * `is_*_filter.filter_inf` : replace a filter `l` with `l ⊓ l'`; * `is_*_on.on_subset` : restrict to a smaller set; * `is_*_on.inter` : replace a set `s` wtih `s ∩ t`. ### Composition * `is_*_*.comp_mono` : if `x` is an extremum for `f` and `g` is a monotone function, then `x` is an extremum for `g ∘ f`; * `is_*_*.comp_antimono` : similarly for the case of monotonically decreasing `g`; * `is_*_*.bicomp_mono` : if `x` is an extremum of the same type for `f` and `g` and a binary operation `op` is monotone in both arguments, then `x` is an extremum of the same type for `λ x, op (f x) (g x)`. * `is_*_filter.comp_tendsto` : if `g x` is an extremum for `f` w.r.t. `l'` and `tendsto g l l'`, then `x` is an extremum for `f ∘ g` w.r.t. `l`. * `is_*_on.on_preimage` : if `g x` is an extremum for `f` on `s`, then `x` is an extremum for `f ∘ g` on `g ⁻¹' s`. ### Algebraic operations * `is_*_*.add` : if `x` is an extremum of the same type for two functions, then it is an extremum of the same type for their sum; * `is_*_*.neg` : if `x` is an extremum for `f`, then it is an extremum of the opposite type for `-f`; * `is_*_*.sub` : if `x` is an a minimum for `f` and a maximum for `g`, then it is a minimum for `f - g` and a maximum for `g - f`; * `is_*_*.max`, `is_*_*.min`, `is_*_*.sup`, `is_*_*.inf` : similarly for `is_*_*.add` for pointwise `max`, `min`, `sup`, `inf`, respectively. ### Miscellaneous definitions * `is_*_*_const` : any point is both a minimum and maximum for a constant function; * `is_min/max_*.is_ext` : any minimum/maximum point is an extremum; * `is_*_*.dual`, `is_*_*.undual`: conversion between codomains `α` and `dual α`; ## Missing features (TODO) * Multiplication and division; * `is_*_*.bicompl` : if `x` is a minimum for `f`, `y` is a minimum for `g`, and `op` is a monotone binary operation, then `(x, y)` is a minimum for `uncurry' (bicompl op f g)`. From this point of view, `is_*_*.bicomp` is a composition * It would be nice to have a tactic that specializes `comp_(anti)mono` or `bicomp_mono` based on a proof of monotonicity of a given (binary) function. The tactic should maintain a `meta` list of known (anti)monotone (binary) functions with their names, as well as a list of special types of filters, and define the missing lemmas once one of these two lists grows. -/ universes u v w x variables {α : Type u} {β : Type v} {γ : Type w} {δ : Type x} open set lattice filter section preorder variables [preorder β] [preorder γ] variables (f : α → β) (s : set α) (l : filter α) (a : α) /-! ### Definitions -/ /-- `is_min_filter f l a` means that `f a ≤ f x` in some `l`-neighborhood of `a` -/ def is_min_filter : Prop := ∀ᶠ x in l, f a ≤ f x /-- `is_max_filter f l a` means that `f x ≤ f a` in some `l`-neighborhood of `a` -/ def is_max_filter : Prop := ∀ᶠ x in l, f x ≤ f a /-- `is_extr_filter f l a` means `is_min_filter f l a` or `is_max_filter f l a` -/ def is_extr_filter : Prop := is_min_filter f l a ∨ is_max_filter f l a /-- `is_min_on f s a` means that `f a ≤ f x` for all `x ∈ a`. Note that we do not assume `a ∈ s`. -/ def is_min_on := is_min_filter f (principal s) a /-- `is_max_on f s a` means that `f x ≤ f a` for all `x ∈ a`. Note that we do not assume `a ∈ s`. -/ def is_max_on := is_max_filter f (principal s) a /-- `is_extr_on f s a` means `is_min_on f s a` or `is_max_on f s a` -/ def is_extr_on : Prop := is_extr_filter f (principal s) a variables {f s a l} {t : set α} {l' : filter α} lemma is_extr_on.elim {p : Prop} : is_extr_on f s a → (is_min_on f s a → p) → (is_max_on f s a → p) → p := or.elim lemma is_min_on_iff : is_min_on f s a ↔ ∀ x ∈ s, f a ≤ f x := iff.rfl lemma is_max_on_iff : is_max_on f s a ↔ ∀ x ∈ s, f x ≤ f a := iff.rfl lemma is_min_on_univ_iff : is_min_on f univ a ↔ ∀ x, f a ≤ f x := univ_subset_iff.trans eq_univ_iff_forall lemma is_max_on_univ_iff : is_max_on f univ a ↔ ∀ x, f x ≤ f a := univ_subset_iff.trans eq_univ_iff_forall /-! ### Conversion to `is_extr_*` -/ lemma is_min_filter.is_extr : is_min_filter f l a → is_extr_filter f l a := or.inl lemma is_max_filter.is_extr : is_max_filter f l a → is_extr_filter f l a := or.inr lemma is_min_on.is_extr (h : is_min_on f s a) : is_extr_on f s a := h.is_extr lemma is_max_on.is_extr (h : is_max_on f s a) : is_extr_on f s a := h.is_extr /-! ### Constant function -/ lemma is_min_filter_const {b : β} : is_min_filter (λ _, b) l a := univ_mem_sets' $ λ _, le_refl _ lemma is_max_filter_const {b : β} : is_max_filter (λ _, b) l a := univ_mem_sets' $ λ _, le_refl _ lemma is_extr_filter_const {b : β} : is_extr_filter (λ _, b) l a := is_min_filter_const.is_extr lemma is_min_on_const {b : β} : is_min_on (λ _, b) s a := is_min_filter_const lemma is_max_on_const {b : β} : is_max_on (λ _, b) s a := is_max_filter_const lemma is_extr_on_const {b : β} : is_extr_on (λ _, b) s a := is_extr_filter_const /-! ### Order dual -/ lemma is_min_filter_dual_iff : @is_min_filter α (order_dual β) _ f l a ↔ is_max_filter f l a := iff.rfl lemma is_max_filter_dual_iff : @is_max_filter α (order_dual β) _ f l a ↔ is_min_filter f l a := iff.rfl lemma is_extr_filter_dual_iff : @is_extr_filter α (order_dual β) _ f l a ↔ is_extr_filter f l a := or_comm _ _ alias is_min_filter_dual_iff ↔ is_min_filter.undual is_max_filter.dual alias is_max_filter_dual_iff ↔ is_max_filter.undual is_min_filter.dual alias is_extr_filter_dual_iff ↔ is_extr_filter.undual is_extr_filter.dual lemma is_min_on_dual_iff : @is_min_on α (order_dual β) _ f s a ↔ is_max_on f s a := iff.rfl lemma is_max_on_dual_iff : @is_max_on α (order_dual β) _ f s a ↔ is_min_on f s a := iff.rfl lemma is_extr_on_dual_iff : @is_extr_on α (order_dual β) _ f s a ↔ is_extr_on f s a := or_comm _ _ alias is_min_on_dual_iff ↔ is_min_on.undual is_max_on.dual alias is_max_on_dual_iff ↔ is_max_on.undual is_min_on.dual alias is_extr_on_dual_iff ↔ is_extr_on.undual is_extr_on.dual /-! ### Operations on the filter/set -/ lemma is_min_filter.filter_mono (h : is_min_filter f l a) (hl : l' ≤ l) : is_min_filter f l' a := hl h lemma is_max_filter.filter_mono (h : is_max_filter f l a) (hl : l' ≤ l) : is_max_filter f l' a := hl h lemma is_extr_filter.filter_mono (h : is_extr_filter f l a) (hl : l' ≤ l) : is_extr_filter f l' a := h.elim (λ h, (h.filter_mono hl).is_extr) (λ h, (h.filter_mono hl).is_extr) lemma is_min_filter.filter_inf (h : is_min_filter f l a) (l') : is_min_filter f (l ⊓ l') a := h.filter_mono inf_le_left lemma is_max_filter.filter_inf (h : is_max_filter f l a) (l') : is_max_filter f (l ⊓ l') a := h.filter_mono inf_le_left lemma is_extr_filter.filter_inf (h : is_extr_filter f l a) (l') : is_extr_filter f (l ⊓ l') a := h.filter_mono inf_le_left lemma is_min_on.on_subset (hf : is_min_on f t a) (h : s ⊆ t) : is_min_on f s a := hf.filter_mono $ principal_mono.2 h lemma is_max_on.on_subset (hf : is_max_on f t a) (h : s ⊆ t) : is_max_on f s a := hf.filter_mono $ principal_mono.2 h lemma is_extr_on.on_subset (hf : is_extr_on f t a) (h : s ⊆ t) : is_extr_on f s a := hf.filter_mono $ principal_mono.2 h lemma is_min_on.inter (hf : is_min_on f s a) (t) : is_min_on f (s ∩ t) a := hf.on_subset (inter_subset_left s t) lemma is_max_on.inter (hf : is_max_on f s a) (t) : is_max_on f (s ∩ t) a := hf.on_subset (inter_subset_left s t) lemma is_extr_on.inter (hf : is_extr_on f s a) (t) : is_extr_on f (s ∩ t) a := hf.on_subset (inter_subset_left s t) /-! ### Composition with (anti)monotone functions -/ lemma is_min_filter.comp_mono (hf : is_min_filter f l a) {g : β → γ} (hg : monotone g) : is_min_filter (g ∘ f) l a := mem_sets_of_superset hf $ λ x hx, hg hx lemma is_max_filter.comp_mono (hf : is_max_filter f l a) {g : β → γ} (hg : monotone g) : is_max_filter (g ∘ f) l a := mem_sets_of_superset hf $ λ x hx, hg hx lemma is_extr_filter.comp_mono (hf : is_extr_filter f l a) {g : β → γ} (hg : monotone g) : is_extr_filter (g ∘ f) l a := hf.elim (λ hf, (hf.comp_mono hg).is_extr) (λ hf, (hf.comp_mono hg).is_extr) lemma is_min_filter.comp_antimono (hf : is_min_filter f l a) {g : β → γ} (hg : ∀ ⦃x y⦄, x ≤ y → g y ≤ g x) : is_max_filter (g ∘ f) l a := hf.dual.comp_mono (λ x y h, hg h) lemma is_max_filter.comp_antimono (hf : is_max_filter f l a) {g : β → γ} (hg : ∀ ⦃x y⦄, x ≤ y → g y ≤ g x) : is_min_filter (g ∘ f) l a := hf.dual.comp_mono (λ x y h, hg h) lemma is_extr_filter.comp_antimono (hf : is_extr_filter f l a) {g : β → γ} (hg : ∀ ⦃x y⦄, x ≤ y → g y ≤ g x) : is_extr_filter (g ∘ f) l a := hf.dual.comp_mono (λ x y h, hg h) lemma is_min_on.comp_mono (hf : is_min_on f s a) {g : β → γ} (hg : monotone g) : is_min_on (g ∘ f) s a := hf.comp_mono hg lemma is_max_on.comp_mono (hf : is_max_on f s a) {g : β → γ} (hg : monotone g) : is_max_on (g ∘ f) s a := hf.comp_mono hg lemma is_extr_on.comp_mono (hf : is_extr_on f s a) {g : β → γ} (hg : monotone g) : is_extr_on (g ∘ f) s a := hf.comp_mono hg lemma is_min_on.comp_antimono (hf : is_min_on f s a) {g : β → γ} (hg : ∀ ⦃x y⦄, x ≤ y → g y ≤ g x) : is_max_on (g ∘ f) s a := hf.comp_antimono hg lemma is_max_on.comp_antimono (hf : is_max_on f s a) {g : β → γ} (hg : ∀ ⦃x y⦄, x ≤ y → g y ≤ g x) : is_min_on (g ∘ f) s a := hf.comp_antimono hg lemma is_extr_on.comp_antimono (hf : is_extr_on f s a) {g : β → γ} (hg : ∀ ⦃x y⦄, x ≤ y → g y ≤ g x) : is_extr_on (g ∘ f) s a := hf.comp_antimono hg lemma is_min_filter.bicomp_mono [preorder δ] {op : β → γ → δ} (hop : ((≤) ⇒ (≤) ⇒ (≤)) op op) (hf : is_min_filter f l a) {g : α → γ} (hg : is_min_filter g l a) : is_min_filter (λ x, op (f x) (g x)) l a := mem_sets_of_superset (inter_mem_sets hf hg) $ λ x ⟨hfx, hgx⟩, hop hfx hgx lemma is_max_filter.bicomp_mono [preorder δ] {op : β → γ → δ} (hop : ((≤) ⇒ (≤) ⇒ (≤)) op op) (hf : is_max_filter f l a) {g : α → γ} (hg : is_max_filter g l a) : is_max_filter (λ x, op (f x) (g x)) l a := mem_sets_of_superset (inter_mem_sets hf hg) $ λ x ⟨hfx, hgx⟩, hop hfx hgx -- No `extr` version because we need `hf` and `hg` to be of the same kind lemma is_min_on.bicomp_mono [preorder δ] {op : β → γ → δ} (hop : ((≤) ⇒ (≤) ⇒ (≤)) op op) (hf : is_min_on f s a) {g : α → γ} (hg : is_min_on g s a) : is_min_on (λ x, op (f x) (g x)) s a := hf.bicomp_mono hop hg lemma is_max_on.bicomp_mono [preorder δ] {op : β → γ → δ} (hop : ((≤) ⇒ (≤) ⇒ (≤)) op op) (hf : is_max_on f s a) {g : α → γ} (hg : is_max_on g s a) : is_max_on (λ x, op (f x) (g x)) s a := hf.bicomp_mono hop hg /-! ### Composition with `tendsto` -/ lemma is_min_filter.comp_tendsto {g : δ → α} {l' : filter δ} {b : δ} (hf : is_min_filter f l (g b)) (hg : tendsto g l' l) : is_min_filter (f ∘ g) l' b := hg hf lemma is_max_filter.comp_tendsto {g : δ → α} {l' : filter δ} {b : δ} (hf : is_max_filter f l (g b)) (hg : tendsto g l' l) : is_max_filter (f ∘ g) l' b := hg hf lemma is_extr_filter.comp_tendsto {g : δ → α} {l' : filter δ} {b : δ} (hf : is_extr_filter f l (g b)) (hg : tendsto g l' l) : is_extr_filter (f ∘ g) l' b := hf.elim (λ hf, (hf.comp_tendsto hg).is_extr) (λ hf, (hf.comp_tendsto hg).is_extr) lemma is_min_on.on_preimage (g : δ → α) {b : δ} (hf : is_min_on f s (g b)) : is_min_on (f ∘ g) (g ⁻¹' s) b := hf.comp_tendsto (tendsto_principal_principal.mpr $ subset.refl _) lemma is_max_on.on_preimage (g : δ → α) {b : δ} (hf : is_max_on f s (g b)) : is_max_on (f ∘ g) (g ⁻¹' s) b := hf.comp_tendsto (tendsto_principal_principal.mpr $ subset.refl _) lemma is_extr_on.on_preimage (g : δ → α) {b : δ} (hf : is_extr_on f s (g b)) : is_extr_on (f ∘ g) (g ⁻¹' s) b := hf.elim (λ hf, (hf.on_preimage g).is_extr) (λ hf, (hf.on_preimage g).is_extr) end preorder /-! ### Pointwise addition -/ section ordered_comm_monoid variables [ordered_comm_monoid β] {f g : α → β} {a : α} {s : set α} {l : filter α} lemma is_min_filter.add (hf : is_min_filter f l a) (hg : is_min_filter g l a) : is_min_filter (λ x, f x + g x) l a := show is_min_filter (λ x, f x + g x) l a, from hf.bicomp_mono (λ x x' hx y y' hy, add_le_add' hx hy) hg lemma is_max_filter.add (hf : is_max_filter f l a) (hg : is_max_filter g l a) : is_max_filter (λ x, f x + g x) l a := show is_max_filter (λ x, f x + g x) l a, from hf.bicomp_mono (λ x x' hx y y' hy, add_le_add' hx hy) hg lemma is_min_on.add (hf : is_min_on f s a) (hg : is_min_on g s a) : is_min_on (λ x, f x + g x) s a := hf.add hg lemma is_max_on.add (hf : is_max_on f s a) (hg : is_max_on g s a) : is_max_on (λ x, f x + g x) s a := hf.add hg end ordered_comm_monoid /-! ### Pointwise negation and subtraction -/ section ordered_comm_group variables [ordered_comm_group β] {f g : α → β} {a : α} {s : set α} {l : filter α} lemma is_min_filter.neg (hf : is_min_filter f l a) : is_max_filter (λ x, -f x) l a := hf.comp_antimono (λ x y hx, neg_le_neg hx) lemma is_max_filter.neg (hf : is_max_filter f l a) : is_min_filter (λ x, -f x) l a := hf.comp_antimono (λ x y hx, neg_le_neg hx) lemma is_extr_filter.neg (hf : is_extr_filter f l a) : is_extr_filter (λ x, -f x) l a := hf.elim (λ hf, hf.neg.is_extr) (λ hf, hf.neg.is_extr) lemma is_min_on.neg (hf : is_min_on f s a) : is_max_on (λ x, -f x) s a := hf.comp_antimono (λ x y hx, neg_le_neg hx) lemma is_max_on.neg (hf : is_max_on f s a) : is_min_on (λ x, -f x) s a := hf.comp_antimono (λ x y hx, neg_le_neg hx) lemma is_extr_on.neg (hf : is_extr_on f s a) : is_extr_on (λ x, -f x) s a := hf.elim (λ hf, hf.neg.is_extr) (λ hf, hf.neg.is_extr) lemma is_min_filter.sub (hf : is_min_filter f l a) (hg : is_max_filter g l a) : is_min_filter (λ x, f x - g x) l a := hf.add hg.neg lemma is_max_filter.sub (hf : is_max_filter f l a) (hg : is_min_filter g l a) : is_max_filter (λ x, f x - g x) l a := hf.add hg.neg lemma is_min_on.sub (hf : is_min_on f s a) (hg : is_max_on g s a) : is_min_on (λ x, f x - g x) s a := hf.add hg.neg lemma is_max_on.sub (hf : is_max_on f s a) (hg : is_min_on g s a) : is_max_on (λ x, f x - g x) s a := hf.add hg.neg end ordered_comm_group /-! ### Pointwise `sup`/`inf` -/ section semilattice_sup variables [semilattice_sup β] {f g : α → β} {a : α} {s : set α} {l : filter α} lemma is_min_filter.sup (hf : is_min_filter f l a) (hg : is_min_filter g l a) : is_min_filter (λ x, f x ⊔ g x) l a := show is_min_filter (λ x, f x ⊔ g x) l a, from hf.bicomp_mono (λ x x' hx y y' hy, sup_le_sup hx hy) hg lemma is_max_filter.sup (hf : is_max_filter f l a) (hg : is_max_filter g l a) : is_max_filter (λ x, f x ⊔ g x) l a := show is_max_filter (λ x, f x ⊔ g x) l a, from hf.bicomp_mono (λ x x' hx y y' hy, sup_le_sup hx hy) hg lemma is_min_on.sup (hf : is_min_on f s a) (hg : is_min_on g s a) : is_min_on (λ x, f x ⊔ g x) s a := hf.sup hg lemma is_max_on.sup (hf : is_max_on f s a) (hg : is_max_on g s a) : is_max_on (λ x, f x ⊔ g x) s a := hf.sup hg end semilattice_sup section semilattice_inf variables [semilattice_inf β] {f g : α → β} {a : α} {s : set α} {l : filter α} lemma is_min_filter.inf (hf : is_min_filter f l a) (hg : is_min_filter g l a) : is_min_filter (λ x, f x ⊓ g x) l a := show is_min_filter (λ x, f x ⊓ g x) l a, from hf.bicomp_mono (λ x x' hx y y' hy, inf_le_inf hx hy) hg lemma is_max_filter.inf (hf : is_max_filter f l a) (hg : is_max_filter g l a) : is_max_filter (λ x, f x ⊓ g x) l a := show is_max_filter (λ x, f x ⊓ g x) l a, from hf.bicomp_mono (λ x x' hx y y' hy, inf_le_inf hx hy) hg lemma is_min_on.inf (hf : is_min_on f s a) (hg : is_min_on g s a) : is_min_on (λ x, f x ⊓ g x) s a := hf.inf hg lemma is_max_on.inf (hf : is_max_on f s a) (hg : is_max_on g s a) : is_max_on (λ x, f x ⊓ g x) s a := hf.inf hg end semilattice_inf /-! ### Pointwise `min`/`max` -/ section decidable_linear_order variables [decidable_linear_order β] {f g : α → β} {a : α} {s : set α} {l : filter α} lemma is_min_filter.min (hf : is_min_filter f l a) (hg : is_min_filter g l a) : is_min_filter (λ x, min (f x) (g x)) l a := show is_min_filter (λ x, min (f x) (g x)) l a, from hf.bicomp_mono (λ x x' hx y y' hy, min_le_min hx hy) hg lemma is_max_filter.min (hf : is_max_filter f l a) (hg : is_max_filter g l a) : is_max_filter (λ x, min (f x) (g x)) l a := show is_max_filter (λ x, min (f x) (g x)) l a, from hf.bicomp_mono (λ x x' hx y y' hy, min_le_min hx hy) hg lemma is_min_on.min (hf : is_min_on f s a) (hg : is_min_on g s a) : is_min_on (λ x, min (f x) (g x)) s a := hf.min hg lemma is_max_on.min (hf : is_max_on f s a) (hg : is_max_on g s a) : is_max_on (λ x, min (f x) (g x)) s a := hf.min hg lemma is_min_filter.max (hf : is_min_filter f l a) (hg : is_min_filter g l a) : is_min_filter (λ x, max (f x) (g x)) l a := show is_min_filter (λ x, max (f x) (g x)) l a, from hf.bicomp_mono (λ x x' hx y y' hy, max_le_max hx hy) hg lemma is_max_filter.max (hf : is_max_filter f l a) (hg : is_max_filter g l a) : is_max_filter (λ x, max (f x) (g x)) l a := show is_max_filter (λ x, max (f x) (g x)) l a, from hf.bicomp_mono (λ x x' hx y y' hy, max_le_max hx hy) hg lemma is_min_on.max (hf : is_min_on f s a) (hg : is_min_on g s a) : is_min_on (λ x, max (f x) (g x)) s a := hf.max hg lemma is_max_on.max (hf : is_max_on f s a) (hg : is_max_on g s a) : is_max_on (λ x, max (f x) (g x)) s a := hf.max hg end decidable_linear_order