Merge pull request #15 from lenianiva/experiments/dsp
experiment: Draft-Sketch-Prove
This commit is contained in:
commit
009ae08894
41
README.md
41
README.md
|
@ -1,28 +1,21 @@
|
|||
# PyPantograph
|
||||
|
||||
Python interface to the Pantograph library
|
||||
A Machine-to-Machine Interaction System for Lean 4.
|
||||
|
||||
## Getting started
|
||||
Update submodule
|
||||
``` bash
|
||||
git submodule update --init
|
||||
## Installation
|
||||
|
||||
1. Install `poetry`
|
||||
2. Clone this repository with submodules:
|
||||
```sh
|
||||
git clone --recursive-submodules <repo-path>
|
||||
```
|
||||
Install dependencies
|
||||
```bash
|
||||
3. Install `elan` and `lake`: See [Lean Manual](https://docs.lean-lang.org/lean4/doc/setup.html)
|
||||
4. Execute
|
||||
```sh
|
||||
poetry build
|
||||
poetry install
|
||||
```
|
||||
|
||||
Execute
|
||||
```bash
|
||||
poetry build
|
||||
```
|
||||
To run server tests:
|
||||
``` bash
|
||||
python -m pantograph.server
|
||||
python -m pantograph.search
|
||||
```
|
||||
The tests in `pantograph/server.py` also serve as simple interaction examples
|
||||
|
||||
## Examples
|
||||
|
||||
For API interaction examples, see `examples/README.md`
|
||||
|
@ -36,12 +29,13 @@ python3 -m pantograph.search_llm
|
|||
|
||||
## Experiments
|
||||
|
||||
In `experiments/`, there is an experiment on running a LLM prover on miniF2F
|
||||
data. Run with
|
||||
In `experiments/`, there are some experiments:
|
||||
1. `minif2f/` is an example of executing a SGLANG based prover on the miniF2F dataset
|
||||
2. `dsp` is an Lean implementation of Draft-Sketch-Prove
|
||||
|
||||
```sh
|
||||
python3 experiments/miniF2F_search.py [--dry-run]
|
||||
```
|
||||
If the experiments don't work, run them in `poetry shell`. The environment
|
||||
variable `OPENAI_API_KEY` must be set when running experiments calling the
|
||||
OpenAI API.
|
||||
|
||||
## Referencing
|
||||
|
||||
|
@ -53,3 +47,4 @@ python3 experiments/miniF2F_search.py [--dry-run]
|
|||
howpublished = {\url{https://github.com/lenianiva/PyPantograph}}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
# Instructions for the SNAP Cluster
|
||||
|
||||
Brando's [self-contained `install.sh` script for
|
||||
lean](https://github.com/brando90/learning_lean/blob/main/install.sh). (Warning:
|
||||
The Lean version in the script is outdated.)
|
||||
|
||||
## Install 1: With Conda and Pip in the SNAP cluster
|
||||
|
||||
```bash
|
||||
# - Install Lean 4 manually (elan & lake): gets install script (doesn't save it) & directly gives it to sh to install it
|
||||
curl -sSf https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh | sh -s -- -y
|
||||
# (install command from the Lean4 official instlal guide, not the one we use)
|
||||
# curl -sSf https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh | sh -s
|
||||
|
||||
# - Make sure Lean4 tools (lean, lake) are available
|
||||
echo $PATH | tr ':' '\n'
|
||||
export PATH="$HOME/.elan/bin:$PATH"
|
||||
echo 'export PATH="$HOME/.elan/bin:$PATH"' >> ~/.bashrc
|
||||
# bash
|
||||
elan
|
||||
lake
|
||||
|
||||
# - Create and activate the right python env (this is needed so that poetry build works)
|
||||
conda create -n pypantograph_env python=3.11 -y
|
||||
conda activate pypantograph_env
|
||||
#conda remove --name pypantograph_env --all
|
||||
|
||||
# - Install poetry with python venv (needs seperate install so poetry & your projs deps don't crash)
|
||||
mkdir $HOME/.virtualenvs
|
||||
|
||||
# put the follow BEFORE your conda init stuff in your .bashrc
|
||||
export VENV_PATH=$HOME/.virtualenvs/venv_for_poetry
|
||||
export PATH="$VENV_PATH/bin:$PATH"
|
||||
|
||||
# now actually install poetry in a python env after creating an python env for poetry with venv
|
||||
python3 -m venv $VENV_PATH
|
||||
$VENV_PATH/bin/pip install -U pip setuptools
|
||||
$VENV_PATH/bin/pip install poetry
|
||||
|
||||
poetry
|
||||
|
||||
# - Init the git submodules (i.e., make git aware of them/track them) + fetch/clone/update (and double check submodule is inited)
|
||||
git submodule init
|
||||
git submodule update --init
|
||||
|
||||
# - For snap make sure the repo is sym linked you're using your
|
||||
git clone git@github.com:lenianiva/PyPantograph.git
|
||||
# git checkout <your-branch>
|
||||
git checkout brando
|
||||
ln -s $AFS/PyPantograph $HOME/PyPantograph
|
||||
|
||||
# - Build the PyPantograph proj (build the py distribution, py deps and custom (lean4) installs). Note: pip install -e doesn't work on the dist .whl builds etc so you instead the next command
|
||||
cd $HOME/PyPantograph
|
||||
poetry build
|
||||
|
||||
```
|
||||
To run server tests:
|
||||
``` bash
|
||||
python -m pantograph.server
|
||||
python -m pantograph.search
|
||||
```
|
||||
The tests in `pantograph/server.py` also serve as simple interaction examples
|
||||
|
||||
|
||||
# - Install pypantograph in editable mode (only pyproject.toml (or setup.py!) needed! Assuming your at the proj root)
|
||||
cd $HOME/PyPantograph
|
||||
pip install -e .
|
||||
|
||||
# - Confirm intalls
|
||||
pip list | grep pantograph
|
||||
pip list | grep vllm
|
||||
pip list | grep torch
|
||||
|
||||
# - Make sure the PyPantrograph server tests by Leni work
|
||||
cd ~/PyPantograph
|
||||
python $HOME/PyPantograph/pantograph/server.py
|
||||
python $HOME/PyPantograph/test_vllm.py
|
||||
```
|
||||
Note: the tests in `pantograph/server.py` also serve as simple interaction examples
|
||||
|
||||
References:
|
||||
- My SNAP `.bashrc`: https://github.com/brando90/snap-cluster-setup/blob/main/.bashrc
|
||||
- Especially useful for Conda vs Poetry export order
|
||||
- Poetry in SNAP: https://github.com/brando90/snap-cluster-setup?tab=readme-ov-file#poetry
|
||||
- Gitsubmodules: https://github.com/brando90/snap-cluster-setup?tab=readme-ov-file#git-submodules
|
||||
- Lean in SNAP: https://github.com/brando90/snap-cluster-setup?tab=readme-ov-file#lean-in-snap
|
||||
- ChatGPT: https://chat.openai.com/c/e01336a7-6f67-4cd2-b6cd-09b8ee8aef5a
|
||||
|
||||
# Install 2: With only Poetry in the SNAP cluster
|
||||
|
||||
```bash
|
||||
# - Install Lean4 manually (elan and lake), 1st one is the SNAP one, 2nd is the most common one
|
||||
curl -sSf https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh | sh -s -- -y
|
||||
# curl -sSf https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh | sh -s
|
||||
|
||||
# - Make sure Lean4 tools (lean, lake) are available
|
||||
export PATH="$HOME/.elan/bin:$PATH"
|
||||
echo 'export PATH="$HOME/.elan/bin:$PATH"' >> ~/.bashrc
|
||||
bash
|
||||
elan
|
||||
lake
|
||||
|
||||
# - Init the git submodules (i.e., make git aware of them/track them) + fetch/clone/update (and double check submodule is inited)
|
||||
git submodule init
|
||||
git submodule update --init --recursive
|
||||
git clone git@github.com:lenianiva/PyPantograph.git --recurse-submodules
|
||||
|
||||
# - For snap make sure the repo is sym linked you're using your
|
||||
git clone git@github.com:lenianiva/PyPantograph.git
|
||||
git checkout <your-branch>
|
||||
ln -s $AFS/PyPantograph $HOME/PyPantograph
|
||||
|
||||
# - Install poetry with python venv (needs seperate install so poetry & your projs deps don't crash)
|
||||
mkdir $HOME/.virtualenvs
|
||||
|
||||
# - Put the follow BEFORE your conda init stuff in your .bashrc
|
||||
export VENV_PATH=$HOME/.virtualenvs/venv_for_poetry
|
||||
export PATH="$VENV_PATH/bin:$PATH"
|
||||
|
||||
# - Now actually install poetry in a python env after creating an python env for poetry with venv
|
||||
python3 -m venv $VENV_PATH
|
||||
$VENV_PATH/bin/pip install -U pip setuptools
|
||||
$VENV_PATH/bin/pip install poetry
|
||||
|
||||
poetry
|
||||
|
||||
# poetry build is only needed when you build a python distribution e.g., .whl or .tar.gz and want to distribute it. You can't use those files for edtiable development anyway
|
||||
# # - Build the PyPantograph proj (build the py distribution, py deps and custom (lean4) installs)
|
||||
# cd $HOME/PyPantograph
|
||||
# poetry build
|
||||
|
||||
# - Install pypantograph in editable mode with poetry
|
||||
cd $HOME/PyPantograph
|
||||
#Installs the project and its dependencies into the virtual environment, creating the environment if it doesn't exist, in editable mode. This will run our custom build for Lean already (the build.py file!)
|
||||
poetry install
|
||||
# if it create a new python env, check it out
|
||||
poetry env list
|
||||
# activate the current poetry env in a new shell
|
||||
poetry shell
|
||||
|
||||
# - Confirm intalls
|
||||
# poetry show | grep pantograph # note, doesn't do anything since poetry already only works by installing things in editable mode
|
||||
poetry show | grep vllm
|
||||
poetry show | grep torch
|
||||
|
||||
# - Make sure the PyPantrograph server tests by Leni work
|
||||
cd ~/PyPantograph
|
||||
python -m pantograph.server
|
||||
# python $HOME/PyPantograph/pantograph/server.py
|
||||
# python $HOME/PyPantograph/test_vllm.py
|
7
build.py
7
build.py
|
@ -3,13 +3,16 @@
|
|||
import subprocess, shutil, os, stat
|
||||
from pathlib import Path
|
||||
|
||||
# -- Install Panograph
|
||||
# Define paths for Pantograph source and Pantograph Python interface
|
||||
PATH_PANTOGRAPH = Path("./src")
|
||||
PATH_PY = Path("./pantograph")
|
||||
|
||||
with subprocess.Popen(["lake", "build", "repl"], cwd=PATH_PANTOGRAPH) as p:
|
||||
p.wait()
|
||||
|
||||
path_executable = PATH_PY / "pantograph-repl"
|
||||
shutil.copyfile(PATH_PANTOGRAPH / ".lake/build/bin/repl", path_executable)
|
||||
os.chmod(path_executable, os.stat(path_executable).st_mode | stat.S_IEXEC)
|
||||
shutil.copyfile(PATH_PANTOGRAPH / "lean-toolchain", PATH_PY / "lean-toolchain")
|
||||
|
||||
# -- Copy the Lean toolchain file to the specified path
|
||||
shutil.copyfile(PATH_PANTOGRAPH / "lean-toolchain", PATH_PY / "lean-toolchain")
|
|
@ -18,6 +18,7 @@ This would generate compiled `.olean` files. Then run one of the examples from t
|
|||
project root:
|
||||
``` sh
|
||||
poetry run examples/aesop.py
|
||||
poetry run examples/sketch.py
|
||||
poetry run examples/data.py
|
||||
```
|
||||
|
||||
|
@ -26,3 +27,7 @@ build`! Moreover, the version of the Lean used in the example folder (including
|
|||
dependencies in `lakefile.lean` and `lean-toolchain`) **must match exactly**
|
||||
with the version in `src/`!
|
||||
|
||||
* `aesop.py`: Example of how to use the `aesop` tactic
|
||||
* `data.py`: Example of loading training data
|
||||
* `sketch.py`: Example of loading a sketch
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from pantograph.server import Server
|
||||
|
||||
sketch = """
|
||||
theorem add_comm_proved_formal_sketch : ∀ n m : Nat, n + m = m + n := by
|
||||
-- Consider some n and m in Nats.
|
||||
intros n m
|
||||
-- Perform induction on n.
|
||||
induction n with
|
||||
| zero =>
|
||||
-- Base case: When n = 0, we need to show 0 + m = m + 0.
|
||||
-- We have the fact 0 + m = m by the definition of addition.
|
||||
have h_base: 0 + m = m := sorry
|
||||
-- We also have the fact m + 0 = m by the definition of addition.
|
||||
have h_symm: m + 0 = m := sorry
|
||||
-- Combine facts to close goal
|
||||
sorry
|
||||
| succ n ih =>
|
||||
-- Inductive step: Assume n + m = m + n, we need to show succ n + m = m + succ n.
|
||||
-- By the inductive hypothesis, we have n + m = m + n.
|
||||
have h_inductive: n + m = m + n := sorry
|
||||
-- 1. Note we start with: Nat.succ n + m = m + Nat.succ n, so, pull the succ out from m + Nat.succ n on the right side from the addition using addition facts Nat.add_succ.
|
||||
have h_pull_succ_out_from_right: m + Nat.succ n = Nat.succ (m + n) := sorry
|
||||
-- 2. then to flip m + S n to something like S (n + m) we need to use the IH.
|
||||
have h_flip_n_plus_m: Nat.succ (n + m) = Nat.succ (m + n) := sorry
|
||||
-- 3. Now the n & m are on the correct sides Nat.succ n + m = Nat.succ (n + m), so let's use the def of addition to pull out the succ from the addition on the left using Nat.succ_add.
|
||||
have h_pull_succ_out_from_left: Nat.succ n + m = Nat.succ (n + m) := sorry
|
||||
-- Combine facts to close goal
|
||||
sorry
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
server = Server()
|
||||
state0, = server.load_sorry(sketch)
|
||||
print(state0)
|
|
@ -1,3 +0,0 @@
|
|||
import Mathlib
|
||||
|
||||
-- Ensure that Aesop is running
|
|
@ -1,16 +0,0 @@
|
|||
import Lake
|
||||
open Lake DSL
|
||||
|
||||
require proofwidgets from git
|
||||
"https://github.com/leanprover-community/ProofWidgets4" @ "ade8c50c8d1172b974738a01447c29bf6f85f7f8"
|
||||
|
||||
require aesop from git
|
||||
"https://github.com/leanprover-community/aesop.git" @ "v4.10.0-rc1"
|
||||
|
||||
require mathlib from git
|
||||
"https://github.com/leanprover-community/mathlib4" @ "v4.10.0-rc1"
|
||||
|
||||
package Example
|
||||
|
||||
@[default_target]
|
||||
lean_lib Example
|
|
@ -1 +0,0 @@
|
|||
../../src/lean-toolchain
|
|
@ -1,15 +0,0 @@
|
|||
# Usage Example
|
||||
|
||||
This example showcases how to bind library dependencies and execute the `Aesop`
|
||||
tactic in Lean. First build the example project:
|
||||
``` sh
|
||||
pushd Example
|
||||
lake build
|
||||
popd
|
||||
```
|
||||
This would generate compiled `.olean` files. Then run the example from the
|
||||
project root:
|
||||
``` sh
|
||||
poetry run examples/aesop.py
|
||||
```
|
||||
|
|
@ -0,0 +1 @@
|
|||
/result
|
|
@ -0,0 +1,56 @@
|
|||
# Lean Draft Sketch Prove (DSP)
|
||||
|
||||
based on Sean Welleck's DSP for Isabelle: https://github.com/wellecks/ntptutorial/tree/main/partII_dsp
|
||||
|
||||
## Execution
|
||||
|
||||
First of all, build the experiment repo.
|
||||
|
||||
``` sh
|
||||
# experiments/dsp
|
||||
cd lean_src_proj
|
||||
lake build
|
||||
```
|
||||
Then run `main.py`
|
||||
``` sh
|
||||
python3 experiments/dsp/main.py -h
|
||||
```
|
||||
|
||||
The main command for running DSP is `eval`. Due to the multitude of data format
|
||||
out there, use the `--format` flag to specify the data format. For example,
|
||||
running DSP on minif2f is:
|
||||
|
||||
``` sh
|
||||
python3 experiments/dsp/main.py eval --dataset ../minif2f/valid.jsonl --format minif2f
|
||||
```
|
||||
|
||||
## Related work
|
||||
|
||||
### Tony's AF
|
||||
Ton'y original AF: ((Yuhuai et al.))[https://arxiv.org/abs/2205.12615]
|
||||
Tony's paper improve MiniF2F from: `29.6% to 35.2%`, by `5.6%`.
|
||||
|
||||
Expert Iteration:
|
||||
- AF used: "We explore if one can improve neural theorem provers by training the neural models on proofs of automatically translated theorems".
|
||||
- they only translate **problem theorems** (nl_thm := "problem + answer") then use a prover to get the formal proof.
|
||||
- ExpIt algorithn:
|
||||
- `M_0 := Isabelle_Thor()`
|
||||
- `Search/Prover := Best_First_Search()` # TODO recall best first search
|
||||
- ExpIT.fine_tune := "train model to predict next proof_step/tactic given current proof_state and previous proof_step on successful proofs.
|
||||
- i.e., `<x=(proof_state_{t}, proof_step_{t-1}), y=(proof_step_{t})>` #TODO: I think, confirm with Albert https://twitter.com/messages/1253358235-1267913180153548800
|
||||
|
||||
Base Model for Neural Theorem Prover (NTP):
|
||||
- Thor_GPT2 := "We use a pre-trained and fine-tuned Thor based on a GPT-2 with 700M non-embedding parameters." Note: ReProver used 299M parameters enc-dec.
|
||||
- fine-tuned on the PILE arxiv + github
|
||||
|
||||
Neural Theorem Prover (NTP) for `M_0`:
|
||||
- Thor :=
|
||||
- The Thor agent is fine-tuned on the PISA dataset which consists of 2.49 million proof steps from the Isabelle/HOL library.
|
||||
- The model is trained with the objective to predict the next token in va proof step, given the proof state and the last proof step.
|
||||
- proof step := "tactic in Isabelle" #TODO confirm with Albert https://twitter.com/messages/1253358235-1267913180153548800
|
||||
|
||||
Questions:
|
||||
- Q1: what is this: "we perform deduplication by problem statements" when does it matter? All MATH train are unique, so why would I care about this?
|
||||
|
||||
Idea:
|
||||
- Idea1: use the formal ground truth solution string in MATH, implement Draft Sketch Proof (DSP) for Lean4 + use some symbolic/ntp solver (hammer/tidy/ReProver)
|
|
@ -0,0 +1,3 @@
|
|||
{"problem": "$ E = \\left[\\begin{array}{rr}5 & 1 \\\\ 2 & 3\\end{array}\\right]$ What is the determinant of $ E$ ?", "hints": ["The determinant of a 2x2 matrix can be computed the following way:", "$ = $", "In this specific case,", "$ = $", "$ = 13 $"]}
|
||||
{"problem": "If $a + b + c = 9$, what is $7c + 7a + 7b$ ?", "hints": ["$= 7a + 7b + 7c$", "$= (7) \\cdot (a + b + c) $", "$= (7) \\cdot (9) $", "$= 63$"]}
|
||||
{"problem": "Find $\\lim_{x\\to\\infty}\\dfrac{x^2-4}{\\cos(x)}$. Choose 1 answer: Choose 1 answer: (Choice A) A $4$ (Choice B) B $-2$ (Choice C) C $0$ (Choice D) D The limit doesn't exist", "hints": ["When dealing with limits that include $\\cos(x)$, it's important to remember that $\\lim_{x\\to\\infty}\\cos(x)$ doesn't exist, as $\\cos(x)$ keeps oscillating between $-1$ and $1$ forever. ${2}$ ${4}$ ${6}$ ${8}$ ${\\llap{-}4}$ ${\\llap{-}6}$ ${\\llap{-}8}$ ${2}$ $y$ $x$ $y=\\cos(x)$ This doesn't necessarily mean that our limit doesn't exist. Think what happens to $\\dfrac{x^2-4}{\\cos(x)}$ as $x$ increases towards positive infinity.", "While $x^2-4$ keeps growing boundlessly, $\\cos(x)$ oscillates from $-1$, to $0$, to $1$, to $0$, to $-1$ again. The result is a graph that goes up and down forever, with vertical asymptotes every now and then. ${5}$ ${10}$ ${15}$ ${\\llap{-}5}$ ${\\llap{-}10}$ ${\\llap{-}15}$ ${50}$ ${100}$ ${150}$ ${\\llap{-}50}$ ${\\llap{-}100}$ ${\\llap{-}150}$ $y$ $x$ $y=\\dfrac{x^2-4}{\\cos(x)}$ This limit doesn't approach any specific value as $x$ increases towards infinity.", "In conclusion, $\\lim_{x\\to\\infty}\\dfrac{x^2-4}{\\cos(x)}$ doesn't exist."]}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"problem": "For any natural number n, n + 0 = n.",
|
||||
"level": "SF foundations level 1",
|
||||
"type": "Algebra",
|
||||
"solution": [
|
||||
"Consider some natural number n. The proof will be by induction. Consider the base case n=0. We have 0 + 0 = 0 which holds by the definition of addion.",
|
||||
"Now the inductive case we want to show n'+1 + 0 = n'+1. Assume it holds for n i.e., n' + 0 = n. So now by the we know the LHS is equal to (n'+0) + 1.",
|
||||
"Then by the induction hypothesis we know the LHS simplifies to n'+1 completing the proof. Qed."
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"problem": "For any natural number n, 0 + n = n.",
|
||||
"level": "SF foundations level 1",
|
||||
"type": "Algebra",
|
||||
"solution": "Consider some natural number n. We now want to show 0 + n = n. Using addition both sides are equal."
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"problem": "For any natural number n, 0 + n = n.",
|
||||
"level": "SF foundations level 1",
|
||||
"type": "Algebra",
|
||||
"solution": "Consider some natural number n. We now want to show 0 + n = n. For that we use the definition of addition to get n = n and conclude both sides are equal (by reflexity)."
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
[
|
||||
{
|
||||
"problem": "For any natural number n, 0 + n = n.",
|
||||
"level": "SF foundations level 1",
|
||||
"type": "Logical Foundations",
|
||||
"solution": [
|
||||
"Consider some natural number n. We want to show 0 + n = n. ",
|
||||
"By using definition of addition on both sides, LHS and RHS are now equal, done."
|
||||
]
|
||||
},
|
||||
{
|
||||
"problem": "For any natural number n, n + 0 = n.",
|
||||
"level": "SF foundations level 1",
|
||||
"type": "Logical Foundations",
|
||||
"solution": [
|
||||
"Consider some natural number n. The proof will be by induction. ",
|
||||
"The base case n=0, so we have 0 + 0 = 0, which holds by the definition of addion. ",
|
||||
"Consider the inductive case, so we want to show (k + 1) + 0 = (k + 1) for any k < n assuming the IH holds for such k (IH: k + 0 = k). ",
|
||||
"By the IH we have (k + 1) + 0 = (k + 1). ",
|
||||
"By def of addition we have (k + 0) + 1 = (k + 1). ",
|
||||
"By the induction hypothesis (IH) we have k + 0 = k. ",
|
||||
"LHS and RHS are equal so proof is complete."
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,368 @@
|
|||
[
|
||||
{
|
||||
"nl_problem": "For any natural number n, n + 0 = n.",
|
||||
"nl_solution": [
|
||||
"Consider some natural number n. We want to show n + 0 = n. ",
|
||||
"By using fats of addition on both sides, LHS and RHS are now equal, done."
|
||||
],
|
||||
"fl_problem": "theorem n_plus_zero : ∀ n : ℕ, n + 0 = n := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + 0 = n.\n",
|
||||
"theorem n_plus_zero : ∀ n : ℕ, n + 0 = n := by\n",
|
||||
" -- Consider some n in Nats.\n",
|
||||
" intro n",
|
||||
"-- Using facts of addition simplify n + 0 to n.\n",
|
||||
" rw [Nat.add_zero]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
],
|
||||
|
||||
"nl_problem_proved_sketch": "For any natural number n, n + 0 = n.",
|
||||
"nl_solution_proved_sketch": [
|
||||
"We want to show n + 0 = n. ",
|
||||
"We have the fact of addition that, n + 0 = n. ",
|
||||
"Thus, the left-hand side and right-hand side are equal, which completes the proof."
|
||||
],
|
||||
"fl_problem_proved_sketch": "theorem n_plus_zero_proved_formal_sketch : ∀ n : ℕ, n + 0 = n := by",
|
||||
"fl_solution_proved_sketch": [
|
||||
"-- Prove that n + 0 = n via a formal proof sketch",
|
||||
"theorem n_plus_zero_proved_formal_sketch : ∀ n : ℕ, n + 0 = n := by",
|
||||
" -- We have the fact of addition n + 0 = n, use it to show left and right are equal.",
|
||||
" have h_nat_add_zero: ∀ n : ℕ, n + 0 = n := Nat.add_zero",
|
||||
" exact h_nat_add_zero"
|
||||
],
|
||||
"src_header_fl_solution_proved_sketch": ["import Mathlib.Data.Nat.Basic"],
|
||||
|
||||
"nl_problem_proved_sketch_aesop": "For any natural number n, n + 0 = n.",
|
||||
"nl_solution_proved_sketch_aesop": [
|
||||
"We want to show n + 0 = n. ",
|
||||
"We have the fact of addition that, n + 0 = n. ",
|
||||
"Thus, the left-hand side and right-hand side are equal, which completes the proof."
|
||||
],
|
||||
"fl_problem_proved_sketch_aesop": "theorem n_plus_zero_proved_formal_sketch' : ∀ n : ℕ, n + 0 = n := by",
|
||||
"fl_solution_proved_sketch_aesop": [
|
||||
"-- Prove that n + 0 = n via a formal proof sketch with aesop. ",
|
||||
"theorem n_plus_zero_proved_formal_sketch' : ∀ n : ℕ, n + 0 = n := by",
|
||||
" -- We have the fact of addition n + 0 = n, use it to show left and right are equal. ",
|
||||
" have h_nat_add_zero: ∀ n : ℕ, n + 0 = n := by aesop",
|
||||
" exact h_nat_add_zero"
|
||||
],
|
||||
"src_header_fl_solution_proved_sketch_aesop": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": "For any natural number n, 0 + n = n.",
|
||||
"nl_solution": [
|
||||
"Consider some natural number n. We want to show 0 + n = n.",
|
||||
"By using facts of addition and induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem zero_plus_n : ∀ n : ℕ, 0 + n = n := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that 0 + n = n by induction",
|
||||
"theorem zero_plus_n : ∀ n : ℕ, 0 + n = n := by",
|
||||
"-- Consider some n in Nats.",
|
||||
"intro n",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: 0 + 0 = 0",
|
||||
"rw [Nat.add_zero]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: assume 0 + n = n, prove 0 + succ n = succ n",
|
||||
"rw [Nat.add_succ]",
|
||||
"rw [ih]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
],
|
||||
|
||||
"nl_problem_proved_sketch": "For any natural number n, 0 + n = n.",
|
||||
"nl_solution_proved_sketch": [
|
||||
"We want to show 0 + n = n.",
|
||||
"By using the fact of addition and performing induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem_proved_sketch": "theorem zero_plus_n_proved_formal_sketch : ∀ n : ℕ, 0 + n = n := by",
|
||||
"fl_solution_proved_sketch": [
|
||||
"-- Prove that 0 + n = n by induction via a formal proof sketch",
|
||||
"theorem zero_plus_n_proved_formal_sketch : ∀ n : ℕ, 0 + n = n := by",
|
||||
"-- Consider some n in Nats.",
|
||||
"intro n",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: 0 + 0 = 0",
|
||||
"have h_base: 0 + 0 = 0 := by rw [Nat.add_zero]",
|
||||
"exact h_base",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: assume 0 + n = n, prove 0 + succ n = succ n",
|
||||
"have h_inductive: 0 + Nat.succ n = Nat.succ n := by",
|
||||
"rw [Nat.add_succ]",
|
||||
"rw [ih]",
|
||||
"exact h_inductive"
|
||||
],
|
||||
"src_header_fl_solution_proved_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
],
|
||||
|
||||
"nl_problem_proved_sketch_aesop": "For any natural number n, 0 + n = n.",
|
||||
"nl_solution_proved_sketch_aesop": [
|
||||
"We want to show 0 + n = n.",
|
||||
"By using the fact of addition and performing induction on n, we can prove the statement for both the base case and the inductive step using aesop."
|
||||
],
|
||||
|
||||
"fl_problem_proved_sketch_aesop": "theorem zero_plus_n_proved_formal_sketch' : ∀ n : ℕ, 0 + n = n := by",
|
||||
"fl_solution_proved_sketch_aesop": [
|
||||
"-- Prove that 0 + n = n by induction via a formal proof sketch with aesop.",
|
||||
"theorem zero_plus_n_proved_formal_sketch' : ∀ n : ℕ, 0 + n = n := by",
|
||||
"-- Consider some n in Nats.",
|
||||
"intro n",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: 0 + 0 = 0",
|
||||
"have h_base: 0 + 0 = 0 := by aesop",
|
||||
"exact h_base",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: assume 0 + n = n, prove 0 + succ n = succ n",
|
||||
"have h_inductive: 0 + Nat.succ n = Nat.succ n := by aesop",
|
||||
"exact h_inductive"
|
||||
],
|
||||
"src_header_fl_solution_proved_sketch_aesop": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": "For any natural numbers n and m we have commutativity, n + m = m + n.",
|
||||
"nl_solution": [
|
||||
"Consider some natural numbers n and m. We want to show n + m = m + n.",
|
||||
"By using facts of addition and induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem add_comm_normal : ∀ n m : ℕ, n + m = m + n := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + m = m + n",
|
||||
"theorem add_comm_normal : ∀ n m : ℕ, n + m = m + n := by",
|
||||
"-- Consider some n and m in Nats.",
|
||||
"intros n m",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: When n = 0, we need to show 0 + m = m + 0.",
|
||||
"-- Using the definition of addition, 0 + m = m and m + 0 = m.",
|
||||
"rw [Nat.zero_add, Nat.add_zero]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: Assume n + m = m + n, we need to show succ n + m = m + succ n.",
|
||||
"-- We use the fact n + (m + 1) = (n + m) + 1.",
|
||||
"have plus_n_Sm_normal: ∀ n m : ℕ, n + (m + 1) = (n + m) + 1 := by",
|
||||
" intros n m",
|
||||
" rw [Nat.add_succ]",
|
||||
"-- Apply the fact to rewrite succ n + m = (n + m) + 1.",
|
||||
"rw [Nat.add_succ, Nat.add_zero]",
|
||||
"rw [← ih]",
|
||||
"rw [Nat.succ_add]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"nl_problem": "For any natural numbers n and m, n + m = m + n.",
|
||||
"nl_solution": [
|
||||
"Consider some natural numbers n and m. We want to show n + m = m + n.",
|
||||
"By using the fact of addition and performing induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem add_comm_proved_formal_sketch : ∀ n m : ℕ, n + m = m + n := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + m = m + n via a formal proof sketch",
|
||||
"theorem add_comm_proved_formal_sketch : ∀ n m : ℕ, n + m = m + n := by",
|
||||
"-- Consider some n and m in Nats.",
|
||||
"intros n m",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: When n = 0, we need to show 0 + m = m + 0.",
|
||||
"-- We have the fact 0 + m = m by the definition of addition.",
|
||||
"have h_base: 0 + m = m := Nat.zero_add m",
|
||||
"-- We also have the fact m + 0 = m by the definition of addition.",
|
||||
"have h_symm: m + 0 = m := Nat.add_zero m",
|
||||
"-- Combining these, we get 0 + m = m + 0.",
|
||||
"rw [h_base, h_symm]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: Assume n + m = m + n, we need to show succ n + m = m + succ n.",
|
||||
"-- By the inductive hypothesis, we have n + m = m + n.",
|
||||
"have h_inductive: n + m = m + n := ih",
|
||||
"-- proof is:",
|
||||
"-- We eventually want to flip n + m and simplify to make both sides the same. Thus,",
|
||||
"-- 1. Note we start with: Nat.succ n + m = m + Nat.succ n, so, pull the succ out from m + Nat.succ n on the right side from the addition using addition facts Nat.add_succ.",
|
||||
"have h_pull_succ_out_from_right: m + Nat.succ n = Nat.succ (m + n) := by rw [Nat.add_succ]",
|
||||
"-- 2. then to flip m + S n to something like S (n + m) we need to use the IH.",
|
||||
"have h_flip_n_plus_m: Nat.succ (n + m) = Nat.succ (m + n) := by rw [h_inductive]",
|
||||
"-- 3. Now the n & m are on the correct sides Nat.succ n + m = Nat.succ (n + m), so let's use the def of addition to pull out the succ from the addition on the left using Nat.succ_add.",
|
||||
"have h_pull_succ_out_from_left: Nat.succ n + m = Nat.succ (n + m) := by rw [Nat.succ_add]",
|
||||
"-- Combining these, we get succ n + m = m + succ n.",
|
||||
"rw [h_pull_succ_out_from_right, ←h_flip_n_plus_m, h_pull_succ_out_from_left]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"nl_problem": "For any natural numbers n and m, n + m = m + n.",
|
||||
"nl_solution": [
|
||||
"Consider some natural numbers n and m. We want to show n + m = m + n.",
|
||||
"By using the fact of addition and performing induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem add_comm_proved_formal_sketch_aesop : ∀ n m : ℕ, n + m = m + n := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + m = m + n via a formal proof sketch with aesop.",
|
||||
"theorem add_comm_proved_formal_sketch_aesop : ∀ n m : ℕ, n + m = m + n := by",
|
||||
"-- Consider some n and m in Nats.",
|
||||
"intros n m",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: When n = 0, we need to show 0 + m = m + 0.",
|
||||
"-- We have the fact 0 + m = m by the definition of addition.",
|
||||
"have h_base: 0 + m = m := by aesop",
|
||||
"-- We also have the fact m + 0 = m by the definition of addition.",
|
||||
"have h_symm: m + 0 = m := by aesop",
|
||||
"-- Combining these, we get 0 + m = m + 0.",
|
||||
"rw [h_base, h_symm]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: Assume n + m = m + n, we need to show succ n + m = m + succ n.",
|
||||
"-- By the inductive hypothesis, we have n + m = m + n.",
|
||||
"have h_inductive: n + m = m + n := by aesop",
|
||||
"-- proof is:",
|
||||
"-- We eventually want to flip n + m and simplify to make both sides the same. Thus,",
|
||||
"-- 1. Note we start with: Nat.succ n + m = m + Nat.succ n, so, pull the succ out from m + Nat.succ n on the right side from the addition using addition facts Nat.add_succ.",
|
||||
"have h_pull_succ_out_from_right: m + Nat.succ n = Nat.succ (m + n) := by aesop",
|
||||
"-- 2. then to flip m + S n to something like S (n + m) we need to use the IH.",
|
||||
"have h_flip_n_plus_m: Nat.succ (n + m) = Nat.succ (m + n) := by aesop",
|
||||
"-- 3. Now the n & m are on the correct sides Nat.succ n + m = Nat.succ (n + m), so let's use the def of addition to pull out the succ from the addition on the left using Nat.succ_add.",
|
||||
"have h_pull_succ_out_from_left: Nat.succ n + m = Nat.succ (n + m) := by rw [Nat.succ_add]",
|
||||
"-- Combining these, we get succ n + m = m + succ n.",
|
||||
"rw [h_pull_succ_out_from_right, ←h_flip_n_plus_m, h_pull_succ_out_from_left]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": "Prove that for any natural numbers n, m, and p, n + (m + p) = (n + m) + p.",
|
||||
"nl_solution": [
|
||||
"Consider some natural numbers n, m, and p. We want to show n + (m + p) = (n + m) + p.",
|
||||
"By using facts of addition and induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem add_assoc_normal : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + (m + p) = (n + m) + p",
|
||||
"theorem add_assoc_normal : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by",
|
||||
"-- Consider some n, m, and p in Nats.",
|
||||
"intros n m p",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: When n = 0, we need to show 0 + (m + p) = (0 + m) + p.",
|
||||
"-- Using the definition of addition, 0 + (m + p) = m + p and (0 + m) + p = m + p.",
|
||||
"rw [Nat.zero_add, Nat.zero_add]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: Assume n + (m + p) = (n + m) + p, we need to show succ n + (m + p) = (succ n + m) + p.",
|
||||
"-- proof strategy is, we move succ n out (or in) enough times then use the IH until both sides are the same.",
|
||||
"-- 1. let's start by pulling out the succ from the left side and have the entire addition inside the succ.",
|
||||
"rw [Nat.succ_add]",
|
||||
"-- 2. Now that we have the IH hypothesis appearing inside the left, let's apply it so we have n + (m + p) = (n + m) + p.",
|
||||
"rw [ih]",
|
||||
"-- 3. Now that the parentheses (apps of plus) are in the right place for both sides, push the succ on the left twice so both terms are the same.",
|
||||
"rw [← Nat.succ_add, ← Nat.succ_add]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"nl_problem": "Prove that for any natural numbers n, m, and p, n + (m + p) = (n + m) + p.",
|
||||
"nl_solution": [
|
||||
"Consider some natural numbers n, m, and p. We want to show n + (m + p) = (n + m) + p.",
|
||||
"By using facts of addition and induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem add_assoc_proved_formal_sketch : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + (m + p) = (n + m) + p",
|
||||
"theorem add_assoc_proved_formal_sketch : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by",
|
||||
"-- Consider some n, m, and p in Nats.",
|
||||
"intros n m p",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: When n = 0, we need to show 0 + (m + p) = (0 + m) + p.",
|
||||
"-- Using the definition of addition, 0 + (m + p) = m + p and (0 + m) + p = m + p.",
|
||||
"rw [Nat.zero_add, Nat.zero_add]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: Assume n + (m + p) = (n + m) + p, we need to show succ n + (m + p) = (succ n + m) + p.",
|
||||
"-- proof strategy is, we move succ n out (or in) enough times then use the IH until both sides are the same.",
|
||||
"-- 1. let's start by pulling out the succ from the left side and have the entire addition inside the succ.",
|
||||
"have h_pull_add_succ_out_from_left: Nat.succ n + (m + p) = Nat.succ (n + (m + p)) := by rw [Nat.succ_add]",
|
||||
"-- 2. Now that we have the IH hypothesis appearing inside the left, let's apply it so we have n + (m + p) = (n + m) + p.",
|
||||
"have h_inside_left_associates: Nat.succ (n + (m + p)) = Nat.succ ((n + m) + p) := by rw [ih]",
|
||||
"-- 3. Now that the parentheses (apps of plus) are in the right place for both sides, push the succ on the left twice so both terms are the same.",
|
||||
"have h_push_succ_in_left_twice: Nat.succ ((n + m) + p) = ((Nat.succ n) + m) + p := by rw [← Nat.succ_add, ← Nat.succ_add]",
|
||||
"-- Combining these, we get succ n + (m + p) = (succ n + m) + p.",
|
||||
"rw [h_pull_add_succ_out_from_left, h_inside_left_associates, h_push_succ_in_left_twice]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"nl_problem": "Prove that for any natural numbers n, m, and p, n + (m + p) = (n + m) + p.",
|
||||
"nl_solution": [
|
||||
"Consider some natural numbers n, m, and p. We want to show n + (m + p) = (n + m) + p.",
|
||||
"By using facts of addition and induction on n, we can prove the statement for both the base case and the inductive step."
|
||||
],
|
||||
"fl_problem": "theorem add_assoc_proved_formal_sketch_aesop : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by",
|
||||
"fl_solution": [
|
||||
"-- Prove that n + (m + p) = (n + m) + p via a formal proof sketch with aesop",
|
||||
"theorem add_assoc_proved_formal_sketch_aesop : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by",
|
||||
"-- Consider some n, m, and p in Nats.",
|
||||
"intros n m p",
|
||||
"-- Perform induction on n.",
|
||||
"induction n with",
|
||||
"| zero =>",
|
||||
"-- Base case: When n = 0, we need to show 0 + (m + p) = (0 + m) + p.",
|
||||
"-- Using the definition of addition, 0 + (m + p) = m + p and (0 + m) + p = m + p.",
|
||||
"rw [Nat.zero_add, Nat.zero_add]",
|
||||
"| succ n ih =>",
|
||||
"-- Inductive step: Assume n + (m + p) = (n + m) + p, we need to show succ n + (m + p) = (succ n + m) + p.",
|
||||
"-- proof strategy is, we move succ n out (or in) enough times then use the IH until both sides are the same.",
|
||||
"-- 1. let's start by pulling out the succ from the left side and have the entire addition inside the succ.",
|
||||
"have h_pull_add_succ_out_from_left: Nat.succ n + (m + p) = Nat.succ (n + (m + p)) := by rw [Nat.succ_add]",
|
||||
"-- 2. Now that we have the IH hypothesis appearing inside the left, let's apply it so we have n + (m + p) = (n + m) + p.",
|
||||
"have h_inside_left_associates: Nat.succ (n + (m + p)) = Nat.succ ((n + m) + p) := by aesop",
|
||||
"-- 3. Now that the parentheses (apps of plus) are in the right place for both sides, push the succ on the left twice so both terms are the same.",
|
||||
"have h_push_succ_in_left_twice: Nat.succ ((n + m) + p) = ((Nat.succ n) + m) + p := by rw [← Nat.succ_add, ← Nat.succ_add]",
|
||||
"-- Combining these, we get succ n + (m + p) = (succ n + m) + p.",
|
||||
"rw [h_pull_add_succ_out_from_left, h_inside_left_associates, h_push_succ_in_left_twice]"
|
||||
],
|
||||
"src_header_fl_solution": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,98 @@
|
|||
[
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n, 0 + n = n."],
|
||||
"nl_solution": [
|
||||
"Consider any natural number n. We will prove the statement by induction on n.",
|
||||
"Base case: When n = 0, we need to show that 0 + 0 = 0. This is true by the definition of addition.",
|
||||
"Inductive step: Assume that for some natural number n, 0 + n = n. We need to show that 0 + (n + 1) = (n + 1). By the definition of addition and the inductive hypothesis, we have 0 + (n + 1) = (0 + n) + 1 = n + 1. Therefore, the statement holds for n + 1.",
|
||||
"Thus, by induction, we have proved that for any natural number n, 0 + n = n."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural number n, and do induction on n.",
|
||||
"Base case: 0 + 0 = 0 by properties of addition.",
|
||||
"Inductive step we have 0 + n = n. Then 0 + (n + 1) = (0 + n) + 1 = n + 1.",
|
||||
"Where, 0 + n = n by assumption,qed."
|
||||
],
|
||||
"fl_problem": ["theorem zero_plus_n_proved_formal_sketch : ∀ n : ℕ, 0 + n = n := "],
|
||||
"fl_partial_sketch": [
|
||||
"by\n",
|
||||
" -- Consider some n in Nats.\n",
|
||||
" intro n\n",
|
||||
" -- Perform induction on n.\n",
|
||||
" induction n with\n",
|
||||
" | zero =>\n",
|
||||
" -- Base case: 0 + 0 = 0\n",
|
||||
" have h_base: 0 + 0 = 0 := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n",
|
||||
" | succ n ih =>\n",
|
||||
" -- Inductive step: assume 0 + n = n, prove 0 + succ n = succ n\n",
|
||||
" have h_inductive: 0 + Nat.succ n = Nat.succ n := <TODO_PROOF_OR_HAMMER>\\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
],
|
||||
"path_2_file": "~/gold-ai-olympiad/lean_src_proj/lean_basics/basic_nats_using_mathlib_nats2_simp_no_rw.lean",
|
||||
"fl_statement_idx": "1"
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n, m, and p, n + (m + p) = (n + m) + p."],
|
||||
"nl_solution": [
|
||||
"Consider any natural numbers n, m, and p. We will prove the statement by induction on n.",
|
||||
"Base case: When n = 0, we need to show that 0 + (m + p) = (0 + m) + p. By the definition of addition, we have 0 + (m + p) = m + p and (0 + m) + p = m + p. Therefore, 0 + (m + p) = (0 + m) + p.",
|
||||
"Inductive step: Assume that for some natural number n, n + (m + p) = (n + m) + p. We need to show that (n + 1) + (m + p) = ((n + 1) + m) + p.",
|
||||
"1. First, pull out the successor from the left side to have the entire addition inside the successor: (n + 1) + (m + p) = (n + (m + p)) + 1.",
|
||||
"2. By the inductive hypothesis, we know that n + (m + p) = (n + m) + p. So we can replace n + (m + p) with (n + m) + p inside the successor: (n + (m + p)) + 1 = ((n + m) + p) + 1.",
|
||||
"3. Finally, push the successor on the left twice to align both sides: ((n + m) + p) + 1 = (n + 1) + (m + p) = ((n + 1) + m) + p.",
|
||||
"Thus, by induction, we have proved that for any natural numbers n, m, and p, n + (m + p) = (n + m) + p."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural numbers n, m, and p. We will do induction on n.",
|
||||
"Base case: 0 + (m + p) = (0 + m) + p by properties of addition.",
|
||||
"Inductive step, we have n + (m + p) = (n + m) + p. Then (n + 1) + (m + p) = (n + (m + p)) + 1 = ((n + m) + p) + 1.",
|
||||
"Thus, (n + 1) + (m + p) = ((n + 1) + m) + p, qed."
|
||||
],
|
||||
"fl_problem": ["theorem add_assoc_proved_formal_sketch : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := "],
|
||||
"fl_partial_sketch": [
|
||||
"by\n",
|
||||
" -- Consider some n, m, and p in Nats.\n",
|
||||
" intros n m p\n",
|
||||
" -- Perform induction on n.\n",
|
||||
" induction n with\n",
|
||||
" | zero =>\n",
|
||||
" -- Base case: When n = 0, we need to show 0 + (m + p) = (0 + m) + p.\n",
|
||||
" -- We have the fact 0 + (m + p) = m + p by the definition of addition.\n",
|
||||
" have h_base: 0 + (m + p) = m + p := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- We also have the fact (0 + m) + p = m + p by the definition of addition.\n",
|
||||
" have h_symm: (0 + m) + p = m + p := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n",
|
||||
" | succ n ih =>\n",
|
||||
" -- Inductive step: Assume n + (m + p) = (n + m) + p, we need to show succ n + (m + p) = (succ n + m) + p.\n",
|
||||
" -- By the inductive hypothesis, we have n + (m + p) = (n + m) + p.\n",
|
||||
" have h_inductive: n + (m + p) = (n + m) + p := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- 1. Let's start by pulling out the succ from left side and have the entire addition inside the succ.\n",
|
||||
" have h_pull_succ_out_from_left: Nat.succ n + (m + p) = Nat.succ (n + (m + p)) := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- 2. Now that we have the IH hypothesis appearing inside the left, let's apply it so we have n + (m + p) = (n + m) + p.\n",
|
||||
" have h_inside_left_associates: Nat.succ (n + (m + p)) = Nat.succ ((n + m) + p) := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- 3. Now that the parentheses (apps of plus) are in the right place for both sides, push the succ on the left twice so both terms are the same.\n",
|
||||
" have h_push_succ_in_left_twice: Nat.succ ((n + m) + p) = ((Nat.succ n) + m) + p := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
],
|
||||
"path_2_file": "~/gold-ai-olympiad/lean_src_proj/lean_basics/basic_nats_using_mathlib_nats2_simp_no_rw.lean",
|
||||
"fl_statement_idx": "4"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,117 @@
|
|||
[
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n, n + 0 = n."],
|
||||
"nl_solution": [
|
||||
"Consider any natural number n.",
|
||||
"Using the properties of addition, we know that adding zero to any number does not change the value of that number.",
|
||||
"Therefore, we can conclude that n + 0 = n."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural number n.",
|
||||
"From properties of addition, adding zero does not change its values.",
|
||||
"Thus, n + 0 = n."
|
||||
],
|
||||
"fl_problem": ["theorem n_plus_zero_normal : ∀ n : ℕ, n + 0 = n := "],
|
||||
"fl_partial_sketch": [
|
||||
"by\n",
|
||||
" -- We have the fact of addition n + 0 = n, use it to show left and right are equal.\n",
|
||||
" have h_nat_add_zero: ∀ n : ℕ, n + 0 = n := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts with to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
],
|
||||
"path_2_file": "~/gold-ai-olympiad/lean_src_proj/lean_basics/basic_nats_using_mathlib_nats2_simp_no_rw.lean",
|
||||
"fl_statement_idx": "0"
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n, n + (m + 1) = (n + m) + 1."],
|
||||
"nl_solution": [
|
||||
"Consider any natural numbers n and m. We want to show that n + (m + 1) = (n + m) + 1.",
|
||||
"Using the properties of addition, we know that adding 1 to the sum of n and m is the same as first adding m to n and then adding 1.",
|
||||
"Therefore, we can conclude that n + (m + 1) = (n + m) + 1."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural numbers n and m.",
|
||||
"From properties of addition, adding 1 to the sum of n and m is the same as first adding m to n and then adding 1.",
|
||||
"Thus, n + (m + 1) = (n + m) + 1."
|
||||
],
|
||||
"fl_problem": ["theorem plus_n_Sm_proved_formal_sketch : ∀ n m : ℕ, n + (m + 1) = (n + m) + 1 := "],
|
||||
"fl_partial_sketch": [
|
||||
"by\n",
|
||||
" -- We have the fact of addition n + (m + 1) = (n + m) + 1, use it to show left and right are equal.\n",
|
||||
" have h_nat_add_succ: ∀ n m : ℕ, n + (m + 1) = (n + m) + 1 := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
],
|
||||
"path_2_file": "~/gold-ai-olympiad/lean_src_proj/lean_basics/basic_nats_using_mathlib_nats2_simp_no_rw.lean",
|
||||
"fl_statement_idx": "2"
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n and m, n + m = m + n."],
|
||||
"nl_solution": [
|
||||
"Consider any natural numbers n and m. We will prove the statement by induction on n.",
|
||||
"Base case: When n = 0, we need to show that 0 + m = m + 0. By the definition of addition, we have 0 + m = m and m + 0 = m. Therefore, 0 + m = m + 0.",
|
||||
"Inductive step: Assume that for some natural number n, n + m = m + n. We need to show that (n + 1) + m = m + (n + 1).",
|
||||
"1. Start by using the fact that (n + 1) + m = n + (m + 1) and m + (n + 1) = (m + n) + 1.",
|
||||
"2. By the inductive hypothesis, we have n + m = m + n. So we can replace n + (m + 1) with (m + n) + 1.",
|
||||
"3. Now, both sides have the same structure, showing that (n + 1) + m = m + (n + 1).",
|
||||
"Thus, by induction, we have proved that for any natural numbers n and m, n + m = m + n."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural numbers n and m. We will do induction on n.",
|
||||
"Base case: 0 + m = m + 0 by properties of addition.",
|
||||
"Inductive step, we have n + m = m + n. Then (n + 1) + m = (n + m) + 1 = (m + n) + 1 = m + (n + 1).",
|
||||
"Thus, by induction, n + m = m + n, qed."
|
||||
],
|
||||
"fl_problem": ["theorem add_comm_proved_formal_sketch : ∀ n m : ℕ, n + m = m + n := "],
|
||||
"fl_partial_sketch": [
|
||||
"by\n",
|
||||
" -- Consider some n and m in Nats.\n",
|
||||
" intros n m\n",
|
||||
" -- Perform induction on n.\n",
|
||||
" induction n with\n",
|
||||
" | zero =>\n",
|
||||
" -- Base case: When n = 0, we need to show 0 + m = m + 0.\n",
|
||||
" -- We have the fact 0 + m = m by the definition of addition.\n",
|
||||
" have h_base: 0 + m = m := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- We also have the fact m + 0 = m by the definition of addition.\n",
|
||||
" have h_symm: m + 0 = m := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n",
|
||||
" | succ n ih =>\n",
|
||||
" -- Inductive step: Assume n + m = m + n, we need to show succ n + m = m + succ n.\n",
|
||||
" -- By the inductive hypothesis, we have n + m = m + n.\n",
|
||||
" have h_inductive: n + m = m + n := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- 1. Note we start with: Nat.succ n + m = m + Nat.succ n, so, pull the succ out from m + Nat.succ n on the right side from the addition using addition facts Nat.add_succ.\n",
|
||||
" have h_pull_succ_out_from_right: m + Nat.succ n = Nat.succ (m + n) := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- 2. then to flip m + S n to something like S (n + m) we need to use the IH.\n",
|
||||
" have h_flip_n_plus_m: Nat.succ (n + m) = Nat.succ (m + n) := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- 3. Now the n & m are on the correct sides Nat.succ n + m = Nat.succ (n + m), so let's use the def of addition to pull out the succ from the addition on the left using Nat.succ_add.\n",
|
||||
" have h_pull_succ_out_from_left: Nat.succ n + m = Nat.succ (n + m) := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
],
|
||||
"path_2_file": "~/gold-ai-olympiad/lean_src_proj/lean_basics/basic_nats_using_mathlib_nats2_simp_no_rw.lean",
|
||||
"fl_statement_idx": "3"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,106 @@
|
|||
https://www.evernote.com/shard/s410/nl/75276202/2170cbbd-24a1-2d25-da32-bd8f3270d190?title=prompt%20for%20creating%20toy%20example
|
||||
https://chatgpt.com/c/0ad32608-cbc9-4627-a705-786ed7421826
|
||||
I want all final responses in this format:
|
||||
```json
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n, n + 0 = n."],
|
||||
"nl_solution": [
|
||||
"Consider any natural number n.",
|
||||
"Using the properties of addition, we know that adding zero to any number does not change the value of that number.",
|
||||
"Therefore, we can conclude that n + 0 = n."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural number n.",
|
||||
"From properties of addition, adding zero does not change its values.",
|
||||
"Thus, n + 0 = n."
|
||||
],
|
||||
"fl_problem": ["theorem n_plus_zero_normal : ∀ n : ℕ, n + 0 = n :="],
|
||||
"fl_partial_sketch": [
|
||||
"-- Prove that n + 0 = n via a formal proof sketch with holes to be filled\n",
|
||||
"theorem n_plus_zero_proved_formal_sketch'' : ∀ n : ℕ, n + 0 = n := by\n",
|
||||
" -- We have the fact of addition n + 0 = n, use it to show left and right are equal.\n",
|
||||
" have h_nat_add_zero: ∀ n : ℕ, n + 0 = n := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts with to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
],
|
||||
"path_2_file": "~/gold-ai-olympiad/lean_src_proj/lean_basics/basic_nats_using_mathlib_nats2_simp_no_rw.lean",
|
||||
"fl_statement_idx": "0"
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"nl_problem": ["Prove that for any natural number n, 0 + n = n."],
|
||||
"nl_solution": [
|
||||
"Consider any natural number n. We will prove the statement by induction on n.",
|
||||
"Base case: When n = 0, we need to show that 0 + 0 = 0. This is true by the definition of addition.",
|
||||
"Inductive step: Assume that for some natural number n, 0 + n = n. We need to show that 0 + (n + 1) = (n + 1). By the definition of addition and the inductive hypothesis, we have 0 + (n + 1) = (0 + n) + 1 = n + 1. Therefore, the statement holds for n + 1.",
|
||||
"Thus, by induction, we have proved that for any natural number n, 0 + n = n."
|
||||
],
|
||||
"nl_solution_sketch": [
|
||||
"Consider any natural number n, and do induction on n.",
|
||||
"Base case: 0 + 0 = 0 by properties of addition.",
|
||||
"Inductive step we have 0 + n = n. Then 0 + (n + 1) = (0 + n) + 1 = n + 1.",
|
||||
"Where, 0 + n = n by assumption,qed."
|
||||
],
|
||||
"fl_problem": ["theorem zero_plus_n_proved_formal_sketch : ∀ n : ℕ, 0 + n = n :="],
|
||||
"fl_partial_sketch": [
|
||||
"-- Prove that 0 + n = n by induction via a formal proof sketch with holes to be filled\n",
|
||||
"theorem zero_plus_n_proved_formal_sketch'' : ∀ n : ℕ, 0 + n = n := by\n",
|
||||
" -- Consider some n in Nats.\n",
|
||||
" intro n\n",
|
||||
" -- Perform induction on n.\n",
|
||||
" induction n with\n",
|
||||
" | zero =>\n",
|
||||
" -- Base case: 0 + 0 = 0\n",
|
||||
" have h_base: 0 + 0 = 0 := <TODO_PROOF_OR_HAMMER>\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n",
|
||||
" | succ n ih =>\n",
|
||||
" -- Inductive step: assume 0 + n = n, prove 0 + succ n = succ n\n",
|
||||
" have h_inductive: 0 + Nat.succ n = Nat.succ n := <TODO_PROOF_OR_HAMMER>\\n",
|
||||
" -- Combine facts to close goal\n",
|
||||
" <TODO_PROOF_OR_HAMMER>\n"
|
||||
],
|
||||
"src_header_fl_problem": ["import Mathlib.Data.Nat.Basic"],
|
||||
"fl_header_sketch": [
|
||||
"import Mathlib.Data.Nat.Basic",
|
||||
"import Aesop"
|
||||
]
|
||||
}
|
||||
```
|
||||
I want to translate the following formal proof (solution) in lean 4 to a natural language proof (solution) that a human would write (without lean code in it) and eventually make it into a concise nl_solution_sketch, like the following one:
|
||||
```human_problem_solution_proof.json
|
||||
"nl_problem": ["Let \\[f(x) = \\left\\{\n\\begin{array}{cl} ax+3, &\\text{ if }x>2, \\\\\nx-5 &\\text{ if } -2 \\le x \\le 2, \\\\\n2x-b &\\text{ if } x <-2.\n\\end{array}\n\\right.\\]Find $a+b$ if the piecewise function is continuous (which means that its graph can be drawn without lifting your pencil from the paper)."],
|
||||
"nl_solution_sketch": ["For the piecewise function to be continuous, the cases must \"meet\" at $2$ and $-2$. For example, $ax+3$ and $x-5$ must be equal when $x=2$. This implies $a(2)+3=2-5$, which we solve to get $2a=-6 \\Rightarrow a=-3$. Similarly, $x-5$ and $2x-b$ must be equal when $x=-2$. Substituting, we get $-2-5=2(-2)-b$, which implies $b=3$. So $a+b=-3+3=\\boxed{0}$."]
|
||||
```
|
||||
This is my lean 4 fl theorem (fl problem) and fl proof (fl solution):
|
||||
```
|
||||
-- Prove that n + (m + p) = (n + m) + p
|
||||
theorem add_assoc_proved_formal_sketch : ∀ n m p : ℕ, n + (m + p) = (n + m) + p := by
|
||||
-- Consider some n, m, and p in Nats.
|
||||
intros n m p
|
||||
-- Perform induction on n.
|
||||
induction n with
|
||||
| zero =>
|
||||
-- Base case: When n = 0, we need to show 0 + (m + p) = (0 + m) + p.
|
||||
-- Using the definition of addition, 0 + (m + p) = m + p and (0 + m) + p = m + p.
|
||||
simp [Nat.zero_add, Nat.zero_add]
|
||||
| succ n ih =>
|
||||
-- Inductive step: Assume n + (m + p) = (n + m) + p, we need to show succ n + (m + p) = (succ n + m) + p.
|
||||
-- proof strategy is, we move succ n out (or in) enough times then use the IH until both sides are the same.
|
||||
-- 1. let's start by pulling out the scc from left side and have the entire addition inside the succ.
|
||||
have h_pull_add_succ_out_from_left: Nat.succ n + (m + p) = Nat.succ (n + (m + p)) := by simp [Nat.succ_add]
|
||||
-- 2. Now that we have the IH hypothesis appearing inside the left, let's apply it so we have n + (m + p) = (n + m) + p.
|
||||
have h_inside_left_associates: Nat.succ (n + (m + p)) = Nat.succ ((n + m) + p) := by simp [ih]
|
||||
-- 3. Now that the parenthesis (apps of plus) are on the right place for both side, push the succ on the left twice so both terms are the same.
|
||||
have h_push_succ_in_left_twice: Nat.succ ((n + m) + p) = ((Nat.succ n) + m) + p := by simp [Nat.succ_add, Nat.succ_add]
|
||||
-- Combining these, we get succ n + (m + p) = (succ n + m) + p.
|
||||
simp [h_pull_add_succ_out_from_left, h_inside_left_associates, h_push_succ_in_left_twice]
|
||||
```
|
||||
use the comments to translate the fl proof (solution) to natural language solution then use that to output a natural language concise sketch. Make the natural language proof (solution) sketch concise with the core elements of the solution proof. Do this by first outputting the natural language solution, distill it into a very concise proof sketch in natural language with only the core components. Output everything in a json code block please:
|
|
@ -0,0 +1,186 @@
|
|||
examples_for_dsp_draft_prompt_original = [
|
||||
{"tag": "aimeI_2000_p7", "category": "algebra", "metadata": {}, "prompt": "Informal:\n(*### Problem\n\nSuppose that $x,$ $y,$ and $z$ are three positive numbers that satisfy the equations $xyz = 1,$ $x + \\frac {1}{z} = 5,$ and $y + \\frac {1}{x} = 29.$ Then $z + \\frac {1}{y} = \\frac {m}{n},$ where $m$ and $n$ are [[relatively prime]] positive integers. Find $m + n$. Show that it is 5.\n\n\nnote: this is the type of problem that makes you think symmetry, but actually can be solved easily with substitution, and other normal technniques\n\n### Solution\n\nWe can rewrite $xyz=1$ as $\\frac{1}{z}=xy$.\n\nSubstituting into one of the given equations, we have \n$x+xy=5$\n$x(1+y)=5$\n$\\frac{1}{x}=\\frac{1+y}{5}.$\n\nWe can substitute back into $y+\\frac{1}{x}=29$ to obtain\n$y+\\frac{1+y}{5}=29$\n$5y+1+y=145$\n$y=24.$\n\nWe can then substitute once again to get\n$x=\\frac15$\n$z=\\frac{5}{24}.$\nThus, $z+\\frac1y=\\frac{5}{24}+\\frac{1}{24}=\\frac{1}{4}$, so $m+n=005$.*)\n\nFormal:\ntheorem\n fixes x y z :: real\n and p :: rat\n assumes \"0 < x \\<and> 0 < y \\<and> 0 < z\"\n and \"x * y * z = 1\"\n and \"x + 1 / z = 5\"\n and \"y + 1 / x = 29\"\n and \"z + 1 / y = p\"\n and \"0 < p\" \n shows \"let (m,n) = quotient_of p in m + n = 5\"\nproof -\n (* We can rewrite $xyz=1$ as $\\frac{1}{z}=xy$. *)\n have c0: \"z = 1 / (x*y)\"\n sledgehammer\n (* Substituting into one of the given equations, we have \n $x+xy=5$\n $x(1+y)=5$\n $\\frac{1}{x}=\\frac{1+y}{5}.$ *)\n have c1: \"1 / x = (1+y) / 5\" \n proof -\n have \"x + x * y = 5\" using assms(3) unfolding c0\n sledgehammer\n then have \"x * (1 + y) = 5\"\n sledgehammer\n then have t1: \"x = 5 / (1+y)\"\n sledgehammer\n then show ?thesis\n sledgehammer\n qed\n (* We can substitute back into $y+\\frac{1}{x}=29$ to obtain\n $y+\\frac{1+y}{5}=29$\n $5y+1+y=145$\n $y=24.$ *)\n have \"y + (1+y)/5 = 29\" using assms(4) unfolding c1 sledgehammer\n then have \"5* (y + (1+y)/5) = 5 * 29\" sledgehammer\n also have \"... = 145\" sledgehammer\n finally have c2_1: \"5* (y + (1+y)/5) = 145\" sledgehammer\n have \"5* (y + (1+y)/5) = 5*y + (1+y)\" sledgehammer\n also have \"... = 6*y + 1\" sledgehammer\n finally have c2_2: \"5* (y + (1+y)/5) = 6*y + 1\" sledgehammer\n have \"6*y + 1 = 145\" using c2_1 c2_2 sledgehammer\n then have c2: \"y = 24\" sledgehammer\n (* We can then substitute once again to get\n $x=\\frac15$\n $z=\\frac{5}{24}.$ *)\n have \"1/x = 5\" using c1 unfolding c2 sledgehammer\n then have c3: \"x = 1/5\"\n sledgehammer\n then have c4: \"z = 5/24\"\n sledgehammer\n (* Thus, $z+\\frac1y=\\frac{5}{24}+\\frac{1}{24}=\\frac{1}{4}$, so $m+n=005$. *)\n have \"p = z + 1/y\" using assms(5) sledgehammer\n also have \"... = 5/24 + 1/24\" unfolding c2 c4 sledgehammer\n also have \"... = 1/4\" sledgehammer\n finally have c5: \"p = 1/4\"\n sledgehammer\n have \"quotient_of p = (1, 4)\" unfolding c5 sledgehammer\n then show ?thesis sledgehammer\nqed"},
|
||||
{"tag": "algebra_2rootsintpoly_am10tap11eqasqpam110", "category": "algebra", "metadata": {}, "prompt": "Informal:\n(*### Problem\n\nShow that for any complex number a, $(a-10)(a+11) = a^2 + a - 110$.\n\n### Solution\n\nWe first expand all terms of the left hand side to get $a^2 - 10a + 11a - 10*11$.\nThis equals $a^2 + a - 10*11 = a^2 + a - 110$.*)\n\nFormal:\ntheorem\n fixes a :: complex\n shows \"(a-10) * (a+11) = a^2 + a -110\"\nproof -\n (* We first expand all terms of the left hand side to get $a^2 - 10a + 11a - 10*11$. *)\n have \"(a-10) * (a+11) = a^2 - 10*a + 11*a - 10 *11\"\n sledgehammer\n (* This equals $a^2 + a - 10*11 = a^2 + a - 110$. *)\n also have \"\\<dots> = a^2 + a - 10 * 11\"\n sledgehammer\n also have \"\\<dots> = a^2 + a - 110\"\n sledgehammer\n finally show ?thesis\n sledgehammer\nqed"},
|
||||
{"tag": "mathd_numbertheory_335", "category": "number_theory", "metadata": {}, "prompt": "Informal:\n(*### Problem\n\nWhen Rachel divides her favorite number by 7, she gets a remainder of 5. What will the remainder be if she multiplies her favorite number by 5 and then divides by 7? Show that it is 4.\n\n### Solution\n\nLet $n$ be Rachel's favorite number. \nThen $n \\equiv 5 \\pmod{7}$, so $5n \\equiv 5 \\cdot 5 \\equiv 25 \\equiv 4 \\pmod{7}$.\n*)\n\nFormal:\ntheorem\n fixes n :: nat\n assumes h0 : \"n mod 7 = 5\"\n shows \"(5 * n) mod 7 = 4\"\nproof -\n (* Then $n \\equiv 5 \\pmod{7}$, so $5n \\equiv 5 \\cdot 5 \\equiv 25 \\equiv 4 \\pmod{7}$. *)\n have c0:\"(5 * n) mod 7 = (5 * 5) mod 7\" using h0\n sledgehammer\n then have \"\\<dots> = 4\" sledgehammer\n then have \"(5 * n) mod 7 = 4\" using c0 sledgehammer\n then show ?thesis sledgehammer\nqed"}
|
||||
]
|
||||
|
||||
examples_for_dsp_draft_prompt_template = [
|
||||
{
|
||||
"tag": "aimeI_2000_p7",
|
||||
"category": "algebra",
|
||||
"metadata": {},
|
||||
"prompt": (
|
||||
"Informal:\n"
|
||||
"(*### Problem\n\n"
|
||||
"Suppose that $x,$ $y,$ and $z$ are three positive numbers that satisfy the equations $xyz = 1,$ "
|
||||
"$x + \\frac {1}{z} = 5,$ and $y + \\frac {1}{x} = 29.$ Then $z + \\frac {1}{y} = \\frac {m}{n},$ "
|
||||
"where $m$ and $n$ are [[relatively prime]] positive integers. Find $m + n$. Show that it is 5.\n\n"
|
||||
"note: this is the type of problem that makes you think symmetry, but actually can be solved easily "
|
||||
"with substitution, and other normal technniques\n\n"
|
||||
"### Solution\n\n"
|
||||
"We can rewrite $xyz=1$ as $\\frac{1}{z}=xy$.\n\n"
|
||||
"Substituting into one of the given equations, we have \n$x+xy=5$\n$x(1+y)=5$\n$\\frac{1}{x}=\\frac{1+y}{5}.$\n\n"
|
||||
"We can substitute back into $y+\\frac{1}{x}=29$ to obtain\n"
|
||||
"$y+\\frac{1+y}{5}=29$\n$5y+1+y=145$\n$y=24.$\n\n"
|
||||
"We can then substitute once again to get\n$x=\\frac15$\n$z=\\frac{5}{24}.$\n"
|
||||
"Thus, $z+\\frac1y=\\frac{5}{24}+\\frac{1}{24}=\\frac{1}{4}$, so $m+n=005$.*)\n\n"
|
||||
"Formal:\n"
|
||||
"theorem\n"
|
||||
" fixes x y z :: real\n"
|
||||
" and p :: rat\n"
|
||||
" assumes \"0 < x \\<and> 0 < y \\<and> 0 < z\"\n"
|
||||
" and \"x * y * z = 1\"\n"
|
||||
" and \"x + 1 / z = 5\"\n"
|
||||
" and \"y + 1 / x = 29\"\n"
|
||||
" and \"z + 1 / y = p\"\n"
|
||||
" and \"0 < p\" \n"
|
||||
" shows \"let (m,n) = quotient_of p in m + n = 5\"\n"
|
||||
"proof -\n"
|
||||
" (* We can rewrite $xyz=1$ as $\\frac{1}{z}=xy$. *)\n"
|
||||
" have c0: \"z = 1 / (x*y)\"\n"
|
||||
" sledgehammer\n"
|
||||
" (* Substituting into one of the given equations, we have \n"
|
||||
" $x+xy=5$\n"
|
||||
" $x(1+y)=5$\n"
|
||||
" $\\frac{1}{x}=\\frac{1+y}{5}.$ *)\n"
|
||||
" have c1: \"1 / x = (1+y) / 5\" \n"
|
||||
" proof -\n"
|
||||
" have \"x + x * y = 5\" using assms(3) unfolding c0\n"
|
||||
" sledgehammer\n"
|
||||
" then have \"x * (1 + y) = 5\"\n"
|
||||
" sledgehammer\n"
|
||||
" then have t1: \"x = 5 / (1+y)\"\n"
|
||||
" sledgehammer\n"
|
||||
" then show ?thesis\n"
|
||||
" sledgehammer\n"
|
||||
" qed\n"
|
||||
" (* We can substitute back into $y+\\frac{1}{x}=29$ to obtain\n"
|
||||
" $y+\\frac{1+y}{5}=29$\n"
|
||||
" $5y+1+y=145$\n"
|
||||
" $y=24.$ *)\n"
|
||||
" have \"y + (1+y)/5 = 29\" using assms(4) unfolding c1 sledgehammer\n"
|
||||
" then have \"5* (y + (1+y)/5) = 5 * 29\" sledgehammer\n"
|
||||
" also have \"... = 145\" sledgehammer\n"
|
||||
" finally have c2_1: \"5* (y + (1+y)/5) = 145\" sledgehammer\n"
|
||||
" have \"5* (y + (1+y)/5) = 5*y + (1+y)\" sledgehammer\n"
|
||||
" also have \"... = 6*y + 1\" sledgehammer\n"
|
||||
" finally have c2_2: \"5* (y + (1+y)/5) = 6*y + 1\" sledgehammer\n"
|
||||
" have \"6*y + 1 = 145\" using c2_1 c2_2 sledgehammer\n"
|
||||
" then have c2: \"y = 24\" sledgehammer\n"
|
||||
" (* We can then substitute once again to get\n"
|
||||
" $x=\\frac15$\n"
|
||||
" $z=\\frac{5}{24}.$ *)\n"
|
||||
" have \"1/x = 5\" using c1 unfolding c2 sledgehammer\n"
|
||||
" then have c3: \"x = 1/5\"\n"
|
||||
" sledgehammer\n"
|
||||
" then have c4: \"z = 5/24\"\n"
|
||||
" sledgehammer\n"
|
||||
" (* Thus, $z+\\frac1y=\\frac{5}{24}+\\frac{1}{24}=\\frac{1}{4}$, so $m+n=005$. *)\n"
|
||||
" have \"p = z + 1/y\" using assms(5) sledgehammer\n"
|
||||
" also have \"... = 5/24 + 1/24\" unfolding c2 c4 sledgehammer\n"
|
||||
" also have \"... = 1/4\" sledgehammer\n"
|
||||
" finally have c5: \"p = 1/4\"\n"
|
||||
" sledgehammer\n"
|
||||
" have \"quotient_of p = (1, 4)\" unfolding c5 sledgehammer\n"
|
||||
" then show ?thesis sledgehammer\n"
|
||||
"qed"
|
||||
),
|
||||
},
|
||||
{
|
||||
"tag": "algebra_2rootsintpoly_am10tap11eqasqpam110",
|
||||
"category": "algebra",
|
||||
"metadata": {},
|
||||
"prompt": (
|
||||
"Informal:\n"
|
||||
"(*### Problem\n\n"
|
||||
"Show that for any complex number a, $(a-10)(a+11) = a^2 + a - 110$.\n\n"
|
||||
"### Solution\n\n"
|
||||
"We first expand all terms of the left hand side to get $a^2 - 10a + 11a - 10*11$.\n"
|
||||
"This equals $a^2 + a - 10*11 = a^2 + a - 110$.*)\n\n"
|
||||
"Formal:\n"
|
||||
"theorem\n"
|
||||
" fixes a :: complex\n"
|
||||
" shows \"(a-10) * (a+11) = a^2 + a -110\"\n"
|
||||
"proof -\n"
|
||||
" (* We first expand all terms of the left hand side to get $a^2 - 10a + 11a - 10*11$. *)\n"
|
||||
" have \"(a-10) * (a+11) = a^2 - 10*a + 11*a - 10 *11\"\n"
|
||||
" sledgehammer\n"
|
||||
" (* This equals $a^2 + a - 10*11 = a^2 + a - 110$. *)\n"
|
||||
" also have \"\\<dots> = a^2 + a - 10 * 11\"\n"
|
||||
" sledgehammer\n"
|
||||
" also have \"\\<dots> = a^2 + a - 110\"\n"
|
||||
" sledgehammer\n"
|
||||
" finally show ?thesis\n"
|
||||
" sledgehammer\n"
|
||||
"qed"
|
||||
),
|
||||
},
|
||||
{
|
||||
"tag": "mathd_numbertheory_335",
|
||||
"category": "number_theory",
|
||||
"metadata": {},
|
||||
"prompt": (
|
||||
"Informal:\n"
|
||||
"(*### Problem\n\n"
|
||||
"When Rachel divides her favorite number by 7, she gets a remainder of 5. What will the remainder be if she "
|
||||
"multiplies her favorite number by 5 and then divides by 7? Show that it is 4.\n\n"
|
||||
"### Solution\n\n"
|
||||
"Let $n$ be Rachel's favorite number. \n"
|
||||
"Then $n \\equiv 5 \\pmod{7}$, so $5n \\equiv 5 \\cdot 5 \\equiv 25 \\equiv 4 \\pmod{7}$.\n*)\n\n"
|
||||
"Formal:\n"
|
||||
"theorem\n"
|
||||
" fixes n :: nat\n"
|
||||
" assumes h0 : \"n mod 7 = 5\"\n"
|
||||
" shows \"(5 * n) mod 7 = 4\"\n"
|
||||
"proof -\n"
|
||||
" (* Then $n \\equiv 5 \\pmod{7}$, so $5n \\equiv 5 \\cdot 5 \\equiv 25 \\equiv 4 \\pmod{7}$. *)\n"
|
||||
" have c0:\"(5 * n) mod 7 = (5 * 5) mod 7\" using h0\n"
|
||||
" sledgehammer\n"
|
||||
" then have \"\\<dots> = 4\" sledgehammer\n"
|
||||
" then have \"(5 * n) mod 7 = 4\" using c0 sledgehammer\n"
|
||||
" then show ?thesis sledgehammer\n"
|
||||
"qed"
|
||||
),
|
||||
}
|
||||
]
|
||||
|
||||
# -- Prompts for generating (informal) drafts (basically informal/natural language solution strings, that contain less details than a formal proof, hence why they are called "drafts")
|
||||
prompt_draft_template_4_isabelle = """Draft an informal solution similar to the one below.
|
||||
The informal solution will be used to sketch a formal Isabelle proof.
|
||||
Here are some examples: \n"""
|
||||
for example in examples_for_dsp_draft_prompt_template:
|
||||
# P_draft_isa_prompt_template += ("Example:\n" + x['prompt'][:x['prompt'].find('Formal:')] + "\n\n")
|
||||
# - Extract the 'prompt' field from the current example
|
||||
prompt_text = example['prompt']
|
||||
# - Find the index where the 'Formal:' keyword starts
|
||||
formal_index = prompt_text.find('Formal:')
|
||||
# - Extract the part of the prompt before the 'Formal:' keyword
|
||||
nl_prob_soln = prompt_text[:formal_index] # Append nl/i draft examples: prob_nl, soln_nl/draft_nl
|
||||
# - Append this i draft example our prompt draft/P_draft
|
||||
prompt_draft_template_4_isabelle += f"Example:\n{informal_part}\n\n"
|
||||
# append the final part of the prompt template that prompts model to do prediction, we'd need to insert new nl problem text here before using it
|
||||
prompt_draft_template_4_isabelle += """Informal:
|
||||
(*### Problem
|
||||
|
||||
"""
|
||||
|
||||
# P_sketch isabelle, ref: https://github.com/brando90/ntptutorial-II/blob/main/partII_dsp/notebooks/II_dsp__part2_dsp.ipynb
|
||||
prompt = """Translate the informal solution into a sketch of the
|
||||
formal Isabelle proof. Add `sledgehammer` in the sketch whenever
|
||||
possible. `sledgehammer` will be used to call the automated Sledgehammer prover.
|
||||
Here are some examples:
|
||||
"""
|
||||
for x in examples:
|
||||
prompt += (x['prompt'] + "\n\n")
|
||||
prompt += """Informal:
|
||||
(*### Problem
|
||||
|
||||
"""
|
||||
|
||||
xf = """theorem
|
||||
fixes x :: int
|
||||
assumes h0: "even x"
|
||||
shows "odd (x+5)" """
|
||||
|
||||
zi = p.f(prompt, xi + '\n\n' + yi + '\n\n' + xf)
|
||||
print(zi)
|
|
@ -1,3 +1,2 @@
|
|||
/build
|
||||
/lakefile.olean
|
||||
/lake-packages/*
|
|
@ -0,0 +1,68 @@
|
|||
inductive UnaryNat : Type
|
||||
| zero : UnaryNat
|
||||
| succ : UnaryNat → UnaryNat
|
||||
deriving Repr
|
||||
|
||||
#check UnaryNat
|
||||
#check UnaryNat.zero
|
||||
#check UnaryNat.succ
|
||||
#check UnaryNat.succ UnaryNat.zero
|
||||
|
||||
-- 0
|
||||
#eval UnaryNat.zero
|
||||
-- 1
|
||||
#eval (UnaryNat.succ UnaryNat.zero)
|
||||
-- 2
|
||||
#eval (UnaryNat.succ (UnaryNat.succ UnaryNat.zero))
|
||||
|
||||
-- open the namespace for UnaryNat
|
||||
open UnaryNat
|
||||
#check zero
|
||||
|
||||
def add_left : UnaryNat → UnaryNat → UnaryNat
|
||||
| zero, n => n
|
||||
| succ m', n => succ (add_left m' n)
|
||||
|
||||
#check add_left zero
|
||||
#eval add_left zero zero
|
||||
#eval add_left zero (succ zero)
|
||||
#eval add_left (succ zero) zero
|
||||
|
||||
def add_right (m n : UnaryNat) : UnaryNat :=
|
||||
match n with
|
||||
| zero => m
|
||||
| succ n' => succ (add_right m n')
|
||||
|
||||
#eval add_right zero zero
|
||||
|
||||
-- todo add_right == add_left
|
||||
|
||||
infixl:65 "+" => add_left
|
||||
|
||||
#eval zero + zero -- add(0, 0)
|
||||
-- a + b + c -> add(add(a, b), c) or add(a, add(b, c))
|
||||
|
||||
theorem add_zero_is_zero : zero + zero = zero := rfl
|
||||
|
||||
-- 0 + n = n
|
||||
theorem zero_add_n_eq_n : ∀ n : UnaryNat, zero + n = n := by
|
||||
intro n
|
||||
rfl
|
||||
-- simp [add_left]
|
||||
-- rw [add_left]
|
||||
-- print the proof term for me please
|
||||
#print zero_add_n_eq_n
|
||||
|
||||
theorem zero_add_n_eq_n' (n : UnaryNat) : zero + n = n := by rfl
|
||||
#print zero_add_n_eq_n'
|
||||
|
||||
-- n + 0 = n
|
||||
theorem n_add_zero_eq_n : ∀ n : UnaryNat, n + zero = n := by
|
||||
intro n
|
||||
induction n with
|
||||
| zero => apply rfl
|
||||
-- | succ n' ih => rw [add_left]; rw [ih]
|
||||
| succ n' ih => rw [add_left, ih]
|
||||
#print n_add_zero_eq_n
|
||||
|
||||
-- comm, assoc, distrib, etc proofs? see software foundations?
|
|
@ -0,0 +1,107 @@
|
|||
---- Example: define unary natural numbers
|
||||
|
||||
---- define unary nats
|
||||
-- define unary natural numbers
|
||||
inductive UnaryNat : Type
|
||||
| Zero: UnaryNat
|
||||
| Succ: UnaryNat -> UnaryNat
|
||||
-- make unary nats printable
|
||||
deriving Repr
|
||||
|
||||
-- define unary natural numbers
|
||||
inductive MyNat : Type
|
||||
| O: MyNat
|
||||
| S: MyNat -> MyNat
|
||||
-- make unary nats printable
|
||||
deriving Repr
|
||||
----
|
||||
|
||||
----
|
||||
-- bring contents of unary nat into scope
|
||||
open UnaryNat
|
||||
-- bring contents of unary nat into scope
|
||||
open MyNat
|
||||
----
|
||||
|
||||
---- check types and evals
|
||||
-- check type of unary nat, zero and succ
|
||||
#check UnaryNat
|
||||
#check UnaryNat.Zero
|
||||
#check UnaryNat.Succ
|
||||
#check UnaryNat.Succ UnaryNat.Zero
|
||||
#check Succ (Succ Zero)
|
||||
#eval UnaryNat.Zero
|
||||
#eval UnaryNat.Succ UnaryNat.Zero
|
||||
#eval UnaryNat.Succ (UnaryNat.Succ UnaryNat.Zero)
|
||||
#eval Succ (Succ Zero)
|
||||
#check O
|
||||
#eval S (S O)
|
||||
----
|
||||
|
||||
---- define addition for unary natural numbers
|
||||
-- define addition for unary natural numbers (without explicit names in function declaration)
|
||||
def add_left : UnaryNat -> UnaryNat -> UnaryNat
|
||||
| Zero, n => n
|
||||
| Succ m, n => Succ (add_left m n)
|
||||
|
||||
-- define addition for unary natural numbers (with explicit names in function declaration)
|
||||
def add_left' (m n : UnaryNat) : UnaryNat :=
|
||||
match m with
|
||||
| Zero => n
|
||||
| Succ m' => Succ (add_left' m' n)
|
||||
|
||||
-- define addition infix notation
|
||||
infixl:65 "+l" => add_left'
|
||||
|
||||
-- define right addition for unary natural numbers (without explicit names in function declaration)
|
||||
def add_right : UnaryNat -> UnaryNat -> UnaryNat
|
||||
| m, Zero => m
|
||||
| m, Succ n => Succ (add_right m n)
|
||||
|
||||
-- define right addition for unary natural numbers (with explicit names in function declaration)
|
||||
def add_right' (m n : UnaryNat) : UnaryNat :=
|
||||
match n with
|
||||
| Zero => m
|
||||
| Succ n' => Succ (add_right' m n')
|
||||
|
||||
-- define right addition infix notation
|
||||
infixl:65 "+r " => add_right'
|
||||
---
|
||||
|
||||
---- evals for addition
|
||||
-- eval addition for unary natural numbers left and right
|
||||
#eval Zero +l Zero
|
||||
#eval Zero +l (Succ Zero)
|
||||
#eval (Succ Zero) +l (Succ Zero)
|
||||
#eval (Succ (Succ Zero)) +r (Succ Zero)
|
||||
---
|
||||
|
||||
---- theorem show non inductive case of addition
|
||||
-- theorem left addition, 0 + n = n (not inductive proof)
|
||||
theorem add_left_zero_plus_n_eq_n (n : UnaryNat) : Zero +l n = n := by rfl
|
||||
-- theorem left addition, 0 + n = n (not inductive proof) with forall statements
|
||||
theorem add_left_zero_plus_n_eq_n' : Zero +l n = n := by intros; rfl
|
||||
theorem add_left_zero_plus_n_eq_n'' : Zero +l n = n := by
|
||||
intros
|
||||
rfl
|
||||
-- theorem right addition, n + 0 = n (not inductive proof)
|
||||
theorem add_right_n_plus_zero_eq_n (n : UnaryNat) : n +r Zero = n := by rfl
|
||||
-- theorem right addition, n + 0 = n (not inductive proof) with forall statements
|
||||
theorem add_right_n_plus_zero_eq_n' : n +r Zero = n := by intros; rfl
|
||||
theorem add_right_n_plus_zero_eq_n'' : n +r Zero = n := by
|
||||
intros
|
||||
rfl
|
||||
----
|
||||
|
||||
---- theorem show inductive case of addition
|
||||
-- theorem left addition, n + 0 = n (inductive proof)
|
||||
theorem add_left_n_plus_zero_eq_n (n : UnaryNat) : n +l Zero = n := by
|
||||
induction n with
|
||||
| Zero => rfl
|
||||
| Succ n' ih => simp [add_left', ih]
|
||||
-- theorem left addition, n + 0 = n (inductive proof) with forall and use inductive hypothesis explicitly
|
||||
theorem add_left_n_plus_zero_eq_n' : ∀ (n : UnaryNat), n +l Zero = n := by
|
||||
intros n
|
||||
induction n with
|
||||
| Zero => rfl
|
||||
| Succ n' ih => simp [add_left']; assumption
|
|
@ -0,0 +1,25 @@
|
|||
/-
|
||||
f(x) = m*x + c at x=x' and anything else o.w. (e.g., x)
|
||||
|
||||
WTS: lim_{x -> x'} f(x) = m*x' + c
|
||||
-/
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
-- Define the limit of a function at a point
|
||||
def limit (f : ℝ → ℝ) (x' : ℝ) (l : ℝ) : Prop :=
|
||||
∀ ε : ℝ, 0 < ε → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < abs (x - x') ∧ abs (x - x') < δ → abs (f x - l) < ε
|
||||
|
||||
-- Define the target function to reason about f(x) = m*x + c at x=x' and anything else o.w. (e.g., x)
|
||||
noncomputable def lin (m c : ℝ) (x : ℝ) : ℝ := m*x + c
|
||||
noncomputable def f (m c hole_x : ℝ) (x : ℝ) : ℝ := if x = hole_x then lin m c x else x
|
||||
|
||||
-- Prove the limit of a linear funtion with a hole at the point would be the lin value at the hole i.e., f(x) = m*x + c at x=x' is m*x' + c
|
||||
theorem limit_of_lin_func_with_hole_eq_lin_func (m c limit_pt_x : ℝ) : limit (f m c hole_x) hole_x (lin m c hole_x) := by
|
||||
unfold limit
|
||||
intros ε ε_pos
|
||||
-- we want 0 < | f(x) - (m*x' + c) | < ε but in format 0 < | x - x' | < δ, so "invert f on both sides and put in δ format"
|
||||
-- we want 0 < | m*x + c - (m*x' + c) | < ε using def of f not at x'
|
||||
-- we want 0 < |m| * | x - x' | < ε --> 0 < | x - x' | < ε / |m| so δ = ε / |m|
|
||||
use ε / abs m
|
||||
apply And.intro
|
||||
.
|
|
@ -0,0 +1,8 @@
|
|||
-- Define a singly linked list
|
||||
inductive Singly_Node (α : Type) : Type
|
||||
| nil : Singly_Node α
|
||||
| cons : α → Singly_Node α → Singly_Node α
|
||||
|
||||
#check Singly_Node
|
||||
#check Singly_Node.nil
|
||||
#check Singly_Node.cons
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
|
||||
## Appendix
|
||||
|
||||
### Questions:
|
||||
|
||||
Q:
|
|
@ -0,0 +1,128 @@
|
|||
/-
|
||||
Task: prove that f(x) = 1/x has a vertical asymptote (unbounded limit) at x = 0 from both sides.
|
||||
|
||||
def unbounded_limit (f : ℝ → ℝ) (c : ℝ) : Prop := ∀ M > 0, ∃ δ > 0, ∀ x, 0 < |x - c| < δ → M < |f x|
|
||||
|
||||
theorem one_over_x_has_vertical_asymptote_both_sides : lim_{x -> c} f(x) = +-∞
|
||||
Proof:
|
||||
consider any M > 0
|
||||
now show: ∃ δ > 0, ∀ x, 0 < |x - c| < δ → M < |f x|
|
||||
So show: ∃ δ > 0, ∀ x, 0 < |x| < δ → M < |1/x|, so in particular don't forget you want -δ < x < δ when guessing δ from goal.
|
||||
-- guess, delta (s.tif antecedent holds goal holds), so use goal M < |f(x)|, which is M < |1/x| ->
|
||||
1. M < 1/x (so x > 0 since M>0) -> x < M^⁻¹
|
||||
2. M < -1/x (so x < 0 since M>0 <-> M <-M) -> M * -x < 1 -> -x < M^⁻¹ -> -M^⁻¹ < -x
|
||||
1 & 2 means -M^⁻¹ < x < M^⁻¹ <-> |x| < M^⁻¹, so choose δ = M^⁻¹
|
||||
-- end guess heuristic reasoning
|
||||
So continue proof by choosing δ = M^⁻¹, and then show that for all x, 0 < |x| < δ -> M < |1/x|
|
||||
wts: for all x, 0 < |x| < M⁻¹ → M < |1/x|
|
||||
so consider any x such that 0 < |x| < M⁻¹
|
||||
I don't really know how to manipulate things freely with abs |.| so I will consider all the cases.
|
||||
Hypothesis: 0 < |x| < M⁻¹ <-> either 0 < x < M⁻¹ or 0 < -x < M⁻¹ so for both cases we need to show it implies (either because x ∈ ℝ cannot satisfy both)
|
||||
Goal: M < |1/x| <-> M < 1/x for positives or M < -1/x for negatives (either because 1/x ∈ ℝ cannot satisfy both)
|
||||
case 1: I conjecture 0 < x < M⁻¹ -> M < 1/x
|
||||
1. M < 1/x -> x < 1/M = M^⁻¹ (valid since M > 0, so 1/M > 0, x > 0 so 1/x > 0)
|
||||
2. 0 < x < M^⁻¹ (as currently required)
|
||||
case 2: I conjecture 0 < -x < M⁻¹ -> M < -1/x
|
||||
1. M < -1/x -> M * -x < 1 -> -x < 1/M = M^⁻¹ (valid since M > 0, so 1/M > 0, -x > 0 so -1/x > 0)
|
||||
2. 0 < -x < M^⁻¹ (as currently required)
|
||||
Qed.
|
||||
|
||||
facts we will need (I think):
|
||||
identity cancellation (which needs val ≠ 0)
|
||||
multiply on both sides by some value and inequality doesn't change (or if it does that we show the multiplying val is negative)
|
||||
simplifying 1 * val = val in either side
|
||||
perhaps communtativity or/and associativity of multiplication to make sure things cancel simplifying as needed
|
||||
|
||||
note: to concluse p ∨ q we only need to show p or q, so we can consider them separately (if one holds you can conclude the disjoncution but also if both hold)
|
||||
-/
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
-- define f(x) = 1/x = x^⁻¹ for x ≠ 0 latter for mathlib notation (less friction during proofs)
|
||||
noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
#check f
|
||||
-- note evals don't work so for unit tests we will de a theorem, due to ℝ not being "computable"
|
||||
theorem f_evals_unit_test : f 2 = 1/2 := by simp [f]
|
||||
#print f_evals_unit_test
|
||||
|
||||
-- define unbounded limit (form both sides) as a predicate (proposition)
|
||||
def unbounded_limit (f : ℝ → ℝ) (c : ℝ) : Prop := ∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < |x - c| ∧ |x - c| < δ → M < |f x|
|
||||
#check unbounded_limit
|
||||
#print unbounded_limit
|
||||
-- note: writing everything in terms of lt since gt is written in terms of lt
|
||||
|
||||
-- theorem to prove that f(x) = 1/x has a vertical asymptote (unbounded limit) at x = 0 from both sides
|
||||
theorem one_over_x_has_vertical_asymptote_both_sides : unbounded_limit f 0 := by
|
||||
unfold unbounded_limit f
|
||||
-- consider some M > 0
|
||||
intro M h_zero_lt_M
|
||||
-- since goal doesn't have zeros, but we want to use it to match the antecedent, let's simplify the zeros by using the fact x - 0 = 0 at the goal
|
||||
simp only [sub_zero]
|
||||
-- guess δ = M^⁻¹ using goal i.e. M < |1/x| so M < 1/x so x < 1/M = M^⁻¹ and -M < -1/x so -x < M^⁻¹ as δ = M^⁻¹ should work
|
||||
use M⁻¹
|
||||
-- show 0 < δ = M^⁻¹, first deconstruct the ∧ in the goal
|
||||
apply And.intro
|
||||
-- show 0 < M^⁻¹
|
||||
. exact inv_pos.2 h_zero_lt_M
|
||||
. --introduce x and hypothesis deconstructed by and
|
||||
intro x ⟨h_zero_lt_abs_x, h_x_lt_δ⟩
|
||||
-- unfold abs on hypothesis and goal (since I assume it's harder to manipulate abs |.| function)
|
||||
#check abs -- abs := mabs (a : α) : α := a ⊔ a⁻¹ == a -> a ⊔ -a
|
||||
unfold abs at h_x_lt_δ h_zero_lt_abs_x; unfold abs
|
||||
|
||||
-- want to show (wts) M < |1/x|, so transform the goal to M < 1/x for x > 0 and M < -1/x for x < 0
|
||||
-- transform the goal M < x⁻¹ ⊔ -x⁻¹ --> M < x⁻¹ ∨ M < -x⁻¹
|
||||
#check lt_sup_iff -- lt_sup_iff : a < b ⊔ c ↔ a < b ∨ a < c
|
||||
-- simp only [lt_sup_iff] -- also works
|
||||
apply lt_sup_iff.mpr
|
||||
-- transform hypothesis 0 < x ⊔ -x --> 0 < x ∨ 0 < -x
|
||||
apply lt_sup_iff.mp at h_zero_lt_abs_x
|
||||
-- transform hypothesis x ⊔ -x < M⁻¹ --> x < M⁻¹ ∧ -x < M⁻¹
|
||||
#check sup_lt_iff -- sup_lt_iff : a ⊔ b < c ↔ a < c ∧ b < c
|
||||
apply sup_lt_iff.mp at h_x_lt_δ
|
||||
-- to try to close goal M < |1/x|, let's consider both cases by break h_zero_lt_abs_x into both cases 0 < x and 0 < -x and close goals with both cases
|
||||
#check Or
|
||||
#check Or.inl
|
||||
cases h_zero_lt_abs_x with -- TODO: how to name hypothesis with cases in lean4
|
||||
| inl h_x_pos =>
|
||||
-- focus on positive target M < x⁻¹ given we are on the x > 0 case x, so also use positive hypothesis x < M⁻¹, simplify any 1 * val = val or val * 1 = val
|
||||
apply Or.inl
|
||||
apply And.left at h_x_lt_δ
|
||||
-- on goal: mul right goal both sides by x (x > 0), then cancel x⁻¹ with mul x (needs x⁻¹ ≠ 0)
|
||||
have h_x_ne_zero : x ≠ 0 := ne_of_gt h_x_pos
|
||||
-- mul both sides by M right
|
||||
#check mul_lt_mul_right -- (a0 : 0 < a) : b * a < c * a ↔ b < c
|
||||
-- exact (lt_inv h_zero_lt_M h_x_pos).mpr h_x_lt_δ -- also worked!
|
||||
rw [← mul_lt_mul_right h_x_pos]
|
||||
nth_rewrite 2 [mul_comm]
|
||||
#check mul_inv_cancel -- (h : a ≠ 0) : a * a⁻¹ = 1
|
||||
rw [mul_inv_cancel h_x_ne_zero]
|
||||
-- move M to the left by mul by M⁻¹ > 0 (needs M⁻¹ ≠ 0 and/or M ≠ 0)
|
||||
have h_M_inv_lt_zero : 0 < M⁻¹ := inv_pos.2 h_zero_lt_M
|
||||
rw [← mul_lt_mul_left h_M_inv_lt_zero]
|
||||
rw [← mul_assoc]
|
||||
have h_M_ne_zero : M ≠ 0 := ne_of_gt h_zero_lt_M
|
||||
nth_rewrite 2 [mul_comm]; rewrite [mul_inv_cancel h_M_ne_zero]; simp
|
||||
assumption
|
||||
| inr h_x_neg =>
|
||||
-- focus on negative target M < -x⁻¹ given we are on the x < 0 case x, so also use negative hypothesis -x < M⁻¹, simplify any 1 * val = val or val * 1 = val
|
||||
apply Or.inr
|
||||
apply And.right at h_x_lt_δ
|
||||
-- pass -x⁻¹ to the left and pass M to the right
|
||||
#check neg_lt -- -a < b ↔ -b < a
|
||||
-- transform expression -(x⁻¹) to (-x)⁻¹
|
||||
#check neg_inv -- -a⁻¹ = (-a)⁻¹
|
||||
rw [neg_inv]
|
||||
-- multiply both sides by -x (needs -x > 0) left
|
||||
#check mul_lt_mul_left -- (a0 : 0 < a) : a * b < a * c ↔ b < c
|
||||
rw [← mul_lt_mul_left h_x_neg]
|
||||
-- simp only [neg_mul, neg_lt_neg_iff]
|
||||
have h_neg_x_ne_zero : -x ≠ 0 := ne_of_gt h_x_neg
|
||||
rw [mul_inv_cancel h_neg_x_ne_zero]
|
||||
-- move M to the right of the lt by mul right by 0 < M⁻¹ (needs M ≠ 0 for inv cancelation)
|
||||
have h_M_inv_lt_zero : 0 < M⁻¹ := inv_pos.mpr h_zero_lt_M
|
||||
rw [← mul_lt_mul_right h_M_inv_lt_zero]
|
||||
rw [mul_assoc]
|
||||
have h_M_ne_zero : M ≠ 0 := ne_of_gt h_zero_lt_M
|
||||
simp only [mul_inv_cancel h_M_ne_zero]
|
||||
simp
|
||||
assumption
|
|
@ -0,0 +1,104 @@
|
|||
/-
|
||||
Task: prove that f(x) = 1/x has a vertical asymptote (unbounded limit) at x = 0 from both sides.
|
||||
|
||||
def unbounded_limit (f : ℝ → ℝ) (c : ℝ) : Prop := ∀ M > 0, ∃ δ > 0, ∀ x, 0 < |x - c| < δ → M < |f x|
|
||||
|
||||
theorem one_over_x_has_vertical_asymptote_both_sides : lim_{x -> c} f(x) = +-∞
|
||||
Proof:
|
||||
consider any M > 0
|
||||
now show: ∃ δ > 0, ∀ x, 0 < |x - c| < δ → M < |f x|
|
||||
So show: ∃ δ > 0, ∀ x, 0 < |x| < δ → M < |1/x|, so in particular don't forget you want -δ < x < δ when guessing δ from goal.
|
||||
-- guess, delta (s.tif antecedent holds goal holds), so use goal M < |f(x)|, which is M < |1/x| ->
|
||||
1. M < 1/x (so x > 0 since M>0) -> x < M^⁻¹
|
||||
2. M < -1/x (so x < 0 since M>0 <-> M <-M) -> M * -x < 1 -> -x < M^⁻¹ -> -M^⁻¹ < -x
|
||||
1 & 2 means -M^⁻¹ < x < M^⁻¹ <-> |x| < M^⁻¹, so choose δ = M^⁻¹
|
||||
-- end guess heuristic reasoning
|
||||
So continue proof by choosing δ = M^⁻¹, and then show that for all x, 0 < |x| < δ -> M < |1/x|
|
||||
wts: for all x, 0 < |x| < M⁻¹ → M < |1/x|
|
||||
so consider any x such that 0 < |x| < M⁻¹
|
||||
I don't really know how to manipulate things freely with abs |.| so I will consider all the cases.
|
||||
Hypothesis: 0 < |x| < M⁻¹ <-> either 0 < x < M⁻¹ or 0 < -x < M⁻¹ so for both cases we need to show it implies (either because x ∈ ℝ cannot satisfy both)
|
||||
Goal: M < |1/x| <-> M < 1/x for positives or M < -1/x for negatives (either because 1/x ∈ ℝ cannot satisfy both)
|
||||
case 1: I conjecture 0 < x < M⁻¹ -> M < 1/x
|
||||
1. M < 1/x -> x < 1/M = M^⁻¹ (valid since M > 0, so 1/M > 0, x > 0 so 1/x > 0)
|
||||
2. 0 < x < M^⁻¹ (as currently required)
|
||||
case 2: I conjecture 0 < -x < M⁻¹ -> M < -1/x
|
||||
1. M < -1/x -> M * -x < 1 -> -x < 1/M = M^⁻¹ (valid since M > 0, so 1/M > 0, -x > 0 so -1/x > 0)
|
||||
2. 0 < -x < M^⁻¹ (as currently required)
|
||||
Qed.
|
||||
|
||||
facts we will need (I think):
|
||||
identity cancellation (which needs val ≠ 0)
|
||||
multiply on both sides by some value and inequality doesn't change (or if it does that we show the multiplying val is negative)
|
||||
simplifying 1 * val = val in either side
|
||||
perhaps communtativity or/and associativity of multiplication to make sure things cancel simplifying as needed
|
||||
|
||||
note: to concluse p ∨ q we only need to show p or q, so we can consider them separately (if one holds you can conclude the disjoncution but also if both hold)
|
||||
-/
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
-- define f(x) = 1/x = x^⁻¹ for x ≠ 0 latter for mathlib notation (less friction during proofs)
|
||||
noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
#check f
|
||||
-- note evals don't work so for unit tests we will de a theorem, due to ℝ not being "computable"
|
||||
theorem f_evals_unit_test : f 2 = 1/2 := by simp [f]
|
||||
#print f_evals_unit_test
|
||||
|
||||
-- define unbounded limit (form both sides) as a predicate (proposition)
|
||||
def unbounded_limit (f : ℝ → ℝ) (c : ℝ) : Prop := ∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < |x - c| ∧ |x - c| < δ → M < |f x|
|
||||
#check unbounded_limit
|
||||
#print unbounded_limit
|
||||
-- note: writing everything in terms of lt since gt is written in terms of lt
|
||||
|
||||
-- theorem to prove that f(x) = 1/x has a vertical asymptote (unbounded limit) at x = 0 from both sides
|
||||
theorem one_over_x_has_vertical_asymptote_both_sides : unbounded_limit f 0 := by
|
||||
unfold unbounded_limit f
|
||||
-- consider some M > 0
|
||||
intro M h_zero_lt_M
|
||||
-- since goal doesn't have zeros, but we want to use it to match the antecedent, let's simplify the zeros by using the fact x - 0 = 0 at the goal
|
||||
simp only [sub_zero]
|
||||
-- guess δ = M^⁻¹ using goal i.e. M < |1/x| so M < 1/x so x < 1/M = M^⁻¹ and -M < -1/x so -x < M^⁻¹ as δ = M^⁻¹ should work
|
||||
use M⁻¹
|
||||
-- show 0 < δ = M^⁻¹, first deconstruct the ∧ in the goal
|
||||
apply And.intro
|
||||
-- show 0 < M^⁻¹
|
||||
. exact inv_pos.2 h_zero_lt_M
|
||||
. --introduce x and hypothesis deconstructed by and
|
||||
intro x ⟨h_zero_lt_abs_x, h_x_lt_δ⟩
|
||||
-- unfold abs on hypothesis and goal (since I assume it's harder to manipulate abs |.| function)
|
||||
#check abs -- abs := mabs (a : α) : α := a ⊔ a⁻¹ == a -> a ⊔ -a
|
||||
unfold abs at h_x_lt_δ h_zero_lt_abs_x; unfold abs
|
||||
|
||||
-- want to show (wts) M < |1/x|, so transform the goal to M < 1/x for x > 0 and M < -1/x for x < 0
|
||||
-- transform the goal M < x⁻¹ ⊔ -x⁻¹ --> M < x⁻¹ ∨ M < -x⁻¹
|
||||
#check lt_sup_iff -- lt_sup_iff : a < b ⊔ c ↔ a < b ∨ a < c
|
||||
-- simp only [lt_sup_iff] -- also works
|
||||
apply lt_sup_iff.mpr
|
||||
-- transform hypothesis 0 < x ⊔ -x --> 0 < x ∨ 0 < -x
|
||||
apply lt_sup_iff.mp at h_zero_lt_abs_x
|
||||
-- transform hypothesis x ⊔ -x < M⁻¹ --> x < M⁻¹ ∧ -x < M⁻¹
|
||||
#check sup_lt_iff -- sup_lt_iff : a ⊔ b < c ↔ a < c ∧ b < c
|
||||
apply sup_lt_iff.mp at h_x_lt_δ
|
||||
-- to try to close goal M < |1/x|, let's consider both cases by break h_zero_lt_abs_x into both cases 0 < x and 0 < -x and close goals with both cases
|
||||
#check Or
|
||||
#check Or.inl
|
||||
cases h_zero_lt_abs_x with -- TODO: how to name hypothesis with cases in lean4
|
||||
| inl h_x_pos =>
|
||||
-- focus on positive target M < x⁻¹ given we are on the x > 0 case x, so also use positive hypothesis x < M⁻¹, simplify any 1 * val = val or val * 1 = val
|
||||
apply Or.inl
|
||||
apply And.left at h_x_lt_δ
|
||||
-- on goal: mul right goal both sides by x (x > 0), then cancel x⁻¹ with mul x (needs x⁻¹ ≠ 0)
|
||||
-- mul both sides by M right
|
||||
#check mul_lt_mul_right -- (a0 : 0 < a) : b * a < c * a ↔ b < c
|
||||
#check lt_inv -- (ha : 0 < a) (hb : 0 < b) : a < b⁻¹ ↔ b < a⁻¹
|
||||
exact (lt_inv h_zero_lt_M h_x_pos).mpr h_x_lt_δ -- also worked!
|
||||
| inr h_x_neg =>
|
||||
-- focus on negative target M < -x⁻¹ given we are on the x < 0 case x, so also use negative hypothesis -x < M⁻¹, simplify any 1 * val = val or val * 1 = val
|
||||
apply Or.inr
|
||||
apply And.right at h_x_lt_δ
|
||||
-- on goal: mul right goal both sides by -x (x < 0), then cancel -x⁻¹ with mul -x (needs -x⁻¹ ≠ 0)
|
||||
#check lt_inv -- (ha : 0 < a) (hb : 0 < b) : a < b⁻¹ ↔ b < a⁻¹
|
||||
-- rewrite -x⁻¹ --> -(x⁻¹) so swamp sides of inequality using lt_inv works
|
||||
rw [neg_inv]
|
||||
-- have h_neg_x_inv_eq_neg_inv_x : -x⁻¹ = -(x⁻¹) := by simp
|
||||
exact (lt_inv h_zero_lt_M h_x_neg).mpr h_x_lt_δ -- also worked!
|
|
@ -0,0 +1,135 @@
|
|||
-- /-
|
||||
-- Task: prove that f(x) = 1/x has a vertical asymptote (unbounded limit) at x = 0 from both sides.
|
||||
|
||||
-- def unbounded_limit (f : ℝ → ℝ) (c : ℝ) : Prop := ∀ M > 0, ∃ δ > 0, ∀ x, 0 < |x - c| < δ → M < |f x|
|
||||
|
||||
-- theorem one_over_x_has_vertical_asymptote_both_sides : lim_{x -> c} f(x) = +-∞
|
||||
-- Proof:
|
||||
-- consider any M > 0
|
||||
-- now show: ∃ δ > 0, ∀ x, 0 < |x - c| < δ → M < |f x|
|
||||
-- So show: ∃ δ > 0, ∀ x, 0 < |x| < δ → M < |1/x|, so in particular don't forget you want -δ < x < δ when guessing δ from goal.
|
||||
-- -- guess, delta (s.tif antecedent holds goal holds), so use goal M < |f(x)|, which is M < |1/x| ->
|
||||
-- 1. M < 1/x (so x > 0 since M>0) -> x < M^⁻¹
|
||||
-- 2. M < -1/x (so x < 0 since M>0 <-> M <-M) -> M * -x < 1 -> -x < M^⁻¹ -> -M^⁻¹ < -x
|
||||
-- 1 & 2 means -M^⁻¹ < x < M^⁻¹ <-> |x| < M^⁻¹, so choose δ = M^⁻¹
|
||||
-- -- end guess heuristic reasoning
|
||||
-- So continue proof by choosing δ = M^⁻¹, and then show that for all x, 0 < |x| < δ -> M < |1/x|
|
||||
-- wts: for all x, 0 < |x| < M⁻¹ → M < |1/x|
|
||||
-- so consider any x such that 0 < |x| < M⁻¹
|
||||
-- I don't really know how to manipulate things freely with abs |.| so I will consider all the cases.
|
||||
-- Hypothesis: 0 < |x| < M⁻¹ <-> either 0 < x < M⁻¹ or 0 < -x < M⁻¹ so for both cases we need to show it implies (either because x ∈ ℝ cannot satisfy both)
|
||||
-- Goal: M < |1/x| <-> M < 1/x for positives or M < -1/x for negatives (either because 1/x ∈ ℝ cannot satisfy both)
|
||||
-- case 1: I conjecture 0 < x < M⁻¹ -> M < 1/x
|
||||
-- 1. M < 1/x -> x < 1/M = M^⁻¹ (valid since M > 0, so 1/M > 0, x > 0 so 1/x > 0)
|
||||
-- 2. 0 < x < M^⁻¹ (as currently required)
|
||||
-- case 2: I conjecture 0 < -x < M⁻¹ -> M < -1/x
|
||||
-- 1. M < -1/x -> M * -x < 1 -> -x < 1/M = M^⁻¹ (valid since M > 0, so 1/M > 0, -x > 0 so -1/x > 0)
|
||||
-- 2. 0 < -x < M^⁻¹ (as currently required)
|
||||
-- Qed.
|
||||
|
||||
-- facts we will need (I think):
|
||||
-- identity cancellation (which needs val ≠ 0)
|
||||
-- multiply on both sides by some value and inequality doesn't change (or if it does that we show the multiplying val is negative)
|
||||
-- simplifying 1 * val = val in either side
|
||||
-- perhaps communtativity or/and associativity of multiplication to make sure things cancel simplifying as needed
|
||||
|
||||
-- note: to concluse p ∨ q we only need to show p or q, so we can consider them separately (if one holds you can conclude the disjoncution but also if both hold)
|
||||
-- -/
|
||||
-- import Mathlib.Data.Real.Basic
|
||||
|
||||
-- -- define f(x) = 1/x = x^⁻¹ for x ≠ 0 latter for mathlib notation (less friction during proofs)
|
||||
-- noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
-- #check f
|
||||
-- -- note evals don't work so for unit tests we will de a theorem, due to ℝ not being "computable"
|
||||
-- theorem f_evals_unit_test : f 2 = 1/2 := by simp [f]
|
||||
-- #print f_evals_unit_test
|
||||
|
||||
-- -- define unbounded limit (form both sides) as a predicate (proposition)
|
||||
-- def unbounded_limit (f : ℝ → ℝ) (c : ℝ) : Prop := ∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < |x - c| ∧ |x - c| < δ → M < |f x|
|
||||
-- #check unbounded_limit
|
||||
-- #print unbounded_limit
|
||||
-- -- note: writing everything in terms of lt since gt is written in terms of lt
|
||||
|
||||
-- -- theorem to prove that f(x) = 1/x has a vertical asymptote (unbounded limit) at x = 0 from both sides
|
||||
-- theorem one_over_x_has_vertical_asymptote_both_sides : unbounded_limit f 0 := by
|
||||
-- unfold unbounded_limit f
|
||||
-- -- consider some M > 0
|
||||
-- intro M h_zero_lt_M
|
||||
-- -- since goal doesn't have zeros, but we want to use it to match the antecedent, let's simplify the zeros by using the fact x - 0 = 0 at the goal
|
||||
-- simp only [sub_zero]
|
||||
-- -- guess δ = M^⁻¹ using goal i.e. M < |1/x| so M < 1/x so x < 1/M = M^⁻¹ and -M < -1/x so -x < M^⁻¹ as δ = M^⁻¹ should work
|
||||
-- use M⁻¹
|
||||
-- -- show 0 < δ = M^⁻¹, first deconstruct the ∧ in the goal
|
||||
-- apply And.intro
|
||||
-- -- show 0 < M^⁻¹
|
||||
-- . exact inv_pos.2 h_zero_lt_M
|
||||
-- . --introduce x and hypothesis deconstructed by and
|
||||
-- intro x ⟨h_zero_lt_abs_x, h_x_lt_δ⟩
|
||||
-- -- unfold abs on hypothesis and goal (since I assume it's harder to manipulate abs |.| function)
|
||||
-- #check abs -- abs := mabs (a : α) : α := a ⊔ a⁻¹ == a -> a ⊔ -a
|
||||
-- unfold abs at h_x_lt_δ h_zero_lt_abs_x; unfold abs
|
||||
|
||||
-- -- want to show (wts) M < |1/x|, so transform the goal to M < 1/x for x > 0 and M < -1/x for x < 0
|
||||
-- -- transform the goal M < x⁻¹ ⊔ -x⁻¹ --> M < x⁻¹ ∨ M < -x⁻¹
|
||||
-- #check lt_sup_iff -- lt_sup_iff : a < b ⊔ c ↔ a < b ∨ a < c
|
||||
-- -- simp only [lt_sup_iff] -- also works
|
||||
-- apply lt_sup_iff.mpr
|
||||
-- -- transform hypothesis 0 < x ⊔ -x --> 0 < x ∨ 0 < -x
|
||||
-- apply lt_sup_iff.mp at h_zero_lt_abs_x
|
||||
-- -- transform hypothesis x ⊔ -x < M⁻¹ --> x < M⁻¹ ∧ -x < M⁻¹
|
||||
-- #check sup_lt_iff -- sup_lt_iff : a ⊔ b < c ↔ a < c ∧ b < c
|
||||
-- apply sup_lt_iff.mp at h_x_lt_δ
|
||||
-- -- to try to close goal M < |1/x|, let's consider both cases by break h_zero_lt_abs_x into both cases 0 < x and 0 < -x and close goals with both cases
|
||||
-- #check Or
|
||||
-- #check Or.inl
|
||||
-- cases h_zero_lt_abs_x
|
||||
-- #check h_zero_lt_M
|
||||
-- #check h✝
|
||||
-- rename 0 < x h_x_pos
|
||||
|
||||
|
||||
|
||||
-- -- cases h_zero_lt_abs_x with -- TODO: how to name hypothesis with cases in lean4
|
||||
-- -- | inl h_x_pos =>
|
||||
-- -- -- focus on positive target M < x⁻¹ given we are on the x > 0 case x, so also use positive hypothesis x < M⁻¹, simplify any 1 * val = val or val * 1 = val
|
||||
-- -- apply Or.inl
|
||||
-- -- apply And.left at h_x_lt_δ
|
||||
-- -- -- on goal: mul right goal both sides by x (x > 0), then cancel x⁻¹ with mul x (needs x⁻¹ ≠ 0)
|
||||
-- -- have h_x_ne_zero : x ≠ 0 := ne_of_gt h_x_pos
|
||||
-- -- -- mul both sides by M right
|
||||
-- -- #check mul_lt_mul_right -- (a0 : 0 < a) : b * a < c * a ↔ b < c
|
||||
-- -- -- exact (lt_inv h_zero_lt_M h_x_pos).mpr h_x_lt_δ -- also worked!
|
||||
-- -- rw [← mul_lt_mul_right h_x_pos]
|
||||
-- -- nth_rewrite 2 [mul_comm]
|
||||
-- -- #check mul_inv_cancel -- (h : a ≠ 0) : a * a⁻¹ = 1
|
||||
-- -- rw [mul_inv_cancel h_x_ne_zero]
|
||||
-- -- -- move M to the left by mul by M⁻¹ > 0 (needs M⁻¹ ≠ 0 and/or M ≠ 0)
|
||||
-- -- have h_M_inv_lt_zero : 0 < M⁻¹ := inv_pos.2 h_zero_lt_M
|
||||
-- -- rw [← mul_lt_mul_left h_M_inv_lt_zero]
|
||||
-- -- rw [← mul_assoc]
|
||||
-- -- have h_M_ne_zero : M ≠ 0 := ne_of_gt h_zero_lt_M
|
||||
-- -- nth_rewrite 2 [mul_comm]; rewrite [mul_inv_cancel h_M_ne_zero]; simp
|
||||
-- -- assumption
|
||||
-- -- | inr h_x_neg =>
|
||||
-- -- -- focus on negative target M < -x⁻¹ given we are on the x < 0 case x, so also use negative hypothesis -x < M⁻¹, simplify any 1 * val = val or val * 1 = val
|
||||
-- -- apply Or.inr
|
||||
-- -- apply And.right at h_x_lt_δ
|
||||
-- -- -- pass -x⁻¹ to the left and pass M to the right
|
||||
-- -- #check neg_lt -- -a < b ↔ -b < a
|
||||
-- -- -- transform expression -(x⁻¹) to (-x)⁻¹
|
||||
-- -- #check neg_inv -- -a⁻¹ = (-a)⁻¹
|
||||
-- -- rw [neg_inv]
|
||||
-- -- -- multiply both sides by -x (needs -x > 0) left
|
||||
-- -- #check mul_lt_mul_left -- (a0 : 0 < a) : a * b < a * c ↔ b < c
|
||||
-- -- rw [← mul_lt_mul_left h_x_neg]
|
||||
-- -- -- simp only [neg_mul, neg_lt_neg_iff]
|
||||
-- -- have h_neg_x_ne_zero : -x ≠ 0 := ne_of_gt h_x_neg
|
||||
-- -- rw [mul_inv_cancel h_neg_x_ne_zero]
|
||||
-- -- -- move M to the right of the lt by mul right by 0 < M⁻¹ (needs M ≠ 0 for inv cancelation)
|
||||
-- -- have h_M_inv_lt_zero : 0 < M⁻¹ := inv_pos.mpr h_zero_lt_M
|
||||
-- -- rw [← mul_lt_mul_right h_M_inv_lt_zero]
|
||||
-- -- rw [mul_assoc]
|
||||
-- -- have h_M_ne_zero : M ≠ 0 := ne_of_gt h_zero_lt_M
|
||||
-- -- simp only [mul_inv_cancel h_M_ne_zero]
|
||||
-- -- simp
|
||||
-- -- assumption
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"problem": "How many vertical asymptotes does 1/x have around 0 from the right?",
|
||||
"level": "Level 2",
|
||||
"type": "Algebra",
|
||||
"solution": "$1/x$ goes to positive infinity from the right as $x$ goes to zero and nowhere else, so it has $\\boxed{1}$ veritcal asymptote."
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"problem": "Show that 1/x has an unbounded limit from the right as x approaches zero?",
|
||||
"level": "Level 2",
|
||||
"type": "Algebra",
|
||||
"solution": "..."
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/-
|
||||
theorem: lim_{x -> c+} f(x) = +infinity
|
||||
|
||||
x + infinit = +infinity
|
||||
|
||||
lim_{x -> c} f(x) = L
|
||||
∀ ε > 0, ∃ δ > 0, 0 < |x - c| < δ → 0 < |f(x) - L| < ε
|
||||
|
||||
L = + infinity
|
||||
consider some ε > 0
|
||||
0 < |f(x) - L| < ε
|
||||
0 < |f(x) - +infinity| < ε
|
||||
|
||||
--> this formalization doens't seem promising
|
||||
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: lim_{x -> 0+} 1/x = +infinity
|
||||
∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
-- unboudned limit := "for any M, there exists a sufficiently close x s.t. f(x) is strictly greater than M"
|
||||
∀ M: ℝ, 0 < M, ∃ δ : ℝ, 0 < δ, ∀ x : ℝ, 0 < x - c < δ → M < f(x)
|
||||
|
||||
proof:
|
||||
consider some M > 0 (intro M)
|
||||
-- choose delta, M < f(x) --> M < 1/x --> 1/M > x --> x < M⁻¹
|
||||
δ = M⁻¹
|
||||
. show 0 < δ
|
||||
fact M > 0 --> M⁻¹ > 0 (by lemma in lean, division by positive number)
|
||||
0 < x - c -> rewrite
|
||||
-> 0 < x
|
||||
x - c < δ -> rewrite
|
||||
-> x < M⁻¹
|
||||
(WTS: M < x⁻¹)
|
||||
x < M⁻¹
|
||||
-- multiply both sides by x⁻¹ if x⁻¹ > 0 (lemma, have stmt)
|
||||
-> 0 < x --> x⁻¹ > 0
|
||||
x⁻¹ * x < M^⁻¹ * x⁻¹
|
||||
by identity x⁻¹ * x = 1 of fields (lemma in lean or automation)
|
||||
1 < M⁻¹ * x⁻¹
|
||||
-- multiply both sides by M if M > 0
|
||||
1 < M⁻¹ * x⁻¹
|
||||
M * 1 < M * M⁻¹ * x⁻¹
|
||||
-- identity
|
||||
M < x⁻¹
|
||||
Qed
|
||||
|
||||
-/
|
||||
|
||||
-- import real numbers form mathlib
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
#print f
|
||||
#check f
|
||||
#check f 1
|
||||
-- #eval f 1
|
||||
-- theorem any_R : ℝ -> R := λ x : ℝ, x -- TODO
|
||||
theorem unit_test_f_1 : f 1 = 1 := by simp [f]
|
||||
theorem unit_test_f_2 : f 2 = 1/2 := by simp [f]
|
||||
noncomputable def f' (x : ℝ) : ℝ := 1/x
|
||||
theorem units_f_eq_f' : ∀ x : ℝ , f x = f' x := by simp [f, f']
|
||||
#print units_f_eq_f'
|
||||
|
||||
-- lim_{x -> c+} f(x) = +infinity := ∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
def unbounded_limit (f : ℝ -> ℝ) (c : ℝ) : Prop :=
|
||||
∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < x - c ∧ x - c < δ → M < f x
|
||||
|
||||
-- show 1/x is unbounded as x -> 0 (or 1/x has a veritcal asymptote at x = 0)
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: unbounded_limit f 0 := by
|
||||
unfold unbounded_limit f
|
||||
-- choose M : ℝ and is M > 0
|
||||
intro M h_M_pos
|
||||
-- choose delta = M⁻¹ by a tactic
|
||||
use M⁻¹
|
||||
-- deconstruct the constructor Left ∧ Right = And(Left, Right) to Left, Right using a tactic
|
||||
apply And.intro
|
||||
. exact (by simp [h_M_pos]) -- TODO try to find the lemma in mathlib to prove this
|
||||
. intro x ⟨h_x_pos, h_x_lt_M⟩
|
||||
-- rewrite x - 0 to x using a tactic for sub
|
||||
rw [sub_zero] at h_x_pos h_x_lt_M
|
||||
-- multiply both sides by x we know 0 < x so it should work, using a tactic rewrite
|
||||
-- mul_lt_mul_left: (a0 : 0 < a) : a * b < a * c ← b < c
|
||||
rw [← mul_lt_mul_left h_x_pos]
|
||||
-- rewrite x * x⁻¹ = 1
|
||||
-- mul_inv_cancel: a ≠ 0 → a * a⁻¹ = 1
|
||||
have h_x_neq_zero: x ≠ 0 := by exact ne_of_gt h_x_pos
|
||||
rw [mul_inv_cancel h_x_neq_zero]
|
||||
have h_M_inv_pos: 0 < M⁻¹ := by simp [h_M_pos]
|
||||
-- multiply both sides by M⁻¹ on the right
|
||||
rw [← mul_lt_mul_right h_M_inv_pos]
|
||||
-- rewrite 1 * M = M
|
||||
rw [one_mul]
|
||||
-- rewrite M * M⁻¹ = 1
|
||||
-- mul_inv_cancel: a ≠ 0 → a * a⁻¹ = 1
|
||||
have h_M_neq_zero: M ≠ 0 := by exact ne_of_gt h_M_pos
|
||||
-- have h_M_inv: M * M⁻¹ = 1 := by rw [mul_inv_cancel h_M_neq_zero]
|
||||
rw [mul_inv_cancel_right₀ h_M_neq_zero x]
|
||||
assumption
|
|
@ -0,0 +1,39 @@
|
|||
/-
|
||||
-/
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
-- define 1/x (reciprical) for reals
|
||||
noncomputable def f (x : ℝ ): ℝ := x⁻¹
|
||||
#check f
|
||||
|
||||
-- unit test that f 1 = 1, f 2 = 1/2
|
||||
theorem test_f1 : f 1 = 1 := by simp[f]
|
||||
theorem test_f2 : f 2 = 2⁻¹ := by simp[f]
|
||||
#print test_f1
|
||||
#print test_f2
|
||||
|
||||
-- set_option pp.notation false
|
||||
-- The limit of f x as x approaches c+ from the right is +infinity i.e., limit is unbounded from the right
|
||||
-- i.e., lim_{x -> c+} f(x) = +infinity
|
||||
def has_unbounded_limit_right (f: ℝ -> ℝ) (c : ℝ) : Prop :=
|
||||
∀ M : ℝ, 0 < M → ∃ δ, 0 < δ ∧ ∀ x : ℝ, 0 < x - c ∧ x - c < δ → M < f x
|
||||
#print has_unbounded_limit_right
|
||||
|
||||
theorem reciprocal_has_unbounded_limit_right : has_unbounded_limit_right f 0 := by
|
||||
unfold has_unbounded_limit_right
|
||||
intro M h_0_lt_M
|
||||
-- select delta that works since func is 1/x then anything less than 1/M will make f x be greater than M (so it should work)
|
||||
use M⁻¹
|
||||
-- TODO split (what did scott want with this, read)
|
||||
constructor
|
||||
. rwa [inv_pos]
|
||||
. -- consider any x with 0 < x - 0 < M⁻¹ but introduce both hypothesis 0 < x - 0 and x - 0 < M⁻¹
|
||||
intro x ⟨h_x_pos, h_x_lt_δ⟩
|
||||
-- rintro x ⟨h_x_pos, h_x_lt_δ⟩ -- TODO tomorrow, why did scott do this?
|
||||
-- rewrite both hypothesis using fact m - 0 = m
|
||||
rw [sub_zero] at h_x_pos h_x_lt_δ
|
||||
unfold f
|
||||
-- multiply both sides of h_x_lt_δ by x⁻¹ on the left using mul_lt_mul_right
|
||||
rwa [propext (lt_inv h_0_lt_M h_x_pos)]
|
||||
|
||||
-- state p f = 1 todo: https://proofassistants.stackexchange.com/questions/3800/given-some-proposition-in-lean-4-how-do-we-state-a-theorem-saying-that-we-want
|
|
@ -0,0 +1,99 @@
|
|||
/-
|
||||
theorem: lim_{x -> c+} f(x) = +infinity
|
||||
|
||||
x + infinit = +infinity
|
||||
|
||||
lim_{x -> c} f(x) = L
|
||||
∀ ε > 0, ∃ δ > 0, 0 < |x - c| < δ → 0 < |f(x) - L| < ε
|
||||
|
||||
L = + infinity
|
||||
consider some ε > 0
|
||||
0 < |f(x) - L| < ε
|
||||
0 < |f(x) - +infinity| < ε
|
||||
|
||||
--> this formalization doens't seem promising
|
||||
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: lim_{x -> 0+} 1/x = +infinity
|
||||
∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
-- unboudned limit := "for any M, there exists a sufficiently close x s.t. f(x) is strictly greater than M"
|
||||
∀ M: ℝ, 0 < M, ∃ δ : ℝ, 0 < δ, ∀ x : ℝ, 0 < x - c < δ → M < f(x)
|
||||
|
||||
proof:
|
||||
consider some M > 0 (intro M)
|
||||
-- choose delta, M < f(x) --> M < 1/x --> 1/M > x --> x < M⁻¹
|
||||
δ = M⁻¹
|
||||
. show 0 < δ
|
||||
fact M > 0 --> M⁻¹ > 0 (by lemma in lean, division by positive number)
|
||||
0 < x - c -> rewrite
|
||||
-> 0 < x
|
||||
x - c < δ -> rewrite
|
||||
-> x < M⁻¹
|
||||
(WTS: M < x⁻¹)
|
||||
x < M⁻¹
|
||||
-- multiply both sides by x⁻¹ if x⁻¹ > 0 (lemma, have stmt)
|
||||
-> 0 < x --> x⁻¹ > 0
|
||||
x⁻¹ * x < M^⁻¹ * x⁻¹
|
||||
by identity x⁻¹ * x = 1 of fields (lemma in lean or automation)
|
||||
1 < M⁻¹ * x⁻¹
|
||||
-- multiply both sides by M if M > 0
|
||||
1 < M⁻¹ * x⁻¹
|
||||
M * 1 < M * M⁻¹ * x⁻¹
|
||||
-- identity
|
||||
M < x⁻¹
|
||||
Qed
|
||||
|
||||
-/
|
||||
|
||||
-- import real numbers form mathlib
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
#print f
|
||||
#check f
|
||||
#check f 1
|
||||
-- #eval f 1
|
||||
-- theorem any_R : ℝ -> R := λ x : ℝ, x -- TODO
|
||||
theorem unit_test_f_1 : f 1 = 1 := by simp [f]
|
||||
theorem unit_test_f_2 : f 2 = 1/2 := by simp [f]
|
||||
noncomputable def f' (x : ℝ) : ℝ := 1/x
|
||||
theorem units_f_eq_f' : ∀ x : ℝ , f x = f' x := by simp [f, f']
|
||||
#print units_f_eq_f'
|
||||
|
||||
-- lim_{x -> c+} f(x) = +infinity := ∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
def unbounded_limit (f : ℝ -> ℝ) (c : ℝ) : Prop :=
|
||||
∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < x - c ∧ x - c < δ → M < f x
|
||||
|
||||
-- show 1/x is unbounded as x -> 0 (or 1/x has a veritcal asymptote at x = 0)
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: unbounded_limit f 0 := by
|
||||
unfold unbounded_limit f
|
||||
-- choose M : ℝ and is M > 0
|
||||
intro M h_M_pos
|
||||
-- choose delta = M⁻¹ by a tactic
|
||||
use M⁻¹
|
||||
-- deconstruct the constructor Left ∧ Right = And(Left, Right) to Left, Right using a tactic
|
||||
apply And.intro
|
||||
. exact (by simp [h_M_pos]) -- TODO try to find the lemma in mathlib to prove this
|
||||
. intro x ⟨h_x_pos, h_x_lt_M⟩
|
||||
-- rewrite x - 0 to x using a tactic for sub
|
||||
rw [sub_zero] at h_x_pos h_x_lt_M
|
||||
-- using rewrite do M < x⁻¹ → M * x < x⁻¹ * x by mulitpling both sides by x on the right
|
||||
-- #print mul_lt_mul_right -- (a0 : 0 < a) : b * a < c * a ↔ b < c
|
||||
rw [← mul_lt_mul_right h_x_pos]
|
||||
-- using rewrite let's cancel the x's i.e. x * x⁻¹ = 1 or use the multiplicatitve identity lemma
|
||||
-- apply commutativity of multiplication to the end part of the equation, to goal part 2
|
||||
nth_rewrite 2 [mul_comm]
|
||||
-- (h : a ≠ 0) : a * a⁻¹ = 1 let define a lemma for x ≠ 0
|
||||
have h_x_neq_zero: x ≠ 0 := ne_of_gt h_x_pos
|
||||
rw [mul_inv_cancel h_x_neq_zero]
|
||||
-- let's (left) multiply both sides by M⁻¹ then cancel the M's then simplify M⁻¹*1 = M⁻¹ the close proof
|
||||
have h_M_inv_pos: 0 < M⁻¹ := by simp [h_M_pos]
|
||||
rw [← mul_lt_mul_left h_M_inv_pos]
|
||||
rw [mul_one]
|
||||
-- rewrite M⁻¹ * M * x = M * M⁻¹ * x via associativity of multiplication
|
||||
-- (a b c : G) : a * b * c = a * (b * c)
|
||||
rw [← mul_assoc]
|
||||
-- cancel the M's then simplify M⁻¹*1 = M⁻¹ the close proof
|
||||
have h_M_neq_zero: M ≠ 0 := ne_of_gt h_M_pos
|
||||
-- mul_inv_cancel : (h : a ≠ 0) : a * a⁻¹ = 1
|
||||
simp [h_M_neq_zero]
|
||||
assumption
|
|
@ -0,0 +1,103 @@
|
|||
/-
|
||||
theorem: lim_{x -> c+} f(x) = +infinity
|
||||
|
||||
x + infinit = +infinity
|
||||
|
||||
lim_{x -> c} f(x) = L
|
||||
∀ ε > 0, ∃ δ > 0, 0 < |x - c| < δ → 0 < |f(x) - L| < ε
|
||||
|
||||
L = + infinity
|
||||
consider some ε > 0
|
||||
0 < |f(x) - L| < ε
|
||||
0 < |f(x) - +infinity| < ε
|
||||
|
||||
--> this formalization doens't seem promising
|
||||
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: lim_{x -> 0+} 1/x = +infinity
|
||||
∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
-- unboudned limit := "for any M, there exists a sufficiently close x s.t. f(x) is strictly greater than M"
|
||||
∀ M: ℝ, 0 < M, ∃ δ : ℝ, 0 < δ, ∀ x : ℝ, 0 < x - c < δ → M < f(x)
|
||||
|
||||
proof:
|
||||
consider some M > 0 (intro M)
|
||||
-- choose delta, M < f(x) --> M < 1/x --> 1/M > x --> x < M⁻¹
|
||||
δ = M⁻¹
|
||||
. show 0 < δ
|
||||
fact M > 0 --> M⁻¹ > 0 (by lemma in lean, division by positive number)
|
||||
0 < x - c -> rewrite
|
||||
-> 0 < x
|
||||
x - c < δ -> rewrite
|
||||
-> x < M⁻¹
|
||||
(WTS: M < x⁻¹)
|
||||
x < M⁻¹
|
||||
-- multiply both sides by x⁻¹ if x⁻¹ > 0 (lemma, have stmt)
|
||||
-> 0 < x --> x⁻¹ > 0
|
||||
x⁻¹ * x < M^⁻¹ * x⁻¹
|
||||
by identity x⁻¹ * x = 1 of fields (lemma in lean or automation)
|
||||
1 < M⁻¹ * x⁻¹
|
||||
-- multiply both sides by M if M > 0
|
||||
1 < M⁻¹ * x⁻¹
|
||||
M * 1 < M * M⁻¹ * x⁻¹
|
||||
-- identity
|
||||
M < x⁻¹
|
||||
Qed
|
||||
|
||||
-/
|
||||
|
||||
-- import real numbers form mathlib
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
#print f
|
||||
#check f
|
||||
#check f 1
|
||||
-- #eval f 1
|
||||
-- theorem any_R : ℝ -> R := λ x : ℝ, x -- TODO
|
||||
theorem unit_test_f_1 : f 1 = 1 := by simp [f]
|
||||
theorem unit_test_f_2 : f 2 = 1/2 := by simp [f]
|
||||
noncomputable def f' (x : ℝ) : ℝ := 1/x
|
||||
theorem units_f_eq_f' : ∀ x : ℝ , f x = f' x := by simp [f, f']
|
||||
#print units_f_eq_f'
|
||||
|
||||
-- lim_{x -> c+} f(x) = +infinity := ∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
def unbounded_limit (f : ℝ -> ℝ) (c : ℝ) : Prop :=
|
||||
∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < x - c ∧ x - c < δ → M < f x
|
||||
|
||||
-- show 1/x is unbounded as x -> 0 (or 1/x has a veritcal asymptote at x = 0)
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: unbounded_limit f 0 := by
|
||||
unfold unbounded_limit f
|
||||
-- choose M : ℝ and is M > 0
|
||||
intro M h_M_pos
|
||||
-- choose delta = M⁻¹ by a tactic
|
||||
use M⁻¹
|
||||
-- deconstruct the constructor Left ∧ Right = And(Left, Right) to Left, Right using a tactic
|
||||
apply And.intro
|
||||
. exact (by simp [h_M_pos]) -- TODO try to find the lemma in mathlib to prove this
|
||||
. intro x ⟨h_x_pos, h_x_lt_M⟩
|
||||
-- rewrite x - 0 to x using a tactic for sub
|
||||
rw [sub_zero] at h_x_pos h_x_lt_M
|
||||
-- using rewrite do M < x⁻¹ → M * x < x⁻¹ * x by mulitpling both sides by x on the right
|
||||
-- #print mul_lt_mul_right -- (a0 : 0 < a) : b * a < c * a ↔ b < c
|
||||
rw [← mul_lt_mul_right h_x_pos]
|
||||
-- using rewrite let's cancel the x's i.e. x * x⁻¹ = 1 or use the multiplicatitve identity lemma
|
||||
-- apply commutativity of multiplication to the end part of the equation, to goal part 2
|
||||
nth_rewrite 2 [mul_comm]
|
||||
-- (h : a ≠ 0) : a * a⁻¹ = 1 let define a lemma for x ≠ 0
|
||||
have h_x_neq_zero: x ≠ 0 := ne_of_gt h_x_pos
|
||||
rw [mul_inv_cancel h_x_neq_zero]
|
||||
-- let's (left) multiply both sides by M⁻¹ then cancel the M's then simplify M⁻¹*1 = M⁻¹ the close proof
|
||||
have h_M_inv_pos: 0 < M⁻¹ := by simp [h_M_pos]
|
||||
rw [← mul_lt_mul_left h_M_inv_pos]
|
||||
rw [mul_one]
|
||||
-- rewrite M⁻¹ * M * x = M * M⁻¹ * x via associativity of multiplication
|
||||
-- (a b c : G) : a * b * c = a * (b * c)
|
||||
rw [← mul_assoc]
|
||||
-- cancel the M's then simplify M⁻¹*1 = M⁻¹ the close proof
|
||||
have h_M_neq_zero: M ≠ 0 := ne_of_gt h_M_pos
|
||||
-- mul_inv_cancel : (h : a ≠ 0) : a * a⁻¹ = 1
|
||||
nth_rewrite 2 [mul_comm]
|
||||
-- -- use mul identity (h : a ≠ 0) : a * a⁻¹ = 1 to cancel the M's
|
||||
rw [mul_inv_cancel h_M_neq_zero]
|
||||
rw [mul_comm]
|
||||
rw [mul_one]
|
||||
assumption
|
|
@ -0,0 +1,101 @@
|
|||
/-
|
||||
theorem: lim_{x -> c+} f(x) = +infinity
|
||||
|
||||
x + infinit = +infinity
|
||||
|
||||
lim_{x -> c} f(x) = L
|
||||
∀ ε > 0, ∃ δ > 0, 0 < |x - c| < δ → 0 < |f(x) - L| < ε
|
||||
|
||||
L = + infinity
|
||||
consider some ε > 0
|
||||
0 < |f(x) - L| < ε
|
||||
0 < |f(x) - +infinity| < ε
|
||||
|
||||
--> this formalization doens't seem promising
|
||||
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: lim_{x -> 0+} 1/x = +infinity
|
||||
∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
-- unboudned limit := "for any M, there exists a sufficiently close x s.t. f(x) is strictly greater than M"
|
||||
∀ M: ℝ, 0 < M, ∃ δ : ℝ, 0 < δ, ∀ x : ℝ, 0 < x - c < δ → M < f(x)
|
||||
|
||||
proof:
|
||||
consider some M > 0 (intro M)
|
||||
-- choose delta, M < f(x) --> M < 1/x --> 1/M > x --> x < M⁻¹
|
||||
δ = M⁻¹
|
||||
. show 0 < δ
|
||||
fact M > 0 --> M⁻¹ > 0 (by lemma in lean, division by positive number)
|
||||
0 < x - c -> rewrite
|
||||
-> 0 < x
|
||||
x - c < δ -> rewrite
|
||||
-> x < M⁻¹
|
||||
(WTS: M < x⁻¹)
|
||||
x < M⁻¹
|
||||
-- multiply both sides by x⁻¹ if x⁻¹ > 0 (lemma, have stmt)
|
||||
-> 0 < x --> x⁻¹ > 0
|
||||
x⁻¹ * x < M^⁻¹ * x⁻¹
|
||||
by identity x⁻¹ * x = 1 of fields (lemma in lean or automation)
|
||||
1 < M⁻¹ * x⁻¹
|
||||
-- multiply both sides by M if M > 0
|
||||
1 < M⁻¹ * x⁻¹
|
||||
M * 1 < M * M⁻¹ * x⁻¹
|
||||
-- identity
|
||||
M < x⁻¹
|
||||
Qed
|
||||
|
||||
-/
|
||||
|
||||
-- import real numbers form mathlib
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
noncomputable def f (x : ℝ) : ℝ := x⁻¹
|
||||
#print f
|
||||
#check f
|
||||
#check f 1
|
||||
-- #eval f 1
|
||||
-- theorem any_R : ℝ -> R := λ x : ℝ, x -- TODO
|
||||
theorem unit_test_f_1 : f 1 = 1 := by simp [f]
|
||||
theorem unit_test_f_2 : f 2 = 1/2 := by simp [f]
|
||||
noncomputable def f' (x : ℝ) : ℝ := 1/x
|
||||
theorem units_f_eq_f' : ∀ x : ℝ , f x = f' x := by simp [f, f']
|
||||
#print units_f_eq_f'
|
||||
|
||||
-- lim_{x -> c+} f(x) = +infinity := ∀ M > 0, ∃ δ > 0, ∀ x : ℝ, 0 < x - c < δ → f(x) > M
|
||||
def unbounded_limit (f : ℝ -> ℝ) (c : ℝ) : Prop :=
|
||||
∀ M : ℝ, 0 < M → ∃ δ : ℝ, 0 < δ ∧ ∀ x : ℝ, 0 < x - c ∧ x - c < δ → M < f x
|
||||
|
||||
-- show 1/x is unbounded as x -> 0 (or 1/x has a veritcal asymptote at x = 0)
|
||||
theorem limit_of_reciprocal_of_x_is_unbounded: unbounded_limit f 0 := by
|
||||
unfold unbounded_limit f
|
||||
-- choose M : ℝ and is M > 0
|
||||
intro M h_M_pos
|
||||
-- choose delta = M⁻¹ by a tactic
|
||||
use M⁻¹
|
||||
-- deconstruct the constructor Left ∧ Right = And(Left, Right) to Left, Right using a tactic
|
||||
apply And.intro
|
||||
. exact (by simp [h_M_pos]) -- TODO try to find the lemma in mathlib to prove this
|
||||
. intro x ⟨h_x_pos, h_x_lt_M⟩
|
||||
-- rewrite x - 0 to x using a tactic for sub
|
||||
rw [sub_zero] at h_x_pos h_x_lt_M
|
||||
-- using rewrite do M < x⁻¹ → M * x < x⁻¹ * x by mulitpling both sides by x on the right
|
||||
-- #print mul_lt_mul_right -- (a0 : 0 < a) : b * a < c * a ↔ b < c
|
||||
rw [←mul_lt_mul_right h_M_pos] at h_x_lt_M
|
||||
-- #print mul_inv_cancel
|
||||
-- mul_inv_cancel: a ≠ 0 → a * a⁻¹ = 1
|
||||
nth_rewrite 2 [mul_comm] at h_x_lt_M
|
||||
have h_M_neq_zero : M ≠ 0 := ne_of_gt h_M_pos
|
||||
rw [mul_inv_cancel h_M_neq_zero] at h_x_lt_M
|
||||
-- multiply both sides by x⁻¹ on the left
|
||||
have h_x_inv_pos : 0 < x⁻¹ := inv_pos.mpr h_x_pos
|
||||
rw [← mul_lt_mul_left h_x_inv_pos] at h_x_lt_M
|
||||
-- apply associativity of mul
|
||||
rw [← mul_assoc] at h_x_lt_M
|
||||
-- mul_inv_cancel: a ≠ 0 → a * a⁻¹ = 1
|
||||
nth_rewrite 2 [mul_comm] at h_x_lt_M
|
||||
-- cancel the x * x⁻¹ to 1
|
||||
have h_x_neq_zero : x ≠ 0 := ne_of_gt h_x_pos
|
||||
rw [mul_inv_cancel h_x_neq_zero] at h_x_lt_M
|
||||
-- apply 1 * M = M
|
||||
rw [one_mul] at h_x_lt_M
|
||||
rw [mul_comm] at h_x_lt_M
|
||||
rw [one_mul] at h_x_lt_M
|
||||
assumption
|
|
@ -0,0 +1 @@
|
|||
def hello := "world"
|
|
@ -0,0 +1,34 @@
|
|||
-- {
|
||||
-- "problem": "Let $t(x) = \\sqrt{3x+1}$ and $f(x)=5-t(x)$. What is $t(f(5))$?",
|
||||
-- "level": "Level 4",
|
||||
-- "type": "Algebra",
|
||||
-- "solution": "We first evaluate $f(5) = 5 -t(5) = 5-\\sqrt{5\\cdot3+1}=1$. Thus $t(f(5))=t(1)=\\sqrt{3\\cdot1 + 1}=\\boxed{2}$."
|
||||
-- }
|
||||
|
||||
import Mathlib.Data.Real.Basic
|
||||
import Mathlib.Data.Real.Sqrt
|
||||
import Mathlib.Algebra.GroupPower.Order
|
||||
|
||||
noncomputable def t (x : ℝ) : ℝ := Real.sqrt (3 * x + 1)
|
||||
noncomputable def f (x : ℝ) : ℝ := 5 - t x
|
||||
|
||||
theorem solve_t_at_5: t 5 = 4 := by
|
||||
have h0 : Real.sqrt 4 ^ 2 = 4 := Real.sq_sqrt (Nat.ofNat_nonneg _)
|
||||
have h1 : 3 * 5 + 1 = 4^2 := by rfl
|
||||
have h2 : Real.sqrt (3 * 5 + 1) = Real.sqrt 4^2:= by sorry
|
||||
unfold t
|
||||
rw[h2, h0]
|
||||
|
||||
theorem solve_f_at_5: f 5 = 1 := by
|
||||
unfold f
|
||||
have h: t 5 = 4 := by apply solve_t_at_5
|
||||
rw[h]
|
||||
ring
|
||||
|
||||
theorem solve_t_f_at_5: t (f 5) = 2 := by
|
||||
unfold t
|
||||
have h0: f 5 = 1 := by apply solve_f_at_5
|
||||
have h1: 3 * 1 + 1 = 2^2 := by rfl
|
||||
have h2: Real.sqrt (3 * 1 + 1) = Real.sqrt 2^2 := by sorry
|
||||
have h3: Real.sqrt 2^2 = 2 := Real.sq_sqrt (Nat.ofNat_nonneg _)
|
||||
rw[h0, h2, h3]
|
|
@ -0,0 +1,26 @@
|
|||
-- {
|
||||
-- "problem": "The perimeter of a rectangle is 24 inches. What is the number of square inches in the maximum possible area for this rectangle?",
|
||||
-- "level": "Level 3",
|
||||
-- "type": "Algebra",
|
||||
-- "solution": "Let one pair of parallel sides have length $x$ and the other pair of parallel sides have length $12-x$. This means that the perimeter of the rectangle is $x+x+12-x+12-x=24$ as the problem states. The area of this rectangle is $12x-x^2$. Completing the square results in $-(x-6)^2+36\\le 36$ since $(x-6)^2\\ge 0$, so the maximum area of $\\boxed{36}$ is obtained when the rectangle is a square of side length 6 inches."
|
||||
-- }
|
||||
|
||||
-- Note: translating this to 2x + 2y = 24, what is xy?
|
||||
import Mathlib.Data.Real.Basic
|
||||
import Mathlib.Algebra.Group.Defs
|
||||
import Mathlib.Algebra.Ring.Defs
|
||||
import Mathlib.Tactic.Linarith.Frontend
|
||||
|
||||
def valid_perimeter (x y : ℕ) : Prop :=
|
||||
2 * x + 2 * y = 24
|
||||
|
||||
def area (x y : ℝ) := x * y
|
||||
|
||||
theorem rewrite_y_as_x: valid_perimeter x y → y = 12 - x := by
|
||||
unfold valid_perimeter
|
||||
intro p
|
||||
have h0 : 24 = 2 * 12 := by rfl
|
||||
have h1 : 2 * x + 2 * y = 2 * (x + y) := by ring
|
||||
have h2 : 2 * (x + y) = 2 * 12 → x + y = 12 := by sorry
|
||||
have h3 : x + y = 12 → y = 12 - x := by sorry
|
||||
rw[h0, h1, h2] at p
|
|
@ -0,0 +1,19 @@
|
|||
-- {
|
||||
-- "problem": "If $\\sqrt{2\\sqrt{t-2}} = \\sqrt[4]{7 - t}$, then find $t$.",
|
||||
-- "level": "Level 4",
|
||||
-- "type": "Algebra",
|
||||
-- "solution": "We raise both sides to the fourth power, which is equivalent to squaring twice, in order to get rid of the radicals. The left-hand side becomes $$\\left(\\sqrt{2\\sqrt{t-2}}\\right)^4 = \\left(2\\sqrt{t-2}\\right)^2 = 4 \\cdot (t-2) = 4t-8.$$The right-hand side becomes $\\left(\\sqrt[4]{7-t}\\right)^4 = 7-t$. Setting them equal, $$4t-8 = 7-t \\quad\\Longrightarrow\\quad 5t = 15,$$and $t = \\boxed{3}$. Checking, we find that this value does indeed satisfy the original equation."
|
||||
-- }
|
||||
|
||||
import Mathlib.Data.Real.Basic
|
||||
import Mathlib.Data.Nat.Pow
|
||||
|
||||
noncomputable def a (t : ℝ) : ℝ := (2 * (t - 2) ^ (1 / 2)) ^ (1/2)
|
||||
noncomputable def b (t : ℝ) : ℝ := (7 - t)^(1/4)
|
||||
|
||||
def valid_t (t : ℝ) : Prop :=
|
||||
a t = b t
|
||||
|
||||
theorem LHS_to_4 : ∀ t : ℝ, (a t) ^ 4 = 4 * t - 8 := by sorry
|
||||
theorem RHS_to_4 : ∀ t : ℝ, (b t) ^ 4 = 7 - t := by sorry
|
||||
theorem solution : valid_t 3 := by sorry
|
|
@ -0,0 +1,50 @@
|
|||
/-
|
||||
Theorem: lim_{x -> 3} f(x) = 6, f(x) = 2x if x ≠ 3 else x if x = 3
|
||||
Proof:
|
||||
WTS: ∀ ε > 0, ∃ δ > 0, ∀ x, 0 < |x - 3| < δ → 0 < |f(x) - 6| < ε.
|
||||
Consider any ε > 0.
|
||||
Then let's start from what we want 0 < |f(x) - 6| < ε.
|
||||
We want to have that be of the form 0 < |x - 3| < δ, and construct delta > 0.
|
||||
Unfold the definition of f(x) when x ≠ 3:
|
||||
0 < |f(x) - 6| < ε
|
||||
0 < |2x - 6| < ε
|
||||
0 < |2(x - 3)| < ε
|
||||
0 < |2|*|x - 3| < ε
|
||||
0 < 2*|x - 3| < ε
|
||||
0 < |x - 3| < ε/2
|
||||
So we can choose δ = ε/2.
|
||||
Since ε > 0, δ > 0.
|
||||
Qed.
|
||||
-/
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
-- define f, f(x) = 2x if x ≠ 3 else x if x = 3
|
||||
def c : ℝ := 3
|
||||
#eval c
|
||||
def L : ℝ := 6
|
||||
|
||||
noncomputable def f (x : ℝ) : ℝ :=
|
||||
if x = 3.0 then x else 2.0 * x
|
||||
|
||||
-- Epsilon-delta definition of a limit for a function f at a point c approaching L
|
||||
def has_limit_at (f : ℝ → ℝ) (L c : ℝ) : Prop :=
|
||||
∀ ε > 0, ∃ δ > 0, ∀ x, 0 < abs (x - c) ∧ abs (x - c) < δ → abs (f x - L) < ε
|
||||
#check abs
|
||||
#eval abs 3
|
||||
|
||||
-- theorem: lim_{x -> 3} f(x) = 6
|
||||
theorem lim_x_3_f_x_eq_6 : has_limit_at f L c := by
|
||||
intros ε ε_pos
|
||||
let δ := ε / 2
|
||||
have δ_pos : δ > 0 := div_pos ε_pos (by norm_num)
|
||||
use δ
|
||||
intro x
|
||||
intro h
|
||||
cases h with h1 h2
|
||||
cases (em (x = 3)) with x_eq_3 x_ne_3
|
||||
case inl =>
|
||||
rw [x_eq_3]
|
||||
simp
|
||||
exact ε_pos
|
||||
case inr =>
|
||||
sorry
|
|
@ -0,0 +1,24 @@
|
|||
/-
|
||||
|
||||
{
|
||||
"problem": "How many vertical asymptotes does the graph of $y=\\frac{2}{x^2+x-6}$ have?",
|
||||
"level": "Level 3",
|
||||
"type": "Algebra",
|
||||
"solution": "The denominator of the rational function factors into $x^2+x-6=(x-2)(x+3)$. Since the numerator is always nonzero, there is a vertical asymptote whenever the denominator is $0$, which occurs for $x = 2$ and $x = -3$. Therefore, the graph has $\\boxed{2}$ vertical asymptotes."
|
||||
}
|
||||
|
||||
theorem:the graph of y=2/(x^2+x-6) has 2 vertical asymptotes.
|
||||
Proof.
|
||||
Define vertical asymptote as lim_{x->c} f(x) = ∞ or -∞.
|
||||
The denominator of the rational function factors into x^2+x-6=(x-2)(x+3).
|
||||
Since the numerator is always nonzero, there is a vertical asymptote whenever the denominator is 0,
|
||||
which occurs for x = 2 and x = -3.
|
||||
Therefore, the graph has 2 vertical asymptotes.
|
||||
Qed.
|
||||
-/
|
||||
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
-- noncomputable def f (x : ℝ) : ℝ := 2 / (x^2 + x - 6)
|
||||
noncomputable def f (x : ℝ) : ℝ := 2 / (x^2 + x - 6)
|
||||
#check f
|
|
@ -0,0 +1,2 @@
|
|||
#eval "Hello, World!"
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import Mathlib.Data.Nat.Basic
|
||||
import Mathlib.Data.Nat.Parity
|
||||
import MIL.Common
|
||||
|
||||
open Nat
|
||||
|
||||
-- These are pieces of data.
|
||||
#check 2 + 2
|
||||
|
||||
def f (x : ℕ) :=
|
||||
x + 3
|
||||
|
||||
#check f
|
||||
|
||||
-- These are propositions, of type `Prop`.
|
||||
#check 2 + 2 = 4
|
||||
|
||||
def FermatLastTheorem :=
|
||||
∀ x y z n : ℕ, n > 2 ∧ x * y * z ≠ 0 → x ^ n + y ^ n ≠ z ^ n
|
||||
|
||||
#check FermatLastTheorem
|
||||
|
||||
-- These are proofs of propositions.
|
||||
theorem easy : 2 + 2 = 4 :=
|
||||
rfl
|
||||
|
||||
#check easy
|
||||
|
||||
theorem hard : FermatLastTheorem :=
|
||||
sorry
|
||||
|
||||
#check hard
|
||||
|
||||
-- Here are some proofs.
|
||||
example : ∀ m n : Nat, Even n → Even (m * n) := fun m n ⟨k, (hk : n = k + k)⟩ ↦
|
||||
have hmn : m * n = m * k + m * k := by rw [hk, mul_add]
|
||||
show ∃ l, m * n = l + l from ⟨_, hmn⟩
|
||||
|
||||
example : ∀ m n : Nat, Even n → Even (m * n) :=
|
||||
fun m n ⟨k, hk⟩ ↦ ⟨m * k, by rw [hk, mul_add]⟩
|
||||
|
||||
example : ∀ m n : Nat, Even n → Even (m * n) := by
|
||||
-- Say m and n are natural numbers, and assume n=2*k.
|
||||
rintro m n ⟨k, hk⟩
|
||||
-- We need to prove m*n is twice a natural number. Let's show it's twice m*k.
|
||||
use m * k
|
||||
-- Substitute for n,
|
||||
rw [hk]
|
||||
-- and now it's obvious.
|
||||
ring
|
||||
|
||||
example : ∀ m n : Nat, Even n → Even (m * n) := by
|
||||
rintro m n ⟨k, hk⟩; use m * k; rw [hk]; ring
|
||||
|
||||
example : ∀ m n : Nat, Even n → Even (m * n) := by
|
||||
intros; simp [*, parity_simps]
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import Mathlib.Data.Nat.Basic
|
||||
import Mathlib.Data.Nat.Parity
|
||||
import MIL.Common
|
||||
|
||||
open Nat
|
||||
|
||||
-- There are no exercises in this section.
|
|
@ -0,0 +1,143 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
-- An example.
|
||||
example (a b c : ℝ) : a * b * c = b * (a * c) := by
|
||||
rw [mul_comm a b]
|
||||
rw [mul_assoc b a c]
|
||||
|
||||
-- Try these.
|
||||
example (a b c : ℝ) : c * b * a = b * (a * c) := by
|
||||
sorry
|
||||
|
||||
example (a b c : ℝ) : a * (b * c) = b * (a * c) := by
|
||||
sorry
|
||||
|
||||
-- An example.
|
||||
example (a b c : ℝ) : a * b * c = b * c * a := by
|
||||
rw [mul_assoc]
|
||||
rw [mul_comm]
|
||||
|
||||
/- Try doing the first of these without providing any arguments at all,
|
||||
and the second with only one argument. -/
|
||||
example (a b c : ℝ) : a * (b * c) = b * (c * a) := by
|
||||
sorry
|
||||
|
||||
example (a b c : ℝ) : a * (b * c) = b * (a * c) := by
|
||||
sorry
|
||||
|
||||
-- Using facts from the local context.
|
||||
example (a b c d e f : ℝ) (h : a * b = c * d) (h' : e = f) : a * (b * e) = c * (d * f) := by
|
||||
rw [h']
|
||||
rw [← mul_assoc]
|
||||
rw [h]
|
||||
rw [mul_assoc]
|
||||
|
||||
example (a b c d e f : ℝ) (h : b * c = e * f) : a * b * c * d = a * e * f * d := by
|
||||
sorry
|
||||
|
||||
example (a b c d : ℝ) (hyp : c = b * a - d) (hyp' : d = a * b) : c = 0 := by
|
||||
sorry
|
||||
|
||||
example (a b c d e f : ℝ) (h : a * b = c * d) (h' : e = f) : a * (b * e) = c * (d * f) := by
|
||||
rw [h', ← mul_assoc, h, mul_assoc]
|
||||
|
||||
section
|
||||
|
||||
variable (a b c d e f : ℝ)
|
||||
|
||||
example (h : a * b = c * d) (h' : e = f) : a * (b * e) = c * (d * f) := by
|
||||
rw [h', ← mul_assoc, h, mul_assoc]
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (a b c : ℝ)
|
||||
|
||||
#check a
|
||||
#check a + b
|
||||
#check (a : ℝ)
|
||||
#check mul_comm a b
|
||||
#check (mul_comm a b : a * b = b * a)
|
||||
#check mul_assoc c a b
|
||||
#check mul_comm a
|
||||
#check mul_comm
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (a b : ℝ)
|
||||
|
||||
example : (a + b) * (a + b) = a * a + 2 * (a * b) + b * b := by
|
||||
rw [mul_add, add_mul, add_mul]
|
||||
rw [← add_assoc, add_assoc (a * a)]
|
||||
rw [mul_comm b a, ← two_mul]
|
||||
|
||||
example : (a + b) * (a + b) = a * a + 2 * (a * b) + b * b :=
|
||||
calc
|
||||
(a + b) * (a + b) = a * a + b * a + (a * b + b * b) := by
|
||||
rw [mul_add, add_mul, add_mul]
|
||||
_ = a * a + (b * a + a * b) + b * b := by
|
||||
rw [← add_assoc, add_assoc (a * a)]
|
||||
_ = a * a + 2 * (a * b) + b * b := by
|
||||
rw [mul_comm b a, ← two_mul]
|
||||
|
||||
example : (a + b) * (a + b) = a * a + 2 * (a * b) + b * b :=
|
||||
calc
|
||||
(a + b) * (a + b) = a * a + b * a + (a * b + b * b) := by
|
||||
sorry
|
||||
_ = a * a + (b * a + a * b) + b * b := by
|
||||
sorry
|
||||
_ = a * a + 2 * (a * b) + b * b := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
-- Try these. For the second, use the theorems listed underneath.
|
||||
section
|
||||
variable (a b c d : ℝ)
|
||||
|
||||
example : (a + b) * (c + d) = a * c + a * d + b * c + b * d := by
|
||||
sorry
|
||||
|
||||
example (a b : ℝ) : (a + b) * (a - b) = a ^ 2 - b ^ 2 := by
|
||||
sorry
|
||||
|
||||
#check pow_two a
|
||||
#check mul_sub a b c
|
||||
#check add_mul a b c
|
||||
#check add_sub a b c
|
||||
#check sub_sub a b c
|
||||
#check add_zero a
|
||||
|
||||
end
|
||||
|
||||
-- Examples.
|
||||
|
||||
section
|
||||
variable (a b c d : ℝ)
|
||||
|
||||
example (a b c d : ℝ) (hyp : c = d * a + b) (hyp' : b = a * d) : c = 2 * a * d := by
|
||||
rw [hyp'] at hyp
|
||||
rw [mul_comm d a] at hyp
|
||||
rw [← two_mul (a * d)] at hyp
|
||||
rw [← mul_assoc 2 a d] at hyp
|
||||
exact hyp
|
||||
|
||||
example : c * b * a = b * (a * c) := by
|
||||
ring
|
||||
|
||||
example : (a + b) * (a + b) = a * a + 2 * (a * b) + b * b := by
|
||||
ring
|
||||
|
||||
example : (a + b) * (a - b) = a ^ 2 - b ^ 2 := by
|
||||
ring
|
||||
|
||||
example (hyp : c = d * a + b) (hyp' : b = a * d) : c = 2 * a * d := by
|
||||
rw [hyp, hyp']
|
||||
ring
|
||||
|
||||
end
|
||||
|
||||
example (a b c : ℕ) (h : a + b = c) : (a + b) * (a + b) = a * c + b * c := by
|
||||
nth_rw 2 [h]
|
||||
rw [add_mul]
|
|
@ -0,0 +1,146 @@
|
|||
import Mathlib.Algebra.Ring.Defs
|
||||
import Mathlib.Data.Real.Basic
|
||||
import MIL.Common
|
||||
|
||||
section
|
||||
variable (R : Type*) [Ring R]
|
||||
|
||||
#check (add_assoc : ∀ a b c : R, a + b + c = a + (b + c))
|
||||
#check (add_comm : ∀ a b : R, a + b = b + a)
|
||||
#check (zero_add : ∀ a : R, 0 + a = a)
|
||||
#check (add_left_neg : ∀ a : R, -a + a = 0)
|
||||
#check (mul_assoc : ∀ a b c : R, a * b * c = a * (b * c))
|
||||
#check (mul_one : ∀ a : R, a * 1 = a)
|
||||
#check (one_mul : ∀ a : R, 1 * a = a)
|
||||
#check (mul_add : ∀ a b c : R, a * (b + c) = a * b + a * c)
|
||||
#check (add_mul : ∀ a b c : R, (a + b) * c = a * c + b * c)
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (R : Type*) [CommRing R]
|
||||
variable (a b c d : R)
|
||||
|
||||
example : c * b * a = b * (a * c) := by ring
|
||||
|
||||
example : (a + b) * (a + b) = a * a + 2 * (a * b) + b * b := by ring
|
||||
|
||||
example : (a + b) * (a - b) = a ^ 2 - b ^ 2 := by ring
|
||||
|
||||
example (hyp : c = d * a + b) (hyp' : b = a * d) : c = 2 * a * d := by
|
||||
rw [hyp, hyp']
|
||||
ring
|
||||
|
||||
end
|
||||
|
||||
namespace MyRing
|
||||
variable {R : Type*} [Ring R]
|
||||
|
||||
theorem add_zero (a : R) : a + 0 = a := by rw [add_comm, zero_add]
|
||||
|
||||
theorem add_right_neg (a : R) : a + -a = 0 := by rw [add_comm, add_left_neg]
|
||||
|
||||
#check MyRing.add_zero
|
||||
#check add_zero
|
||||
|
||||
end MyRing
|
||||
|
||||
namespace MyRing
|
||||
variable {R : Type*} [Ring R]
|
||||
|
||||
theorem neg_add_cancel_left (a b : R) : -a + (a + b) = b := by
|
||||
rw [← add_assoc, add_left_neg, zero_add]
|
||||
|
||||
-- Prove these:
|
||||
theorem add_neg_cancel_right (a b : R) : a + b + -b = a := by
|
||||
sorry
|
||||
|
||||
theorem add_left_cancel {a b c : R} (h : a + b = a + c) : b = c := by
|
||||
sorry
|
||||
|
||||
theorem add_right_cancel {a b c : R} (h : a + b = c + b) : a = c := by
|
||||
sorry
|
||||
|
||||
theorem mul_zero (a : R) : a * 0 = 0 := by
|
||||
have h : a * 0 + a * 0 = a * 0 + 0 := by
|
||||
rw [← mul_add, add_zero, add_zero]
|
||||
rw [add_left_cancel h]
|
||||
|
||||
theorem zero_mul (a : R) : 0 * a = 0 := by
|
||||
sorry
|
||||
|
||||
theorem neg_eq_of_add_eq_zero {a b : R} (h : a + b = 0) : -a = b := by
|
||||
sorry
|
||||
|
||||
theorem eq_neg_of_add_eq_zero {a b : R} (h : a + b = 0) : a = -b := by
|
||||
sorry
|
||||
|
||||
theorem neg_zero : (-0 : R) = 0 := by
|
||||
apply neg_eq_of_add_eq_zero
|
||||
rw [add_zero]
|
||||
|
||||
theorem neg_neg (a : R) : - -a = a := by
|
||||
sorry
|
||||
|
||||
end MyRing
|
||||
|
||||
-- Examples.
|
||||
section
|
||||
variable {R : Type*} [Ring R]
|
||||
|
||||
example (a b : R) : a - b = a + -b :=
|
||||
sub_eq_add_neg a b
|
||||
|
||||
end
|
||||
|
||||
example (a b : ℝ) : a - b = a + -b :=
|
||||
rfl
|
||||
|
||||
example (a b : ℝ) : a - b = a + -b := by
|
||||
rfl
|
||||
|
||||
namespace MyRing
|
||||
variable {R : Type*} [Ring R]
|
||||
|
||||
theorem self_sub (a : R) : a - a = 0 := by
|
||||
sorry
|
||||
|
||||
theorem one_add_one_eq_two : 1 + 1 = (2 : R) := by
|
||||
norm_num
|
||||
|
||||
theorem two_mul (a : R) : 2 * a = a + a := by
|
||||
sorry
|
||||
|
||||
end MyRing
|
||||
|
||||
section
|
||||
variable (A : Type*) [AddGroup A]
|
||||
|
||||
#check (add_assoc : ∀ a b c : A, a + b + c = a + (b + c))
|
||||
#check (zero_add : ∀ a : A, 0 + a = a)
|
||||
#check (add_left_neg : ∀ a : A, -a + a = 0)
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {G : Type*} [Group G]
|
||||
|
||||
#check (mul_assoc : ∀ a b c : G, a * b * c = a * (b * c))
|
||||
#check (one_mul : ∀ a : G, 1 * a = a)
|
||||
#check (mul_left_inv : ∀ a : G, a⁻¹ * a = 1)
|
||||
|
||||
namespace MyGroup
|
||||
|
||||
theorem mul_right_inv (a : G) : a * a⁻¹ = 1 := by
|
||||
sorry
|
||||
|
||||
theorem mul_one (a : G) : a * 1 = a := by
|
||||
sorry
|
||||
|
||||
theorem mul_inv_rev (a b : G) : (a * b)⁻¹ = b⁻¹ * a⁻¹ := by
|
||||
sorry
|
||||
|
||||
end MyGroup
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
import Mathlib.Analysis.SpecialFunctions.Log.Basic
|
||||
import MIL.Common
|
||||
|
||||
variable (a b c d e : ℝ)
|
||||
open Real
|
||||
|
||||
#check (le_refl : ∀ a : ℝ, a ≤ a)
|
||||
#check (le_trans : a ≤ b → b ≤ c → a ≤ c)
|
||||
|
||||
section
|
||||
variable (h : a ≤ b) (h' : b ≤ c)
|
||||
|
||||
#check (le_refl : ∀ a : Real, a ≤ a)
|
||||
#check (le_refl a : a ≤ a)
|
||||
#check (le_trans : a ≤ b → b ≤ c → a ≤ c)
|
||||
#check (le_trans h : b ≤ c → a ≤ c)
|
||||
#check (le_trans h h' : a ≤ c)
|
||||
|
||||
end
|
||||
|
||||
example (x y z : ℝ) (h₀ : x ≤ y) (h₁ : y ≤ z) : x ≤ z := by
|
||||
apply le_trans
|
||||
· apply h₀
|
||||
. apply h₁
|
||||
|
||||
example (x y z : ℝ) (h₀ : x ≤ y) (h₁ : y ≤ z) : x ≤ z := by
|
||||
apply le_trans h₀
|
||||
apply h₁
|
||||
|
||||
example (x y z : ℝ) (h₀ : x ≤ y) (h₁ : y ≤ z) : x ≤ z :=
|
||||
le_trans h₀ h₁
|
||||
|
||||
example (x : ℝ) : x ≤ x := by
|
||||
apply le_refl
|
||||
|
||||
example (x : ℝ) : x ≤ x :=
|
||||
le_refl x
|
||||
|
||||
#check (le_refl : ∀ a, a ≤ a)
|
||||
#check (le_trans : a ≤ b → b ≤ c → a ≤ c)
|
||||
#check (lt_of_le_of_lt : a ≤ b → b < c → a < c)
|
||||
#check (lt_of_lt_of_le : a < b → b ≤ c → a < c)
|
||||
#check (lt_trans : a < b → b < c → a < c)
|
||||
|
||||
-- Try this.
|
||||
example (h₀ : a ≤ b) (h₁ : b < c) (h₂ : c ≤ d) (h₃ : d < e) : a < e := by
|
||||
sorry
|
||||
|
||||
example (h₀ : a ≤ b) (h₁ : b < c) (h₂ : c ≤ d) (h₃ : d < e) : a < e := by
|
||||
linarith
|
||||
|
||||
section
|
||||
|
||||
example (h : 2 * a ≤ 3 * b) (h' : 1 ≤ a) (h'' : d = 2) : d + a ≤ 5 * b := by
|
||||
linarith
|
||||
|
||||
end
|
||||
|
||||
example (h : 1 ≤ a) (h' : b ≤ c) : 2 + a + exp b ≤ 3 * a + exp c := by
|
||||
linarith [exp_le_exp.mpr h']
|
||||
|
||||
#check (exp_le_exp : exp a ≤ exp b ↔ a ≤ b)
|
||||
#check (exp_lt_exp : exp a < exp b ↔ a < b)
|
||||
#check (log_le_log : 0 < a → 0 < b → (log a ≤ log b ↔ a ≤ b))
|
||||
#check (log_lt_log : 0 < a → a < b → log a < log b)
|
||||
#check (add_le_add : a ≤ b → c ≤ d → a + c ≤ b + d)
|
||||
#check (add_le_add_left : a ≤ b → ∀ c, c + a ≤ c + b)
|
||||
#check (add_le_add_right : a ≤ b → ∀ c, a + c ≤ b + c)
|
||||
#check (add_lt_add_of_le_of_lt : a ≤ b → c < d → a + c < b + d)
|
||||
#check (add_lt_add_of_lt_of_le : a < b → c ≤ d → a + c < b + d)
|
||||
#check (add_lt_add_left : a < b → ∀ c, c + a < c + b)
|
||||
#check (add_lt_add_right : a < b → ∀ c, a + c < b + c)
|
||||
#check (add_nonneg : 0 ≤ a → 0 ≤ b → 0 ≤ a + b)
|
||||
#check (add_pos : 0 < a → 0 < b → 0 < a + b)
|
||||
#check (add_pos_of_pos_of_nonneg : 0 < a → 0 ≤ b → 0 < a + b)
|
||||
#check (exp_pos : ∀ a, 0 < exp a)
|
||||
#check add_le_add_left
|
||||
|
||||
example (h : a ≤ b) : exp a ≤ exp b := by
|
||||
rw [exp_le_exp]
|
||||
exact h
|
||||
|
||||
example (h₀ : a ≤ b) (h₁ : c < d) : a + exp c + e < b + exp d + e := by
|
||||
apply add_lt_add_of_lt_of_le
|
||||
· apply add_lt_add_of_le_of_lt h₀
|
||||
apply exp_lt_exp.mpr h₁
|
||||
apply le_refl
|
||||
|
||||
example (h₀ : d ≤ e) : c + exp (a + d) ≤ c + exp (a + e) := by sorry
|
||||
|
||||
example : (0 : ℝ) < 1 := by norm_num
|
||||
|
||||
example (h : a ≤ b) : log (1 + exp a) ≤ log (1 + exp b) := by
|
||||
have h₀ : 0 < 1 + exp a := by sorry
|
||||
have h₁ : 0 < 1 + exp b := by sorry
|
||||
apply (log_le_log h₀ h₁).mpr
|
||||
sorry
|
||||
|
||||
example : 0 ≤ a ^ 2 := by
|
||||
-- apply?
|
||||
exact sq_nonneg a
|
||||
|
||||
example (h : a ≤ b) : c - exp b ≤ c - exp a := by
|
||||
sorry
|
||||
|
||||
example : 2 * a * b ≤ a ^ 2 + b ^ 2 := by
|
||||
have h : 0 ≤ a ^ 2 - 2 * a * b + b ^ 2
|
||||
calc
|
||||
a ^ 2 - 2 * a * b + b ^ 2 = (a - b) ^ 2 := by ring
|
||||
_ ≥ 0 := by apply pow_two_nonneg
|
||||
|
||||
calc
|
||||
2 * a * b = 2 * a * b + 0 := by ring
|
||||
_ ≤ 2 * a * b + (a ^ 2 - 2 * a * b + b ^ 2) :=
|
||||
add_le_add (le_refl _) h
|
||||
_ = a ^ 2 + b ^ 2 := by ring
|
||||
|
||||
|
||||
example : 2 * a * b ≤ a ^ 2 + b ^ 2 := by
|
||||
have h : 0 ≤ a ^ 2 - 2 * a * b + b ^ 2
|
||||
calc
|
||||
a ^ 2 - 2 * a * b + b ^ 2 = (a - b) ^ 2 := by ring
|
||||
_ ≥ 0 := by apply pow_two_nonneg
|
||||
linarith
|
||||
|
||||
example : |a * b| ≤ (a ^ 2 + b ^ 2) / 2 := by
|
||||
sorry
|
||||
|
||||
#check abs_le'.mpr
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C02S04
|
||||
|
||||
section
|
||||
variable (a b c d : ℝ)
|
||||
|
||||
#check (min_le_left a b : min a b ≤ a)
|
||||
#check (min_le_right a b : min a b ≤ b)
|
||||
#check (le_min : c ≤ a → c ≤ b → c ≤ min a b)
|
||||
|
||||
example : min a b = min b a := by
|
||||
apply le_antisymm
|
||||
· show min a b ≤ min b a
|
||||
apply le_min
|
||||
· apply min_le_right
|
||||
apply min_le_left
|
||||
· show min b a ≤ min a b
|
||||
apply le_min
|
||||
· apply min_le_right
|
||||
apply min_le_left
|
||||
|
||||
example : min a b = min b a := by
|
||||
have h : ∀ x y : ℝ, min x y ≤ min y x := by
|
||||
intro x y
|
||||
apply le_min
|
||||
apply min_le_right
|
||||
apply min_le_left
|
||||
apply le_antisymm
|
||||
apply h
|
||||
apply h
|
||||
|
||||
example : min a b = min b a := by
|
||||
apply le_antisymm
|
||||
repeat
|
||||
apply le_min
|
||||
apply min_le_right
|
||||
apply min_le_left
|
||||
|
||||
example : max a b = max b a := by
|
||||
sorry
|
||||
example : min (min a b) c = min a (min b c) := by
|
||||
sorry
|
||||
theorem aux : min a b + c ≤ min (a + c) (b + c) := by
|
||||
sorry
|
||||
example : min a b + c = min (a + c) (b + c) := by
|
||||
sorry
|
||||
#check (abs_add : ∀ a b : ℝ, |a + b| ≤ |a| + |b|)
|
||||
|
||||
example : |a| - |b| ≤ |a - b| :=
|
||||
sorry
|
||||
end
|
||||
|
||||
section
|
||||
variable (w x y z : ℕ)
|
||||
|
||||
example (h₀ : x ∣ y) (h₁ : y ∣ z) : x ∣ z :=
|
||||
dvd_trans h₀ h₁
|
||||
|
||||
example : x ∣ y * x * z := by
|
||||
apply dvd_mul_of_dvd_left
|
||||
apply dvd_mul_left
|
||||
|
||||
example : x ∣ x ^ 2 := by
|
||||
apply dvd_mul_left
|
||||
|
||||
example (h : x ∣ w) : x ∣ y * (x * z) + x ^ 2 + w ^ 2 := by
|
||||
sorry
|
||||
end
|
||||
|
||||
section
|
||||
variable (m n : ℕ)
|
||||
|
||||
#check (Nat.gcd_zero_right n : Nat.gcd n 0 = n)
|
||||
#check (Nat.gcd_zero_left n : Nat.gcd 0 n = n)
|
||||
#check (Nat.lcm_zero_right n : Nat.lcm n 0 = 0)
|
||||
#check (Nat.lcm_zero_left n : Nat.lcm 0 n = 0)
|
||||
|
||||
example : Nat.gcd m n = Nat.gcd n m := by
|
||||
sorry
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Topology.MetricSpace.Basic
|
||||
|
||||
section
|
||||
variable {α : Type*} [PartialOrder α]
|
||||
variable (x y z : α)
|
||||
|
||||
#check x ≤ y
|
||||
#check (le_refl x : x ≤ x)
|
||||
#check (le_trans : x ≤ y → y ≤ z → x ≤ z)
|
||||
|
||||
#check x < y
|
||||
#check (lt_irrefl x : ¬x < x)
|
||||
#check (lt_trans : x < y → y < z → x < z)
|
||||
#check (lt_of_le_of_lt : x ≤ y → y < z → x < z)
|
||||
#check (lt_of_lt_of_le : x < y → y ≤ z → x < z)
|
||||
|
||||
example : x < y ↔ x ≤ y ∧ x ≠ y :=
|
||||
lt_iff_le_and_ne
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [Lattice α]
|
||||
variable (x y z : α)
|
||||
|
||||
#check x ⊓ y
|
||||
#check (inf_le_left : x ⊓ y ≤ x)
|
||||
#check (inf_le_right : x ⊓ y ≤ y)
|
||||
#check (le_inf : z ≤ x → z ≤ y → z ≤ x ⊓ y)
|
||||
#check x ⊔ y
|
||||
#check (le_sup_left : x ≤ x ⊔ y)
|
||||
#check (le_sup_right : y ≤ x ⊔ y)
|
||||
#check (sup_le : x ≤ z → y ≤ z → x ⊔ y ≤ z)
|
||||
|
||||
example : x ⊓ y = y ⊓ x := by
|
||||
sorry
|
||||
|
||||
example : x ⊓ y ⊓ z = x ⊓ (y ⊓ z) := by
|
||||
sorry
|
||||
|
||||
example : x ⊔ y = y ⊔ x := by
|
||||
sorry
|
||||
|
||||
example : x ⊔ y ⊔ z = x ⊔ (y ⊔ z) := by
|
||||
sorry
|
||||
|
||||
theorem absorb1 : x ⊓ (x ⊔ y) = x := by
|
||||
sorry
|
||||
|
||||
theorem absorb2 : x ⊔ x ⊓ y = x := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [DistribLattice α]
|
||||
variable (x y z : α)
|
||||
|
||||
#check (inf_sup_left : x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z)
|
||||
#check (inf_sup_right : (x ⊔ y) ⊓ z = x ⊓ z ⊔ y ⊓ z)
|
||||
#check (sup_inf_left : x ⊔ y ⊓ z = (x ⊔ y) ⊓ (x ⊔ z))
|
||||
#check (sup_inf_right : x ⊓ y ⊔ z = (x ⊔ z) ⊓ (y ⊔ z))
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [Lattice α]
|
||||
variable (a b c : α)
|
||||
|
||||
example (h : ∀ x y z : α, x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z) : a ⊔ b ⊓ c = (a ⊔ b) ⊓ (a ⊔ c) := by
|
||||
sorry
|
||||
|
||||
example (h : ∀ x y z : α, x ⊔ y ⊓ z = (x ⊔ y) ⊓ (x ⊔ z)) : a ⊓ (b ⊔ c) = a ⊓ b ⊔ a ⊓ c := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {R : Type*} [StrictOrderedRing R]
|
||||
variable (a b c : R)
|
||||
|
||||
#check (add_le_add_left : a ≤ b → ∀ c, c + a ≤ c + b)
|
||||
#check (mul_pos : 0 < a → 0 < b → 0 < a * b)
|
||||
|
||||
#check (mul_nonneg : 0 ≤ a → 0 ≤ b → 0 ≤ a * b)
|
||||
|
||||
example (h : a ≤ b) : 0 ≤ b - a := by
|
||||
sorry
|
||||
|
||||
example (h: 0 ≤ b - a) : a ≤ b := by
|
||||
sorry
|
||||
|
||||
example (h : a ≤ b) (h' : 0 ≤ c) : a * c ≤ b * c := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {X : Type*} [MetricSpace X]
|
||||
variable (x y z : X)
|
||||
|
||||
#check (dist_self x : dist x x = 0)
|
||||
#check (dist_comm x y : dist x y = dist y x)
|
||||
#check (dist_triangle x y z : dist x z ≤ dist x y + dist y z)
|
||||
|
||||
example (x y : X) : 0 ≤ dist x y := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
example (a b c : ℝ) : c * b * a = b * (a * c) := by
|
||||
rw [mul_comm c b]
|
||||
rw [mul_assoc b c a]
|
||||
rw [mul_comm c a]
|
||||
|
||||
example (a b c : ℝ) : a * (b * c) = b * (a * c) := by
|
||||
rw [← mul_assoc a b c]
|
||||
rw [mul_comm a b]
|
||||
rw [mul_assoc b a c]
|
||||
|
||||
example (a b c : ℝ) : a * (b * c) = b * (c * a) := by
|
||||
rw [mul_comm]
|
||||
rw [mul_assoc]
|
||||
|
||||
example (a b c : ℝ) : a * (b * c) = b * (a * c) := by
|
||||
rw [← mul_assoc]
|
||||
rw [mul_comm a]
|
||||
rw [mul_assoc]
|
||||
|
||||
example (a b c d e f : ℝ) (h : b * c = e * f) : a * b * c * d = a * e * f * d := by
|
||||
rw [mul_assoc a]
|
||||
rw [h]
|
||||
rw [← mul_assoc]
|
||||
|
||||
example (a b c d : ℝ) (hyp : c = b * a - d) (hyp' : d = a * b) : c = 0 := by
|
||||
rw [hyp]
|
||||
rw [hyp']
|
||||
rw [mul_comm]
|
||||
rw [sub_self]
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import Mathlib.Algebra.Ring.Defs
|
||||
import Mathlib.Data.Real.Basic
|
||||
import MIL.Common
|
||||
|
||||
namespace MyRing
|
||||
variable {R : Type*} [Ring R]
|
||||
|
||||
theorem add_neg_cancel_right (a b : R) : a + b + -b = a := by
|
||||
rw [add_assoc, add_right_neg, add_zero]
|
||||
|
||||
theorem add_left_cancel {a b c : R} (h : a + b = a + c) : b = c := by
|
||||
rw [← neg_add_cancel_left a b, h, neg_add_cancel_left]
|
||||
|
||||
theorem add_right_cancel {a b c : R} (h : a + b = c + b) : a = c := by
|
||||
rw [← add_neg_cancel_right a b, h, add_neg_cancel_right]
|
||||
|
||||
theorem zero_mul (a : R) : 0 * a = 0 := by
|
||||
have h : 0 * a + 0 * a = 0 * a + 0 := by rw [← add_mul, add_zero, add_zero]
|
||||
rw [add_left_cancel h]
|
||||
|
||||
theorem neg_eq_of_add_eq_zero {a b : R} (h : a + b = 0) : -a = b := by
|
||||
rw [← neg_add_cancel_left a b, h, add_zero]
|
||||
|
||||
theorem eq_neg_of_add_eq_zero {a b : R} (h : a + b = 0) : a = -b := by
|
||||
symm
|
||||
apply neg_eq_of_add_eq_zero
|
||||
rw [add_comm, h]
|
||||
|
||||
theorem neg_zero : (-0 : R) = 0 := by
|
||||
apply neg_eq_of_add_eq_zero
|
||||
rw [add_zero]
|
||||
|
||||
theorem neg_neg (a : R) : - -a = a := by
|
||||
apply neg_eq_of_add_eq_zero
|
||||
rw [add_left_neg]
|
||||
|
||||
end MyRing
|
||||
|
||||
namespace MyRing
|
||||
variable {R : Type*} [Ring R]
|
||||
|
||||
theorem self_sub (a : R) : a - a = 0 := by
|
||||
rw [sub_eq_add_neg, add_right_neg]
|
||||
|
||||
theorem one_add_one_eq_two : 1 + 1 = (2 : R) := by
|
||||
norm_num
|
||||
|
||||
theorem two_mul (a : R) : 2 * a = a + a := by
|
||||
rw [← one_add_one_eq_two, add_mul, one_mul]
|
||||
|
||||
end MyRing
|
||||
|
||||
section
|
||||
variable {G : Type*} [Group G]
|
||||
|
||||
namespace MyGroup
|
||||
|
||||
theorem mul_right_inv (a : G) : a * a⁻¹ = 1 := by
|
||||
have h : (a * a⁻¹)⁻¹ * (a * a⁻¹ * (a * a⁻¹)) = 1 := by
|
||||
rw [mul_assoc, ← mul_assoc a⁻¹ a, mul_left_inv, one_mul, mul_left_inv]
|
||||
rw [← h, ← mul_assoc, mul_left_inv, one_mul]
|
||||
|
||||
theorem mul_one (a : G) : a * 1 = a := by
|
||||
rw [← mul_left_inv a, ← mul_assoc, mul_right_inv, one_mul]
|
||||
|
||||
theorem mul_inv_rev (a b : G) : (a * b)⁻¹ = b⁻¹ * a⁻¹ := by
|
||||
rw [← one_mul (b⁻¹ * a⁻¹), ← mul_left_inv (a * b), mul_assoc, mul_assoc, ← mul_assoc b b⁻¹,
|
||||
mul_right_inv, one_mul, mul_right_inv, mul_one]
|
||||
|
||||
end MyGroup
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import Mathlib.Analysis.SpecialFunctions.Log.Basic
|
||||
import MIL.Common
|
||||
|
||||
variable (a b c d e : ℝ)
|
||||
open Real
|
||||
|
||||
example (h₀ : a ≤ b) (h₁ : b < c) (h₂ : c ≤ d) (h₃ : d < e) : a < e := by
|
||||
apply lt_of_le_of_lt h₀
|
||||
apply lt_trans h₁
|
||||
exact lt_of_le_of_lt h₂ h₃
|
||||
|
||||
example (h₀ : d ≤ e) : c + exp (a + d) ≤ c + exp (a + e) := by
|
||||
apply add_le_add_left
|
||||
rw [exp_le_exp]
|
||||
apply add_le_add_left h₀
|
||||
|
||||
-- an alternative using `linarith`.
|
||||
example (h₀ : d ≤ e) : c + exp (a + d) ≤ c + exp (a + e) := by
|
||||
have : exp (a + d) ≤ exp (a + e) := by
|
||||
rw [exp_le_exp]
|
||||
linarith
|
||||
linarith [this]
|
||||
|
||||
example (h : a ≤ b) : log (1 + exp a) ≤ log (1 + exp b) := by
|
||||
have h₀ : 0 < 1 + exp a := by linarith [exp_pos a]
|
||||
have h₁ : 0 < 1 + exp b := by linarith [exp_pos b]
|
||||
apply (log_le_log h₀ h₁).mpr
|
||||
apply add_le_add_left (exp_le_exp.mpr h)
|
||||
|
||||
-- SOLUTION.
|
||||
example (h : a ≤ b) : c - exp b ≤ c - exp a := by
|
||||
apply sub_le_sub_left
|
||||
exact exp_le_exp.mpr h
|
||||
|
||||
-- alternatively:
|
||||
example (h : a ≤ b) : c - exp b ≤ c - exp a := by
|
||||
linarith [exp_le_exp.mpr h]
|
||||
|
||||
theorem fact1 : a * b * 2 ≤ a ^ 2 + b ^ 2 := by
|
||||
have h : 0 ≤ a ^ 2 - 2 * a * b + b ^ 2
|
||||
calc
|
||||
a ^ 2 - 2 * a * b + b ^ 2 = (a - b) ^ 2 := by ring
|
||||
_ ≥ 0 := by apply pow_two_nonneg
|
||||
linarith
|
||||
|
||||
theorem fact2 : -(a * b) * 2 ≤ a ^ 2 + b ^ 2 := by
|
||||
have h : 0 ≤ a ^ 2 + 2 * a * b + b ^ 2
|
||||
calc
|
||||
a ^ 2 + 2 * a * b + b ^ 2 = (a + b) ^ 2 := by ring
|
||||
_ ≥ 0 := by apply pow_two_nonneg
|
||||
linarith
|
||||
|
||||
example : |a * b| ≤ (a ^ 2 + b ^ 2) / 2 := by
|
||||
have h : (0 : ℝ) < 2 := by norm_num
|
||||
apply abs_le'.mpr
|
||||
constructor
|
||||
· rw [le_div_iff h]
|
||||
apply fact1
|
||||
rw [le_div_iff h]
|
||||
apply fact2
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C02S04
|
||||
|
||||
section
|
||||
variable (a b c d : ℝ)
|
||||
|
||||
#check (min_le_left a b : min a b ≤ a)
|
||||
#check (min_le_right a b : min a b ≤ b)
|
||||
#check (le_min : c ≤ a → c ≤ b → c ≤ min a b)
|
||||
|
||||
example : max a b = max b a := by
|
||||
apply le_antisymm
|
||||
repeat'
|
||||
apply max_le
|
||||
apply le_max_right
|
||||
apply le_max_left
|
||||
|
||||
example : min (min a b) c = min a (min b c) := by
|
||||
apply le_antisymm
|
||||
· apply le_min
|
||||
· apply le_trans
|
||||
apply min_le_left
|
||||
apply min_le_left
|
||||
apply le_min
|
||||
· apply le_trans
|
||||
apply min_le_left
|
||||
apply min_le_right
|
||||
apply min_le_right
|
||||
apply le_min
|
||||
· apply le_min
|
||||
· apply min_le_left
|
||||
apply le_trans
|
||||
apply min_le_right
|
||||
apply min_le_left
|
||||
apply le_trans
|
||||
apply min_le_right
|
||||
apply min_le_right
|
||||
|
||||
theorem aux : min a b + c ≤ min (a + c) (b + c) := by
|
||||
apply le_min
|
||||
· apply add_le_add_right
|
||||
apply min_le_left
|
||||
apply add_le_add_right
|
||||
apply min_le_right
|
||||
|
||||
example : min a b + c = min (a + c) (b + c) := by
|
||||
apply le_antisymm
|
||||
· apply aux
|
||||
have h : min (a + c) (b + c) = min (a + c) (b + c) - c + c := by rw [sub_add_cancel]
|
||||
rw [h]
|
||||
apply add_le_add_right
|
||||
rw [sub_eq_add_neg]
|
||||
apply le_trans
|
||||
apply aux
|
||||
rw [add_neg_cancel_right, add_neg_cancel_right]
|
||||
|
||||
example : |a| - |b| ≤ |a - b| :=
|
||||
calc
|
||||
|a| - |b| = |a - b + b| - |b| := by rw [sub_add_cancel]
|
||||
_ ≤ |a - b| + |b| - |b| := by
|
||||
apply sub_le_sub_right
|
||||
apply abs_add
|
||||
_ ≤ |a - b| := by rw [add_sub_cancel]
|
||||
|
||||
|
||||
-- alternatively
|
||||
example : |a| - |b| ≤ |a - b| := by
|
||||
have h := abs_add (a - b) b
|
||||
rw [sub_add_cancel] at h
|
||||
linarith
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (w x y z : ℕ)
|
||||
|
||||
example (h₀ : x ∣ y) (h₁ : y ∣ z) : x ∣ z :=
|
||||
dvd_trans h₀ h₁
|
||||
|
||||
example : x ∣ y * x * z := by
|
||||
apply dvd_mul_of_dvd_left
|
||||
apply dvd_mul_left
|
||||
|
||||
example : x ∣ x ^ 2 := by
|
||||
apply dvd_mul_left
|
||||
|
||||
example (h : x ∣ w) : x ∣ y * (x * z) + x ^ 2 + w ^ 2 := by
|
||||
apply dvd_add
|
||||
· apply dvd_add
|
||||
· apply dvd_mul_of_dvd_right
|
||||
apply dvd_mul_right
|
||||
apply dvd_mul_left
|
||||
rw [pow_two]
|
||||
apply dvd_mul_of_dvd_right
|
||||
exact h
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (m n : ℕ)
|
||||
|
||||
#check (Nat.gcd_zero_right n : Nat.gcd n 0 = n)
|
||||
#check (Nat.gcd_zero_left n : Nat.gcd 0 n = n)
|
||||
#check (Nat.lcm_zero_right n : Nat.lcm n 0 = 0)
|
||||
#check (Nat.lcm_zero_left n : Nat.lcm 0 n = 0)
|
||||
|
||||
example : Nat.gcd m n = Nat.gcd n m := by
|
||||
apply Nat.dvd_antisymm
|
||||
repeat'
|
||||
apply Nat.dvd_gcd
|
||||
apply Nat.gcd_dvd_right
|
||||
apply Nat.gcd_dvd_left
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Topology.MetricSpace.Basic
|
||||
|
||||
section
|
||||
variable {α : Type*} [Lattice α]
|
||||
variable (x y z : α)
|
||||
|
||||
example : x ⊓ y = y ⊓ x := by
|
||||
apply le_antisymm
|
||||
repeat'
|
||||
apply le_inf
|
||||
· apply inf_le_right
|
||||
apply inf_le_left
|
||||
|
||||
example : x ⊓ y ⊓ z = x ⊓ (y ⊓ z) := by
|
||||
apply le_antisymm
|
||||
· apply le_inf
|
||||
· apply le_trans
|
||||
apply inf_le_left
|
||||
apply inf_le_left
|
||||
apply le_inf
|
||||
· apply le_trans
|
||||
apply inf_le_left
|
||||
apply inf_le_right
|
||||
apply inf_le_right
|
||||
apply le_inf
|
||||
· apply le_inf
|
||||
· apply inf_le_left
|
||||
apply le_trans
|
||||
apply inf_le_right
|
||||
apply inf_le_left
|
||||
apply le_trans
|
||||
apply inf_le_right
|
||||
apply inf_le_right
|
||||
|
||||
example : x ⊔ y = y ⊔ x := by
|
||||
apply le_antisymm
|
||||
repeat'
|
||||
apply sup_le
|
||||
· apply le_sup_right
|
||||
apply le_sup_left
|
||||
|
||||
example : x ⊔ y ⊔ z = x ⊔ (y ⊔ z) := by
|
||||
apply le_antisymm
|
||||
· apply sup_le
|
||||
· apply sup_le
|
||||
apply le_sup_left
|
||||
· apply le_trans
|
||||
apply @le_sup_left _ _ y z
|
||||
apply le_sup_right
|
||||
apply le_trans
|
||||
apply @le_sup_right _ _ y z
|
||||
apply le_sup_right
|
||||
apply sup_le
|
||||
· apply le_trans
|
||||
apply @le_sup_left _ _ x y
|
||||
apply le_sup_left
|
||||
apply sup_le
|
||||
· apply le_trans
|
||||
apply @le_sup_right _ _ x y
|
||||
apply le_sup_left
|
||||
apply le_sup_right
|
||||
|
||||
theorem absorb1 : x ⊓ (x ⊔ y) = x := by
|
||||
apply le_antisymm
|
||||
· apply inf_le_left
|
||||
apply le_inf
|
||||
· apply le_refl
|
||||
apply le_sup_left
|
||||
|
||||
theorem absorb2 : x ⊔ x ⊓ y = x := by
|
||||
apply le_antisymm
|
||||
· apply sup_le
|
||||
· apply le_refl
|
||||
apply inf_le_left
|
||||
apply le_sup_left
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [DistribLattice α]
|
||||
variable (x y z : α)
|
||||
|
||||
#check (inf_sup_left : x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z)
|
||||
#check (inf_sup_right : (x ⊔ y) ⊓ z = x ⊓ z ⊔ y ⊓ z)
|
||||
#check (sup_inf_left : x ⊔ y ⊓ z = (x ⊔ y) ⊓ (x ⊔ z))
|
||||
#check (sup_inf_right : x ⊓ y ⊔ z = (x ⊔ z) ⊓ (y ⊔ z))
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [Lattice α]
|
||||
variable (a b c : α)
|
||||
|
||||
example (h : ∀ x y z : α, x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z) : a ⊔ b ⊓ c = (a ⊔ b) ⊓ (a ⊔ c) := by
|
||||
rw [h, @inf_comm _ _ (a ⊔ b), absorb1, @inf_comm _ _ (a ⊔ b), h, ← sup_assoc, @inf_comm _ _ c a,
|
||||
absorb2, inf_comm]
|
||||
|
||||
example (h : ∀ x y z : α, x ⊔ y ⊓ z = (x ⊔ y) ⊓ (x ⊔ z)) : a ⊓ (b ⊔ c) = a ⊓ b ⊔ a ⊓ c := by
|
||||
rw [h, @sup_comm _ _ (a ⊓ b), absorb2, @sup_comm _ _ (a ⊓ b), h, ← inf_assoc, @sup_comm _ _ c a,
|
||||
absorb1, sup_comm]
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {R : Type*} [StrictOrderedRing R]
|
||||
variable (a b c : R)
|
||||
|
||||
theorem aux1 (h : a ≤ b) : 0 ≤ b - a := by
|
||||
rw [← sub_self a, sub_eq_add_neg, sub_eq_add_neg, add_comm, add_comm b]
|
||||
apply add_le_add_left h
|
||||
|
||||
theorem aux2 (h : 0 ≤ b - a) : a ≤ b := by
|
||||
rw [← add_zero a, ← sub_add_cancel b a, add_comm (b - a)]
|
||||
apply add_le_add_left h
|
||||
|
||||
example (h : a ≤ b) (h' : 0 ≤ c) : a * c ≤ b * c := by
|
||||
have h1 : 0 ≤ (b - a) * c := mul_nonneg (aux1 _ _ h) h'
|
||||
rw [sub_mul] at h1
|
||||
exact aux2 _ _ h1
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {X : Type*} [MetricSpace X]
|
||||
variable (x y z : X)
|
||||
|
||||
example (x y : X) : 0 ≤ dist x y :=by
|
||||
have : 0 ≤ dist x y + dist y x := by
|
||||
rw [← dist_self x]
|
||||
apply dist_triangle
|
||||
linarith [dist_comm x y]
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S01
|
||||
|
||||
#check ∀ x : ℝ, 0 ≤ x → |x| = x
|
||||
|
||||
#check ∀ x y ε : ℝ, 0 < ε → ε ≤ 1 → |x| < ε → |y| < ε → |x * y| < ε
|
||||
|
||||
theorem my_lemma : ∀ x y ε : ℝ, 0 < ε → ε ≤ 1 → |x| < ε → |y| < ε → |x * y| < ε :=
|
||||
sorry
|
||||
|
||||
section
|
||||
variable (a b δ : ℝ)
|
||||
variable (h₀ : 0 < δ) (h₁ : δ ≤ 1)
|
||||
variable (ha : |a| < δ) (hb : |b| < δ)
|
||||
|
||||
#check my_lemma a b δ
|
||||
#check my_lemma a b δ h₀ h₁
|
||||
#check my_lemma a b δ h₀ h₁ ha hb
|
||||
|
||||
end
|
||||
|
||||
theorem my_lemma2 : ∀ {x y ε : ℝ}, 0 < ε → ε ≤ 1 → |x| < ε → |y| < ε → |x * y| < ε :=
|
||||
sorry
|
||||
|
||||
section
|
||||
variable (a b δ : ℝ)
|
||||
variable (h₀ : 0 < δ) (h₁ : δ ≤ 1)
|
||||
variable (ha : |a| < δ) (hb : |b| < δ)
|
||||
|
||||
#check my_lemma2 h₀ h₁ ha hb
|
||||
|
||||
end
|
||||
|
||||
theorem my_lemma3 :
|
||||
∀ {x y ε : ℝ}, 0 < ε → ε ≤ 1 → |x| < ε → |y| < ε → |x * y| < ε := by
|
||||
intro x y ε epos ele1 xlt ylt
|
||||
sorry
|
||||
|
||||
theorem my_lemma4 :
|
||||
∀ {x y ε : ℝ}, 0 < ε → ε ≤ 1 → |x| < ε → |y| < ε → |x * y| < ε := by
|
||||
intro x y ε epos ele1 xlt ylt
|
||||
calc
|
||||
|x * y| = |x| * |y| := sorry
|
||||
_ ≤ |x| * ε := sorry
|
||||
_ < 1 * ε := sorry
|
||||
_ = ε := sorry
|
||||
|
||||
def FnUb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
def FnLb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, a ≤ f x
|
||||
|
||||
section
|
||||
variable (f g : ℝ → ℝ) (a b : ℝ)
|
||||
|
||||
example (hfa : FnUb f a) (hgb : FnUb g b) : FnUb (fun x ↦ f x + g x) (a + b) := by
|
||||
intro x
|
||||
dsimp
|
||||
apply add_le_add
|
||||
apply hfa
|
||||
apply hgb
|
||||
|
||||
example (hfa : FnLb f a) (hgb : FnLb g b) : FnLb (fun x ↦ f x + g x) (a + b) :=
|
||||
sorry
|
||||
|
||||
example (nnf : FnLb f 0) (nng : FnLb g 0) : FnLb (fun x ↦ f x * g x) 0 :=
|
||||
sorry
|
||||
|
||||
example (hfa : FnUb f a) (hgb : FnUb g b) (nng : FnLb g 0) (nna : 0 ≤ a) :
|
||||
FnUb (fun x ↦ f x * g x) (a * b) :=
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} {R : Type*} [OrderedCancelAddCommMonoid R]
|
||||
|
||||
#check add_le_add
|
||||
|
||||
def FnUb' (f : α → R) (a : R) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
theorem fnUb_add {f g : α → R} {a b : R} (hfa : FnUb' f a) (hgb : FnUb' g b) :
|
||||
FnUb' (fun x ↦ f x + g x) (a + b) := fun x ↦ add_le_add (hfa x) (hgb x)
|
||||
|
||||
end
|
||||
|
||||
example (f : ℝ → ℝ) (h : Monotone f) : ∀ {a b}, a ≤ b → f a ≤ f b :=
|
||||
@h
|
||||
|
||||
section
|
||||
variable (f g : ℝ → ℝ)
|
||||
|
||||
example (mf : Monotone f) (mg : Monotone g) : Monotone fun x ↦ f x + g x := by
|
||||
intro a b aleb
|
||||
apply add_le_add
|
||||
apply mf aleb
|
||||
apply mg aleb
|
||||
|
||||
example (mf : Monotone f) (mg : Monotone g) : Monotone fun x ↦ f x + g x :=
|
||||
fun a b aleb ↦ add_le_add (mf aleb) (mg aleb)
|
||||
|
||||
example {c : ℝ} (mf : Monotone f) (nnc : 0 ≤ c) : Monotone fun x ↦ c * f x :=
|
||||
sorry
|
||||
|
||||
example (mf : Monotone f) (mg : Monotone g) : Monotone fun x ↦ f (g x) :=
|
||||
sorry
|
||||
|
||||
def FnEven (f : ℝ → ℝ) : Prop :=
|
||||
∀ x, f x = f (-x)
|
||||
|
||||
def FnOdd (f : ℝ → ℝ) : Prop :=
|
||||
∀ x, f x = -f (-x)
|
||||
|
||||
example (ef : FnEven f) (eg : FnEven g) : FnEven fun x ↦ f x + g x := by
|
||||
intro x
|
||||
calc
|
||||
(fun x ↦ f x + g x) x = f x + g x := rfl
|
||||
_ = f (-x) + g (-x) := by rw [ef, eg]
|
||||
|
||||
|
||||
example (of : FnOdd f) (og : FnOdd g) : FnEven fun x ↦ f x * g x := by
|
||||
sorry
|
||||
|
||||
example (ef : FnEven f) (og : FnOdd g) : FnOdd fun x ↦ f x * g x := by
|
||||
sorry
|
||||
|
||||
example (ef : FnEven f) (og : FnOdd g) : FnEven fun x ↦ f (g x) := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
variable {α : Type*} (r s t : Set α)
|
||||
|
||||
example : s ⊆ s := by
|
||||
intro x xs
|
||||
exact xs
|
||||
|
||||
theorem Subset.refl : s ⊆ s := fun x xs ↦ xs
|
||||
|
||||
theorem Subset.trans : r ⊆ s → s ⊆ t → r ⊆ t := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [PartialOrder α]
|
||||
variable (s : Set α) (a b : α)
|
||||
|
||||
def SetUb (s : Set α) (a : α) :=
|
||||
∀ x, x ∈ s → x ≤ a
|
||||
|
||||
example (h : SetUb s a) (h' : a ≤ b) : SetUb s b :=
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Function
|
||||
|
||||
example (c : ℝ) : Injective fun x ↦ x + c := by
|
||||
intro x₁ x₂ h'
|
||||
exact (add_left_inj c).mp h'
|
||||
|
||||
example {c : ℝ} (h : c ≠ 0) : Injective fun x ↦ c * x := by
|
||||
sorry
|
||||
|
||||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||||
variable {g : β → γ} {f : α → β}
|
||||
|
||||
example (injg : Injective g) (injf : Injective f) : Injective fun x ↦ g (f x) := by
|
||||
sorry
|
||||
|
||||
end
|
|
@ -0,0 +1,168 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
namespace C03S02
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 3 := by
|
||||
use 5 / 2
|
||||
norm_num
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 3 := by
|
||||
have h1 : 2 < (5 : ℝ) / 2 := by norm_num
|
||||
have h2 : (5 : ℝ) / 2 < 3 := by norm_num
|
||||
use 5 / 2, h1, h2
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 3 := by
|
||||
have h : 2 < (5 : ℝ) / 2 ∧ (5 : ℝ) / 2 < 3 := by norm_num
|
||||
use 5 / 2
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 3 :=
|
||||
have h : 2 < (5 : ℝ) / 2 ∧ (5 : ℝ) / 2 < 3 := by norm_num
|
||||
⟨5 / 2, h⟩
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 3 :=
|
||||
⟨5 / 2, by norm_num⟩
|
||||
|
||||
def FnUb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
def FnLb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, a ≤ f x
|
||||
|
||||
def FnHasUb (f : ℝ → ℝ) :=
|
||||
∃ a, FnUb f a
|
||||
|
||||
def FnHasLb (f : ℝ → ℝ) :=
|
||||
∃ a, FnLb f a
|
||||
|
||||
theorem fnUb_add {f g : ℝ → ℝ} {a b : ℝ} (hfa : FnUb f a) (hgb : FnUb g b) :
|
||||
FnUb (fun x ↦ f x + g x) (a + b) :=
|
||||
fun x ↦ add_le_add (hfa x) (hgb x)
|
||||
|
||||
section
|
||||
|
||||
variable {f g : ℝ → ℝ}
|
||||
|
||||
example (ubf : FnHasUb f) (ubg : FnHasUb g) : FnHasUb fun x ↦ f x + g x := by
|
||||
rcases ubf with ⟨a, ubfa⟩
|
||||
rcases ubg with ⟨b, ubgb⟩
|
||||
use a + b
|
||||
apply fnUb_add ubfa ubgb
|
||||
|
||||
example (lbf : FnHasLb f) (lbg : FnHasLb g) : FnHasLb fun x ↦ f x + g x := by
|
||||
sorry
|
||||
|
||||
example {c : ℝ} (ubf : FnHasUb f) (h : c ≥ 0) : FnHasUb fun x ↦ c * f x := by
|
||||
sorry
|
||||
|
||||
example : FnHasUb f → FnHasUb g → FnHasUb fun x ↦ f x + g x := by
|
||||
rintro ⟨a, ubfa⟩ ⟨b, ubgb⟩
|
||||
exact ⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
example : FnHasUb f → FnHasUb g → FnHasUb fun x ↦ f x + g x :=
|
||||
fun ⟨a, ubfa⟩ ⟨b, ubgb⟩ ↦ ⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
end
|
||||
|
||||
example (ubf : FnHasUb f) (ubg : FnHasUb g) : FnHasUb fun x ↦ f x + g x := by
|
||||
obtain ⟨a, ubfa⟩ := ubf
|
||||
obtain ⟨b, ubgb⟩ := ubg
|
||||
exact ⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
example (ubf : FnHasUb f) (ubg : FnHasUb g) : FnHasUb fun x ↦ f x + g x := by
|
||||
cases ubf
|
||||
case intro a ubfa =>
|
||||
cases ubg
|
||||
case intro b ubgb =>
|
||||
exact ⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
example (ubf : FnHasUb f) (ubg : FnHasUb g) : FnHasUb fun x ↦ f x + g x := by
|
||||
cases ubf
|
||||
next a ubfa =>
|
||||
cases ubg
|
||||
next b ubgb =>
|
||||
exact ⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
example (ubf : FnHasUb f) (ubg : FnHasUb g) : FnHasUb fun x ↦ f x + g x := by
|
||||
match ubf, ubg with
|
||||
| ⟨a, ubfa⟩, ⟨b, ubgb⟩ =>
|
||||
exact ⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
example (ubf : FnHasUb f) (ubg : FnHasUb g) : FnHasUb fun x ↦ f x + g x :=
|
||||
match ubf, ubg with
|
||||
| ⟨a, ubfa⟩, ⟨b, ubgb⟩ =>
|
||||
⟨a + b, fnUb_add ubfa ubgb⟩
|
||||
|
||||
section
|
||||
|
||||
variable {α : Type*} [CommRing α]
|
||||
|
||||
def SumOfSquares (x : α) :=
|
||||
∃ a b, x = a ^ 2 + b ^ 2
|
||||
|
||||
theorem sumOfSquares_mul {x y : α} (sosx : SumOfSquares x) (sosy : SumOfSquares y) :
|
||||
SumOfSquares (x * y) := by
|
||||
rcases sosx with ⟨a, b, xeq⟩
|
||||
rcases sosy with ⟨c, d, yeq⟩
|
||||
rw [xeq, yeq]
|
||||
use a * c - b * d, a * d + b * c
|
||||
ring
|
||||
|
||||
theorem sumOfSquares_mul' {x y : α} (sosx : SumOfSquares x) (sosy : SumOfSquares y) :
|
||||
SumOfSquares (x * y) := by
|
||||
rcases sosx with ⟨a, b, rfl⟩
|
||||
rcases sosy with ⟨c, d, rfl⟩
|
||||
use a * c - b * d, a * d + b * c
|
||||
ring
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {a b c : ℕ}
|
||||
|
||||
example (divab : a ∣ b) (divbc : b ∣ c) : a ∣ c := by
|
||||
rcases divab with ⟨d, beq⟩
|
||||
rcases divbc with ⟨e, ceq⟩
|
||||
rw [ceq, beq]
|
||||
use d * e; ring
|
||||
|
||||
example (divab : a ∣ b) (divac : a ∣ c) : a ∣ b + c := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Function
|
||||
|
||||
example {c : ℝ} : Surjective fun x ↦ x + c := by
|
||||
intro x
|
||||
use x - c
|
||||
dsimp; ring
|
||||
|
||||
example {c : ℝ} (h : c ≠ 0) : Surjective fun x ↦ c * x := by
|
||||
sorry
|
||||
|
||||
example (x y : ℝ) (h : x - y ≠ 0) : (x ^ 2 - y ^ 2) / (x - y) = x + y := by
|
||||
field_simp [h]
|
||||
ring
|
||||
|
||||
example {f : ℝ → ℝ} (h : Surjective f) : ∃ x, f x ^ 2 = 4 := by
|
||||
rcases h 2 with ⟨x, hx⟩
|
||||
use x
|
||||
rw [hx]
|
||||
norm_num
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
open Function
|
||||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||||
variable {g : β → γ} {f : α → β}
|
||||
|
||||
example (surjg : Surjective g) (surjf : Surjective f) : Surjective fun x ↦ g (f x) := by
|
||||
sorry
|
||||
|
||||
end
|
|
@ -0,0 +1,139 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S03
|
||||
|
||||
section
|
||||
variable (a b : ℝ)
|
||||
|
||||
example (h : a < b) : ¬b < a := by
|
||||
intro h'
|
||||
have : a < a := lt_trans h h'
|
||||
apply lt_irrefl a this
|
||||
|
||||
def FnUb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
def FnLb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, a ≤ f x
|
||||
|
||||
def FnHasUb (f : ℝ → ℝ) :=
|
||||
∃ a, FnUb f a
|
||||
|
||||
def FnHasLb (f : ℝ → ℝ) :=
|
||||
∃ a, FnLb f a
|
||||
|
||||
variable (f : ℝ → ℝ)
|
||||
|
||||
example (h : ∀ a, ∃ x, f x > a) : ¬FnHasUb f := by
|
||||
intro fnub
|
||||
rcases fnub with ⟨a, fnuba⟩
|
||||
rcases h a with ⟨x, hx⟩
|
||||
have : f x ≤ a := fnuba x
|
||||
linarith
|
||||
|
||||
example (h : ∀ a, ∃ x, f x < a) : ¬FnHasLb f :=
|
||||
sorry
|
||||
|
||||
example : ¬FnHasUb fun x ↦ x :=
|
||||
sorry
|
||||
|
||||
#check (not_le_of_gt : a > b → ¬a ≤ b)
|
||||
#check (not_lt_of_ge : a ≥ b → ¬a < b)
|
||||
#check (lt_of_not_ge : ¬a ≥ b → a < b)
|
||||
#check (le_of_not_gt : ¬a > b → a ≤ b)
|
||||
|
||||
example (h : Monotone f) (h' : f a < f b) : a < b := by
|
||||
sorry
|
||||
|
||||
example (h : a ≤ b) (h' : f b < f a) : ¬Monotone f := by
|
||||
sorry
|
||||
|
||||
example : ¬∀ {f : ℝ → ℝ}, Monotone f → ∀ {a b}, f a ≤ f b → a ≤ b := by
|
||||
intro h
|
||||
let f := fun x : ℝ ↦ (0 : ℝ)
|
||||
have monof : Monotone f := by sorry
|
||||
have h' : f 1 ≤ f 0 := le_refl _
|
||||
sorry
|
||||
|
||||
example (x : ℝ) (h : ∀ ε > 0, x < ε) : x ≤ 0 := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} (P : α → Prop) (Q : Prop)
|
||||
|
||||
example (h : ¬∃ x, P x) : ∀ x, ¬P x := by
|
||||
sorry
|
||||
|
||||
example (h : ∀ x, ¬P x) : ¬∃ x, P x := by
|
||||
sorry
|
||||
|
||||
example (h : ¬∀ x, P x) : ∃ x, ¬P x := by
|
||||
sorry
|
||||
|
||||
example (h : ∃ x, ¬P x) : ¬∀ x, P x := by
|
||||
sorry
|
||||
|
||||
example (h : ¬∀ x, P x) : ∃ x, ¬P x := by
|
||||
by_contra h'
|
||||
apply h
|
||||
intro x
|
||||
show P x
|
||||
by_contra h''
|
||||
exact h' ⟨x, h''⟩
|
||||
|
||||
example (h : ¬¬Q) : Q := by
|
||||
sorry
|
||||
|
||||
example (h : Q) : ¬¬Q := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (f : ℝ → ℝ)
|
||||
|
||||
example (h : ¬FnHasUb f) : ∀ a, ∃ x, f x > a := by
|
||||
sorry
|
||||
|
||||
example (h : ¬∀ a, ∃ x, f x > a) : FnHasUb f := by
|
||||
push_neg at h
|
||||
exact h
|
||||
|
||||
example (h : ¬FnHasUb f) : ∀ a, ∃ x, f x > a := by
|
||||
dsimp only [FnHasUb, FnUb] at h
|
||||
push_neg at h
|
||||
exact h
|
||||
|
||||
example (h : ¬Monotone f) : ∃ x y, x ≤ y ∧ f y < f x := by
|
||||
sorry
|
||||
|
||||
example (h : ¬FnHasUb f) : ∀ a, ∃ x, f x > a := by
|
||||
contrapose! h
|
||||
exact h
|
||||
|
||||
example (x : ℝ) (h : ∀ ε > 0, x ≤ ε) : x ≤ 0 := by
|
||||
contrapose! h
|
||||
use x / 2
|
||||
constructor <;> linarith
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (a : ℕ)
|
||||
|
||||
example (h : 0 < 0) : a > 37 := by
|
||||
exfalso
|
||||
apply lt_irrefl 0 h
|
||||
|
||||
example (h : 0 < 0) : a > 37 :=
|
||||
absurd h (lt_irrefl 0)
|
||||
|
||||
example (h : 0 < 0) : a > 37 := by
|
||||
have h' : ¬0 < 0 := lt_irrefl 0
|
||||
contradiction
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
import Mathlib.Data.Nat.Prime
|
||||
|
||||
namespace C03S04
|
||||
|
||||
example {x y : ℝ} (h₀ : x ≤ y) (h₁ : ¬y ≤ x) : x ≤ y ∧ x ≠ y := by
|
||||
constructor
|
||||
· assumption
|
||||
intro h
|
||||
apply h₁
|
||||
rw [h]
|
||||
|
||||
example {x y : ℝ} (h₀ : x ≤ y) (h₁ : ¬y ≤ x) : x ≤ y ∧ x ≠ y :=
|
||||
⟨h₀, fun h ↦ h₁ (by rw [h])⟩
|
||||
|
||||
example {x y : ℝ} (h₀ : x ≤ y) (h₁ : ¬y ≤ x) : x ≤ y ∧ x ≠ y :=
|
||||
have h : x ≠ y := by
|
||||
contrapose! h₁
|
||||
rw [h₁]
|
||||
⟨h₀, h⟩
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x := by
|
||||
rcases h with ⟨h₀, h₁⟩
|
||||
contrapose! h₁
|
||||
exact le_antisymm h₀ h₁
|
||||
|
||||
example {x y : ℝ} : x ≤ y ∧ x ≠ y → ¬y ≤ x := by
|
||||
rintro ⟨h₀, h₁⟩ h'
|
||||
exact h₁ (le_antisymm h₀ h')
|
||||
|
||||
example {x y : ℝ} : x ≤ y ∧ x ≠ y → ¬y ≤ x :=
|
||||
fun ⟨h₀, h₁⟩ h' ↦ h₁ (le_antisymm h₀ h')
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x := by
|
||||
have ⟨h₀, h₁⟩ := h
|
||||
contrapose! h₁
|
||||
exact le_antisymm h₀ h₁
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x := by
|
||||
cases h
|
||||
case intro h₀ h₁ =>
|
||||
contrapose! h₁
|
||||
exact le_antisymm h₀ h₁
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x := by
|
||||
cases h
|
||||
next h₀ h₁ =>
|
||||
contrapose! h₁
|
||||
exact le_antisymm h₀ h₁
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x := by
|
||||
match h with
|
||||
| ⟨h₀, h₁⟩ =>
|
||||
contrapose! h₁
|
||||
exact le_antisymm h₀ h₁
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x := by
|
||||
intro h'
|
||||
apply h.right
|
||||
exact le_antisymm h.left h'
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y ∧ x ≠ y) : ¬y ≤ x :=
|
||||
fun h' ↦ h.right (le_antisymm h.left h')
|
||||
|
||||
example {m n : ℕ} (h : m ∣ n ∧ m ≠ n) : m ∣ n ∧ ¬n ∣ m :=
|
||||
sorry
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 4 :=
|
||||
⟨5 / 2, by norm_num, by norm_num⟩
|
||||
|
||||
example (x y : ℝ) : (∃ z : ℝ, x < z ∧ z < y) → x < y := by
|
||||
rintro ⟨z, xltz, zlty⟩
|
||||
exact lt_trans xltz zlty
|
||||
|
||||
example (x y : ℝ) : (∃ z : ℝ, x < z ∧ z < y) → x < y :=
|
||||
fun ⟨z, xltz, zlty⟩ ↦ lt_trans xltz zlty
|
||||
|
||||
example : ∃ x : ℝ, 2 < x ∧ x < 4 := by
|
||||
use 5 / 2
|
||||
constructor <;> norm_num
|
||||
|
||||
example : ∃ m n : ℕ, 4 < m ∧ m < n ∧ n < 10 ∧ Nat.Prime m ∧ Nat.Prime n := by
|
||||
use 5
|
||||
use 7
|
||||
norm_num
|
||||
|
||||
example {x y : ℝ} : x ≤ y ∧ x ≠ y → x ≤ y ∧ ¬y ≤ x := by
|
||||
rintro ⟨h₀, h₁⟩
|
||||
use h₀
|
||||
exact fun h' ↦ h₁ (le_antisymm h₀ h')
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y) : ¬y ≤ x ↔ x ≠ y := by
|
||||
constructor
|
||||
· contrapose!
|
||||
rintro rfl
|
||||
rfl
|
||||
contrapose!
|
||||
exact le_antisymm h
|
||||
|
||||
example {x y : ℝ} (h : x ≤ y) : ¬y ≤ x ↔ x ≠ y :=
|
||||
⟨fun h₀ h₁ ↦ h₀ (by rw [h₁]), fun h₀ h₁ ↦ h₀ (le_antisymm h h₁)⟩
|
||||
|
||||
example {x y : ℝ} : x ≤ y ∧ ¬y ≤ x ↔ x ≤ y ∧ x ≠ y :=
|
||||
sorry
|
||||
|
||||
theorem aux {x y : ℝ} (h : x ^ 2 + y ^ 2 = 0) : x = 0 :=
|
||||
have h' : x ^ 2 = 0 := by sorry
|
||||
pow_eq_zero h'
|
||||
|
||||
example (x y : ℝ) : x ^ 2 + y ^ 2 = 0 ↔ x = 0 ∧ y = 0 :=
|
||||
sorry
|
||||
|
||||
section
|
||||
|
||||
example (x : ℝ) : |x + 3| < 5 → -8 < x ∧ x < 2 := by
|
||||
rw [abs_lt]
|
||||
intro h
|
||||
constructor <;> linarith
|
||||
|
||||
example : 3 ∣ Nat.gcd 6 15 := by
|
||||
rw [Nat.dvd_gcd_iff]
|
||||
constructor <;> norm_num
|
||||
|
||||
end
|
||||
|
||||
theorem not_monotone_iff {f : ℝ → ℝ} : ¬Monotone f ↔ ∃ x y, x ≤ y ∧ f x > f y := by
|
||||
rw [Monotone]
|
||||
push_neg
|
||||
rfl
|
||||
|
||||
example : ¬Monotone fun x : ℝ ↦ -x := by
|
||||
sorry
|
||||
|
||||
section
|
||||
variable {α : Type*} [PartialOrder α]
|
||||
variable (a b : α)
|
||||
|
||||
example : a < b ↔ a ≤ b ∧ a ≠ b := by
|
||||
rw [lt_iff_le_not_le]
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [Preorder α]
|
||||
variable (a b c : α)
|
||||
|
||||
example : ¬a < a := by
|
||||
rw [lt_iff_le_not_le]
|
||||
sorry
|
||||
|
||||
example : a < b → b < c → a < c := by
|
||||
simp only [lt_iff_le_not_le]
|
||||
sorry
|
||||
|
||||
end
|
|
@ -0,0 +1,129 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S05
|
||||
|
||||
section
|
||||
|
||||
variable {x y : ℝ}
|
||||
|
||||
example (h : y > x ^ 2) : y > 0 ∨ y < -1 := by
|
||||
left
|
||||
linarith [pow_two_nonneg x]
|
||||
|
||||
example (h : -y > x ^ 2 + 1) : y > 0 ∨ y < -1 := by
|
||||
right
|
||||
linarith [pow_two_nonneg x]
|
||||
|
||||
example (h : y > 0) : y > 0 ∨ y < -1 :=
|
||||
Or.inl h
|
||||
|
||||
example (h : y < -1) : y > 0 ∨ y < -1 :=
|
||||
Or.inr h
|
||||
|
||||
example : x < |y| → x < y ∨ x < -y := by
|
||||
rcases le_or_gt 0 y with h | h
|
||||
· rw [abs_of_nonneg h]
|
||||
intro h; left; exact h
|
||||
. rw [abs_of_neg h]
|
||||
intro h; right; exact h
|
||||
|
||||
example : x < |y| → x < y ∨ x < -y := by
|
||||
cases le_or_gt 0 y
|
||||
case inl h =>
|
||||
rw [abs_of_nonneg h]
|
||||
intro h; left; exact h
|
||||
case inr h =>
|
||||
rw [abs_of_neg h]
|
||||
intro h; right; exact h
|
||||
|
||||
example : x < |y| → x < y ∨ x < -y := by
|
||||
cases le_or_gt 0 y
|
||||
next h =>
|
||||
rw [abs_of_nonneg h]
|
||||
intro h; left; exact h
|
||||
next h =>
|
||||
rw [abs_of_neg h]
|
||||
intro h; right; exact h
|
||||
|
||||
|
||||
example : x < |y| → x < y ∨ x < -y := by
|
||||
match le_or_gt 0 y with
|
||||
| Or.inl h =>
|
||||
rw [abs_of_nonneg h]
|
||||
intro h; left; exact h
|
||||
| Or.inr h =>
|
||||
rw [abs_of_neg h]
|
||||
intro h; right; exact h
|
||||
|
||||
namespace MyAbs
|
||||
|
||||
theorem le_abs_self (x : ℝ) : x ≤ |x| := by
|
||||
sorry
|
||||
|
||||
theorem neg_le_abs_self (x : ℝ) : -x ≤ |x| := by
|
||||
sorry
|
||||
|
||||
theorem abs_add (x y : ℝ) : |x + y| ≤ |x| + |y| := by
|
||||
sorry
|
||||
|
||||
theorem lt_abs : x < |y| ↔ x < y ∨ x < -y := by
|
||||
sorry
|
||||
|
||||
theorem abs_lt : |x| < y ↔ -y < x ∧ x < y := by
|
||||
sorry
|
||||
|
||||
end MyAbs
|
||||
|
||||
end
|
||||
|
||||
example {x : ℝ} (h : x ≠ 0) : x < 0 ∨ x > 0 := by
|
||||
rcases lt_trichotomy x 0 with xlt | xeq | xgt
|
||||
· left
|
||||
exact xlt
|
||||
· contradiction
|
||||
. right; exact xgt
|
||||
|
||||
example {m n k : ℕ} (h : m ∣ n ∨ m ∣ k) : m ∣ n * k := by
|
||||
rcases h with ⟨a, rfl⟩ | ⟨b, rfl⟩
|
||||
· rw [mul_assoc]
|
||||
apply dvd_mul_right
|
||||
. rw [mul_comm, mul_assoc]
|
||||
apply dvd_mul_right
|
||||
|
||||
example {z : ℝ} (h : ∃ x y, z = x ^ 2 + y ^ 2 ∨ z = x ^ 2 + y ^ 2 + 1) : z ≥ 0 := by
|
||||
sorry
|
||||
|
||||
example {x : ℝ} (h : x ^ 2 = 1) : x = 1 ∨ x = -1 := by
|
||||
sorry
|
||||
|
||||
example {x y : ℝ} (h : x ^ 2 = y ^ 2) : x = y ∨ x = -y := by
|
||||
sorry
|
||||
|
||||
section
|
||||
variable {R : Type*} [CommRing R] [IsDomain R]
|
||||
variable (x y : R)
|
||||
|
||||
example (h : x ^ 2 = 1) : x = 1 ∨ x = -1 := by
|
||||
sorry
|
||||
|
||||
example (h : x ^ 2 = y ^ 2) : x = y ∨ x = -y := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
example (P : Prop) : ¬¬P → P := by
|
||||
intro h
|
||||
cases em P
|
||||
· assumption
|
||||
. contradiction
|
||||
|
||||
example (P : Prop) : ¬¬P → P := by
|
||||
intro h
|
||||
by_cases h' : P
|
||||
· assumption
|
||||
contradiction
|
||||
|
||||
example (P Q : Prop) : P → Q ↔ ¬P ∨ Q := by
|
||||
sorry
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S06
|
||||
|
||||
def ConvergesTo (s : ℕ → ℝ) (a : ℝ) :=
|
||||
∀ ε > 0, ∃ N, ∀ n ≥ N, |s n - a| < ε
|
||||
|
||||
example : (fun x y : ℝ ↦ (x + y) ^ 2) = fun x y : ℝ ↦ x ^ 2 + 2 * x * y + y ^ 2 := by
|
||||
ext
|
||||
ring
|
||||
|
||||
example (a b : ℝ) : |a| = |a - b + b| := by
|
||||
congr
|
||||
ring
|
||||
|
||||
example {a : ℝ} (h : 1 < a) : a < a * a := by
|
||||
convert (mul_lt_mul_right _).2 h
|
||||
· rw [one_mul]
|
||||
exact lt_trans zero_lt_one h
|
||||
|
||||
theorem convergesTo_const (a : ℝ) : ConvergesTo (fun x : ℕ ↦ a) a := by
|
||||
intro ε εpos
|
||||
use 0
|
||||
intro n nge
|
||||
rw [sub_self, abs_zero]
|
||||
apply εpos
|
||||
|
||||
theorem convergesTo_add {s t : ℕ → ℝ} {a b : ℝ}
|
||||
(cs : ConvergesTo s a) (ct : ConvergesTo t b) :
|
||||
ConvergesTo (fun n ↦ s n + t n) (a + b) := by
|
||||
intro ε εpos
|
||||
dsimp -- this line is not needed but cleans up the goal a bit.
|
||||
have ε2pos : 0 < ε / 2 := by linarith
|
||||
rcases cs (ε / 2) ε2pos with ⟨Ns, hs⟩
|
||||
rcases ct (ε / 2) ε2pos with ⟨Nt, ht⟩
|
||||
use max Ns Nt
|
||||
sorry
|
||||
|
||||
theorem convergesTo_mul_const {s : ℕ → ℝ} {a : ℝ} (c : ℝ) (cs : ConvergesTo s a) :
|
||||
ConvergesTo (fun n ↦ c * s n) (c * a) := by
|
||||
by_cases h : c = 0
|
||||
· convert convergesTo_const 0
|
||||
· rw [h]
|
||||
ring
|
||||
rw [h]
|
||||
ring
|
||||
have acpos : 0 < |c| := abs_pos.mpr h
|
||||
sorry
|
||||
|
||||
theorem exists_abs_le_of_convergesTo {s : ℕ → ℝ} {a : ℝ} (cs : ConvergesTo s a) :
|
||||
∃ N b, ∀ n, N ≤ n → |s n| < b := by
|
||||
rcases cs 1 zero_lt_one with ⟨N, h⟩
|
||||
use N, |a| + 1
|
||||
sorry
|
||||
|
||||
theorem aux {s t : ℕ → ℝ} {a : ℝ} (cs : ConvergesTo s a) (ct : ConvergesTo t 0) :
|
||||
ConvergesTo (fun n ↦ s n * t n) 0 := by
|
||||
intro ε εpos
|
||||
dsimp
|
||||
rcases exists_abs_le_of_convergesTo cs with ⟨N₀, B, h₀⟩
|
||||
have Bpos : 0 < B := lt_of_le_of_lt (abs_nonneg _) (h₀ N₀ (le_refl _))
|
||||
have pos₀ : ε / B > 0 := div_pos εpos Bpos
|
||||
rcases ct _ pos₀ with ⟨N₁, h₁⟩
|
||||
sorry
|
||||
|
||||
theorem convergesTo_mul {s t : ℕ → ℝ} {a b : ℝ}
|
||||
(cs : ConvergesTo s a) (ct : ConvergesTo t b) :
|
||||
ConvergesTo (fun n ↦ s n * t n) (a * b) := by
|
||||
have h₁ : ConvergesTo (fun n ↦ s n * (t n + -b)) 0 := by
|
||||
apply aux cs
|
||||
convert convergesTo_add ct (convergesTo_const (-b))
|
||||
ring
|
||||
have := convergesTo_add h₁ (convergesTo_mul_const b cs)
|
||||
convert convergesTo_add h₁ (convergesTo_mul_const b cs) using 1
|
||||
· ext; ring
|
||||
ring
|
||||
|
||||
theorem convergesTo_unique {s : ℕ → ℝ} {a b : ℝ}
|
||||
(sa : ConvergesTo s a) (sb : ConvergesTo s b) :
|
||||
a = b := by
|
||||
by_contra abne
|
||||
have : |a - b| > 0 := by sorry
|
||||
let ε := |a - b| / 2
|
||||
have εpos : ε > 0 := by
|
||||
change |a - b| / 2 > 0
|
||||
linarith
|
||||
rcases sa ε εpos with ⟨Na, hNa⟩
|
||||
rcases sb ε εpos with ⟨Nb, hNb⟩
|
||||
let N := max Na Nb
|
||||
have absa : |s N - a| < ε := by sorry
|
||||
have absb : |s N - b| < ε := by sorry
|
||||
have : |a - b| < |a - b| := by sorry
|
||||
exact lt_irrefl _ this
|
||||
|
||||
section
|
||||
variable {α : Type*} [LinearOrder α]
|
||||
|
||||
def ConvergesTo' (s : α → ℝ) (a : ℝ) :=
|
||||
∀ ε > 0, ∃ N, ∀ n ≥ N, |s n - a| < ε
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S01
|
||||
|
||||
theorem my_lemma4 :
|
||||
∀ {x y ε : ℝ}, 0 < ε → ε ≤ 1 → |x| < ε → |y| < ε → |x * y| < ε := by
|
||||
intro x y ε epos ele1 xlt ylt
|
||||
calc
|
||||
|x * y| = |x| * |y| := by apply abs_mul
|
||||
_ ≤ |x| * ε := by apply mul_le_mul; linarith; linarith; apply abs_nonneg; apply abs_nonneg;
|
||||
_ < 1 * ε := by rw [mul_lt_mul_right epos]; linarith
|
||||
_ = ε := by apply one_mul
|
||||
|
||||
def FnUb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
def FnLb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, a ≤ f x
|
||||
|
||||
section
|
||||
variable (f g : ℝ → ℝ) (a b : ℝ)
|
||||
|
||||
example (hfa : FnLb f a) (hgb : FnLb g b) : FnLb (fun x ↦ f x + g x) (a + b) := by
|
||||
intro x
|
||||
apply add_le_add
|
||||
apply hfa
|
||||
apply hgb
|
||||
|
||||
example (nnf : FnLb f 0) (nng : FnLb g 0) : FnLb (fun x ↦ f x * g x) 0 := by
|
||||
intro x
|
||||
apply mul_nonneg
|
||||
apply nnf
|
||||
apply nng
|
||||
|
||||
example (hfa : FnUb f a) (hgb : FnUb g b) (nng : FnLb g 0) (nna : 0 ≤ a) :
|
||||
FnUb (fun x ↦ f x * g x) (a * b) := by
|
||||
intro x
|
||||
apply mul_le_mul
|
||||
apply hfa
|
||||
apply hgb
|
||||
apply nng
|
||||
apply nna
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (f g : ℝ → ℝ)
|
||||
|
||||
example {c : ℝ} (mf : Monotone f) (nnc : 0 ≤ c) : Monotone fun x ↦ c * f x := by
|
||||
intro a b aleb
|
||||
apply mul_le_mul_of_nonneg_left _ nnc
|
||||
apply mf aleb
|
||||
|
||||
example {c : ℝ} (mf : Monotone f) (nnc : 0 ≤ c) : Monotone fun x ↦ c * f x :=
|
||||
fun a b aleb ↦ mul_le_mul_of_nonneg_left (mf aleb) nnc
|
||||
|
||||
example (mf : Monotone f) (mg : Monotone g) : Monotone fun x ↦ f (g x) := by
|
||||
intro a b aleb
|
||||
apply mf
|
||||
apply mg
|
||||
apply aleb
|
||||
|
||||
example (mf : Monotone f) (mg : Monotone g) : Monotone fun x ↦ f (g x) :=
|
||||
fun a b aleb ↦ mf (mg aleb)
|
||||
|
||||
def FnEven (f : ℝ → ℝ) : Prop :=
|
||||
∀ x, f x = f (-x)
|
||||
|
||||
def FnOdd (f : ℝ → ℝ) : Prop :=
|
||||
∀ x, f x = -f (-x)
|
||||
|
||||
example (of : FnOdd f) (og : FnOdd g) : FnEven fun x ↦ f x * g x := by
|
||||
intro x
|
||||
calc
|
||||
(fun x ↦ f x * g x) x = f x * g x := rfl
|
||||
_ = f (-x) * g (-x) := by rw [of, og, neg_mul_neg]
|
||||
|
||||
|
||||
example (ef : FnEven f) (og : FnOdd g) : FnOdd fun x ↦ f x * g x := by
|
||||
intro x
|
||||
dsimp
|
||||
rw [ef, og, neg_mul_eq_mul_neg]
|
||||
|
||||
example (ef : FnEven f) (og : FnOdd g) : FnEven fun x ↦ f (g x) := by
|
||||
intro x
|
||||
dsimp
|
||||
rw [og, ← ef]
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
variable {α : Type*} (r s t : Set α)
|
||||
|
||||
example : r ⊆ s → s ⊆ t → r ⊆ t := by
|
||||
intro rsubs ssubt x xr
|
||||
apply ssubt
|
||||
apply rsubs
|
||||
apply xr
|
||||
|
||||
theorem Subset.trans : r ⊆ s → s ⊆ t → r ⊆ t :=
|
||||
fun rsubs ssubt x xr ↦ ssubt (rsubs xr)
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [PartialOrder α]
|
||||
variable (s : Set α) (a b : α)
|
||||
|
||||
def SetUb (s : Set α) (a : α) :=
|
||||
∀ x, x ∈ s → x ≤ a
|
||||
|
||||
example (h : SetUb s a) (h' : a ≤ b) : SetUb s b := by
|
||||
intro x xs
|
||||
apply le_trans (h x xs) h'
|
||||
|
||||
example (h : SetUb s a) (h' : a ≤ b) : SetUb s b :=
|
||||
fun x xs ↦ le_trans (h x xs) h'
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Function
|
||||
|
||||
example {c : ℝ} (h : c ≠ 0) : Injective fun x ↦ c * x := by
|
||||
intro x₁ x₂ h'
|
||||
apply (mul_right_inj' h).mp h'
|
||||
|
||||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||||
variable {g : β → γ} {f : α → β}
|
||||
|
||||
example (injg : Injective g) (injf : Injective f) : Injective fun x ↦ g (f x) := by
|
||||
intro x₁ x₂ h
|
||||
apply injf
|
||||
apply injg
|
||||
apply h
|
||||
|
||||
end
|
|
@ -0,0 +1,85 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
namespace C03S02
|
||||
|
||||
def FnUb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
def FnLb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, a ≤ f x
|
||||
|
||||
def FnHasUb (f : ℝ → ℝ) :=
|
||||
∃ a, FnUb f a
|
||||
|
||||
def FnHasLb (f : ℝ → ℝ) :=
|
||||
∃ a, FnLb f a
|
||||
|
||||
theorem fnUb_add {f g : ℝ → ℝ} {a b : ℝ} (hfa : FnUb f a) (hgb : FnUb g b) :
|
||||
FnUb (fun x ↦ f x + g x) (a + b) :=
|
||||
fun x ↦ add_le_add (hfa x) (hgb x)
|
||||
|
||||
section
|
||||
|
||||
variable {f g : ℝ → ℝ}
|
||||
|
||||
example (lbf : FnHasLb f) (lbg : FnHasLb g) : FnHasLb fun x ↦ f x + g x := by
|
||||
rcases lbf with ⟨a, lbfa⟩
|
||||
rcases lbg with ⟨b, lbgb⟩
|
||||
use a + b
|
||||
intro x
|
||||
exact add_le_add (lbfa x) (lbgb x)
|
||||
|
||||
example {c : ℝ} (ubf : FnHasUb f) (h : c ≥ 0) : FnHasUb fun x ↦ c * f x := by
|
||||
rcases ubf with ⟨a, lbfa⟩
|
||||
use c * a
|
||||
intro x
|
||||
exact mul_le_mul_of_nonneg_left (lbfa x) h
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {a b c : ℕ}
|
||||
|
||||
example (divab : a ∣ b) (divbc : b ∣ c) : a ∣ c := by
|
||||
rcases divab with ⟨d, rfl⟩
|
||||
rcases divbc with ⟨e, rfl⟩
|
||||
use d * e; ring
|
||||
|
||||
example (divab : a ∣ b) (divac : a ∣ c) : a ∣ b + c := by
|
||||
rcases divab with ⟨d, rfl⟩
|
||||
rcases divac with ⟨e, rfl⟩
|
||||
use d + e; ring
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Function
|
||||
|
||||
example {c : ℝ} (h : c ≠ 0) : Surjective fun x ↦ c * x := by
|
||||
intro x
|
||||
use x / c
|
||||
dsimp; rw [mul_div_cancel' _ h]
|
||||
|
||||
example {c : ℝ} (h : c ≠ 0) : Surjective fun x ↦ c * x := by
|
||||
intro x
|
||||
use x / c
|
||||
field_simp [h] ; ring
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
open Function
|
||||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||||
variable {g : β → γ} {f : α → β}
|
||||
|
||||
example (surjg : Surjective g) (surjf : Surjective f) : Surjective fun x ↦ g (f x) := by
|
||||
intro z
|
||||
rcases surjg z with ⟨y, rfl⟩
|
||||
rcases surjf y with ⟨x, rfl⟩
|
||||
use x
|
||||
|
||||
end
|
|
@ -0,0 +1,111 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S03
|
||||
|
||||
section
|
||||
variable (a b : ℝ)
|
||||
|
||||
def FnUb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, f x ≤ a
|
||||
|
||||
def FnLb (f : ℝ → ℝ) (a : ℝ) : Prop :=
|
||||
∀ x, a ≤ f x
|
||||
|
||||
def FnHasUb (f : ℝ → ℝ) :=
|
||||
∃ a, FnUb f a
|
||||
|
||||
def FnHasLb (f : ℝ → ℝ) :=
|
||||
∃ a, FnLb f a
|
||||
|
||||
variable (f : ℝ → ℝ)
|
||||
|
||||
example (h : ∀ a, ∃ x, f x < a) : ¬FnHasLb f := by
|
||||
rintro ⟨a, ha⟩
|
||||
rcases h a with ⟨x, hx⟩
|
||||
have := ha x
|
||||
linarith
|
||||
|
||||
example : ¬FnHasUb fun x ↦ x := by
|
||||
rintro ⟨a, ha⟩
|
||||
have : a + 1 ≤ a := ha (a + 1)
|
||||
linarith
|
||||
|
||||
example (h : Monotone f) (h' : f a < f b) : a < b := by
|
||||
apply lt_of_not_ge
|
||||
intro h''
|
||||
apply absurd h'
|
||||
apply not_lt_of_ge (h h'')
|
||||
|
||||
example (h : a ≤ b) (h' : f b < f a) : ¬Monotone f := by
|
||||
intro h''
|
||||
apply absurd h'
|
||||
apply not_lt_of_ge
|
||||
apply h'' h
|
||||
|
||||
example : ¬∀ {f : ℝ → ℝ}, Monotone f → ∀ {a b}, f a ≤ f b → a ≤ b := by
|
||||
intro h
|
||||
let f := fun x : ℝ ↦ (0 : ℝ)
|
||||
have monof : Monotone f := by
|
||||
intro a b leab
|
||||
rfl
|
||||
have h' : f 1 ≤ f 0 := le_refl _
|
||||
have : (1 : ℝ) ≤ 0 := h monof h'
|
||||
linarith
|
||||
|
||||
example (x : ℝ) (h : ∀ ε > 0, x < ε) : x ≤ 0 := by
|
||||
apply le_of_not_gt
|
||||
intro h'
|
||||
linarith [h _ h']
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} (P : α → Prop) (Q : Prop)
|
||||
|
||||
example (h : ¬∃ x, P x) : ∀ x, ¬P x := by
|
||||
intro x Px
|
||||
apply h
|
||||
use x
|
||||
|
||||
example (h : ∀ x, ¬P x) : ¬∃ x, P x := by
|
||||
rintro ⟨x, Px⟩
|
||||
exact h x Px
|
||||
|
||||
example (h : ∃ x, ¬P x) : ¬∀ x, P x := by
|
||||
intro h'
|
||||
rcases h with ⟨x, nPx⟩
|
||||
apply nPx
|
||||
apply h'
|
||||
|
||||
example (h : ¬¬Q) : Q := by
|
||||
by_contra h'
|
||||
exact h h'
|
||||
|
||||
example (h : Q) : ¬¬Q := by
|
||||
intro h'
|
||||
exact h' h
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable (f : ℝ → ℝ)
|
||||
|
||||
example (h : ¬FnHasUb f) : ∀ a, ∃ x, f x > a := by
|
||||
intro a
|
||||
by_contra h'
|
||||
apply h
|
||||
use a
|
||||
intro x
|
||||
apply le_of_not_gt
|
||||
intro h''
|
||||
apply h'
|
||||
use x
|
||||
|
||||
example (h : ¬Monotone f) : ∃ x y, x ≤ y ∧ f y < f x := by
|
||||
rw [Monotone] at h
|
||||
push_neg at h
|
||||
exact h
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
import Mathlib.Data.Nat.Prime
|
||||
|
||||
namespace C03S04
|
||||
|
||||
example {m n : ℕ} (h : m ∣ n ∧ m ≠ n) : m ∣ n ∧ ¬n ∣ m := by
|
||||
rcases h with ⟨h0, h1⟩
|
||||
constructor
|
||||
· exact h0
|
||||
intro h2
|
||||
apply h1
|
||||
apply Nat.dvd_antisymm h0 h2
|
||||
|
||||
example {x y : ℝ} : x ≤ y ∧ ¬y ≤ x ↔ x ≤ y ∧ x ≠ y := by
|
||||
constructor
|
||||
· rintro ⟨h0, h1⟩
|
||||
constructor
|
||||
· exact h0
|
||||
intro h2
|
||||
apply h1
|
||||
rw [h2]
|
||||
rintro ⟨h0, h1⟩
|
||||
constructor
|
||||
· exact h0
|
||||
intro h2
|
||||
apply h1
|
||||
apply le_antisymm h0 h2
|
||||
|
||||
theorem aux {x y : ℝ} (h : x ^ 2 + y ^ 2 = 0) : x = 0 :=
|
||||
have h' : x ^ 2 = 0 := by linarith [pow_two_nonneg x, pow_two_nonneg y]
|
||||
pow_eq_zero h'
|
||||
|
||||
example (x y : ℝ) : x ^ 2 + y ^ 2 = 0 ↔ x = 0 ∧ y = 0 := by
|
||||
constructor
|
||||
· intro h
|
||||
constructor
|
||||
· exact aux h
|
||||
rw [add_comm] at h
|
||||
exact aux h
|
||||
rintro ⟨rfl, rfl⟩
|
||||
norm_num
|
||||
|
||||
theorem not_monotone_iff {f : ℝ → ℝ} : ¬Monotone f ↔ ∃ x y, x ≤ y ∧ f x > f y := by
|
||||
rw [Monotone]
|
||||
push_neg
|
||||
rfl
|
||||
|
||||
example : ¬Monotone fun x : ℝ ↦ -x := by
|
||||
rw [not_monotone_iff]
|
||||
use 0, 1
|
||||
norm_num
|
||||
|
||||
section
|
||||
variable {α : Type*} [PartialOrder α]
|
||||
variable (a b : α)
|
||||
|
||||
example : a < b ↔ a ≤ b ∧ a ≠ b := by
|
||||
rw [lt_iff_le_not_le]
|
||||
constructor
|
||||
· rintro ⟨h0, h1⟩
|
||||
constructor
|
||||
· exact h0
|
||||
intro h2
|
||||
apply h1
|
||||
rw [h2]
|
||||
rintro ⟨h0, h1⟩
|
||||
constructor
|
||||
· exact h0
|
||||
intro h2
|
||||
apply h1
|
||||
apply le_antisymm h0 h2
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [Preorder α]
|
||||
variable (a b c : α)
|
||||
|
||||
example : ¬a < a := by
|
||||
rw [lt_iff_le_not_le]
|
||||
rintro ⟨h0, h1⟩
|
||||
exact h1 h0
|
||||
|
||||
example : a < b → b < c → a < c := by
|
||||
simp only [lt_iff_le_not_le]
|
||||
rintro ⟨h0, h1⟩ ⟨h2, h3⟩
|
||||
constructor
|
||||
· apply le_trans h0 h2
|
||||
intro h4
|
||||
apply h1
|
||||
apply le_trans h2 h4
|
||||
|
||||
end
|
|
@ -0,0 +1,141 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S05
|
||||
|
||||
section
|
||||
|
||||
variable {x y : ℝ}
|
||||
|
||||
namespace MyAbs
|
||||
|
||||
theorem le_abs_self (x : ℝ) : x ≤ |x| := by
|
||||
rcases le_or_gt 0 x with h | h
|
||||
· rw [abs_of_nonneg h]
|
||||
. rw [abs_of_neg h]
|
||||
linarith
|
||||
|
||||
theorem neg_le_abs_self (x : ℝ) : -x ≤ |x| := by
|
||||
rcases le_or_gt 0 x with h | h
|
||||
· rw [abs_of_nonneg h]
|
||||
linarith
|
||||
. rw [abs_of_neg h]
|
||||
|
||||
theorem abs_add (x y : ℝ) : |x + y| ≤ |x| + |y| := by
|
||||
rcases le_or_gt 0 (x + y) with h | h
|
||||
· rw [abs_of_nonneg h]
|
||||
linarith [le_abs_self x, le_abs_self y]
|
||||
. rw [abs_of_neg h]
|
||||
linarith [neg_le_abs_self x, neg_le_abs_self y]
|
||||
|
||||
theorem lt_abs : x < |y| ↔ x < y ∨ x < -y := by
|
||||
rcases le_or_gt 0 y with h | h
|
||||
· rw [abs_of_nonneg h]
|
||||
constructor
|
||||
· intro h'
|
||||
left
|
||||
exact h'
|
||||
. intro h'
|
||||
rcases h' with h' | h'
|
||||
· exact h'
|
||||
. linarith
|
||||
rw [abs_of_neg h]
|
||||
constructor
|
||||
· intro h'
|
||||
right
|
||||
exact h'
|
||||
. intro h'
|
||||
rcases h' with h' | h'
|
||||
· linarith
|
||||
. exact h'
|
||||
|
||||
theorem abs_lt : |x| < y ↔ -y < x ∧ x < y := by
|
||||
rcases le_or_gt 0 x with h | h
|
||||
· rw [abs_of_nonneg h]
|
||||
constructor
|
||||
· intro h'
|
||||
constructor
|
||||
· linarith
|
||||
exact h'
|
||||
. intro h'
|
||||
rcases h' with ⟨h1, h2⟩
|
||||
exact h2
|
||||
. rw [abs_of_neg h]
|
||||
constructor
|
||||
· intro h'
|
||||
constructor
|
||||
· linarith
|
||||
. linarith
|
||||
. intro h'
|
||||
linarith
|
||||
|
||||
end MyAbs
|
||||
|
||||
end
|
||||
|
||||
example {z : ℝ} (h : ∃ x y, z = x ^ 2 + y ^ 2 ∨ z = x ^ 2 + y ^ 2 + 1) : z ≥ 0 := by
|
||||
rcases h with ⟨x, y, rfl | rfl⟩ <;> linarith [sq_nonneg x, sq_nonneg y]
|
||||
|
||||
example {x : ℝ} (h : x ^ 2 = 1) : x = 1 ∨ x = -1 := by
|
||||
have h' : x ^ 2 - 1 = 0 := by rw [h, sub_self]
|
||||
have h'' : (x + 1) * (x - 1) = 0 := by
|
||||
rw [← h']
|
||||
ring
|
||||
rcases eq_zero_or_eq_zero_of_mul_eq_zero h'' with h1 | h1
|
||||
· right
|
||||
exact eq_neg_iff_add_eq_zero.mpr h1
|
||||
. left
|
||||
exact eq_of_sub_eq_zero h1
|
||||
|
||||
example {x y : ℝ} (h : x ^ 2 = y ^ 2) : x = y ∨ x = -y := by
|
||||
have h' : x ^ 2 - y ^ 2 = 0 := by rw [h, sub_self]
|
||||
have h'' : (x + y) * (x - y) = 0 := by
|
||||
rw [← h']
|
||||
ring
|
||||
rcases eq_zero_or_eq_zero_of_mul_eq_zero h'' with h1 | h1
|
||||
· right
|
||||
exact eq_neg_iff_add_eq_zero.mpr h1
|
||||
. left
|
||||
exact eq_of_sub_eq_zero h1
|
||||
|
||||
section
|
||||
variable {R : Type*} [CommRing R] [IsDomain R]
|
||||
variable (x y : R)
|
||||
|
||||
example (h : x ^ 2 = 1) : x = 1 ∨ x = -1 := by
|
||||
have h' : x ^ 2 - 1 = 0 := by rw [h, sub_self]
|
||||
have h'' : (x + 1) * (x - 1) = 0 := by
|
||||
rw [← h']
|
||||
ring
|
||||
rcases eq_zero_or_eq_zero_of_mul_eq_zero h'' with h1 | h1
|
||||
· right
|
||||
exact eq_neg_iff_add_eq_zero.mpr h1
|
||||
. left
|
||||
exact eq_of_sub_eq_zero h1
|
||||
|
||||
example (h : x ^ 2 = y ^ 2) : x = y ∨ x = -y := by
|
||||
have h' : x ^ 2 - y ^ 2 = 0 := by rw [h, sub_self]
|
||||
have h'' : (x + y) * (x - y) = 0 := by
|
||||
rw [← h']
|
||||
ring
|
||||
rcases eq_zero_or_eq_zero_of_mul_eq_zero h'' with h1 | h1
|
||||
· right
|
||||
exact eq_neg_iff_add_eq_zero.mpr h1
|
||||
. left
|
||||
exact eq_of_sub_eq_zero h1
|
||||
|
||||
end
|
||||
|
||||
example (P Q : Prop) : P → Q ↔ ¬P ∨ Q := by
|
||||
constructor
|
||||
· intro h
|
||||
by_cases h' : P
|
||||
· right
|
||||
exact h h'
|
||||
. left
|
||||
exact h'
|
||||
rintro (h | h)
|
||||
· intro h'
|
||||
exact absurd h' h
|
||||
. intro
|
||||
exact h
|
|
@ -0,0 +1,131 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C03S06
|
||||
|
||||
def ConvergesTo (s : ℕ → ℝ) (a : ℝ) :=
|
||||
∀ ε > 0, ∃ N, ∀ n ≥ N, |s n - a| < ε
|
||||
|
||||
theorem convergesTo_const (a : ℝ) : ConvergesTo (fun x : ℕ ↦ a) a := by
|
||||
intro ε εpos
|
||||
use 0
|
||||
intro n nge
|
||||
rw [sub_self, abs_zero]
|
||||
apply εpos
|
||||
|
||||
theorem convergesTo_add {s t : ℕ → ℝ} {a b : ℝ}
|
||||
(cs : ConvergesTo s a) (ct : ConvergesTo t b) :
|
||||
ConvergesTo (fun n ↦ s n + t n) (a + b) := by
|
||||
intro ε εpos
|
||||
dsimp
|
||||
have ε2pos : 0 < ε / 2 := by linarith
|
||||
rcases cs (ε / 2) ε2pos with ⟨Ns, hs⟩
|
||||
rcases ct (ε / 2) ε2pos with ⟨Nt, ht⟩
|
||||
use max Ns Nt
|
||||
intro n hn
|
||||
have ngeNs : n ≥ Ns := le_of_max_le_left hn
|
||||
have ngeNt : n ≥ Nt := le_of_max_le_right hn
|
||||
calc
|
||||
|s n + t n - (a + b)| = |s n - a + (t n - b)| := by
|
||||
congr
|
||||
ring
|
||||
_ ≤ |s n - a| + |t n - b| := (abs_add _ _)
|
||||
_ < ε / 2 + ε / 2 := (add_lt_add (hs n ngeNs) (ht n ngeNt))
|
||||
_ = ε := by norm_num
|
||||
|
||||
theorem convergesTo_mul_const {s : ℕ → ℝ} {a : ℝ} (c : ℝ) (cs : ConvergesTo s a) :
|
||||
ConvergesTo (fun n ↦ c * s n) (c * a) := by
|
||||
by_cases h : c = 0
|
||||
· convert convergesTo_const 0
|
||||
· rw [h]
|
||||
ring
|
||||
rw [h]
|
||||
ring
|
||||
have acpos : 0 < |c| := abs_pos.mpr h
|
||||
intro ε εpos
|
||||
dsimp
|
||||
have εcpos : 0 < ε / |c| := by apply div_pos εpos acpos
|
||||
rcases cs (ε / |c|) εcpos with ⟨Ns, hs⟩
|
||||
use Ns
|
||||
intro n ngt
|
||||
calc
|
||||
|c * s n - c * a| = |c| * |s n - a| := by rw [← abs_mul, mul_sub]
|
||||
_ < |c| * (ε / |c|) := (mul_lt_mul_of_pos_left (hs n ngt) acpos)
|
||||
_ = ε := mul_div_cancel' _ (ne_of_lt acpos).symm
|
||||
|
||||
theorem exists_abs_le_of_convergesTo {s : ℕ → ℝ} {a : ℝ} (cs : ConvergesTo s a) :
|
||||
∃ N b, ∀ n, N ≤ n → |s n| < b := by
|
||||
rcases cs 1 zero_lt_one with ⟨N, h⟩
|
||||
use N, |a| + 1
|
||||
intro n ngt
|
||||
calc
|
||||
|s n| = |s n - a + a| := by
|
||||
congr
|
||||
abel
|
||||
_ ≤ |s n - a| + |a| := (abs_add _ _)
|
||||
_ < |a| + 1 := by linarith [h n ngt]
|
||||
|
||||
theorem aux {s t : ℕ → ℝ} {a : ℝ} (cs : ConvergesTo s a) (ct : ConvergesTo t 0) :
|
||||
ConvergesTo (fun n ↦ s n * t n) 0 := by
|
||||
intro ε εpos
|
||||
dsimp
|
||||
rcases exists_abs_le_of_convergesTo cs with ⟨N₀, B, h₀⟩
|
||||
have Bpos : 0 < B := lt_of_le_of_lt (abs_nonneg _) (h₀ N₀ (le_refl _))
|
||||
have pos₀ : ε / B > 0 := div_pos εpos Bpos
|
||||
rcases ct _ pos₀ with ⟨N₁, h₁⟩
|
||||
use max N₀ N₁
|
||||
intro n ngt
|
||||
have ngeN₀ : n ≥ N₀ := le_of_max_le_left ngt
|
||||
have ngeN₁ : n ≥ N₁ := le_of_max_le_right ngt
|
||||
calc
|
||||
|s n * t n - 0| = |s n| * |t n - 0| := by rw [sub_zero, abs_mul, sub_zero]
|
||||
_ < B * (ε / B) := (mul_lt_mul'' (h₀ n ngeN₀) (h₁ n ngeN₁) (abs_nonneg _) (abs_nonneg _))
|
||||
_ = ε := mul_div_cancel' _ (ne_of_lt Bpos).symm
|
||||
|
||||
theorem convergesTo_mul {s t : ℕ → ℝ} {a b : ℝ}
|
||||
(cs : ConvergesTo s a) (ct : ConvergesTo t b) :
|
||||
ConvergesTo (fun n ↦ s n * t n) (a * b) := by
|
||||
have h₁ : ConvergesTo (fun n ↦ s n * (t n + -b)) 0 := by
|
||||
apply aux cs
|
||||
convert convergesTo_add ct (convergesTo_const (-b))
|
||||
ring
|
||||
have := convergesTo_add h₁ (convergesTo_mul_const b cs)
|
||||
convert convergesTo_add h₁ (convergesTo_mul_const b cs) using 1
|
||||
· ext; ring
|
||||
ring
|
||||
|
||||
theorem convergesTo_unique {s : ℕ → ℝ} {a b : ℝ}
|
||||
(sa : ConvergesTo s a) (sb : ConvergesTo s b) :
|
||||
a = b := by
|
||||
by_contra abne
|
||||
have : |a - b| > 0 := by
|
||||
apply lt_of_le_of_ne
|
||||
· apply abs_nonneg
|
||||
intro h''
|
||||
apply abne
|
||||
apply eq_of_abs_sub_eq_zero h''.symm
|
||||
let ε := |a - b| / 2
|
||||
have εpos : ε > 0 := by
|
||||
change |a - b| / 2 > 0
|
||||
linarith
|
||||
rcases sa ε εpos with ⟨Na, hNa⟩
|
||||
rcases sb ε εpos with ⟨Nb, hNb⟩
|
||||
let N := max Na Nb
|
||||
have absa : |s N - a| < ε := by
|
||||
apply hNa
|
||||
apply le_max_left
|
||||
have absb : |s N - b| < ε := by
|
||||
apply hNb
|
||||
apply le_max_right
|
||||
have : |a - b| < |a - b|
|
||||
calc
|
||||
|a - b| = |(-(s N - a)) + (s N - b)| := by
|
||||
congr
|
||||
ring
|
||||
_ ≤ |(-(s N - a))| + |s N - b| := (abs_add _ _)
|
||||
_ = |s N - a| + |s N - b| := by rw [abs_neg]
|
||||
_ < ε + ε := (add_lt_add absa absb)
|
||||
_ = |a - b| := by norm_num
|
||||
|
||||
exact lt_irrefl _ this
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
import Mathlib.Data.Set.Lattice
|
||||
import Mathlib.Data.Nat.Prime
|
||||
import Mathlib.Data.Nat.Parity
|
||||
import MIL.Common
|
||||
|
||||
section
|
||||
variable {α : Type*}
|
||||
variable (s t u : Set α)
|
||||
open Set
|
||||
|
||||
example (h : s ⊆ t) : s ∩ u ⊆ t ∩ u := by
|
||||
rw [subset_def, inter_def, inter_def]
|
||||
rw [subset_def] at h
|
||||
simp only [mem_setOf]
|
||||
rintro x ⟨xs, xu⟩
|
||||
exact ⟨h _ xs, xu⟩
|
||||
|
||||
example (h : s ⊆ t) : s ∩ u ⊆ t ∩ u := by
|
||||
simp only [subset_def, mem_inter_iff] at *
|
||||
rintro x ⟨xs, xu⟩
|
||||
exact ⟨h _ xs, xu⟩
|
||||
|
||||
example (h : s ⊆ t) : s ∩ u ⊆ t ∩ u := by
|
||||
intro x xsu
|
||||
exact ⟨h xsu.1, xsu.2⟩
|
||||
|
||||
theorem foo (h : s ⊆ t) : s ∩ u ⊆ t ∩ u :=
|
||||
fun x ⟨xs, xu⟩ ↦ ⟨h xs, xu⟩
|
||||
|
||||
example (h : s ⊆ t) : s ∩ u ⊆ t ∩ u :=
|
||||
fun x ⟨xs, xu⟩ ↦ ⟨h xs, xu⟩
|
||||
|
||||
example : s ∩ (t ∪ u) ⊆ s ∩ t ∪ s ∩ u := by
|
||||
intro x hx
|
||||
have xs : x ∈ s := hx.1
|
||||
have xtu : x ∈ t ∪ u := hx.2
|
||||
rcases xtu with xt | xu
|
||||
· left
|
||||
show x ∈ s ∩ t
|
||||
exact ⟨xs, xt⟩
|
||||
. right
|
||||
show x ∈ s ∩ u
|
||||
exact ⟨xs, xu⟩
|
||||
|
||||
example : s ∩ (t ∪ u) ⊆ s ∩ t ∪ s ∩ u := by
|
||||
rintro x ⟨xs, xt | xu⟩
|
||||
· left; exact ⟨xs, xt⟩
|
||||
. right; exact ⟨xs, xu⟩
|
||||
|
||||
example : s ∩ t ∪ s ∩ u ⊆ s ∩ (t ∪ u) := by
|
||||
sorry
|
||||
example : (s \ t) \ u ⊆ s \ (t ∪ u) := by
|
||||
intro x xstu
|
||||
have xs : x ∈ s := xstu.1.1
|
||||
have xnt : x ∉ t := xstu.1.2
|
||||
have xnu : x ∉ u := xstu.2
|
||||
constructor
|
||||
· exact xs
|
||||
intro xtu
|
||||
-- x ∈ t ∨ x ∈ u
|
||||
rcases xtu with xt | xu
|
||||
· show False; exact xnt xt
|
||||
. show False; exact xnu xu
|
||||
|
||||
example : (s \ t) \ u ⊆ s \ (t ∪ u) := by
|
||||
rintro x ⟨⟨xs, xnt⟩, xnu⟩
|
||||
use xs
|
||||
rintro (xt | xu) <;> contradiction
|
||||
|
||||
example : s \ (t ∪ u) ⊆ (s \ t) \ u := by
|
||||
sorry
|
||||
example : s ∩ t = t ∩ s := by
|
||||
ext x
|
||||
simp only [mem_inter_iff]
|
||||
constructor
|
||||
· rintro ⟨xs, xt⟩; exact ⟨xt, xs⟩
|
||||
. rintro ⟨xt, xs⟩; exact ⟨xs, xt⟩
|
||||
|
||||
example : s ∩ t = t ∩ s :=
|
||||
Set.ext fun x ↦ ⟨fun ⟨xs, xt⟩ ↦ ⟨xt, xs⟩, fun ⟨xt, xs⟩ ↦ ⟨xs, xt⟩⟩
|
||||
|
||||
example : s ∩ t = t ∩ s := by ext x; simp [and_comm]
|
||||
|
||||
example : s ∩ t = t ∩ s := by
|
||||
apply Subset.antisymm
|
||||
· rintro x ⟨xs, xt⟩; exact ⟨xt, xs⟩
|
||||
. rintro x ⟨xt, xs⟩; exact ⟨xs, xt⟩
|
||||
|
||||
example : s ∩ t = t ∩ s :=
|
||||
Subset.antisymm sorry sorry
|
||||
example : s ∩ (s ∪ t) = s := by
|
||||
sorry
|
||||
|
||||
example : s ∪ s ∩ t = s := by
|
||||
sorry
|
||||
|
||||
example : s \ t ∪ t = s ∪ t := by
|
||||
sorry
|
||||
|
||||
example : s \ t ∪ t \ s = (s ∪ t) \ (s ∩ t) := by
|
||||
sorry
|
||||
|
||||
def evens : Set ℕ :=
|
||||
{ n | Even n }
|
||||
|
||||
def odds : Set ℕ :=
|
||||
{ n | ¬Even n }
|
||||
|
||||
example : evens ∪ odds = univ := by
|
||||
rw [evens, odds]
|
||||
ext n
|
||||
simp
|
||||
apply Classical.em
|
||||
|
||||
example (x : ℕ) (h : x ∈ (∅ : Set ℕ)) : False :=
|
||||
h
|
||||
|
||||
example (x : ℕ) : x ∈ (univ : Set ℕ) :=
|
||||
trivial
|
||||
|
||||
example : { n | Nat.Prime n } ∩ { n | n > 2 } ⊆ { n | ¬Even n } := by
|
||||
sorry
|
||||
|
||||
#print Prime
|
||||
|
||||
#print Nat.Prime
|
||||
|
||||
example (n : ℕ) : Prime n ↔ Nat.Prime n :=
|
||||
Nat.prime_iff.symm
|
||||
|
||||
example (n : ℕ) (h : Prime n) : Nat.Prime n := by
|
||||
rw [Nat.prime_iff]
|
||||
exact h
|
||||
|
||||
example (n : ℕ) (h : Prime n) : Nat.Prime n := by
|
||||
rwa [Nat.prime_iff]
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
variable (s t : Set ℕ)
|
||||
|
||||
example (h₀ : ∀ x ∈ s, ¬Even x) (h₁ : ∀ x ∈ s, Prime x) : ∀ x ∈ s, ¬Even x ∧ Prime x := by
|
||||
intro x xs
|
||||
constructor
|
||||
· apply h₀ x xs
|
||||
apply h₁ x xs
|
||||
|
||||
example (h : ∃ x ∈ s, ¬Even x ∧ Prime x) : ∃ x ∈ s, Prime x := by
|
||||
rcases h with ⟨x, xs, _, prime_x⟩
|
||||
use x, xs
|
||||
|
||||
section
|
||||
variable (ssubt : s ⊆ t)
|
||||
|
||||
example (h₀ : ∀ x ∈ t, ¬Even x) (h₁ : ∀ x ∈ t, Prime x) : ∀ x ∈ s, ¬Even x ∧ Prime x := by
|
||||
sorry
|
||||
|
||||
example (h : ∃ x ∈ s, ¬Even x ∧ Prime x) : ∃ x ∈ t, Prime x := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α I : Type*}
|
||||
variable (A B : I → Set α)
|
||||
variable (s : Set α)
|
||||
|
||||
open Set
|
||||
|
||||
example : (s ∩ ⋃ i, A i) = ⋃ i, A i ∩ s := by
|
||||
ext x
|
||||
simp only [mem_inter_iff, mem_iUnion]
|
||||
constructor
|
||||
· rintro ⟨xs, ⟨i, xAi⟩⟩
|
||||
exact ⟨i, xAi, xs⟩
|
||||
rintro ⟨i, xAi, xs⟩
|
||||
exact ⟨xs, ⟨i, xAi⟩⟩
|
||||
|
||||
example : (⋂ i, A i ∩ B i) = (⋂ i, A i) ∩ ⋂ i, B i := by
|
||||
ext x
|
||||
simp only [mem_inter_iff, mem_iInter]
|
||||
constructor
|
||||
· intro h
|
||||
constructor
|
||||
· intro i
|
||||
exact (h i).1
|
||||
intro i
|
||||
exact (h i).2
|
||||
rintro ⟨h1, h2⟩ i
|
||||
constructor
|
||||
· exact h1 i
|
||||
exact h2 i
|
||||
|
||||
|
||||
example : (s ∪ ⋂ i, A i) = ⋂ i, A i ∪ s := by
|
||||
sorry
|
||||
|
||||
def primes : Set ℕ :=
|
||||
{ x | Nat.Prime x }
|
||||
|
||||
example : (⋃ p ∈ primes, { x | p ^ 2 ∣ x }) = { x | ∃ p ∈ primes, p ^ 2 ∣ x } :=by
|
||||
ext
|
||||
rw [mem_iUnion₂]
|
||||
simp
|
||||
|
||||
example : (⋃ p ∈ primes, { x | p ^ 2 ∣ x }) = { x | ∃ p ∈ primes, p ^ 2 ∣ x } := by
|
||||
ext
|
||||
simp
|
||||
|
||||
example : (⋂ p ∈ primes, { x | ¬p ∣ x }) ⊆ { x | x = 1 } := by
|
||||
intro x
|
||||
contrapose!
|
||||
simp
|
||||
apply Nat.exists_prime_and_dvd
|
||||
|
||||
example : (⋃ p ∈ primes, { x | x ≤ p }) = univ := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Set
|
||||
|
||||
variable {α : Type*} (s : Set (Set α))
|
||||
|
||||
example : ⋃₀ s = ⋃ t ∈ s, t := by
|
||||
ext x
|
||||
rw [mem_iUnion₂]
|
||||
simp
|
||||
|
||||
example : ⋂₀ s = ⋂ t ∈ s, t := by
|
||||
ext x
|
||||
rw [mem_iInter₂]
|
||||
rfl
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Set.Lattice
|
||||
import Mathlib.Data.Set.Function
|
||||
import Mathlib.Analysis.SpecialFunctions.Log.Basic
|
||||
|
||||
section
|
||||
|
||||
variable {α β : Type*}
|
||||
variable (f : α → β)
|
||||
variable (s t : Set α)
|
||||
variable (u v : Set β)
|
||||
|
||||
open Function
|
||||
open Set
|
||||
|
||||
example : f ⁻¹' (u ∩ v) = f ⁻¹' u ∩ f ⁻¹' v := by
|
||||
ext
|
||||
rfl
|
||||
|
||||
example : f '' (s ∪ t) = f '' s ∪ f '' t := by
|
||||
ext y; constructor
|
||||
· rintro ⟨x, xs | xt, rfl⟩
|
||||
· left
|
||||
use x, xs
|
||||
right
|
||||
use x, xt
|
||||
rintro (⟨x, xs, rfl⟩ | ⟨x, xt, rfl⟩)
|
||||
· use x, Or.inl xs
|
||||
use x, Or.inr xt
|
||||
|
||||
example : s ⊆ f ⁻¹' (f '' s) := by
|
||||
intro x xs
|
||||
show f x ∈ f '' s
|
||||
use x, xs
|
||||
|
||||
example : f '' s ⊆ v ↔ s ⊆ f ⁻¹' v := by
|
||||
sorry
|
||||
|
||||
example (h : Injective f) : f ⁻¹' (f '' s) ⊆ s := by
|
||||
sorry
|
||||
|
||||
example : f '' (f ⁻¹' u) ⊆ u := by
|
||||
sorry
|
||||
|
||||
example (h : Surjective f) : u ⊆ f '' (f ⁻¹' u) := by
|
||||
sorry
|
||||
|
||||
example (h : s ⊆ t) : f '' s ⊆ f '' t := by
|
||||
sorry
|
||||
|
||||
example (h : u ⊆ v) : f ⁻¹' u ⊆ f ⁻¹' v := by
|
||||
sorry
|
||||
|
||||
example : f ⁻¹' (u ∪ v) = f ⁻¹' u ∪ f ⁻¹' v := by
|
||||
sorry
|
||||
|
||||
example : f '' (s ∩ t) ⊆ f '' s ∩ f '' t := by
|
||||
sorry
|
||||
|
||||
example (h : Injective f) : f '' s ∩ f '' t ⊆ f '' (s ∩ t) := by
|
||||
sorry
|
||||
|
||||
example : f '' s \ f '' t ⊆ f '' (s \ t) := by
|
||||
sorry
|
||||
|
||||
example : f ⁻¹' u \ f ⁻¹' v ⊆ f ⁻¹' (u \ v) := by
|
||||
sorry
|
||||
|
||||
example : f '' s ∩ v = f '' (s ∩ f ⁻¹' v) := by
|
||||
sorry
|
||||
|
||||
example : f '' (s ∩ f ⁻¹' u) ⊆ f '' s ∩ u := by
|
||||
sorry
|
||||
|
||||
example : s ∩ f ⁻¹' u ⊆ f ⁻¹' (f '' s ∩ u) := by
|
||||
sorry
|
||||
|
||||
example : s ∪ f ⁻¹' u ⊆ f ⁻¹' (f '' s ∪ u) := by
|
||||
sorry
|
||||
|
||||
variable {I : Type*} (A : I → Set α) (B : I → Set β)
|
||||
|
||||
example : (f '' ⋃ i, A i) = ⋃ i, f '' A i := by
|
||||
ext y; simp
|
||||
constructor
|
||||
· rintro ⟨x, ⟨i, xAi⟩, fxeq⟩
|
||||
use i, x
|
||||
rintro ⟨i, x, xAi, fxeq⟩
|
||||
exact ⟨x, ⟨i, xAi⟩, fxeq⟩
|
||||
|
||||
example : (f '' ⋂ i, A i) ⊆ ⋂ i, f '' A i := by
|
||||
intro y; simp
|
||||
intro x h fxeq i
|
||||
use x
|
||||
exact ⟨h i, fxeq⟩
|
||||
|
||||
example (i : I) (injf : Injective f) : (⋂ i, f '' A i) ⊆ f '' ⋂ i, A i := by
|
||||
intro y; simp
|
||||
intro h
|
||||
rcases h i with ⟨x, xAi, fxeq⟩
|
||||
use x; constructor
|
||||
· intro i'
|
||||
rcases h i' with ⟨x', x'Ai, fx'eq⟩
|
||||
have : f x = f x' := by rw [fxeq, fx'eq]
|
||||
have : x = x' := injf this
|
||||
rw [this]
|
||||
exact x'Ai
|
||||
exact fxeq
|
||||
|
||||
example : (f ⁻¹' ⋃ i, B i) = ⋃ i, f ⁻¹' B i := by
|
||||
ext x
|
||||
simp
|
||||
|
||||
example : (f ⁻¹' ⋂ i, B i) = ⋂ i, f ⁻¹' B i := by
|
||||
ext x
|
||||
simp
|
||||
|
||||
example : InjOn f s ↔ ∀ x₁ ∈ s, ∀ x₂ ∈ s, f x₁ = f x₂ → x₁ = x₂ :=
|
||||
Iff.refl _
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Set Real
|
||||
|
||||
example : InjOn log { x | x > 0 } := by
|
||||
intro x xpos y ypos
|
||||
intro e
|
||||
-- log x = log y
|
||||
calc
|
||||
x = exp (log x) := by rw [exp_log xpos]
|
||||
_ = exp (log y) := by rw [e]
|
||||
_ = y := by rw [exp_log ypos]
|
||||
|
||||
|
||||
example : range exp = { y | y > 0 } := by
|
||||
ext y; constructor
|
||||
· rintro ⟨x, rfl⟩
|
||||
apply exp_pos
|
||||
intro ypos
|
||||
use log y
|
||||
rw [exp_log ypos]
|
||||
|
||||
example : InjOn sqrt { x | x ≥ 0 } := by
|
||||
sorry
|
||||
|
||||
example : InjOn (fun x ↦ x ^ 2) { x : ℝ | x ≥ 0 } := by
|
||||
sorry
|
||||
|
||||
example : sqrt '' { x | x ≥ 0 } = { y | y ≥ 0 } := by
|
||||
sorry
|
||||
|
||||
example : (range fun x ↦ x ^ 2) = { y : ℝ | y ≥ 0 } := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α β : Type*} [Inhabited α]
|
||||
|
||||
#check (default : α)
|
||||
|
||||
variable (P : α → Prop) (h : ∃ x, P x)
|
||||
|
||||
#check Classical.choose h
|
||||
|
||||
example : P (Classical.choose h) :=
|
||||
Classical.choose_spec h
|
||||
|
||||
noncomputable section
|
||||
|
||||
open Classical
|
||||
|
||||
def inverse (f : α → β) : β → α := fun y : β ↦
|
||||
if h : ∃ x, f x = y then Classical.choose h else default
|
||||
|
||||
theorem inverse_spec {f : α → β} (y : β) (h : ∃ x, f x = y) : f (inverse f y) = y := by
|
||||
rw [inverse, dif_pos h]
|
||||
exact Classical.choose_spec h
|
||||
|
||||
variable (f : α → β)
|
||||
|
||||
open Function
|
||||
|
||||
example : Injective f ↔ LeftInverse (inverse f) f :=
|
||||
sorry
|
||||
|
||||
example : Surjective f ↔ RightInverse (inverse f) f :=
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*}
|
||||
open Function
|
||||
|
||||
theorem Cantor : ∀ f : α → Set α, ¬Surjective f := by
|
||||
intro f surjf
|
||||
let S := { i | i ∉ f i }
|
||||
rcases surjf S with ⟨j, h⟩
|
||||
have h₁ : j ∉ f j := by
|
||||
intro h'
|
||||
have : j ∉ f j := by rwa [h] at h'
|
||||
contradiction
|
||||
have h₂ : j ∈ S
|
||||
sorry
|
||||
have h₃ : j ∉ S
|
||||
sorry
|
||||
contradiction
|
||||
|
||||
-- COMMENTS: TODO: improve this
|
||||
end
|
|
@ -0,0 +1,97 @@
|
|||
import Mathlib.Data.Set.Lattice
|
||||
import Mathlib.Data.Set.Function
|
||||
import MIL.Common
|
||||
|
||||
open Set
|
||||
open Function
|
||||
|
||||
noncomputable section
|
||||
open Classical
|
||||
variable {α β : Type*} [Nonempty β]
|
||||
|
||||
section
|
||||
variable (f : α → β) (g : β → α)
|
||||
|
||||
def sbAux : ℕ → Set α
|
||||
| 0 => univ \ g '' univ
|
||||
| n + 1 => g '' (f '' sbAux n)
|
||||
|
||||
def sbSet :=
|
||||
⋃ n, sbAux f g n
|
||||
|
||||
def sbFun (x : α) : β :=
|
||||
if x ∈ sbSet f g then f x else invFun g x
|
||||
|
||||
theorem sb_right_inv {x : α} (hx : x ∉ sbSet f g) : g (invFun g x) = x := by
|
||||
have : x ∈ g '' univ := by
|
||||
contrapose! hx
|
||||
rw [sbSet, mem_iUnion]
|
||||
use 0
|
||||
rw [sbAux, mem_diff]
|
||||
sorry
|
||||
have : ∃ y, g y = x := by
|
||||
sorry
|
||||
sorry
|
||||
|
||||
theorem sb_injective (hf : Injective f) (hg : Injective g) : Injective (sbFun f g) := by
|
||||
set A := sbSet f g with A_def
|
||||
set h := sbFun f g with h_def
|
||||
intro x₁ x₂
|
||||
intro (hxeq : h x₁ = h x₂)
|
||||
show x₁ = x₂
|
||||
simp only [h_def, sbFun, ← A_def] at hxeq
|
||||
by_cases xA : x₁ ∈ A ∨ x₂ ∈ A
|
||||
· wlog x₁A : x₁ ∈ A generalizing x₁ x₂ hxeq xA
|
||||
· symm
|
||||
apply this hxeq.symm xA.symm (xA.resolve_left x₁A)
|
||||
have x₂A : x₂ ∈ A := by
|
||||
apply not_imp_self.mp
|
||||
intro (x₂nA : x₂ ∉ A)
|
||||
rw [if_pos x₁A, if_neg x₂nA] at hxeq
|
||||
rw [A_def, sbSet, mem_iUnion] at x₁A
|
||||
have x₂eq : x₂ = g (f x₁) := by
|
||||
sorry
|
||||
rcases x₁A with ⟨n, hn⟩
|
||||
rw [A_def, sbSet, mem_iUnion]
|
||||
use n + 1
|
||||
simp [sbAux]
|
||||
exact ⟨x₁, hn, x₂eq.symm⟩
|
||||
sorry
|
||||
push_neg at xA
|
||||
sorry
|
||||
|
||||
theorem sb_surjective (hf : Injective f) (hg : Injective g) : Surjective (sbFun f g) := by
|
||||
set A := sbSet f g with A_def
|
||||
set h := sbFun f g with h_def
|
||||
intro y
|
||||
by_cases gyA : g y ∈ A
|
||||
· rw [A_def, sbSet, mem_iUnion] at gyA
|
||||
rcases gyA with ⟨n, hn⟩
|
||||
rcases n with _ | n
|
||||
· simp [sbAux] at hn
|
||||
simp [sbAux] at hn
|
||||
rcases hn with ⟨x, xmem, hx⟩
|
||||
use x
|
||||
have : x ∈ A := by
|
||||
rw [A_def, sbSet, mem_iUnion]
|
||||
exact ⟨n, xmem⟩
|
||||
simp only [h_def, sbFun, if_pos this]
|
||||
exact hg hx
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Injective f) (hg : Injective g) :
|
||||
∃ h : α → β, Bijective h :=
|
||||
⟨sbFun f g, sb_injective f g hf hg, sb_surjective f g hf hg⟩
|
||||
|
||||
-- Auxiliary information
|
||||
section
|
||||
variable (g : β → α) (x : α)
|
||||
|
||||
#check (invFun g : α → β)
|
||||
#check (leftInverse_invFun : Injective g → LeftInverse (invFun g) g)
|
||||
#check (leftInverse_invFun : Injective g → ∀ y, invFun g (g y) = y)
|
||||
#check (invFun_eq : (∃ y, g y = x) → g (invFun g x) = x)
|
||||
|
||||
end
|
|
@ -0,0 +1,153 @@
|
|||
import Mathlib.Data.Set.Lattice
|
||||
import Mathlib.Data.Nat.Prime
|
||||
import Mathlib.Data.Nat.Parity
|
||||
import MIL.Common
|
||||
|
||||
section
|
||||
variable {α : Type*}
|
||||
variable (s t u : Set α)
|
||||
open Set
|
||||
|
||||
example : s ∩ t ∪ s ∩ u ⊆ s ∩ (t ∪ u) := by
|
||||
rintro x (⟨xs, xt⟩ | ⟨xs, xu⟩)
|
||||
· use xs; left; exact xt
|
||||
. use xs; right; exact xu
|
||||
|
||||
example : s \ (t ∪ u) ⊆ (s \ t) \ u := by
|
||||
rintro x ⟨xs, xntu⟩
|
||||
constructor
|
||||
use xs
|
||||
· intro xt
|
||||
exact xntu (Or.inl xt)
|
||||
intro xu
|
||||
apply xntu (Or.inr xu)
|
||||
|
||||
example : s ∩ t = t ∩ s :=
|
||||
Subset.antisymm
|
||||
(fun x ⟨xs, xt⟩ ↦ ⟨xt, xs⟩) fun x ⟨xt, xs⟩ ↦ ⟨xs, xt⟩
|
||||
|
||||
example : s ∩ (s ∪ t) = s := by
|
||||
ext x; constructor
|
||||
· rintro ⟨xs, _⟩
|
||||
exact xs
|
||||
. intro xs
|
||||
use xs; left; exact xs
|
||||
|
||||
example : s ∪ s ∩ t = s := by
|
||||
ext x; constructor
|
||||
· rintro (xs | ⟨xs, xt⟩) <;> exact xs
|
||||
. intro xs; left; exact xs
|
||||
|
||||
example : s \ t ∪ t = s ∪ t := by
|
||||
ext x; constructor
|
||||
· rintro (⟨xs, nxt⟩ | xt)
|
||||
· left
|
||||
exact xs
|
||||
. right
|
||||
exact xt
|
||||
by_cases h : x ∈ t
|
||||
· intro
|
||||
right
|
||||
exact h
|
||||
rintro (xs | xt)
|
||||
· left
|
||||
use xs
|
||||
right; exact xt
|
||||
|
||||
example : s \ t ∪ t \ s = (s ∪ t) \ (s ∩ t) := by
|
||||
ext x; constructor
|
||||
· rintro (⟨xs, xnt⟩ | ⟨xt, xns⟩)
|
||||
· constructor
|
||||
left
|
||||
exact xs
|
||||
rintro ⟨_, xt⟩
|
||||
contradiction
|
||||
. constructor
|
||||
right
|
||||
exact xt
|
||||
rintro ⟨xs, _⟩
|
||||
contradiction
|
||||
rintro ⟨xs | xt, nxst⟩
|
||||
· left
|
||||
use xs
|
||||
intro xt
|
||||
apply nxst
|
||||
constructor <;> assumption
|
||||
. right; use xt; intro xs
|
||||
apply nxst
|
||||
constructor <;> assumption
|
||||
|
||||
example : { n | Nat.Prime n } ∩ { n | n > 2 } ⊆ { n | ¬Even n } := by
|
||||
intro n
|
||||
simp
|
||||
intro nprime
|
||||
rcases Nat.Prime.eq_two_or_odd nprime with h | h
|
||||
· rw [h]
|
||||
intro
|
||||
linarith
|
||||
rw [Nat.even_iff, h]
|
||||
norm_num
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
variable (s t : Set ℕ)
|
||||
|
||||
section
|
||||
variable (ssubt : s ⊆ t)
|
||||
|
||||
example (h₀ : ∀ x ∈ t, ¬Even x) (h₁ : ∀ x ∈ t, Prime x) : ∀ x ∈ s, ¬Even x ∧ Prime x := by
|
||||
intro x xs
|
||||
constructor
|
||||
· apply h₀ x (ssubt xs)
|
||||
apply h₁ x (ssubt xs)
|
||||
|
||||
example (h : ∃ x ∈ s, ¬Even x ∧ Prime x) : ∃ x ∈ t, Prime x := by
|
||||
rcases h with ⟨x, xs, _, px⟩
|
||||
use x, ssubt xs
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α I : Type*}
|
||||
variable (A B : I → Set α)
|
||||
variable (s : Set α)
|
||||
|
||||
open Set
|
||||
|
||||
example : (s ∪ ⋂ i, A i) = ⋂ i, A i ∪ s := by
|
||||
ext x
|
||||
simp only [mem_union, mem_iInter]
|
||||
constructor
|
||||
· rintro (xs | xI)
|
||||
· intro i
|
||||
right
|
||||
exact xs
|
||||
intro i
|
||||
left
|
||||
exact xI i
|
||||
intro h
|
||||
by_cases xs : x ∈ s
|
||||
· left
|
||||
exact xs
|
||||
right
|
||||
intro i
|
||||
cases h i
|
||||
· assumption
|
||||
contradiction
|
||||
|
||||
def primes : Set ℕ :=
|
||||
{ x | Nat.Prime x }
|
||||
|
||||
example : (⋃ p ∈ primes, { x | x ≤ p }) = univ := by
|
||||
apply eq_univ_of_forall
|
||||
intro x
|
||||
simp
|
||||
rcases Nat.exists_infinite_primes x with ⟨p, primep, pge⟩
|
||||
use p, pge
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Set.Lattice
|
||||
import Mathlib.Data.Set.Function
|
||||
import Mathlib.Analysis.SpecialFunctions.Log.Basic
|
||||
|
||||
section
|
||||
|
||||
variable {α β : Type*}
|
||||
variable (f : α → β)
|
||||
variable (s t : Set α)
|
||||
variable (u v : Set β)
|
||||
|
||||
open Function
|
||||
open Set
|
||||
|
||||
example : f '' s ⊆ v ↔ s ⊆ f ⁻¹' v := by
|
||||
constructor
|
||||
· intro h x xs
|
||||
have : f x ∈ f '' s := mem_image_of_mem _ xs
|
||||
exact h this
|
||||
intro h y ymem
|
||||
rcases ymem with ⟨x, xs, fxeq⟩
|
||||
rw [← fxeq]
|
||||
apply h xs
|
||||
|
||||
example (h : Injective f) : f ⁻¹' (f '' s) ⊆ s := by
|
||||
rintro x ⟨y, ys, fxeq⟩
|
||||
rw [← h fxeq]
|
||||
exact ys
|
||||
|
||||
example : f '' (f ⁻¹' u) ⊆ u := by
|
||||
rintro y ⟨x, xmem, rfl⟩
|
||||
exact xmem
|
||||
|
||||
example (h : Surjective f) : u ⊆ f '' (f ⁻¹' u) := by
|
||||
intro y yu
|
||||
rcases h y with ⟨x, fxeq⟩
|
||||
use x
|
||||
constructor
|
||||
· show f x ∈ u
|
||||
rw [fxeq]
|
||||
exact yu
|
||||
exact fxeq
|
||||
|
||||
example (h : s ⊆ t) : f '' s ⊆ f '' t := by
|
||||
rintro y ⟨x, xs, fxeq⟩
|
||||
use x, h xs
|
||||
|
||||
example (h : u ⊆ v) : f ⁻¹' u ⊆ f ⁻¹' v := by
|
||||
intro x; apply h
|
||||
|
||||
example : f ⁻¹' (u ∪ v) = f ⁻¹' u ∪ f ⁻¹' v := by
|
||||
ext x; rfl
|
||||
|
||||
example : f '' (s ∩ t) ⊆ f '' s ∩ f '' t := by
|
||||
rintro y ⟨x, ⟨xs, xt⟩, rfl⟩
|
||||
constructor
|
||||
. use x, xs
|
||||
. use x, xt
|
||||
|
||||
example (h : Injective f) : f '' s ∩ f '' t ⊆ f '' (s ∩ t) := by
|
||||
rintro y ⟨⟨x₁, x₁s, rfl⟩, ⟨x₂, x₂t, fx₂eq⟩⟩
|
||||
use x₁
|
||||
constructor
|
||||
. use x₁s
|
||||
rw [← h fx₂eq]
|
||||
exact x₂t
|
||||
. rfl
|
||||
|
||||
example : f '' s \ f '' t ⊆ f '' (s \ t) := by
|
||||
rintro y ⟨⟨x₁, x₁s, rfl⟩, h⟩
|
||||
use x₁
|
||||
constructor
|
||||
. constructor
|
||||
. exact x₁s
|
||||
. intro h'
|
||||
apply h
|
||||
use x₁, h'
|
||||
. rfl
|
||||
|
||||
example : f ⁻¹' u \ f ⁻¹' v ⊆ f ⁻¹' (u \ v) :=
|
||||
fun x ↦ id
|
||||
|
||||
example : f '' s ∩ v = f '' (s ∩ f ⁻¹' v) := by
|
||||
ext y; constructor
|
||||
· rintro ⟨⟨x, xs, rfl⟩, fxv⟩
|
||||
use x, ⟨xs, fxv⟩
|
||||
rintro ⟨x, ⟨⟨xs, fxv⟩, rfl⟩⟩
|
||||
exact ⟨⟨x, xs, rfl⟩, fxv⟩
|
||||
|
||||
example : f '' (s ∩ f ⁻¹' u) ⊆ f '' s ∩ u := by
|
||||
rintro y ⟨x, ⟨xs, fxu⟩, rfl⟩
|
||||
exact ⟨⟨x, xs, rfl⟩, fxu⟩
|
||||
|
||||
example : s ∩ f ⁻¹' u ⊆ f ⁻¹' (f '' s ∩ u) := by
|
||||
rintro x ⟨xs, fxu⟩
|
||||
exact ⟨⟨x, xs, rfl⟩, fxu⟩
|
||||
|
||||
example : s ∪ f ⁻¹' u ⊆ f ⁻¹' (f '' s ∪ u) := by
|
||||
rintro x (xs | fxu)
|
||||
· left
|
||||
exact ⟨x, xs, rfl⟩
|
||||
right; exact fxu
|
||||
|
||||
variable {I : Type*} (A : I → Set α) (B : I → Set β)
|
||||
|
||||
example : (f '' ⋃ i, A i) = ⋃ i, f '' A i := by
|
||||
ext y; simp
|
||||
constructor
|
||||
· rintro ⟨x, ⟨i, xAi⟩, fxeq⟩
|
||||
use i, x
|
||||
rintro ⟨i, x, xAi, fxeq⟩
|
||||
exact ⟨x, ⟨i, xAi⟩, fxeq⟩
|
||||
|
||||
example : (f '' ⋂ i, A i) ⊆ ⋂ i, f '' A i := by
|
||||
intro y; simp
|
||||
intro x h fxeq i
|
||||
use x
|
||||
exact ⟨h i, fxeq⟩
|
||||
|
||||
example (i : I) (injf : Injective f) : (⋂ i, f '' A i) ⊆ f '' ⋂ i, A i := by
|
||||
intro y; simp
|
||||
intro h
|
||||
rcases h i with ⟨x, xAi, fxeq⟩
|
||||
use x; constructor
|
||||
· intro i'
|
||||
rcases h i' with ⟨x', x'Ai, fx'eq⟩
|
||||
have : f x = f x' := by rw [fxeq, fx'eq]
|
||||
have : x = x' := injf this
|
||||
rw [this]
|
||||
exact x'Ai
|
||||
exact fxeq
|
||||
|
||||
example : (f ⁻¹' ⋃ i, B i) = ⋃ i, f ⁻¹' B i := by
|
||||
ext x
|
||||
simp
|
||||
|
||||
example : (f ⁻¹' ⋂ i, B i) = ⋂ i, f ⁻¹' B i := by
|
||||
ext x
|
||||
simp
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
open Set Real
|
||||
|
||||
example : InjOn sqrt { x | x ≥ 0 } := by
|
||||
intro x xnonneg y ynonneg
|
||||
intro e
|
||||
calc
|
||||
x = sqrt x ^ 2 := by rw [sq_sqrt xnonneg]
|
||||
_ = sqrt y ^ 2 := by rw [e]
|
||||
_ = y := by rw [sq_sqrt ynonneg]
|
||||
|
||||
|
||||
example : InjOn (fun x ↦ x ^ 2) { x : ℝ | x ≥ 0 } := by
|
||||
intro x xnonneg y ynonneg
|
||||
intro e
|
||||
dsimp at *
|
||||
calc
|
||||
x = sqrt (x ^ 2) := by rw [sqrt_sq xnonneg]
|
||||
_ = sqrt (y ^ 2) := by rw [e]
|
||||
_ = y := by rw [sqrt_sq ynonneg]
|
||||
|
||||
|
||||
example : sqrt '' { x | x ≥ 0 } = { y | y ≥ 0 } := by
|
||||
ext y; constructor
|
||||
· rintro ⟨x, ⟨xnonneg, rfl⟩⟩
|
||||
apply sqrt_nonneg
|
||||
intro ynonneg
|
||||
use y ^ 2
|
||||
dsimp at *
|
||||
constructor
|
||||
apply pow_nonneg ynonneg
|
||||
apply sqrt_sq
|
||||
assumption
|
||||
|
||||
example : (range fun x ↦ x ^ 2) = { y : ℝ | y ≥ 0 } := by
|
||||
ext y
|
||||
constructor
|
||||
· rintro ⟨x, rfl⟩
|
||||
dsimp at *
|
||||
apply pow_two_nonneg
|
||||
intro ynonneg
|
||||
use sqrt y
|
||||
exact sq_sqrt ynonneg
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α β : Type*} [Inhabited α]
|
||||
|
||||
noncomputable section
|
||||
|
||||
open Classical
|
||||
|
||||
def inverse (f : α → β) : β → α := fun y : β ↦
|
||||
if h : ∃ x, f x = y then Classical.choose h else default
|
||||
|
||||
theorem inverse_spec {f : α → β} (y : β) (h : ∃ x, f x = y) : f (inverse f y) = y := by
|
||||
rw [inverse, dif_pos h]
|
||||
exact Classical.choose_spec h
|
||||
|
||||
variable (f : α → β)
|
||||
|
||||
open Function
|
||||
|
||||
example : Injective f ↔ LeftInverse (inverse f) f := by
|
||||
constructor
|
||||
· intro h y
|
||||
apply h
|
||||
apply inverse_spec
|
||||
use y
|
||||
intro h x1 x2 e
|
||||
rw [← h x1, ← h x2, e]
|
||||
|
||||
example : Injective f ↔ LeftInverse (inverse f) f :=
|
||||
⟨fun h y ↦ h (inverse_spec _ ⟨y, rfl⟩), fun h x1 x2 e ↦ by rw [← h x1, ← h x2, e]⟩
|
||||
|
||||
example : Surjective f ↔ RightInverse (inverse f) f := by
|
||||
constructor
|
||||
· intro h y
|
||||
apply inverse_spec
|
||||
apply h
|
||||
intro h y
|
||||
use inverse f y
|
||||
apply h
|
||||
|
||||
example : Surjective f ↔ RightInverse (inverse f) f :=
|
||||
⟨fun h y ↦ inverse_spec _ (h _), fun h y ↦ ⟨inverse f y, h _⟩⟩
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*}
|
||||
open Function
|
||||
|
||||
theorem Cantor : ∀ f : α → Set α, ¬Surjective f := by
|
||||
intro f surjf
|
||||
let S := { i | i ∉ f i }
|
||||
rcases surjf S with ⟨j, h⟩
|
||||
have h₁ : j ∉ f j := by
|
||||
intro h'
|
||||
have : j ∉ f j := by rwa [h] at h'
|
||||
contradiction
|
||||
have h₂ : j ∈ S := h₁
|
||||
have h₃ : j ∉ S := by rwa [h] at h₁
|
||||
contradiction
|
||||
|
||||
end
|
|
@ -0,0 +1,88 @@
|
|||
import Mathlib.Data.Set.Lattice
|
||||
import Mathlib.Data.Set.Function
|
||||
import MIL.Common
|
||||
|
||||
open Set
|
||||
open Function
|
||||
|
||||
noncomputable section
|
||||
open Classical
|
||||
variable {α β : Type*} [Nonempty β]
|
||||
|
||||
section
|
||||
variable (f : α → β) (g : β → α)
|
||||
|
||||
def sbAux : ℕ → Set α
|
||||
| 0 => univ \ g '' univ
|
||||
| n + 1 => g '' (f '' sbAux n)
|
||||
|
||||
def sbSet :=
|
||||
⋃ n, sbAux f g n
|
||||
|
||||
def sbFun (x : α) : β :=
|
||||
if x ∈ sbSet f g then f x else invFun g x
|
||||
|
||||
theorem sb_right_inv {x : α} (hx : x ∉ sbSet f g) : g (invFun g x) = x := by
|
||||
have : x ∈ g '' univ := by
|
||||
contrapose! hx
|
||||
rw [sbSet, mem_iUnion]
|
||||
use 0
|
||||
rw [sbAux, mem_diff]
|
||||
exact ⟨mem_univ _, hx⟩
|
||||
have : ∃ y, g y = x := by
|
||||
simp at this
|
||||
assumption
|
||||
exact invFun_eq this
|
||||
|
||||
theorem sb_injective (hf : Injective f) (hg : Injective g) : Injective (sbFun f g) := by
|
||||
set A := sbSet f g with A_def
|
||||
set h := sbFun f g with h_def
|
||||
intro x₁ x₂
|
||||
intro (hxeq : h x₁ = h x₂)
|
||||
show x₁ = x₂
|
||||
simp only [h_def, sbFun, ← A_def] at hxeq
|
||||
by_cases xA : x₁ ∈ A ∨ x₂ ∈ A
|
||||
· wlog x₁A : x₁ ∈ A generalizing x₁ x₂ hxeq xA
|
||||
· symm
|
||||
apply this hxeq.symm xA.symm (xA.resolve_left x₁A)
|
||||
have x₂A : x₂ ∈ A := by
|
||||
apply not_imp_self.mp
|
||||
intro (x₂nA : x₂ ∉ A)
|
||||
rw [if_pos x₁A, if_neg x₂nA] at hxeq
|
||||
rw [A_def, sbSet, mem_iUnion] at x₁A
|
||||
have x₂eq : x₂ = g (f x₁) := by
|
||||
rw [hxeq, sb_right_inv f g x₂nA]
|
||||
rcases x₁A with ⟨n, hn⟩
|
||||
rw [A_def, sbSet, mem_iUnion]
|
||||
use n + 1
|
||||
simp [sbAux]
|
||||
exact ⟨x₁, hn, x₂eq.symm⟩
|
||||
rw [if_pos x₁A, if_pos x₂A] at hxeq
|
||||
exact hf hxeq
|
||||
push_neg at xA
|
||||
rw [if_neg xA.1, if_neg xA.2] at hxeq
|
||||
rw [← sb_right_inv f g xA.1, hxeq, sb_right_inv f g xA.2]
|
||||
|
||||
theorem sb_surjective (hf : Injective f) (hg : Injective g) : Surjective (sbFun f g) := by
|
||||
set A := sbSet f g with A_def
|
||||
set h := sbFun f g with h_def
|
||||
intro y
|
||||
by_cases gyA : g y ∈ A
|
||||
· rw [A_def, sbSet, mem_iUnion] at gyA
|
||||
rcases gyA with ⟨n, hn⟩
|
||||
rcases n with _ | n
|
||||
· simp [sbAux] at hn
|
||||
simp [sbAux] at hn
|
||||
rcases hn with ⟨x, xmem, hx⟩
|
||||
use x
|
||||
have : x ∈ A := by
|
||||
rw [A_def, sbSet, mem_iUnion]
|
||||
exact ⟨n, xmem⟩
|
||||
simp only [h_def, sbFun, if_pos this]
|
||||
exact hg hx
|
||||
use g y
|
||||
simp only [h_def, sbFun, if_neg gyA]
|
||||
apply leftInverse_invFun hg
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Nat.Factorization.Basic
|
||||
import Mathlib.Data.Nat.Prime
|
||||
|
||||
#print Nat.Coprime
|
||||
|
||||
example (m n : Nat) (h : m.Coprime n) : m.gcd n = 1 :=
|
||||
h
|
||||
|
||||
example (m n : Nat) (h : m.Coprime n) : m.gcd n = 1 := by
|
||||
rw [Nat.Coprime] at h
|
||||
exact h
|
||||
|
||||
example : Nat.Coprime 12 7 := by norm_num
|
||||
|
||||
example : Nat.gcd 12 8 = 4 := by norm_num
|
||||
|
||||
#check Nat.prime_def_lt
|
||||
|
||||
example (p : ℕ) (prime_p : Nat.Prime p) : 2 ≤ p ∧ ∀ m : ℕ, m < p → m ∣ p → m = 1 := by
|
||||
rwa [Nat.prime_def_lt] at prime_p
|
||||
|
||||
#check Nat.Prime.eq_one_or_self_of_dvd
|
||||
|
||||
example (p : ℕ) (prime_p : Nat.Prime p) : ∀ m : ℕ, m ∣ p → m = 1 ∨ m = p :=
|
||||
prime_p.eq_one_or_self_of_dvd
|
||||
|
||||
example : Nat.Prime 17 := by norm_num
|
||||
|
||||
-- commonly used
|
||||
example : Nat.Prime 2 :=
|
||||
Nat.prime_two
|
||||
|
||||
example : Nat.Prime 3 :=
|
||||
Nat.prime_three
|
||||
|
||||
#check Nat.Prime.dvd_mul
|
||||
#check Nat.Prime.dvd_mul Nat.prime_two
|
||||
#check Nat.prime_two.dvd_mul
|
||||
|
||||
theorem even_of_even_sqr {m : ℕ} (h : 2 ∣ m ^ 2) : 2 ∣ m := by
|
||||
rw [pow_two, Nat.prime_two.dvd_mul] at h
|
||||
cases h <;> assumption
|
||||
|
||||
example {m : ℕ} (h : 2 ∣ m ^ 2) : 2 ∣ m :=
|
||||
Nat.Prime.dvd_of_dvd_pow Nat.prime_two h
|
||||
|
||||
example (a b c : Nat) (h : a * b = a * c) (h' : a ≠ 0) : b = c :=
|
||||
-- apply? suggests the following:
|
||||
(mul_right_inj' h').mp h
|
||||
|
||||
example {m n : ℕ} (coprime_mn : m.Coprime n) : m ^ 2 ≠ 2 * n ^ 2 := by
|
||||
intro sqr_eq
|
||||
have : 2 ∣ m := by
|
||||
sorry
|
||||
obtain ⟨k, meq⟩ := dvd_iff_exists_eq_mul_left.mp this
|
||||
have : 2 * (2 * k ^ 2) = 2 * n ^ 2 := by
|
||||
rw [← sqr_eq, meq]
|
||||
ring
|
||||
have : 2 * k ^ 2 = n ^ 2 :=
|
||||
sorry
|
||||
have : 2 ∣ n := by
|
||||
sorry
|
||||
have : 2 ∣ m.gcd n := by
|
||||
sorry
|
||||
have : 2 ∣ 1 := by
|
||||
sorry
|
||||
norm_num at this
|
||||
|
||||
example {m n p : ℕ} (coprime_mn : m.Coprime n) (prime_p : p.Prime) : m ^ 2 ≠ p * n ^ 2 := by
|
||||
sorry
|
||||
#check Nat.factors
|
||||
#check Nat.prime_of_mem_factors
|
||||
#check Nat.prod_factors
|
||||
#check Nat.factors_unique
|
||||
|
||||
theorem factorization_mul' {m n : ℕ} (mnez : m ≠ 0) (nnez : n ≠ 0) (p : ℕ) :
|
||||
(m * n).factorization p = m.factorization p + n.factorization p := by
|
||||
rw [Nat.factorization_mul mnez nnez]
|
||||
rfl
|
||||
|
||||
theorem factorization_pow' (n k p : ℕ) :
|
||||
(n ^ k).factorization p = k * n.factorization p := by
|
||||
rw [Nat.factorization_pow]
|
||||
rfl
|
||||
|
||||
theorem Nat.Prime.factorization' {p : ℕ} (prime_p : p.Prime) :
|
||||
p.factorization p = 1 := by
|
||||
rw [prime_p.factorization]
|
||||
simp
|
||||
|
||||
example {m n p : ℕ} (nnz : n ≠ 0) (prime_p : p.Prime) : m ^ 2 ≠ p * n ^ 2 := by
|
||||
intro sqr_eq
|
||||
have nsqr_nez : n ^ 2 ≠ 0 := by simpa
|
||||
have eq1 : Nat.factorization (m ^ 2) p = 2 * m.factorization p := by
|
||||
sorry
|
||||
have eq2 : (p * n ^ 2).factorization p = 2 * n.factorization p + 1 := by
|
||||
sorry
|
||||
have : 2 * m.factorization p % 2 = (2 * n.factorization p + 1) % 2 := by
|
||||
rw [← eq1, sqr_eq, eq2]
|
||||
rw [add_comm, Nat.add_mul_mod_self_left, Nat.mul_mod_right] at this
|
||||
norm_num at this
|
||||
|
||||
example {m n k r : ℕ} (nnz : n ≠ 0) (pow_eq : m ^ k = r * n ^ k) {p : ℕ} (prime_p : p.Prime) :
|
||||
k ∣ r.factorization p := by
|
||||
rcases r with _ | r
|
||||
· simp
|
||||
have npow_nz : n ^ k ≠ 0 := fun npowz ↦ nnz (pow_eq_zero npowz)
|
||||
have eq1 : (m ^ k).factorization p = k * m.factorization p := by
|
||||
sorry
|
||||
have eq2 : (r.succ * n ^ k).factorization p =
|
||||
k * n.factorization p + r.succ.factorization p := by
|
||||
sorry
|
||||
have : r.succ.factorization p = k * m.factorization p - k * n.factorization p := by
|
||||
rw [← eq1, pow_eq, eq2, add_comm, Nat.add_sub_cancel]
|
||||
rw [this]
|
||||
sorry
|
||||
|
||||
#check multiplicity
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
import Mathlib.Data.Nat.GCD.Basic
|
||||
import Mathlib.Algebra.BigOperators.Basic
|
||||
import MIL.Common
|
||||
|
||||
example (n : Nat) : n.succ ≠ Nat.zero :=
|
||||
Nat.succ_ne_zero n
|
||||
|
||||
example (m n : Nat) (h : m.succ = n.succ) : m = n :=
|
||||
Nat.succ.inj h
|
||||
|
||||
def fac : ℕ → ℕ
|
||||
| 0 => 1
|
||||
| n + 1 => (n + 1) * fac n
|
||||
|
||||
example : fac 0 = 1 :=
|
||||
rfl
|
||||
|
||||
example : fac 0 = 1 := by
|
||||
rw [fac]
|
||||
|
||||
example : fac 0 = 1 := by
|
||||
simp [fac]
|
||||
|
||||
example (n : ℕ) : fac (n + 1) = (n + 1) * fac n :=
|
||||
rfl
|
||||
|
||||
example (n : ℕ) : fac (n + 1) = (n + 1) * fac n := by
|
||||
rw [fac]
|
||||
|
||||
example (n : ℕ) : fac (n + 1) = (n + 1) * fac n := by
|
||||
simp [fac]
|
||||
|
||||
theorem fac_pos (n : ℕ) : 0 < fac n := by
|
||||
induction' n with n ih
|
||||
· rw [fac]
|
||||
exact zero_lt_one
|
||||
rw [fac]
|
||||
exact mul_pos n.succ_pos ih
|
||||
|
||||
theorem dvd_fac {i n : ℕ} (ipos : 0 < i) (ile : i ≤ n) : i ∣ fac n := by
|
||||
induction' n with n ih
|
||||
· exact absurd ipos (not_lt_of_ge ile)
|
||||
rw [fac]
|
||||
rcases Nat.of_le_succ ile with h | h
|
||||
· apply dvd_mul_of_dvd_right (ih h)
|
||||
rw [h]
|
||||
apply dvd_mul_right
|
||||
|
||||
theorem pow_two_le_fac (n : ℕ) : 2 ^ (n - 1) ≤ fac n := by
|
||||
rcases n with _ | n
|
||||
· simp [fac]
|
||||
sorry
|
||||
section
|
||||
|
||||
variable {α : Type*} (s : Finset ℕ) (f : ℕ → ℕ) (n : ℕ)
|
||||
|
||||
#check Finset.sum s f
|
||||
#check Finset.prod s f
|
||||
|
||||
open BigOperators
|
||||
open Finset
|
||||
|
||||
example : s.sum f = ∑ x in s, f x :=
|
||||
rfl
|
||||
|
||||
example : s.prod f = ∏ x in s, f x :=
|
||||
rfl
|
||||
|
||||
example : (range n).sum f = ∑ x in range n, f x :=
|
||||
rfl
|
||||
|
||||
example : (range n).prod f = ∏ x in range n, f x :=
|
||||
rfl
|
||||
|
||||
example (f : ℕ → ℕ) : ∑ x in range 0, f x = 0 :=
|
||||
Finset.sum_range_zero f
|
||||
|
||||
example (f : ℕ → ℕ) (n : ℕ) : ∑ x in range n.succ, f x = ∑ x in range n, f x + f n :=
|
||||
Finset.sum_range_succ f n
|
||||
|
||||
example (f : ℕ → ℕ) : ∏ x in range 0, f x = 1 :=
|
||||
Finset.prod_range_zero f
|
||||
|
||||
example (f : ℕ → ℕ) (n : ℕ) : ∏ x in range n.succ, f x = (∏ x in range n, f x) * f n :=
|
||||
Finset.prod_range_succ f n
|
||||
|
||||
example (n : ℕ) : fac n = ∏ i in range n, (i + 1) := by
|
||||
induction' n with n ih
|
||||
· rw [fac, prod_range_zero]
|
||||
rw [fac, ih, prod_range_succ, mul_comm]
|
||||
|
||||
example (a b c d e f : ℕ) : a * (b * c * f * (d * e)) = d * (a * f * e) * (c * b) := by
|
||||
simp [mul_assoc, mul_comm, mul_left_comm]
|
||||
|
||||
theorem sum_id (n : ℕ) : ∑ i in range (n + 1), i = n * (n + 1) / 2 := by
|
||||
symm; apply Nat.div_eq_of_eq_mul_right (by norm_num : 0 < 2)
|
||||
induction' n with n ih
|
||||
· simp
|
||||
rw [Finset.sum_range_succ, mul_add 2, ← ih, Nat.succ_eq_add_one]
|
||||
ring
|
||||
|
||||
theorem sum_sqr (n : ℕ) : ∑ i in range (n + 1), i ^ 2 = n * (n + 1) * (2 * n + 1) / 6 := by
|
||||
sorry
|
||||
end
|
||||
|
||||
inductive MyNat
|
||||
| zero : MyNat
|
||||
| succ : MyNat → MyNat
|
||||
|
||||
namespace MyNat
|
||||
|
||||
def add : MyNat → MyNat → MyNat
|
||||
| x, zero => x
|
||||
| x, succ y => succ (add x y)
|
||||
|
||||
def mul : MyNat → MyNat → MyNat
|
||||
| x, zero => zero
|
||||
| x, succ y => add (mul x y) x
|
||||
|
||||
theorem zero_add (n : MyNat) : add zero n = n := by
|
||||
induction' n with n ih
|
||||
· rfl
|
||||
rw [add, ih]
|
||||
|
||||
theorem succ_add (m n : MyNat) : add (succ m) n = succ (add m n) := by
|
||||
induction' n with n ih
|
||||
· rfl
|
||||
rw [add, ih]
|
||||
rfl
|
||||
|
||||
theorem add_comm (m n : MyNat) : add m n = add n m := by
|
||||
induction' n with n ih
|
||||
· rw [zero_add]
|
||||
rfl
|
||||
rw [add, succ_add, ih]
|
||||
|
||||
theorem add_assoc (m n k : MyNat) : add (add m n) k = add m (add n k) := by
|
||||
sorry
|
||||
theorem mul_add (m n k : MyNat) : mul m (add n k) = add (mul m n) (mul m k) := by
|
||||
sorry
|
||||
theorem zero_mul (n : MyNat) : mul zero n = zero := by
|
||||
sorry
|
||||
theorem succ_mul (m n : MyNat) : mul (succ m) n = add (mul m n) n := by
|
||||
sorry
|
||||
theorem mul_comm (m n : MyNat) : mul m n = mul n m := by
|
||||
sorry
|
||||
end MyNat
|
|
@ -0,0 +1,229 @@
|
|||
import Mathlib.Data.Nat.Prime
|
||||
import Mathlib.Algebra.BigOperators.Order
|
||||
import MIL.Common
|
||||
|
||||
open BigOperators
|
||||
|
||||
namespace C05S03
|
||||
|
||||
theorem two_le {m : ℕ} (h0 : m ≠ 0) (h1 : m ≠ 1) : 2 ≤ m := by
|
||||
cases m; contradiction
|
||||
case succ m =>
|
||||
cases m; contradiction
|
||||
repeat' apply Nat.succ_le_succ
|
||||
apply zero_le
|
||||
|
||||
example {m : ℕ} (h0 : m ≠ 0) (h1 : m ≠ 1) : 2 ≤ m := by
|
||||
by_contra h
|
||||
push_neg at h
|
||||
interval_cases m <;> contradiction
|
||||
|
||||
example {m : ℕ} (h0 : m ≠ 0) (h1 : m ≠ 1) : 2 ≤ m := by
|
||||
by_contra h
|
||||
push_neg at h
|
||||
revert h0 h1
|
||||
revert h m
|
||||
decide
|
||||
|
||||
theorem exists_prime_factor {n : Nat} (h : 2 ≤ n) : ∃ p : Nat, p.Prime ∧ p ∣ n := by
|
||||
by_cases np : n.Prime
|
||||
· use n, np
|
||||
induction' n using Nat.strong_induction_on with n ih
|
||||
rw [Nat.prime_def_lt] at np
|
||||
push_neg at np
|
||||
rcases np h with ⟨m, mltn, mdvdn, mne1⟩
|
||||
have : m ≠ 0 := by
|
||||
intro mz
|
||||
rw [mz, zero_dvd_iff] at mdvdn
|
||||
linarith
|
||||
have mgt2 : 2 ≤ m := two_le this mne1
|
||||
by_cases mp : m.Prime
|
||||
· use m, mp
|
||||
. rcases ih m mltn mgt2 mp with ⟨p, pp, pdvd⟩
|
||||
use p, pp
|
||||
apply pdvd.trans mdvdn
|
||||
|
||||
theorem primes_infinite : ∀ n, ∃ p > n, Nat.Prime p := by
|
||||
intro n
|
||||
have : 2 ≤ Nat.factorial (n + 1) + 1 := by
|
||||
sorry
|
||||
rcases exists_prime_factor this with ⟨p, pp, pdvd⟩
|
||||
refine' ⟨p, _, pp⟩
|
||||
show p > n
|
||||
by_contra ple
|
||||
push_neg at ple
|
||||
have : p ∣ Nat.factorial (n + 1) := by
|
||||
sorry
|
||||
have : p ∣ 1 := by
|
||||
sorry
|
||||
show False
|
||||
sorry
|
||||
open Finset
|
||||
|
||||
section
|
||||
variable {α : Type*} [DecidableEq α] (r s t : Finset α)
|
||||
|
||||
example : r ∩ (s ∪ t) ⊆ r ∩ s ∪ r ∩ t := by
|
||||
rw [subset_iff]
|
||||
intro x
|
||||
rw [mem_inter, mem_union, mem_union, mem_inter, mem_inter]
|
||||
tauto
|
||||
|
||||
example : r ∩ (s ∪ t) ⊆ r ∩ s ∪ r ∩ t := by
|
||||
simp [subset_iff]
|
||||
intro x
|
||||
tauto
|
||||
|
||||
example : r ∩ s ∪ r ∩ t ⊆ r ∩ (s ∪ t) := by
|
||||
simp [subset_iff]
|
||||
intro x
|
||||
tauto
|
||||
|
||||
example : r ∩ s ∪ r ∩ t = r ∩ (s ∪ t) := by
|
||||
ext x
|
||||
simp
|
||||
tauto
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
variable {α : Type*} [DecidableEq α] (r s t : Finset α)
|
||||
|
||||
example : (r ∪ s) ∩ (r ∪ t) = r ∪ s ∩ t := by
|
||||
sorry
|
||||
example : (r \ s) \ t = r \ (s ∪ t) := by
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
example (s : Finset ℕ) (n : ℕ) (h : n ∈ s) : n ∣ ∏ i in s, i :=
|
||||
Finset.dvd_prod_of_mem _ h
|
||||
|
||||
theorem _root_.Nat.Prime.eq_of_dvd_of_prime {p q : ℕ}
|
||||
(prime_p : Nat.Prime p) (prime_q : Nat.Prime q) (h : p ∣ q) :
|
||||
p = q := by
|
||||
sorry
|
||||
|
||||
theorem mem_of_dvd_prod_primes {s : Finset ℕ} {p : ℕ} (prime_p : p.Prime) :
|
||||
(∀ n ∈ s, Nat.Prime n) → (p ∣ ∏ n in s, n) → p ∈ s := by
|
||||
intro h₀ h₁
|
||||
induction' s using Finset.induction_on with a s ans ih
|
||||
· simp at h₁
|
||||
linarith [prime_p.two_le]
|
||||
simp [Finset.prod_insert ans, prime_p.dvd_mul] at h₀ h₁
|
||||
rw [mem_insert]
|
||||
sorry
|
||||
example (s : Finset ℕ) (x : ℕ) : x ∈ s.filter Nat.Prime ↔ x ∈ s ∧ x.Prime :=
|
||||
mem_filter
|
||||
|
||||
theorem primes_infinite' : ∀ s : Finset Nat, ∃ p, Nat.Prime p ∧ p ∉ s := by
|
||||
intro s
|
||||
by_contra h
|
||||
push_neg at h
|
||||
set s' := s.filter Nat.Prime with s'_def
|
||||
have mem_s' : ∀ {n : ℕ}, n ∈ s' ↔ n.Prime := by
|
||||
intro n
|
||||
simp [s'_def]
|
||||
apply h
|
||||
have : 2 ≤ (∏ i in s', i) + 1 := by
|
||||
sorry
|
||||
rcases exists_prime_factor this with ⟨p, pp, pdvd⟩
|
||||
have : p ∣ ∏ i in s', i := by
|
||||
sorry
|
||||
have : p ∣ 1 := by
|
||||
convert Nat.dvd_sub' pdvd this
|
||||
simp
|
||||
show False
|
||||
sorry
|
||||
theorem bounded_of_ex_finset (Q : ℕ → Prop) :
|
||||
(∃ s : Finset ℕ, ∀ k, Q k → k ∈ s) → ∃ n, ∀ k, Q k → k < n := by
|
||||
rintro ⟨s, hs⟩
|
||||
use s.sup id + 1
|
||||
intro k Qk
|
||||
apply Nat.lt_succ_of_le
|
||||
show id k ≤ s.sup id
|
||||
apply le_sup (hs k Qk)
|
||||
|
||||
theorem ex_finset_of_bounded (Q : ℕ → Prop) [DecidablePred Q] :
|
||||
(∃ n, ∀ k, Q k → k ≤ n) → ∃ s : Finset ℕ, ∀ k, Q k ↔ k ∈ s := by
|
||||
rintro ⟨n, hn⟩
|
||||
use (range (n + 1)).filter Q
|
||||
intro k
|
||||
simp [Nat.lt_succ_iff]
|
||||
exact hn k
|
||||
|
||||
example : 27 % 4 = 3 := by norm_num
|
||||
|
||||
example (n : ℕ) : (4 * n + 3) % 4 = 3 := by
|
||||
rw [add_comm, Nat.add_mul_mod_self_left]
|
||||
norm_num
|
||||
|
||||
theorem mod_4_eq_3_or_mod_4_eq_3 {m n : ℕ} (h : m * n % 4 = 3) : m % 4 = 3 ∨ n % 4 = 3 := by
|
||||
revert h
|
||||
rw [Nat.mul_mod]
|
||||
have : m % 4 < 4 := Nat.mod_lt m (by norm_num)
|
||||
interval_cases hm : m % 4 <;> simp [hm]
|
||||
have : n % 4 < 4 := Nat.mod_lt n (by norm_num)
|
||||
interval_cases hn : n % 4 <;> simp [hn]
|
||||
|
||||
theorem two_le_of_mod_4_eq_3 {n : ℕ} (h : n % 4 = 3) : 2 ≤ n := by
|
||||
apply two_le <;>
|
||||
· intro neq
|
||||
rw [neq] at h
|
||||
norm_num at h
|
||||
|
||||
theorem aux {m n : ℕ} (h₀ : m ∣ n) (h₁ : 2 ≤ m) (h₂ : m < n) : n / m ∣ n ∧ n / m < n := by
|
||||
sorry
|
||||
theorem exists_prime_factor_mod_4_eq_3 {n : Nat} (h : n % 4 = 3) :
|
||||
∃ p : Nat, p.Prime ∧ p ∣ n ∧ p % 4 = 3 := by
|
||||
by_cases np : n.Prime
|
||||
· use n
|
||||
induction' n using Nat.strong_induction_on with n ih
|
||||
rw [Nat.prime_def_lt] at np
|
||||
push_neg at np
|
||||
rcases np (two_le_of_mod_4_eq_3 h) with ⟨m, mltn, mdvdn, mne1⟩
|
||||
have mge2 : 2 ≤ m := by
|
||||
apply two_le _ mne1
|
||||
intro mz
|
||||
rw [mz, zero_dvd_iff] at mdvdn
|
||||
linarith
|
||||
have neq : m * (n / m) = n := Nat.mul_div_cancel' mdvdn
|
||||
have : m % 4 = 3 ∨ n / m % 4 = 3 := by
|
||||
apply mod_4_eq_3_or_mod_4_eq_3
|
||||
rw [neq, h]
|
||||
rcases this with h1 | h1
|
||||
. sorry
|
||||
. sorry
|
||||
example (m n : ℕ) (s : Finset ℕ) (h : m ∈ erase s n) : m ≠ n ∧ m ∈ s := by
|
||||
rwa [mem_erase] at h
|
||||
|
||||
example (m n : ℕ) (s : Finset ℕ) (h : m ∈ erase s n) : m ≠ n ∧ m ∈ s := by
|
||||
simp at h
|
||||
assumption
|
||||
|
||||
theorem primes_mod_4_eq_3_infinite : ∀ n, ∃ p > n, Nat.Prime p ∧ p % 4 = 3 := by
|
||||
by_contra h
|
||||
push_neg at h
|
||||
rcases h with ⟨n, hn⟩
|
||||
have : ∃ s : Finset Nat, ∀ p : ℕ, p.Prime ∧ p % 4 = 3 ↔ p ∈ s := by
|
||||
apply ex_finset_of_bounded
|
||||
use n
|
||||
contrapose! hn
|
||||
rcases hn with ⟨p, ⟨pp, p4⟩, pltn⟩
|
||||
exact ⟨p, pltn, pp, p4⟩
|
||||
rcases this with ⟨s, hs⟩
|
||||
have h₁ : ((4 * ∏ i in erase s 3, i) + 3) % 4 = 3 := by
|
||||
sorry
|
||||
rcases exists_prime_factor_mod_4_eq_3 h₁ with ⟨p, pp, pdvd, p4eq⟩
|
||||
have ps : p ∈ s := by
|
||||
sorry
|
||||
have pne3 : p ≠ 3 := by
|
||||
sorry
|
||||
have : p ∣ 4 * ∏ i in erase s 3, i := by
|
||||
sorry
|
||||
have : p ∣ 3 := by
|
||||
sorry
|
||||
have : p = 3 := by
|
||||
sorry
|
||||
contradiction
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Nat.Factorization.Basic
|
||||
import Mathlib.Data.Nat.Prime
|
||||
|
||||
theorem even_of_even_sqr {m : ℕ} (h : 2 ∣ m ^ 2) : 2 ∣ m := by
|
||||
rw [pow_two, Nat.prime_two.dvd_mul] at h
|
||||
cases h <;> assumption
|
||||
|
||||
example {m n : ℕ} (coprime_mn : m.Coprime n) : m ^ 2 ≠ 2 * n ^ 2 := by
|
||||
intro sqr_eq
|
||||
have : 2 ∣ m := by
|
||||
apply even_of_even_sqr
|
||||
rw [sqr_eq]
|
||||
apply dvd_mul_right
|
||||
obtain ⟨k, meq⟩ := dvd_iff_exists_eq_mul_left.mp this
|
||||
have : 2 * (2 * k ^ 2) = 2 * n ^ 2 := by
|
||||
rw [← sqr_eq, meq]
|
||||
ring
|
||||
have : 2 * k ^ 2 = n ^ 2 :=
|
||||
(mul_right_inj' (by norm_num)).mp this
|
||||
have : 2 ∣ n := by
|
||||
apply even_of_even_sqr
|
||||
rw [← this]
|
||||
apply dvd_mul_right
|
||||
have : 2 ∣ m.gcd n := by
|
||||
apply Nat.dvd_gcd <;>
|
||||
assumption
|
||||
have : 2 ∣ 1 := by
|
||||
convert this
|
||||
symm
|
||||
exact coprime_mn
|
||||
norm_num at this
|
||||
|
||||
example {m n p : ℕ} (coprime_mn : m.Coprime n) (prime_p : p.Prime) : m ^ 2 ≠ p * n ^ 2 := by
|
||||
intro sqr_eq
|
||||
have : p ∣ m := by
|
||||
apply prime_p.dvd_of_dvd_pow
|
||||
rw [sqr_eq]
|
||||
apply dvd_mul_right
|
||||
obtain ⟨k, meq⟩ := dvd_iff_exists_eq_mul_left.mp this
|
||||
have : p * (p * k ^ 2) = p * n ^ 2 := by
|
||||
rw [← sqr_eq, meq]
|
||||
ring
|
||||
have : p * k ^ 2 = n ^ 2 := by
|
||||
apply (mul_right_inj' _).mp this
|
||||
exact prime_p.ne_zero
|
||||
have : p ∣ n := by
|
||||
apply prime_p.dvd_of_dvd_pow
|
||||
rw [← this]
|
||||
apply dvd_mul_right
|
||||
have : p ∣ Nat.gcd m n := by apply Nat.dvd_gcd <;> assumption
|
||||
have : p ∣ 1 := by
|
||||
convert this
|
||||
symm
|
||||
exact coprime_mn
|
||||
have : 2 ≤ 1 := by
|
||||
apply prime_p.two_le.trans
|
||||
exact Nat.le_of_dvd zero_lt_one this
|
||||
norm_num at this
|
||||
|
||||
theorem factorization_mul' {m n : ℕ} (mnez : m ≠ 0) (nnez : n ≠ 0) (p : ℕ) :
|
||||
(m * n).factorization p = m.factorization p + n.factorization p := by
|
||||
rw [Nat.factorization_mul mnez nnez]
|
||||
rfl
|
||||
|
||||
theorem factorization_pow' (n k p : ℕ) :
|
||||
(n ^ k).factorization p = k * n.factorization p := by
|
||||
rw [Nat.factorization_pow]
|
||||
rfl
|
||||
|
||||
theorem Nat.Prime.factorization' {p : ℕ} (prime_p : p.Prime) :
|
||||
p.factorization p = 1 := by
|
||||
rw [prime_p.factorization]
|
||||
simp
|
||||
|
||||
example {m n p : ℕ} (nnz : n ≠ 0) (prime_p : p.Prime) : m ^ 2 ≠ p * n ^ 2 := by
|
||||
intro sqr_eq
|
||||
have nsqr_nez : n ^ 2 ≠ 0 := by simpa
|
||||
have eq1 : Nat.factorization (m ^ 2) p = 2 * m.factorization p := by
|
||||
rw [factorization_pow']
|
||||
have eq2 : (p * n ^ 2).factorization p = 2 * n.factorization p + 1 := by
|
||||
rw [factorization_mul' prime_p.ne_zero nsqr_nez, prime_p.factorization', factorization_pow',
|
||||
add_comm]
|
||||
have : 2 * m.factorization p % 2 = (2 * n.factorization p + 1) % 2 := by
|
||||
rw [← eq1, sqr_eq, eq2]
|
||||
rw [add_comm, Nat.add_mul_mod_self_left, Nat.mul_mod_right] at this
|
||||
norm_num at this
|
||||
|
||||
example {m n k r : ℕ} (nnz : n ≠ 0) (pow_eq : m ^ k = r * n ^ k) {p : ℕ} (prime_p : p.Prime) :
|
||||
k ∣ r.factorization p := by
|
||||
rcases r with _ | r
|
||||
· simp
|
||||
have npow_nz : n ^ k ≠ 0 := fun npowz ↦ nnz (pow_eq_zero npowz)
|
||||
have eq1 : (m ^ k).factorization p = k * m.factorization p := by
|
||||
rw [factorization_pow']
|
||||
have eq2 : (r.succ * n ^ k).factorization p =
|
||||
k * n.factorization p + r.succ.factorization p := by
|
||||
rw [factorization_mul' r.succ_ne_zero npow_nz, factorization_pow', add_comm]
|
||||
have : r.succ.factorization p = k * m.factorization p - k * n.factorization p := by
|
||||
rw [← eq1, pow_eq, eq2, add_comm, Nat.add_sub_cancel]
|
||||
rw [this]
|
||||
apply Nat.dvd_sub' <;>
|
||||
apply Nat.dvd_mul_right
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
import Mathlib.Data.Nat.GCD.Basic
|
||||
import Mathlib.Algebra.BigOperators.Basic
|
||||
import MIL.Common
|
||||
|
||||
def fac : ℕ → ℕ
|
||||
| 0 => 1
|
||||
| n + 1 => (n + 1) * fac n
|
||||
|
||||
theorem pow_two_le_fac (n : ℕ) : 2 ^ (n - 1) ≤ fac n := by
|
||||
rcases n with _ | n
|
||||
· simp [fac]
|
||||
induction' n with n ih
|
||||
· simp [fac]
|
||||
simp at *
|
||||
rw [pow_succ, fac]
|
||||
apply Nat.mul_le_mul _ ih
|
||||
repeat' apply Nat.succ_le_succ
|
||||
apply zero_le
|
||||
|
||||
section
|
||||
|
||||
variable {α : Type*} (s : Finset ℕ) (f : ℕ → ℕ) (n : ℕ)
|
||||
|
||||
open BigOperators
|
||||
open Finset
|
||||
|
||||
theorem sum_sqr (n : ℕ) : ∑ i in range (n + 1), i ^ 2 = n * (n + 1) * (2 * n + 1) / 6 := by
|
||||
symm;
|
||||
apply Nat.div_eq_of_eq_mul_right (by norm_num : 0 < 6)
|
||||
induction' n with n ih
|
||||
· simp
|
||||
rw [Finset.sum_range_succ, mul_add 6, ← ih, Nat.succ_eq_add_one]
|
||||
ring
|
||||
|
||||
end
|
||||
|
||||
inductive MyNat
|
||||
| zero : MyNat
|
||||
| succ : MyNat → MyNat
|
||||
|
||||
namespace MyNat
|
||||
|
||||
def add : MyNat → MyNat → MyNat
|
||||
| x, zero => x
|
||||
| x, succ y => succ (add x y)
|
||||
|
||||
def mul : MyNat → MyNat → MyNat
|
||||
| x, zero => zero
|
||||
| x, succ y => add (mul x y) x
|
||||
|
||||
theorem zero_add (n : MyNat) : add zero n = n := by
|
||||
induction' n with n ih
|
||||
· rfl
|
||||
rw [add, ih]
|
||||
|
||||
theorem succ_add (m n : MyNat) : add (succ m) n = succ (add m n) := by
|
||||
induction' n with n ih
|
||||
· rfl
|
||||
rw [add, ih]
|
||||
rfl
|
||||
|
||||
theorem add_comm (m n : MyNat) : add m n = add n m := by
|
||||
induction' n with n ih
|
||||
· rw [zero_add]
|
||||
rfl
|
||||
rw [add, succ_add, ih]
|
||||
|
||||
theorem add_assoc (m n k : MyNat) : add (add m n) k = add m (add n k) := by
|
||||
induction' k with k ih
|
||||
· rfl
|
||||
rw [add, ih]
|
||||
rfl
|
||||
|
||||
theorem mul_add (m n k : MyNat) : mul m (add n k) = add (mul m n) (mul m k) := by
|
||||
induction' k with k ih
|
||||
· rfl
|
||||
rw [add, mul, mul, ih, add_assoc]
|
||||
|
||||
theorem zero_mul (n : MyNat) : mul zero n = zero := by
|
||||
induction' n with n ih
|
||||
· rfl
|
||||
rw [mul, ih]
|
||||
rfl
|
||||
|
||||
theorem succ_mul (m n : MyNat) : mul (succ m) n = add (mul m n) n := by
|
||||
induction' n with n ih
|
||||
· rfl
|
||||
rw [mul, mul, ih, add_assoc, add_assoc, add_comm n, succ_add]
|
||||
rfl
|
||||
|
||||
theorem mul_comm (m n : MyNat) : mul m n = mul n m := by
|
||||
induction' n with n ih
|
||||
· rw [zero_mul]
|
||||
rfl
|
||||
rw [mul, ih, succ_mul]
|
||||
|
||||
end MyNat
|
|
@ -0,0 +1,236 @@
|
|||
import Mathlib.Data.Nat.Prime
|
||||
import Mathlib.Algebra.BigOperators.Order
|
||||
import MIL.Common
|
||||
|
||||
open BigOperators
|
||||
|
||||
namespace C05S03
|
||||
|
||||
theorem two_le {m : ℕ} (h0 : m ≠ 0) (h1 : m ≠ 1) : 2 ≤ m := by
|
||||
cases m; contradiction
|
||||
case succ m =>
|
||||
cases m; contradiction
|
||||
repeat' apply Nat.succ_le_succ
|
||||
apply zero_le
|
||||
|
||||
theorem exists_prime_factor {n : Nat} (h : 2 ≤ n) : ∃ p : Nat, p.Prime ∧ p ∣ n := by
|
||||
by_cases np : n.Prime
|
||||
· use n, np
|
||||
induction' n using Nat.strong_induction_on with n ih
|
||||
rw [Nat.prime_def_lt] at np
|
||||
push_neg at np
|
||||
rcases np h with ⟨m, mltn, mdvdn, mne1⟩
|
||||
have : m ≠ 0 := by
|
||||
intro mz
|
||||
rw [mz, zero_dvd_iff] at mdvdn
|
||||
linarith
|
||||
have mgt2 : 2 ≤ m := two_le this mne1
|
||||
by_cases mp : m.Prime
|
||||
· use m, mp
|
||||
. rcases ih m mltn mgt2 mp with ⟨p, pp, pdvd⟩
|
||||
use p, pp
|
||||
apply pdvd.trans mdvdn
|
||||
|
||||
theorem primes_infinite : ∀ n, ∃ p > n, Nat.Prime p := by
|
||||
intro n
|
||||
have : 2 ≤ Nat.factorial (n + 1) + 1 := by
|
||||
apply Nat.succ_le_succ
|
||||
exact Nat.succ_le_of_lt (Nat.factorial_pos _)
|
||||
rcases exists_prime_factor this with ⟨p, pp, pdvd⟩
|
||||
refine' ⟨p, _, pp⟩
|
||||
show p > n
|
||||
by_contra ple
|
||||
push_neg at ple
|
||||
have : p ∣ Nat.factorial (n + 1) := by
|
||||
apply Nat.dvd_factorial
|
||||
apply pp.pos
|
||||
linarith
|
||||
have : p ∣ 1 := by
|
||||
convert Nat.dvd_sub' pdvd this
|
||||
simp
|
||||
show False
|
||||
have := Nat.le_of_dvd zero_lt_one this
|
||||
linarith [pp.two_le]
|
||||
|
||||
open Finset
|
||||
|
||||
section
|
||||
variable {α : Type*} [DecidableEq α] (r s t : Finset α)
|
||||
|
||||
example : (r ∪ s) ∩ (r ∪ t) = r ∪ s ∩ t := by
|
||||
ext x
|
||||
rw [mem_inter, mem_union, mem_union, mem_union, mem_inter]
|
||||
tauto
|
||||
|
||||
example : (r ∪ s) ∩ (r ∪ t) = r ∪ s ∩ t := by
|
||||
ext x
|
||||
simp
|
||||
tauto
|
||||
|
||||
example : (r \ s) \ t = r \ (s ∪ t) := by
|
||||
ext x
|
||||
rw [mem_sdiff, mem_sdiff, mem_sdiff, mem_union]
|
||||
tauto
|
||||
|
||||
example : (r \ s) \ t = r \ (s ∪ t) := by
|
||||
ext x
|
||||
simp
|
||||
tauto
|
||||
|
||||
end
|
||||
|
||||
theorem _root_.Nat.Prime.eq_of_dvd_of_prime {p q : ℕ}
|
||||
(prime_p : Nat.Prime p) (prime_q : Nat.Prime q) (h : p ∣ q) :
|
||||
p = q := by
|
||||
cases prime_q.eq_one_or_self_of_dvd _ h
|
||||
· linarith [prime_p.two_le]
|
||||
assumption
|
||||
|
||||
theorem mem_of_dvd_prod_primes {s : Finset ℕ} {p : ℕ} (prime_p : p.Prime) :
|
||||
(∀ n ∈ s, Nat.Prime n) → (p ∣ ∏ n in s, n) → p ∈ s := by
|
||||
intro h₀ h₁
|
||||
induction' s using Finset.induction_on with a s ans ih
|
||||
· simp at h₁
|
||||
linarith [prime_p.two_le]
|
||||
simp [Finset.prod_insert ans, prime_p.dvd_mul] at h₀ h₁
|
||||
rw [mem_insert]
|
||||
rcases h₁ with h₁ | h₁
|
||||
· left
|
||||
exact prime_p.eq_of_dvd_of_prime h₀.1 h₁
|
||||
right
|
||||
exact ih h₀.2 h₁
|
||||
|
||||
theorem primes_infinite' : ∀ s : Finset Nat, ∃ p, Nat.Prime p ∧ p ∉ s := by
|
||||
intro s
|
||||
by_contra h
|
||||
push_neg at h
|
||||
set s' := s.filter Nat.Prime with s'_def
|
||||
have mem_s' : ∀ {n : ℕ}, n ∈ s' ↔ n.Prime := by
|
||||
intro n
|
||||
simp [s'_def]
|
||||
apply h
|
||||
have : 2 ≤ (∏ i in s', i) + 1 := by
|
||||
apply Nat.succ_le_succ
|
||||
apply Nat.succ_le_of_lt
|
||||
apply Finset.prod_pos
|
||||
intro n ns'
|
||||
apply (mem_s'.mp ns').pos
|
||||
rcases exists_prime_factor this with ⟨p, pp, pdvd⟩
|
||||
have : p ∣ ∏ i in s', i := by
|
||||
apply dvd_prod_of_mem
|
||||
rw [mem_s']
|
||||
apply pp
|
||||
have : p ∣ 1 := by
|
||||
convert Nat.dvd_sub' pdvd this
|
||||
simp
|
||||
show False
|
||||
have := Nat.le_of_dvd zero_lt_one this
|
||||
linarith [pp.two_le]
|
||||
|
||||
theorem bounded_of_ex_finset (Q : ℕ → Prop) :
|
||||
(∃ s : Finset ℕ, ∀ k, Q k → k ∈ s) → ∃ n, ∀ k, Q k → k < n := by
|
||||
rintro ⟨s, hs⟩
|
||||
use s.sup id + 1
|
||||
intro k Qk
|
||||
apply Nat.lt_succ_of_le
|
||||
show id k ≤ s.sup id
|
||||
apply le_sup (hs k Qk)
|
||||
|
||||
theorem ex_finset_of_bounded (Q : ℕ → Prop) [DecidablePred Q] :
|
||||
(∃ n, ∀ k, Q k → k ≤ n) → ∃ s : Finset ℕ, ∀ k, Q k ↔ k ∈ s := by
|
||||
rintro ⟨n, hn⟩
|
||||
use (range (n + 1)).filter Q
|
||||
intro k
|
||||
simp [Nat.lt_succ_iff]
|
||||
exact hn k
|
||||
|
||||
theorem mod_4_eq_3_or_mod_4_eq_3 {m n : ℕ} (h : m * n % 4 = 3) : m % 4 = 3 ∨ n % 4 = 3 := by
|
||||
revert h
|
||||
rw [Nat.mul_mod]
|
||||
have : m % 4 < 4 := Nat.mod_lt m (by norm_num)
|
||||
interval_cases hm : m % 4 <;> simp [hm]
|
||||
have : n % 4 < 4 := Nat.mod_lt n (by norm_num)
|
||||
interval_cases hn : n % 4 <;> simp [hn]
|
||||
|
||||
theorem two_le_of_mod_4_eq_3 {n : ℕ} (h : n % 4 = 3) : 2 ≤ n := by
|
||||
apply two_le <;>
|
||||
· intro neq
|
||||
rw [neq] at h
|
||||
norm_num at h
|
||||
|
||||
theorem aux {m n : ℕ} (h₀ : m ∣ n) (h₁ : 2 ≤ m) (h₂ : m < n) : n / m ∣ n ∧ n / m < n := by
|
||||
constructor
|
||||
· exact Nat.div_dvd_of_dvd h₀
|
||||
exact Nat.div_lt_self (lt_of_le_of_lt (zero_le _) h₂) h₁
|
||||
|
||||
theorem exists_prime_factor_mod_4_eq_3 {n : Nat} (h : n % 4 = 3) :
|
||||
∃ p : Nat, p.Prime ∧ p ∣ n ∧ p % 4 = 3 := by
|
||||
by_cases np : n.Prime
|
||||
· use n
|
||||
induction' n using Nat.strong_induction_on with n ih
|
||||
rw [Nat.prime_def_lt] at np
|
||||
push_neg at np
|
||||
rcases np (two_le_of_mod_4_eq_3 h) with ⟨m, mltn, mdvdn, mne1⟩
|
||||
have mge2 : 2 ≤ m := by
|
||||
apply two_le _ mne1
|
||||
intro mz
|
||||
rw [mz, zero_dvd_iff] at mdvdn
|
||||
linarith
|
||||
have neq : m * (n / m) = n := Nat.mul_div_cancel' mdvdn
|
||||
have : m % 4 = 3 ∨ n / m % 4 = 3 := by
|
||||
apply mod_4_eq_3_or_mod_4_eq_3
|
||||
rw [neq, h]
|
||||
rcases this with h1 | h1
|
||||
· by_cases mp : m.Prime
|
||||
· use m
|
||||
rcases ih m mltn h1 mp with ⟨p, pp, pdvd, p4eq⟩
|
||||
use p
|
||||
exact ⟨pp, pdvd.trans mdvdn, p4eq⟩
|
||||
obtain ⟨nmdvdn, nmltn⟩ := aux mdvdn mge2 mltn
|
||||
by_cases nmp : (n / m).Prime
|
||||
· use n / m
|
||||
rcases ih (n / m) nmltn h1 nmp with ⟨p, pp, pdvd, p4eq⟩
|
||||
use p
|
||||
exact ⟨pp, pdvd.trans nmdvdn, p4eq⟩
|
||||
|
||||
theorem primes_mod_4_eq_3_infinite : ∀ n, ∃ p > n, Nat.Prime p ∧ p % 4 = 3 := by
|
||||
by_contra h
|
||||
push_neg at h
|
||||
rcases h with ⟨n, hn⟩
|
||||
have : ∃ s : Finset Nat, ∀ p : ℕ, p.Prime ∧ p % 4 = 3 ↔ p ∈ s := by
|
||||
apply ex_finset_of_bounded
|
||||
use n
|
||||
contrapose! hn
|
||||
rcases hn with ⟨p, ⟨pp, p4⟩, pltn⟩
|
||||
exact ⟨p, pltn, pp, p4⟩
|
||||
rcases this with ⟨s, hs⟩
|
||||
have h₁ : ((4 * ∏ i in erase s 3, i) + 3) % 4 = 3 := by
|
||||
rw [add_comm, Nat.add_mul_mod_self_left]
|
||||
norm_num
|
||||
rcases exists_prime_factor_mod_4_eq_3 h₁ with ⟨p, pp, pdvd, p4eq⟩
|
||||
have ps : p ∈ s := by
|
||||
rw [← hs p]
|
||||
exact ⟨pp, p4eq⟩
|
||||
have pne3 : p ≠ 3 := by
|
||||
intro peq
|
||||
rw [peq, ← Nat.dvd_add_iff_left (dvd_refl 3)] at pdvd
|
||||
rw [Nat.prime_three.dvd_mul] at pdvd
|
||||
norm_num at pdvd
|
||||
have : 3 ∈ s.erase 3 := by
|
||||
apply mem_of_dvd_prod_primes Nat.prime_three _ pdvd
|
||||
intro n
|
||||
simp [← hs n]
|
||||
tauto
|
||||
simp at this
|
||||
have : p ∣ 4 * ∏ i in erase s 3, i := by
|
||||
apply dvd_trans _ (dvd_mul_left _ _)
|
||||
apply dvd_prod_of_mem
|
||||
simp
|
||||
constructor <;> assumption
|
||||
have : p ∣ 3 := by
|
||||
convert Nat.dvd_sub' pdvd this
|
||||
simp
|
||||
have : p = 3 := by
|
||||
apply pp.eq_of_dvd_of_prime Nat.prime_three this
|
||||
contradiction
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Algebra.BigOperators.Ring
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C06S01
|
||||
noncomputable section
|
||||
|
||||
@[ext]
|
||||
structure Point where
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
|
||||
#check Point.ext
|
||||
|
||||
example (a b : Point) (hx : a.x = b.x) (hy : a.y = b.y) (hz : a.z = b.z) : a = b := by
|
||||
ext
|
||||
repeat' assumption
|
||||
|
||||
def myPoint1 : Point where
|
||||
x := 2
|
||||
y := -1
|
||||
z := 4
|
||||
|
||||
def myPoint2 : Point :=
|
||||
⟨2, -1, 4⟩
|
||||
|
||||
def myPoint3 :=
|
||||
Point.mk 2 (-1) 4
|
||||
|
||||
structure Point' where build ::
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
|
||||
#check Point'.build 2 (-1) 4
|
||||
|
||||
namespace Point
|
||||
|
||||
def add (a b : Point) : Point :=
|
||||
⟨a.x + b.x, a.y + b.y, a.z + b.z⟩
|
||||
|
||||
def add' (a b : Point) : Point where
|
||||
x := a.x + b.x
|
||||
y := a.y + b.y
|
||||
z := a.z + b.z
|
||||
|
||||
#check add myPoint1 myPoint2
|
||||
#check myPoint1.add myPoint2
|
||||
|
||||
end Point
|
||||
|
||||
#check Point.add myPoint1 myPoint2
|
||||
#check myPoint1.add myPoint2
|
||||
|
||||
namespace Point
|
||||
|
||||
protected theorem add_comm (a b : Point) : add a b = add b a := by
|
||||
rw [add, add]
|
||||
ext <;> dsimp
|
||||
repeat' apply add_comm
|
||||
|
||||
example (a b : Point) : add a b = add b a := by simp [add, add_comm]
|
||||
|
||||
theorem add_x (a b : Point) : (a.add b).x = a.x + b.x :=
|
||||
rfl
|
||||
|
||||
def addAlt : Point → Point → Point
|
||||
| Point.mk x₁ y₁ z₁, Point.mk x₂ y₂ z₂ => ⟨x₁ + x₂, y₁ + y₂, z₁ + z₂⟩
|
||||
|
||||
def addAlt' : Point → Point → Point
|
||||
| ⟨x₁, y₁, z₁⟩, ⟨x₂, y₂, z₂⟩ => ⟨x₁ + x₂, y₁ + y₂, z₁ + z₂⟩
|
||||
|
||||
theorem addAlt_x (a b : Point) : (a.addAlt b).x = a.x + b.x := by
|
||||
rfl
|
||||
|
||||
theorem addAlt_comm (a b : Point) : addAlt a b = addAlt b a := by
|
||||
rw [addAlt, addAlt]
|
||||
-- the same proof still works, but the goal view here is harder to read
|
||||
ext <;> dsimp
|
||||
repeat' apply add_comm
|
||||
|
||||
protected theorem add_assoc (a b c : Point) : (a.add b).add c = a.add (b.add c) := by
|
||||
sorry
|
||||
|
||||
def smul (r : ℝ) (a : Point) : Point :=
|
||||
sorry
|
||||
|
||||
theorem smul_distrib (r : ℝ) (a b : Point) :
|
||||
(smul r a).add (smul r b) = smul r (a.add b) := by
|
||||
sorry
|
||||
|
||||
end Point
|
||||
|
||||
structure StandardTwoSimplex where
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
x_nonneg : 0 ≤ x
|
||||
y_nonneg : 0 ≤ y
|
||||
z_nonneg : 0 ≤ z
|
||||
sum_eq : x + y + z = 1
|
||||
|
||||
namespace StandardTwoSimplex
|
||||
|
||||
def swapXy (a : StandardTwoSimplex) : StandardTwoSimplex
|
||||
where
|
||||
x := a.y
|
||||
y := a.x
|
||||
z := a.z
|
||||
x_nonneg := a.y_nonneg
|
||||
y_nonneg := a.x_nonneg
|
||||
z_nonneg := a.z_nonneg
|
||||
sum_eq := by rw [add_comm a.y a.x, a.sum_eq]
|
||||
|
||||
noncomputable section
|
||||
|
||||
def midpoint (a b : StandardTwoSimplex) : StandardTwoSimplex
|
||||
where
|
||||
x := (a.x + b.x) / 2
|
||||
y := (a.y + b.y) / 2
|
||||
z := (a.z + b.z) / 2
|
||||
x_nonneg := div_nonneg (add_nonneg a.x_nonneg b.x_nonneg) (by norm_num)
|
||||
y_nonneg := div_nonneg (add_nonneg a.y_nonneg b.y_nonneg) (by norm_num)
|
||||
z_nonneg := div_nonneg (add_nonneg a.z_nonneg b.z_nonneg) (by norm_num)
|
||||
sum_eq := by field_simp; linarith [a.sum_eq, b.sum_eq]
|
||||
|
||||
def weightedAverage (lambda : Real) (lambda_nonneg : 0 ≤ lambda) (lambda_le : lambda ≤ 1)
|
||||
(a b : StandardTwoSimplex) : StandardTwoSimplex :=
|
||||
sorry
|
||||
|
||||
end
|
||||
|
||||
end StandardTwoSimplex
|
||||
|
||||
open BigOperators
|
||||
|
||||
structure StandardSimplex (n : ℕ) where
|
||||
V : Fin n → ℝ
|
||||
NonNeg : ∀ i : Fin n, 0 ≤ V i
|
||||
sum_eq_one : (∑ i, V i) = 1
|
||||
|
||||
namespace StandardSimplex
|
||||
|
||||
def midpoint (n : ℕ) (a b : StandardSimplex n) : StandardSimplex n
|
||||
where
|
||||
V i := (a.V i + b.V i) / 2
|
||||
NonNeg := by
|
||||
intro i
|
||||
apply div_nonneg
|
||||
· linarith [a.NonNeg i, b.NonNeg i]
|
||||
norm_num
|
||||
sum_eq_one := by
|
||||
simp [div_eq_mul_inv, ← Finset.sum_mul, Finset.sum_add_distrib,
|
||||
a.sum_eq_one, b.sum_eq_one]
|
||||
field_simp
|
||||
|
||||
end StandardSimplex
|
||||
|
||||
structure IsLinear (f : ℝ → ℝ) where
|
||||
is_additive : ∀ x y, f (x + y) = f x + f y
|
||||
preserves_mul : ∀ x c, f (c * x) = c * f x
|
||||
|
||||
section
|
||||
variable (f : ℝ → ℝ) (linf : IsLinear f)
|
||||
|
||||
#check linf.is_additive
|
||||
#check linf.preserves_mul
|
||||
|
||||
end
|
||||
|
||||
def Point'' :=
|
||||
ℝ × ℝ × ℝ
|
||||
|
||||
def IsLinear' (f : ℝ → ℝ) :=
|
||||
(∀ x y, f (x + y) = f x + f y) ∧ ∀ x c, f (c * x) = c * f x
|
||||
|
||||
def PReal :=
|
||||
{ y : ℝ // 0 < y }
|
||||
|
||||
section
|
||||
variable (x : PReal)
|
||||
|
||||
#check x.val
|
||||
#check x.property
|
||||
#check x.1
|
||||
#check x.2
|
||||
|
||||
end
|
||||
|
||||
def StandardTwoSimplex' :=
|
||||
{ p : ℝ × ℝ × ℝ // 0 ≤ p.1 ∧ 0 ≤ p.2.1 ∧ 0 ≤ p.2.2 ∧ p.1 + p.2.1 + p.2.2 = 1 }
|
||||
|
||||
def StandardSimplex' (n : ℕ) :=
|
||||
{ v : Fin n → ℝ // (∀ i : Fin n, 0 ≤ v i) ∧ (∑ i, v i) = 1 }
|
||||
|
||||
def StdSimplex := Σ n : ℕ, StandardSimplex n
|
||||
|
||||
section
|
||||
variable (s : StdSimplex)
|
||||
|
||||
#check s.fst
|
||||
#check s.snd
|
||||
|
||||
#check s.1
|
||||
#check s.2
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C06S02
|
||||
|
||||
structure Group₁ (α : Type*) where
|
||||
mul : α → α → α
|
||||
one : α
|
||||
inv : α → α
|
||||
mul_assoc : ∀ x y z : α, mul (mul x y) z = mul x (mul y z)
|
||||
mul_one : ∀ x : α, mul x one = x
|
||||
one_mul : ∀ x : α, mul one x = x
|
||||
mul_left_inv : ∀ x : α, mul (inv x) x = one
|
||||
|
||||
structure Group₁Cat where
|
||||
α : Type*
|
||||
str : Group₁ α
|
||||
|
||||
section
|
||||
variable (α β γ : Type*)
|
||||
variable (f : α ≃ β) (g : β ≃ γ)
|
||||
|
||||
#check Equiv α β
|
||||
#check (f.toFun : α → β)
|
||||
#check (f.invFun : β → α)
|
||||
#check (f.right_inv : ∀ x : β, f (f.invFun x) = x)
|
||||
#check (f.left_inv : ∀ x : α, f.invFun (f x) = x)
|
||||
#check (Equiv.refl α : α ≃ α)
|
||||
#check (f.symm : β ≃ α)
|
||||
#check (f.trans g : α ≃ γ)
|
||||
|
||||
example (x : α) : (f.trans g).toFun x = g.toFun (f.toFun x) :=
|
||||
rfl
|
||||
|
||||
example (x : α) : (f.trans g) x = g (f x) :=
|
||||
rfl
|
||||
|
||||
example : (f.trans g : α → γ) = g ∘ f :=
|
||||
rfl
|
||||
|
||||
end
|
||||
|
||||
example (α : Type*) : Equiv.Perm α = (α ≃ α) :=
|
||||
rfl
|
||||
|
||||
def permGroup {α : Type*} : Group₁ (Equiv.Perm α)
|
||||
where
|
||||
mul f g := Equiv.trans g f
|
||||
one := Equiv.refl α
|
||||
inv := Equiv.symm
|
||||
mul_assoc f g h := (Equiv.trans_assoc _ _ _).symm
|
||||
one_mul := Equiv.trans_refl
|
||||
mul_one := Equiv.refl_trans
|
||||
mul_left_inv := Equiv.self_trans_symm
|
||||
|
||||
structure AddGroup₁ (α : Type*) where
|
||||
(add : α → α → α)
|
||||
-- fill in the rest
|
||||
@[ext]
|
||||
structure Point where
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
|
||||
namespace Point
|
||||
|
||||
def add (a b : Point) : Point :=
|
||||
⟨a.x + b.x, a.y + b.y, a.z + b.z⟩
|
||||
|
||||
def neg (a : Point) : Point := sorry
|
||||
|
||||
def zero : Point := sorry
|
||||
|
||||
def addGroupPoint : AddGroup₁ Point := sorry
|
||||
|
||||
end Point
|
||||
|
||||
section
|
||||
variable {α : Type*} (f g : Equiv.Perm α) (n : ℕ)
|
||||
|
||||
#check f * g
|
||||
#check mul_assoc f g g⁻¹
|
||||
|
||||
-- group power, defined for any group
|
||||
#check g ^ n
|
||||
|
||||
example : f * g * g⁻¹ = f := by rw [mul_assoc, mul_right_inv, mul_one]
|
||||
|
||||
example : f * g * g⁻¹ = f :=
|
||||
mul_inv_cancel_right f g
|
||||
|
||||
example {α : Type*} (f g : Equiv.Perm α) : g.symm.trans (g.trans f) = f :=
|
||||
mul_inv_cancel_right f g
|
||||
|
||||
end
|
||||
|
||||
class Group₂ (α : Type*) where
|
||||
mul : α → α → α
|
||||
one : α
|
||||
inv : α → α
|
||||
mul_assoc : ∀ x y z : α, mul (mul x y) z = mul x (mul y z)
|
||||
mul_one : ∀ x : α, mul x one = x
|
||||
one_mul : ∀ x : α, mul one x = x
|
||||
mul_left_inv : ∀ x : α, mul (inv x) x = one
|
||||
|
||||
instance {α : Type*} : Group₂ (Equiv.Perm α) where
|
||||
mul f g := Equiv.trans g f
|
||||
one := Equiv.refl α
|
||||
inv := Equiv.symm
|
||||
mul_assoc f g h := (Equiv.trans_assoc _ _ _).symm
|
||||
one_mul := Equiv.trans_refl
|
||||
mul_one := Equiv.refl_trans
|
||||
mul_left_inv := Equiv.self_trans_symm
|
||||
|
||||
#check Group₂.mul
|
||||
|
||||
def mySquare {α : Type*} [Group₂ α] (x : α) :=
|
||||
Group₂.mul x x
|
||||
|
||||
#check mySquare
|
||||
|
||||
section
|
||||
variable {β : Type*} (f g : Equiv.Perm β)
|
||||
|
||||
example : Group₂.mul f g = g.trans f :=
|
||||
rfl
|
||||
|
||||
example : mySquare f = f.trans f :=
|
||||
rfl
|
||||
|
||||
end
|
||||
|
||||
instance : Inhabited Point where default := ⟨0, 0, 0⟩
|
||||
|
||||
#check (default : Point)
|
||||
|
||||
example : ([] : List Point).headI = default :=
|
||||
rfl
|
||||
|
||||
instance : Add Point where add := Point.add
|
||||
|
||||
section
|
||||
variable (x y : Point)
|
||||
|
||||
#check x + y
|
||||
|
||||
example : x + y = Point.add x y :=
|
||||
rfl
|
||||
|
||||
end
|
||||
|
||||
instance hasMulGroup₂ {α : Type*} [Group₂ α] : Mul α :=
|
||||
⟨Group₂.mul⟩
|
||||
|
||||
instance hasOneGroup₂ {α : Type*} [Group₂ α] : One α :=
|
||||
⟨Group₂.one⟩
|
||||
|
||||
instance hasInvGroup₂ {α : Type*} [Group₂ α] : Inv α :=
|
||||
⟨Group₂.inv⟩
|
||||
|
||||
section
|
||||
variable {α : Type*} (f g : Equiv.Perm α)
|
||||
|
||||
#check f * 1 * g⁻¹
|
||||
|
||||
def foo : f * 1 * g⁻¹ = g.symm.trans ((Equiv.refl α).trans f) :=
|
||||
rfl
|
||||
|
||||
end
|
||||
|
||||
class AddGroup₂ (α : Type*) where
|
||||
add : α → α → α
|
||||
-- fill in the rest
|
|
@ -0,0 +1,273 @@
|
|||
import Mathlib.Data.Int.Basic
|
||||
import Mathlib.Algebra.EuclideanDomain.Basic
|
||||
import Mathlib.RingTheory.PrincipalIdealDomain
|
||||
import MIL.Common
|
||||
|
||||
@[ext]
|
||||
structure gaussInt where
|
||||
re : ℤ
|
||||
im : ℤ
|
||||
|
||||
namespace gaussInt
|
||||
|
||||
instance : Zero gaussInt :=
|
||||
⟨⟨0, 0⟩⟩
|
||||
|
||||
instance : One gaussInt :=
|
||||
⟨⟨1, 0⟩⟩
|
||||
|
||||
instance : Add gaussInt :=
|
||||
⟨fun x y ↦ ⟨x.re + y.re, x.im + y.im⟩⟩
|
||||
|
||||
instance : Neg gaussInt :=
|
||||
⟨fun x ↦ ⟨-x.re, -x.im⟩⟩
|
||||
|
||||
instance : Mul gaussInt :=
|
||||
⟨fun x y ↦ ⟨x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re⟩⟩
|
||||
|
||||
theorem zero_def : (0 : gaussInt) = ⟨0, 0⟩ :=
|
||||
rfl
|
||||
|
||||
theorem one_def : (1 : gaussInt) = ⟨1, 0⟩ :=
|
||||
rfl
|
||||
|
||||
theorem add_def (x y : gaussInt) : x + y = ⟨x.re + y.re, x.im + y.im⟩ :=
|
||||
rfl
|
||||
|
||||
theorem neg_def (x : gaussInt) : -x = ⟨-x.re, -x.im⟩ :=
|
||||
rfl
|
||||
|
||||
theorem mul_def (x y : gaussInt) :
|
||||
x * y = ⟨x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re⟩ :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem zero_re : (0 : gaussInt).re = 0 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem zero_im : (0 : gaussInt).im = 0 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem one_re : (1 : gaussInt).re = 1 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem one_im : (1 : gaussInt).im = 0 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem add_re (x y : gaussInt) : (x + y).re = x.re + y.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem add_im (x y : gaussInt) : (x + y).im = x.im + y.im :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem neg_re (x : gaussInt) : (-x).re = -x.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem neg_im (x : gaussInt) : (-x).im = -x.im :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem mul_re (x y : gaussInt) : (x * y).re = x.re * y.re - x.im * y.im :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem mul_im (x y : gaussInt) : (x * y).im = x.re * y.im + x.im * y.re :=
|
||||
rfl
|
||||
|
||||
instance instCommRing : CommRing gaussInt where
|
||||
zero := 0
|
||||
one := 1
|
||||
add := (· + ·)
|
||||
neg x := -x
|
||||
mul := (· * ·)
|
||||
add_assoc := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
zero_add := by
|
||||
intro
|
||||
ext <;> simp
|
||||
add_zero := by
|
||||
intro
|
||||
ext <;> simp
|
||||
add_left_neg := by
|
||||
intro
|
||||
ext <;> simp
|
||||
add_comm := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
mul_assoc := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
one_mul := by
|
||||
intro
|
||||
ext <;> simp
|
||||
mul_one := by
|
||||
intro
|
||||
ext <;> simp
|
||||
left_distrib := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
right_distrib := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
mul_comm := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
zero_mul := sorry
|
||||
mul_zero := sorry
|
||||
|
||||
@[simp]
|
||||
theorem sub_re (x y : gaussInt) : (x - y).re = x.re - y.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem sub_im (x y : gaussInt) : (x - y).im = x.im - y.im :=
|
||||
rfl
|
||||
|
||||
instance : Nontrivial gaussInt := by
|
||||
use 0, 1
|
||||
rw [Ne, gaussInt.ext_iff]
|
||||
simp
|
||||
|
||||
end gaussInt
|
||||
|
||||
example (a b : ℤ) : a = b * (a / b) + a % b :=
|
||||
Eq.symm (Int.ediv_add_emod a b)
|
||||
|
||||
example (a b : ℤ) : b ≠ 0 → 0 ≤ a % b :=
|
||||
Int.emod_nonneg a
|
||||
|
||||
example (a b : ℤ) : b ≠ 0 → a % b < |b| :=
|
||||
Int.emod_lt a
|
||||
|
||||
namespace Int
|
||||
|
||||
def div' (a b : ℤ) :=
|
||||
(a + b / 2) / b
|
||||
|
||||
def mod' (a b : ℤ) :=
|
||||
(a + b / 2) % b - b / 2
|
||||
|
||||
theorem div'_add_mod' (a b : ℤ) : b * div' a b + mod' a b = a := by
|
||||
rw [div', mod']
|
||||
linarith [Int.ediv_add_emod (a + b / 2) b]
|
||||
|
||||
theorem abs_mod'_le (a b : ℤ) (h : 0 < b) : |mod' a b| ≤ b / 2 := by
|
||||
rw [mod', abs_le]
|
||||
constructor
|
||||
· linarith [Int.emod_nonneg (a + b / 2) h.ne']
|
||||
have := Int.emod_lt_of_pos (a + b / 2) h
|
||||
have := Int.ediv_add_emod b 2
|
||||
have := Int.emod_lt_of_pos b zero_lt_two
|
||||
revert this; intro this -- FIXME, this should not be needed
|
||||
linarith
|
||||
|
||||
theorem mod'_eq (a b : ℤ) : mod' a b = a - b * div' a b := by linarith [div'_add_mod' a b]
|
||||
|
||||
end Int
|
||||
|
||||
theorem sq_add_sq_eq_zero {α : Type*} [LinearOrderedRing α] (x y : α) :
|
||||
x ^ 2 + y ^ 2 = 0 ↔ x = 0 ∧ y = 0 := by
|
||||
sorry
|
||||
namespace gaussInt
|
||||
|
||||
def norm (x : gaussInt) :=
|
||||
x.re ^ 2 + x.im ^ 2
|
||||
|
||||
@[simp]
|
||||
theorem norm_nonneg (x : gaussInt) : 0 ≤ norm x := by
|
||||
sorry
|
||||
theorem norm_eq_zero (x : gaussInt) : norm x = 0 ↔ x = 0 := by
|
||||
sorry
|
||||
theorem norm_pos (x : gaussInt) : 0 < norm x ↔ x ≠ 0 := by
|
||||
sorry
|
||||
theorem norm_mul (x y : gaussInt) : norm (x * y) = norm x * norm y := by
|
||||
sorry
|
||||
def conj (x : gaussInt) : gaussInt :=
|
||||
⟨x.re, -x.im⟩
|
||||
|
||||
@[simp]
|
||||
theorem conj_re (x : gaussInt) : (conj x).re = x.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem conj_im (x : gaussInt) : (conj x).im = -x.im :=
|
||||
rfl
|
||||
|
||||
theorem norm_conj (x : gaussInt) : norm (conj x) = norm x := by simp [norm]
|
||||
|
||||
instance : Div gaussInt :=
|
||||
⟨fun x y ↦ ⟨Int.div' (x * conj y).re (norm y), Int.div' (x * conj y).im (norm y)⟩⟩
|
||||
|
||||
instance : Mod gaussInt :=
|
||||
⟨fun x y ↦ x - y * (x / y)⟩
|
||||
|
||||
theorem div_def (x y : gaussInt) :
|
||||
x / y = ⟨Int.div' (x * conj y).re (norm y), Int.div' (x * conj y).im (norm y)⟩ :=
|
||||
rfl
|
||||
|
||||
theorem mod_def (x y : gaussInt) : x % y = x - y * (x / y) :=
|
||||
rfl
|
||||
|
||||
theorem norm_mod_lt (x : gaussInt) {y : gaussInt} (hy : y ≠ 0) :
|
||||
(x % y).norm < y.norm := by
|
||||
have norm_y_pos : 0 < norm y := by rwa [norm_pos]
|
||||
have H1 : x % y * conj y = ⟨Int.mod' (x * conj y).re (norm y), Int.mod' (x * conj y).im (norm y)⟩
|
||||
· ext <;> simp [Int.mod'_eq, mod_def, div_def, norm] <;> ring
|
||||
have H2 : norm (x % y) * norm y ≤ norm y / 2 * norm y
|
||||
· calc
|
||||
norm (x % y) * norm y = norm (x % y * conj y) := by simp only [norm_mul, norm_conj]
|
||||
_ = |Int.mod' (x.re * y.re + x.im * y.im) (norm y)| ^ 2
|
||||
+ |Int.mod' (-(x.re * y.im) + x.im * y.re) (norm y)| ^ 2 := by simp [H1, norm, sq_abs]
|
||||
_ ≤ (y.norm / 2) ^ 2 + (y.norm / 2) ^ 2 := by gcongr <;> apply Int.abs_mod'_le _ _ norm_y_pos
|
||||
_ = norm y / 2 * (norm y / 2 * 2) := by ring
|
||||
_ ≤ norm y / 2 * norm y := by gcongr; apply Int.ediv_mul_le; norm_num
|
||||
calc norm (x % y) ≤ norm y / 2 := le_of_mul_le_mul_right H2 norm_y_pos
|
||||
_ < norm y := by
|
||||
apply Int.ediv_lt_of_lt_mul
|
||||
· norm_num
|
||||
· linarith
|
||||
|
||||
theorem coe_natAbs_norm (x : gaussInt) : (x.norm.natAbs : ℤ) = x.norm :=
|
||||
Int.natAbs_of_nonneg (norm_nonneg _)
|
||||
|
||||
theorem natAbs_norm_mod_lt (x y : gaussInt) (hy : y ≠ 0) :
|
||||
(x % y).norm.natAbs < y.norm.natAbs := by
|
||||
apply Int.ofNat_lt.1
|
||||
simp only [Int.coe_natAbs, abs_of_nonneg, norm_nonneg]
|
||||
apply norm_mod_lt x hy
|
||||
|
||||
theorem not_norm_mul_left_lt_norm (x : gaussInt) {y : gaussInt} (hy : y ≠ 0) :
|
||||
¬(norm (x * y)).natAbs < (norm x).natAbs := by
|
||||
apply not_lt_of_ge
|
||||
rw [norm_mul, Int.natAbs_mul]
|
||||
apply le_mul_of_one_le_right (Nat.zero_le _)
|
||||
apply Int.ofNat_le.1
|
||||
rw [coe_natAbs_norm]
|
||||
exact Int.add_one_le_of_lt ((norm_pos _).mpr hy)
|
||||
|
||||
instance : EuclideanDomain gaussInt :=
|
||||
{ gaussInt.instCommRing with
|
||||
quotient := (· / ·)
|
||||
remainder := (· % ·)
|
||||
quotient_mul_add_remainder_eq :=
|
||||
fun x y ↦ by simp only; rw [mod_def, add_comm, sub_add_cancel]
|
||||
quotient_zero := fun x ↦ by
|
||||
simp [div_def, norm, Int.div']
|
||||
rfl
|
||||
r := (measure (Int.natAbs ∘ norm)).1
|
||||
r_wellFounded := (measure (Int.natAbs ∘ norm)).2
|
||||
remainder_lt := natAbs_norm_mod_lt
|
||||
mul_left_not_lt := not_norm_mul_left_lt_norm }
|
||||
|
||||
example (x : gaussInt) : Irreducible x ↔ Prime x :=
|
||||
PrincipalIdealRing.irreducible_iff_prime
|
||||
|
||||
end gaussInt
|
|
@ -0,0 +1,100 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Algebra.BigOperators.Ring
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C06S01
|
||||
noncomputable section
|
||||
|
||||
@[ext]
|
||||
structure Point where
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
|
||||
namespace Point
|
||||
|
||||
def add (a b : Point) : Point :=
|
||||
⟨a.x + b.x, a.y + b.y, a.z + b.z⟩
|
||||
|
||||
protected theorem add_assoc (a b c : Point) : (a.add b).add c = a.add (b.add c) := by
|
||||
simp [add, add_assoc]
|
||||
|
||||
def smul (r : ℝ) (a : Point) : Point :=
|
||||
⟨r * a.x, r * a.y, r * a.z⟩
|
||||
|
||||
theorem smul_distrib (r : ℝ) (a b : Point) :
|
||||
(smul r a).add (smul r b) = smul r (a.add b) := by
|
||||
simp [add, smul, mul_add]
|
||||
|
||||
end Point
|
||||
|
||||
structure StandardTwoSimplex where
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
x_nonneg : 0 ≤ x
|
||||
y_nonneg : 0 ≤ y
|
||||
z_nonneg : 0 ≤ z
|
||||
sum_eq : x + y + z = 1
|
||||
|
||||
namespace StandardTwoSimplex
|
||||
|
||||
noncomputable section
|
||||
|
||||
def weightedAverage (lambda : Real) (lambda_nonneg : 0 ≤ lambda) (lambda_le : lambda ≤ 1)
|
||||
(a b : StandardTwoSimplex) : StandardTwoSimplex
|
||||
where
|
||||
x := lambda * a.x + (1 - lambda) * b.x
|
||||
y := lambda * a.y + (1 - lambda) * b.y
|
||||
z := lambda * a.z + (1 - lambda) * b.z
|
||||
x_nonneg := add_nonneg (mul_nonneg lambda_nonneg a.x_nonneg) (mul_nonneg (by linarith) b.x_nonneg)
|
||||
y_nonneg := add_nonneg (mul_nonneg lambda_nonneg a.y_nonneg) (mul_nonneg (by linarith) b.y_nonneg)
|
||||
z_nonneg := add_nonneg (mul_nonneg lambda_nonneg a.z_nonneg) (mul_nonneg (by linarith) b.z_nonneg)
|
||||
sum_eq := by
|
||||
trans (a.x + a.y + a.z) * lambda + (b.x + b.y + b.z) * (1 - lambda)
|
||||
· ring
|
||||
simp [a.sum_eq, b.sum_eq]
|
||||
|
||||
end
|
||||
|
||||
end StandardTwoSimplex
|
||||
|
||||
open BigOperators
|
||||
|
||||
structure StandardSimplex (n : ℕ) where
|
||||
V : Fin n → ℝ
|
||||
NonNeg : ∀ i : Fin n, 0 ≤ V i
|
||||
sum_eq_one : (∑ i, V i) = 1
|
||||
|
||||
namespace StandardSimplex
|
||||
|
||||
def midpoint (n : ℕ) (a b : StandardSimplex n) : StandardSimplex n
|
||||
where
|
||||
V i := (a.V i + b.V i) / 2
|
||||
NonNeg := by
|
||||
intro i
|
||||
apply div_nonneg
|
||||
· linarith [a.NonNeg i, b.NonNeg i]
|
||||
norm_num
|
||||
sum_eq_one := by
|
||||
simp [div_eq_mul_inv, ← Finset.sum_mul, Finset.sum_add_distrib,
|
||||
a.sum_eq_one, b.sum_eq_one]
|
||||
field_simp
|
||||
|
||||
end StandardSimplex
|
||||
|
||||
namespace StandardSimplex
|
||||
|
||||
def weightedAverage {n : ℕ} (lambda : Real) (lambda_nonneg : 0 ≤ lambda) (lambda_le : lambda ≤ 1)
|
||||
(a b : StandardSimplex n) : StandardSimplex n
|
||||
where
|
||||
V i := lambda * a.V i + (1 - lambda) * b.V i
|
||||
NonNeg i :=
|
||||
add_nonneg (mul_nonneg lambda_nonneg (a.NonNeg i)) (mul_nonneg (by linarith) (b.NonNeg i))
|
||||
sum_eq_one := by
|
||||
trans (lambda * ∑ i, a.V i) + (1 - lambda) * ∑ i, b.V i
|
||||
· rw [Finset.sum_add_distrib, Finset.mul_sum, Finset.mul_sum]
|
||||
simp [a.sum_eq_one, b.sum_eq_one]
|
||||
|
||||
end StandardSimplex
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
namespace C06S02
|
||||
|
||||
structure AddGroup₁ (α : Type*) where
|
||||
add : α → α → α
|
||||
zero : α
|
||||
neg : α → α
|
||||
add_assoc : ∀ x y z : α, add (add x y) z = add x (add y z)
|
||||
add_zero : ∀ x : α, add x zero = x
|
||||
zero_add : ∀ x : α, add x zero = x
|
||||
add_left_neg : ∀ x : α, add (neg x) x = zero
|
||||
|
||||
@[ext]
|
||||
structure Point where
|
||||
x : ℝ
|
||||
y : ℝ
|
||||
z : ℝ
|
||||
|
||||
namespace Point
|
||||
|
||||
def add (a b : Point) : Point :=
|
||||
⟨a.x + b.x, a.y + b.y, a.z + b.z⟩
|
||||
|
||||
def neg (a : Point) : Point :=
|
||||
⟨-a.x, -a.y, -a.z⟩
|
||||
|
||||
def zero : Point :=
|
||||
⟨0, 0, 0⟩
|
||||
|
||||
def addGroupPoint : AddGroup₁ Point where
|
||||
add := Point.add
|
||||
zero := Point.zero
|
||||
neg := Point.neg
|
||||
add_assoc := by simp [Point.add, add_assoc]
|
||||
add_zero := by simp [Point.add, Point.zero]
|
||||
zero_add := by simp [Point.add, Point.zero]
|
||||
add_left_neg := by simp [Point.add, Point.neg, Point.zero]
|
||||
|
||||
end Point
|
||||
|
||||
class AddGroup₂ (α : Type*) where
|
||||
add : α → α → α
|
||||
zero : α
|
||||
neg : α → α
|
||||
add_assoc : ∀ x y z : α, add (add x y) z = add x (add y z)
|
||||
add_zero : ∀ x : α, add x zero = x
|
||||
zero_add : ∀ x : α, add x zero = x
|
||||
add_left_neg : ∀ x : α, add (neg x) x = zero
|
||||
|
||||
instance hasAddAddGroup₂ {α : Type*} [AddGroup₂ α] : Add α :=
|
||||
⟨AddGroup₂.add⟩
|
||||
|
||||
instance hasZeroAddGroup₂ {α : Type*} [AddGroup₂ α] : Zero α :=
|
||||
⟨AddGroup₂.zero⟩
|
||||
|
||||
instance hasNegAddGroup₂ {α : Type*} [AddGroup₂ α] : Neg α :=
|
||||
⟨AddGroup₂.neg⟩
|
||||
|
||||
instance : AddGroup₂ Point where
|
||||
add := Point.add
|
||||
zero := Point.zero
|
||||
neg := Point.neg
|
||||
add_assoc := by simp [Point.add, add_assoc]
|
||||
add_zero := by simp [Point.add, Point.zero]
|
||||
zero_add := by simp [Point.add, Point.zero]
|
||||
add_left_neg := by simp [Point.add, Point.neg, Point.zero]
|
||||
|
||||
section
|
||||
variable (x y : Point)
|
||||
|
||||
#check x + -y + 0
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
import Mathlib.Data.Int.Basic
|
||||
import Mathlib.Algebra.EuclideanDomain.Basic
|
||||
import Mathlib.RingTheory.PrincipalIdealDomain
|
||||
import MIL.Common
|
||||
|
||||
@[ext]
|
||||
structure gaussInt where
|
||||
re : ℤ
|
||||
im : ℤ
|
||||
|
||||
namespace gaussInt
|
||||
|
||||
instance : Zero gaussInt :=
|
||||
⟨⟨0, 0⟩⟩
|
||||
|
||||
instance : One gaussInt :=
|
||||
⟨⟨1, 0⟩⟩
|
||||
|
||||
instance : Add gaussInt :=
|
||||
⟨fun x y ↦ ⟨x.re + y.re, x.im + y.im⟩⟩
|
||||
|
||||
instance : Neg gaussInt :=
|
||||
⟨fun x ↦ ⟨-x.re, -x.im⟩⟩
|
||||
|
||||
instance : Mul gaussInt :=
|
||||
⟨fun x y ↦ ⟨x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re⟩⟩
|
||||
|
||||
theorem zero_def : (0 : gaussInt) = ⟨0, 0⟩ :=
|
||||
rfl
|
||||
|
||||
theorem one_def : (1 : gaussInt) = ⟨1, 0⟩ :=
|
||||
rfl
|
||||
|
||||
theorem add_def (x y : gaussInt) : x + y = ⟨x.re + y.re, x.im + y.im⟩ :=
|
||||
rfl
|
||||
|
||||
theorem neg_def (x : gaussInt) : -x = ⟨-x.re, -x.im⟩ :=
|
||||
rfl
|
||||
|
||||
theorem mul_def (x y : gaussInt) :
|
||||
x * y = ⟨x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re⟩ :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem zero_re : (0 : gaussInt).re = 0 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem zero_im : (0 : gaussInt).im = 0 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem one_re : (1 : gaussInt).re = 1 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem one_im : (1 : gaussInt).im = 0 :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem add_re (x y : gaussInt) : (x + y).re = x.re + y.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem add_im (x y : gaussInt) : (x + y).im = x.im + y.im :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem neg_re (x : gaussInt) : (-x).re = -x.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem neg_im (x : gaussInt) : (-x).im = -x.im :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem mul_re (x y : gaussInt) : (x * y).re = x.re * y.re - x.im * y.im :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem mul_im (x y : gaussInt) : (x * y).im = x.re * y.im + x.im * y.re :=
|
||||
rfl
|
||||
|
||||
instance instCommRing : CommRing gaussInt where
|
||||
zero := 0
|
||||
one := 1
|
||||
add := (· + ·)
|
||||
neg x := -x
|
||||
mul := (· * ·)
|
||||
add_assoc := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
zero_add := by
|
||||
intro
|
||||
ext <;> simp
|
||||
add_zero := by
|
||||
intro
|
||||
ext <;> simp
|
||||
add_left_neg := by
|
||||
intro
|
||||
ext <;> simp
|
||||
add_comm := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
mul_assoc := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
one_mul := by
|
||||
intro
|
||||
ext <;> simp
|
||||
mul_one := by
|
||||
intro
|
||||
ext <;> simp
|
||||
left_distrib := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
right_distrib := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
mul_comm := by
|
||||
intros
|
||||
ext <;> simp <;> ring
|
||||
zero_mul := sorry
|
||||
mul_zero := sorry
|
||||
|
||||
@[simp]
|
||||
theorem sub_re (x y : gaussInt) : (x - y).re = x.re - y.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem sub_im (x y : gaussInt) : (x - y).im = x.im - y.im :=
|
||||
rfl
|
||||
|
||||
instance : Nontrivial gaussInt := by
|
||||
use 0, 1
|
||||
rw [Ne, gaussInt.ext_iff]
|
||||
simp
|
||||
|
||||
end gaussInt
|
||||
|
||||
namespace Int
|
||||
|
||||
def div' (a b : ℤ) :=
|
||||
(a + b / 2) / b
|
||||
|
||||
def mod' (a b : ℤ) :=
|
||||
(a + b / 2) % b - b / 2
|
||||
|
||||
theorem div'_add_mod' (a b : ℤ) : b * div' a b + mod' a b = a := by
|
||||
rw [div', mod']
|
||||
linarith [Int.ediv_add_emod (a + b / 2) b]
|
||||
|
||||
theorem abs_mod'_le (a b : ℤ) (h : 0 < b) : |mod' a b| ≤ b / 2 := by
|
||||
rw [mod', abs_le]
|
||||
constructor
|
||||
· linarith [Int.emod_nonneg (a + b / 2) h.ne']
|
||||
have := Int.emod_lt_of_pos (a + b / 2) h
|
||||
have := Int.ediv_add_emod b 2
|
||||
have := Int.emod_lt_of_pos b zero_lt_two
|
||||
revert this; intro this -- FIXME, this should not be needed
|
||||
linarith
|
||||
|
||||
theorem mod'_eq (a b : ℤ) : mod' a b = a - b * div' a b := by linarith [div'_add_mod' a b]
|
||||
|
||||
end Int
|
||||
|
||||
private theorem aux {α : Type*} [LinearOrderedRing α] {x y : α} (h : x ^ 2 + y ^ 2 = 0) : x = 0 :=
|
||||
haveI h' : x ^ 2 = 0 := by
|
||||
apply le_antisymm _ (sq_nonneg x)
|
||||
rw [← h]
|
||||
apply le_add_of_nonneg_right (sq_nonneg y)
|
||||
pow_eq_zero h'
|
||||
|
||||
theorem sq_add_sq_eq_zero {α : Type*} [LinearOrderedRing α] (x y : α) :
|
||||
x ^ 2 + y ^ 2 = 0 ↔ x = 0 ∧ y = 0 := by
|
||||
constructor
|
||||
· intro h
|
||||
constructor
|
||||
· exact aux h
|
||||
rw [add_comm] at h
|
||||
exact aux h
|
||||
rintro ⟨rfl, rfl⟩
|
||||
norm_num
|
||||
|
||||
namespace gaussInt
|
||||
|
||||
def norm (x : gaussInt) :=
|
||||
x.re ^ 2 + x.im ^ 2
|
||||
|
||||
@[simp]
|
||||
theorem norm_nonneg (x : gaussInt) : 0 ≤ norm x := by
|
||||
apply add_nonneg <;>
|
||||
apply sq_nonneg
|
||||
|
||||
theorem norm_eq_zero (x : gaussInt) : norm x = 0 ↔ x = 0 := by
|
||||
rw [norm, sq_add_sq_eq_zero, gaussInt.ext_iff]
|
||||
rfl
|
||||
|
||||
theorem norm_pos (x : gaussInt) : 0 < norm x ↔ x ≠ 0 := by
|
||||
rw [lt_iff_le_and_ne, ne_comm, Ne, norm_eq_zero]
|
||||
simp [norm_nonneg]
|
||||
|
||||
theorem norm_mul (x y : gaussInt) : norm (x * y) = norm x * norm y := by
|
||||
simp [norm]
|
||||
ring
|
||||
|
||||
def conj (x : gaussInt) : gaussInt :=
|
||||
⟨x.re, -x.im⟩
|
||||
|
||||
@[simp]
|
||||
theorem conj_re (x : gaussInt) : (conj x).re = x.re :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem conj_im (x : gaussInt) : (conj x).im = -x.im :=
|
||||
rfl
|
||||
|
||||
theorem norm_conj (x : gaussInt) : norm (conj x) = norm x := by simp [norm]
|
||||
|
||||
instance : Div gaussInt :=
|
||||
⟨fun x y ↦ ⟨Int.div' (x * conj y).re (norm y), Int.div' (x * conj y).im (norm y)⟩⟩
|
||||
|
||||
instance : Mod gaussInt :=
|
||||
⟨fun x y ↦ x - y * (x / y)⟩
|
||||
|
||||
theorem div_def (x y : gaussInt) :
|
||||
x / y = ⟨Int.div' (x * conj y).re (norm y), Int.div' (x * conj y).im (norm y)⟩ :=
|
||||
rfl
|
||||
|
||||
theorem mod_def (x y : gaussInt) : x % y = x - y * (x / y) :=
|
||||
rfl
|
||||
|
||||
theorem norm_mod_lt (x : gaussInt) {y : gaussInt} (hy : y ≠ 0) :
|
||||
(x % y).norm < y.norm := by
|
||||
have norm_y_pos : 0 < norm y := by rwa [norm_pos]
|
||||
have H1 : x % y * conj y = ⟨Int.mod' (x * conj y).re (norm y), Int.mod' (x * conj y).im (norm y)⟩
|
||||
· ext <;> simp [Int.mod'_eq, mod_def, div_def, norm] <;> ring
|
||||
have H2 : norm (x % y) * norm y ≤ norm y / 2 * norm y
|
||||
· calc
|
||||
norm (x % y) * norm y = norm (x % y * conj y) := by simp only [norm_mul, norm_conj]
|
||||
_ = |Int.mod' (x.re * y.re + x.im * y.im) (norm y)| ^ 2
|
||||
+ |Int.mod' (-(x.re * y.im) + x.im * y.re) (norm y)| ^ 2 := by simp [H1, norm, sq_abs]
|
||||
_ ≤ (y.norm / 2) ^ 2 + (y.norm / 2) ^ 2 := by gcongr <;> apply Int.abs_mod'_le _ _ norm_y_pos
|
||||
_ = norm y / 2 * (norm y / 2 * 2) := by ring
|
||||
_ ≤ norm y / 2 * norm y := by gcongr; apply Int.ediv_mul_le; norm_num
|
||||
calc norm (x % y) ≤ norm y / 2 := le_of_mul_le_mul_right H2 norm_y_pos
|
||||
_ < norm y := by
|
||||
apply Int.ediv_lt_of_lt_mul
|
||||
· norm_num
|
||||
· linarith
|
||||
|
||||
theorem coe_natAbs_norm (x : gaussInt) : (x.norm.natAbs : ℤ) = x.norm :=
|
||||
Int.natAbs_of_nonneg (norm_nonneg _)
|
||||
|
||||
theorem natAbs_norm_mod_lt (x y : gaussInt) (hy : y ≠ 0) :
|
||||
(x % y).norm.natAbs < y.norm.natAbs := by
|
||||
apply Int.ofNat_lt.1
|
||||
simp only [Int.coe_natAbs, abs_of_nonneg, norm_nonneg]
|
||||
apply norm_mod_lt x hy
|
||||
|
||||
theorem not_norm_mul_left_lt_norm (x : gaussInt) {y : gaussInt} (hy : y ≠ 0) :
|
||||
¬(norm (x * y)).natAbs < (norm x).natAbs := by
|
||||
apply not_lt_of_ge
|
||||
rw [norm_mul, Int.natAbs_mul]
|
||||
apply le_mul_of_one_le_right (Nat.zero_le _)
|
||||
apply Int.ofNat_le.1
|
||||
rw [coe_natAbs_norm]
|
||||
exact Int.add_one_le_of_lt ((norm_pos _).mpr hy)
|
||||
|
||||
instance : EuclideanDomain gaussInt :=
|
||||
{ gaussInt.instCommRing with
|
||||
quotient := (· / ·)
|
||||
remainder := (· % ·)
|
||||
quotient_mul_add_remainder_eq :=
|
||||
fun x y ↦ by simp only; rw [mod_def, add_comm, sub_add_cancel]
|
||||
quotient_zero := fun x ↦ by
|
||||
simp [div_def, norm, Int.div']
|
||||
rfl
|
||||
r := (measure (Int.natAbs ∘ norm)).1
|
||||
r_wellFounded := (measure (Int.natAbs ∘ norm)).2
|
||||
remainder_lt := natAbs_norm_mod_lt
|
||||
mul_left_not_lt := not_norm_mul_left_lt_norm }
|
||||
|
||||
example (x : gaussInt) : Irreducible x ↔ Prime x :=
|
||||
PrincipalIdealRing.irreducible_iff_prime
|
||||
|
||||
end gaussInt
|
|
@ -0,0 +1,311 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Algebra.BigOperators.Ring
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
|
||||
class One₁ (α : Type) where
|
||||
/-- The element one -/
|
||||
one : α
|
||||
|
||||
|
||||
#check One₁.one -- One₁.one {α : Type} [self : One₁ α] : α
|
||||
|
||||
@[class] structure One₂ (α : Type) where
|
||||
/-- The element one -/
|
||||
one : α
|
||||
|
||||
#check One₂.one
|
||||
|
||||
|
||||
example (α : Type) [One₁ α] : α := One₁.one
|
||||
|
||||
example (α : Type) [One₁ α] := (One₁.one : α)
|
||||
|
||||
@[inherit_doc]
|
||||
notation "𝟙" => One₁.one
|
||||
|
||||
example {α : Type} [One₁ α] : α := 𝟙
|
||||
|
||||
example {α : Type} [One₁ α] : (𝟙 : α) = 𝟙 := rfl
|
||||
|
||||
|
||||
class Dia₁ (α : Type) where
|
||||
dia : α → α → α
|
||||
|
||||
infixl:70 " ⋄ " => Dia₁.dia
|
||||
|
||||
|
||||
class Semigroup₁ (α : Type) where
|
||||
toDia₁ : Dia₁ α
|
||||
/-- Diamond is associative -/
|
||||
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)
|
||||
|
||||
|
||||
attribute [instance] Semigroup₁.toDia₁
|
||||
|
||||
example {α : Type} [Semigroup₁ α] (a b : α) : α := a ⋄ b
|
||||
|
||||
|
||||
class Semigroup₂ (α : Type) extends Dia₁ α where
|
||||
/-- Diamond is associative -/
|
||||
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)
|
||||
|
||||
example {α : Type} [Semigroup₂ α] (a b : α) : α := a ⋄ b
|
||||
|
||||
class DiaOneClass₁ (α : Type) extends One₁ α, Dia₁ α where
|
||||
/-- One is a left neutral element for diamond. -/
|
||||
one_dia : ∀ a : α, 𝟙 ⋄ a = a
|
||||
/-- One is a right neutral element for diamond -/
|
||||
dia_one : ∀ a : α, a ⋄ 𝟙 = a
|
||||
|
||||
|
||||
|
||||
set_option trace.Meta.synthInstance true in
|
||||
example {α : Type} [DiaOneClass₁ α] (a b : α) : Prop := a ⋄ b = 𝟙
|
||||
|
||||
|
||||
class Monoid₁ (α : Type) extends Semigroup₁ α, DiaOneClass₁ α
|
||||
|
||||
|
||||
class Monoid₂ (α : Type) where
|
||||
toSemigroup₁ : Semigroup₁ α
|
||||
toDiaOneClass₁ : DiaOneClass₁ α
|
||||
|
||||
|
||||
example {α : Type} [Monoid₁ α] :
|
||||
(Monoid₁.toSemigroup₁.toDia₁.dia : α → α → α) = Monoid₁.toDiaOneClass₁.toDia₁.dia := rfl
|
||||
|
||||
|
||||
/- Monoid₂.mk {α : Type} (toSemigroup₁ : Semigroup₁ α) (toDiaOneClass₁ : DiaOneClass₁ α) : Monoid₂ α -/
|
||||
#check Monoid₂.mk
|
||||
|
||||
/- Monoid₁.mk {α : Type} [toSemigroup₁ : Semigroup₁ α] [toOne₁ : One₁ α] (one_dia : ∀ (a : α), 𝟙 ⋄ a = a) (dia_one : ∀ (a : α), a ⋄ 𝟙 = a) : Monoid₁ α -/
|
||||
#check Monoid₁.mk
|
||||
|
||||
|
||||
#check Monoid₁.toSemigroup₁
|
||||
#check Monoid₁.toDiaOneClass₁
|
||||
|
||||
|
||||
class Inv₁ (α : Type) where
|
||||
/-- The inversion function -/
|
||||
inv : α → α
|
||||
|
||||
@[inherit_doc]
|
||||
postfix:max "⁻¹" => Inv₁.inv
|
||||
|
||||
class Group₁ (G : Type) extends Monoid₁ G, Inv G where
|
||||
inv_dia : ∀ a : G, a⁻¹ ⋄ a = 𝟙
|
||||
|
||||
|
||||
lemma left_inv_eq_right_inv₁ {M : Type} [Monoid₁ M] {a b c : M} (hba : b ⋄ a = 𝟙) (hac : a ⋄ c = 𝟙) : b = c := by
|
||||
rw [← DiaOneClass₁.one_dia c, ← hba, Semigroup₁.dia_assoc, hac, DiaOneClass₁.dia_one b]
|
||||
|
||||
|
||||
export DiaOneClass₁ (one_dia dia_one)
|
||||
export Semigroup₁ (dia_assoc)
|
||||
export Group₁ (inv_dia)
|
||||
|
||||
|
||||
example {M : Type} [Monoid₁ M] {a b c : M} (hba : b ⋄ a = 𝟙) (hac : a ⋄ c = 𝟙) : b = c := by
|
||||
rw [← one_dia c, ← hba, dia_assoc, hac, dia_one b]
|
||||
|
||||
|
||||
lemma inv_eq_of_dia [Group₁ G] {a b : G} (h : a ⋄ b = 𝟙) : a⁻¹ = b :=
|
||||
sorry
|
||||
|
||||
lemma dia_inv [Group₁ G] (a : G) : a ⋄ a⁻¹ = 𝟙 :=
|
||||
sorry
|
||||
|
||||
|
||||
|
||||
|
||||
class AddSemigroup₃ (α : Type) extends Add α where
|
||||
/-- Addition is associative -/
|
||||
add_assoc₃ : ∀ a b c : α, a + b + c = a + (b + c)
|
||||
|
||||
@[to_additive AddSemigroup₃]
|
||||
class Semigroup₃ (α : Type) extends Mul α where
|
||||
/-- Multiplication is associative -/
|
||||
mul_assoc₃ : ∀ a b c : α, a * b * c = a * (b * c)
|
||||
|
||||
class AddMonoid₃ (α : Type) extends AddSemigroup₃ α, AddZeroClass α
|
||||
|
||||
@[to_additive AddMonoid₃]
|
||||
class Monoid₃ (α : Type) extends Semigroup₃ α, MulOneClass α
|
||||
|
||||
attribute [to_additive existing] Monoid₃.toMulOneClass
|
||||
|
||||
export Semigroup₃ (mul_assoc₃)
|
||||
export AddSemigroup₃ (add_assoc₃)
|
||||
|
||||
whatsnew in
|
||||
@[to_additive]
|
||||
lemma left_inv_eq_right_inv' {M : Type} [Monoid₃ M] {a b c : M} (hba : b * a = 1) (hac : a * c = 1) : b = c := by
|
||||
rw [← one_mul c, ← hba, mul_assoc₃, hac, mul_one b]
|
||||
|
||||
#check left_neg_eq_right_neg'
|
||||
|
||||
class AddCommSemigroup₃ (α : Type) extends AddSemigroup₃ α where
|
||||
add_comm : ∀ a b : α, a + b = b + a
|
||||
|
||||
@[to_additive AddCommSemigroup₃]
|
||||
class CommSemigroup₃ (α : Type) extends Semigroup₃ α where
|
||||
mul_comm : ∀ a b : α, a * b = b * a
|
||||
|
||||
class AddCommMonoid₃ (α : Type) extends AddMonoid₃ α, AddCommSemigroup₃ α
|
||||
|
||||
@[to_additive AddCommMonoid₃]
|
||||
class CommMonoid₃ (α : Type) extends Monoid₃ α, CommSemigroup₃ α
|
||||
|
||||
class AddGroup₃ (G : Type) extends AddMonoid₃ G, Neg G where
|
||||
neg_add : ∀ a : G, -a + a = 0
|
||||
|
||||
@[to_additive AddGroup₃]
|
||||
class Group₃ (G : Type) extends Monoid₃ G, Inv G where
|
||||
inv_mul : ∀ a : G, a⁻¹ * a = 1
|
||||
|
||||
|
||||
attribute [simp] Group₃.inv_mul AddGroup₃.neg_add
|
||||
|
||||
|
||||
|
||||
@[to_additive]
|
||||
lemma inv_eq_of_mul [Group₃ G] {a b : G} (h : a * b = 1) : a⁻¹ = b :=
|
||||
sorry
|
||||
|
||||
|
||||
@[to_additive (attr := simp)]
|
||||
lemma Group₃.mul_inv {G : Type} [Group₃ G] {a : G} : a * a⁻¹ = 1 := by
|
||||
sorry
|
||||
|
||||
@[to_additive]
|
||||
lemma mul_left_cancel₃ {G : Type} [Group₃ G] {a b c : G} (h : a * b = a * c) : b = c := by
|
||||
sorry
|
||||
|
||||
@[to_additive]
|
||||
lemma mul_right_cancel₃ {G : Type} [Group₃ G] {a b c : G} (h : b*a = c*a) : b = c := by
|
||||
sorry
|
||||
|
||||
class AddCommGroup₃ (G : Type) extends AddGroup₃ G, AddCommMonoid₃ G
|
||||
|
||||
@[to_additive AddCommGroup₃]
|
||||
class CommGroup₃ (G : Type) extends Group₃ G, CommMonoid₃ G
|
||||
|
||||
|
||||
|
||||
class Ring₃ (R : Type) extends AddGroup₃ R, Monoid₃ R, MulZeroClass R where
|
||||
/-- Multiplication is left distributive over addition -/
|
||||
left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c
|
||||
/-- Multiplication is right distributive over addition -/
|
||||
right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c
|
||||
|
||||
instance {R : Type} [Ring₃ R] : AddCommGroup₃ R :=
|
||||
{ Ring₃.toAddGroup₃ with
|
||||
add_comm := by
|
||||
sorry }
|
||||
|
||||
instance : Ring₃ ℤ where
|
||||
add := (· + ·)
|
||||
add_assoc₃ := add_assoc
|
||||
zero := 0
|
||||
zero_add := by simp
|
||||
add_zero := by simp
|
||||
neg := (- ·)
|
||||
neg_add := by simp
|
||||
mul := (· * ·)
|
||||
mul_assoc₃ := mul_assoc
|
||||
one := 1
|
||||
one_mul := by simp
|
||||
mul_one := by simp
|
||||
zero_mul := by simp
|
||||
mul_zero := by simp
|
||||
left_distrib := Int.mul_add
|
||||
right_distrib := Int.add_mul
|
||||
|
||||
class LE₁ (α : Type) where
|
||||
/-- The Less-or-Equal relation. -/
|
||||
le : α → α → Prop
|
||||
|
||||
@[inherit_doc] infix:50 " ≤₁ " => LE₁.le
|
||||
|
||||
class Preorder₁ (α : Type)
|
||||
|
||||
class PartialOrder₁ (α : Type)
|
||||
|
||||
class OrderedCommMonoid₁ (α : Type)
|
||||
|
||||
instance : OrderedCommMonoid₁ ℕ where
|
||||
|
||||
class SMul₃ (α : Type) (β : Type) where
|
||||
/-- Scalar multiplication -/
|
||||
smul : α → β → β
|
||||
|
||||
infixr:73 " • " => SMul₃.smul
|
||||
|
||||
|
||||
class Module₁ (R : Type) [Ring₃ R] (M : Type) [AddCommGroup₃ M] extends SMul₃ R M where
|
||||
zero_smul : ∀ m : M, (0 : R) • m = 0
|
||||
one_smul : ∀ m : M, (1 : R) • m = m
|
||||
mul_smul : ∀ (a b : R) (m : M), (a * b) • m = a • b • m
|
||||
add_smul : ∀ (a b : R) (m : M), (a + b) • m = a • m + b • m
|
||||
smul_add : ∀ (a : R) (m n : M), a • (m + n) = a • m + a • n
|
||||
|
||||
instance selfModule (R : Type) [Ring₃ R] : Module₁ R R where
|
||||
smul := fun r s ↦ r*s
|
||||
zero_smul := zero_mul
|
||||
one_smul := one_mul
|
||||
mul_smul := mul_assoc₃
|
||||
add_smul := Ring₃.right_distrib
|
||||
smul_add := Ring₃.left_distrib
|
||||
|
||||
def nsmul₁ [Zero M] [Add M] : ℕ → M → M
|
||||
| 0, _ => 0
|
||||
| n + 1, a => a + nsmul₁ n a
|
||||
|
||||
def zsmul₁ {M : Type*} [Zero M] [Add M] [Neg M] : ℤ → M → M
|
||||
| Int.ofNat n, a => nsmul₁ n a
|
||||
| Int.negSucc n, a => -nsmul₁ n.succ a
|
||||
|
||||
instance abGrpModule (A : Type) [AddCommGroup₃ A] : Module₁ ℤ A where
|
||||
smul := zsmul₁
|
||||
zero_smul := sorry
|
||||
one_smul := sorry
|
||||
mul_smul := sorry
|
||||
add_smul := sorry
|
||||
smul_add := sorry
|
||||
|
||||
#synth Module₁ ℤ ℤ -- abGrpModule ℤ
|
||||
|
||||
|
||||
class AddMonoid₄ (M : Type) extends AddSemigroup₃ M, AddZeroClass M where
|
||||
/-- Multiplication by a natural number. -/
|
||||
nsmul : ℕ → M → M := nsmul₁
|
||||
/-- Multiplication by `(0 : ℕ)` gives `0`. -/
|
||||
nsmul_zero : ∀ x, nsmul 0 x = 0 := by intros; rfl
|
||||
/-- Multiplication by `(n + 1 : ℕ)` behaves as expected. -/
|
||||
nsmul_succ : ∀ (n : ℕ) (x), nsmul (n + 1) x = x + nsmul n x := by intros; rfl
|
||||
|
||||
instance mySMul {M : Type} [AddMonoid₄ M] : SMul ℕ M := ⟨AddMonoid₄.nsmul⟩
|
||||
|
||||
instance (M N : Type) [AddMonoid₄ M] [AddMonoid₄ N] : AddMonoid₄ (M × N) where
|
||||
add := fun p q ↦ (p.1 + q.1, p.2 + q.2)
|
||||
add_assoc₃ := fun a b c ↦ by ext <;> apply add_assoc₃
|
||||
zero := (0, 0)
|
||||
zero_add := fun a ↦ by ext <;> apply zero_add
|
||||
add_zero := fun a ↦ by ext <;> apply add_zero
|
||||
|
||||
instance : AddMonoid₄ ℤ where
|
||||
add := (· + ·)
|
||||
add_assoc₃ := Int.add_assoc
|
||||
zero := 0
|
||||
zero_add := Int.zero_add
|
||||
add_zero := Int.add_zero
|
||||
nsmul := fun n m ↦ (n : ℤ) * m
|
||||
nsmul_zero := Int.zero_mul
|
||||
nsmul_succ := fun n m ↦ show (n + 1 : ℤ) * m = m + n * m
|
||||
by rw [Int.add_mul, Int.add_comm, Int.one_mul]
|
||||
|
||||
example (n : ℕ) (m : ℤ) : SMul.smul (self := mySMul) n m = n * m := rfl
|
|
@ -0,0 +1,117 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Topology.Instances.Real
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
|
||||
def isMonoidHom₁ [Monoid G] [Monoid H] (f : G → H) : Prop :=
|
||||
f 1 = 1 ∧ ∀ g g', f (g * g') = f g * f g'
|
||||
structure isMonoidHom₂ [Monoid G] [Monoid H] (f : G → H) : Prop where
|
||||
map_one : f 1 = 1
|
||||
map_mul : ∀ g g', f (g * g') = f g * f g'
|
||||
example : Continuous (id : ℝ → ℝ) := continuous_id
|
||||
@[ext]
|
||||
structure MonoidHom₁ (G H : Type) [Monoid G] [Monoid H] where
|
||||
toFun : G → H
|
||||
map_one : toFun 1 = 1
|
||||
map_mul : ∀ g g', toFun (g * g') = toFun g * toFun g'
|
||||
|
||||
instance [Monoid G] [Monoid H] : CoeFun (MonoidHom₁ G H) (fun _ ↦ G → H) where
|
||||
coe := MonoidHom₁.toFun
|
||||
|
||||
attribute [coe] MonoidHom₁.toFun
|
||||
|
||||
|
||||
example [Monoid G] [Monoid H] (f : MonoidHom₁ G H) : f 1 = 1 := f.map_one
|
||||
|
||||
@[ext]
|
||||
structure AddMonoidHom₁ (G H : Type) [AddMonoid G] [AddMonoid H] where
|
||||
toFun : G → H
|
||||
map_zero : toFun 0 = 0
|
||||
map_add : ∀ g g', toFun (g + g') = toFun g + toFun g'
|
||||
|
||||
instance [AddMonoid G] [AddMonoid H] : CoeFun (AddMonoidHom₁ G H) (fun _ ↦ G → H) where
|
||||
coe := AddMonoidHom₁.toFun
|
||||
|
||||
attribute [coe] AddMonoidHom₁.toFun
|
||||
|
||||
@[ext]
|
||||
structure RingHom₁ (R S : Type) [Ring R] [Ring S] extends MonoidHom₁ R S, AddMonoidHom₁ R S
|
||||
|
||||
|
||||
|
||||
class MonoidHomClass₁ (F : Type) (M N : Type) [Monoid M] [Monoid N] where
|
||||
toFun : F → M → N
|
||||
map_one : ∀ f : F, toFun f 1 = 1
|
||||
map_mul : ∀ f g g', toFun f (g * g') = toFun f g * toFun f g'
|
||||
|
||||
|
||||
def badInst [Monoid M] [Monoid N] [MonoidHomClass₁ F M N] : CoeFun F (fun _ ↦ M → N) where
|
||||
coe := MonoidHomClass₁.toFun
|
||||
|
||||
|
||||
class MonoidHomClass₂ (F : Type) (M N : outParam Type) [Monoid M] [Monoid N] where
|
||||
toFun : F → M → N
|
||||
map_one : ∀ f : F, toFun f 1 = 1
|
||||
map_mul : ∀ f g g', toFun f (g * g') = toFun f g * toFun f g'
|
||||
|
||||
instance [Monoid M] [Monoid N] [MonoidHomClass₂ F M N] : CoeFun F (fun _ ↦ M → N) where
|
||||
coe := MonoidHomClass₂.toFun
|
||||
|
||||
attribute [coe] MonoidHomClass₂.toFun
|
||||
|
||||
|
||||
instance (M N : Type) [Monoid M] [Monoid N] : MonoidHomClass₂ (MonoidHom₁ M N) M N where
|
||||
toFun := MonoidHom₁.toFun
|
||||
map_one := fun f ↦ f.map_one
|
||||
map_mul := fun f ↦ f.map_mul
|
||||
|
||||
instance (R S : Type) [Ring R] [Ring S] : MonoidHomClass₂ (RingHom₁ R S) R S where
|
||||
toFun := fun f ↦ f.toMonoidHom₁.toFun
|
||||
map_one := fun f ↦ f.toMonoidHom₁.map_one
|
||||
map_mul := fun f ↦ f.toMonoidHom₁.map_mul
|
||||
|
||||
|
||||
lemma map_inv_of_inv [Monoid M] [Monoid N] [MonoidHomClass₂ F M N] (f : F) {m m' : M} (h : m*m' = 1) :
|
||||
f m * f m' = 1 := by
|
||||
rw [← MonoidHomClass₂.map_mul, h, MonoidHomClass₂.map_one]
|
||||
|
||||
example [Monoid M] [Monoid N] (f : MonoidHom₁ M N) {m m' : M} (h : m*m' = 1) : f m * f m' = 1 :=
|
||||
map_inv_of_inv f h
|
||||
|
||||
example [Ring R] [Ring S] (f : RingHom₁ R S) {r r' : R} (h : r*r' = 1) : f r * f r' = 1 :=
|
||||
map_inv_of_inv f h
|
||||
|
||||
|
||||
|
||||
class MonoidHomClass₃ (F : Type) (M N : outParam Type) [Monoid M] [Monoid N] extends
|
||||
FunLike F M (fun _ ↦ N) where
|
||||
map_one : ∀ f : F, f 1 = 1
|
||||
map_mul : ∀ (f : F) g g', f (g * g') = f g * f g'
|
||||
|
||||
instance (M N : Type) [Monoid M] [Monoid N] : MonoidHomClass₃ (MonoidHom₁ M N) M N where
|
||||
coe := MonoidHom₁.toFun
|
||||
coe_injective' := MonoidHom₁.ext
|
||||
map_one := MonoidHom₁.map_one
|
||||
map_mul := MonoidHom₁.map_mul
|
||||
|
||||
|
||||
@[ext]
|
||||
structure OrderPresHom (α β : Type) [LE α] [LE β] where
|
||||
toFun : α → β
|
||||
le_of_le : ∀ a a', a ≤ a' → toFun a ≤ toFun a'
|
||||
|
||||
@[ext]
|
||||
structure OrderPresMonoidHom (M N : Type) [Monoid M] [LE M] [Monoid N] [LE N] extends
|
||||
MonoidHom₁ M N, OrderPresHom M N
|
||||
|
||||
class OrderPresHomClass (F : Type) (α β : outParam Type) [LE α] [LE β]
|
||||
|
||||
instance (α β : Type) [LE α] [LE β] : OrderPresHomClass (OrderPresHom α β) α β where
|
||||
|
||||
instance (α β : Type) [LE α] [Monoid α] [LE β] [Monoid β] :
|
||||
OrderPresHomClass (OrderPresMonoidHom α β) α β where
|
||||
|
||||
instance (α β : Type) [LE α] [Monoid α] [LE β] [Monoid β] :
|
||||
MonoidHomClass₃ (OrderPresMonoidHom α β) α β
|
||||
:= sorry
|
|
@ -0,0 +1,90 @@
|
|||
import MIL.Common
|
||||
import Mathlib.GroupTheory.QuotientGroup
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
|
||||
@[ext]
|
||||
structure Submonoid₁ (M : Type) [Monoid M] where
|
||||
/-- The carrier of a submonoid. -/
|
||||
carrier : Set M
|
||||
/-- The product of two elements of a submonoid belongs to the submonoid. -/
|
||||
mul_mem {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier
|
||||
/-- The unit element belongs to the submonoid. -/
|
||||
one_mem : 1 ∈ carrier
|
||||
|
||||
/-- Submonoids in `M` can be seen as sets in `M`. -/
|
||||
instance [Monoid M] : SetLike (Submonoid₁ M) M where
|
||||
coe := Submonoid₁.carrier
|
||||
coe_injective' := Submonoid₁.ext
|
||||
|
||||
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) : 1 ∈ N := N.one_mem
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) (α : Type) (f : M → α) := f '' N
|
||||
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) (x : N) : (x : M) ∈ N := x.property
|
||||
|
||||
|
||||
instance SubMonoid₁Monoid [Monoid M] (N : Submonoid₁ M) : Monoid N where
|
||||
mul := fun x y ↦ ⟨x*y, N.mul_mem x.property y.property⟩
|
||||
mul_assoc := fun x y z ↦ SetCoe.ext (mul_assoc (x : M) y z)
|
||||
one := ⟨1, N.one_mem⟩
|
||||
one_mul := fun x ↦ SetCoe.ext (one_mul (x : M))
|
||||
mul_one := fun x ↦ SetCoe.ext (mul_one (x : M))
|
||||
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) : Monoid N where
|
||||
mul := fun ⟨x, hx⟩ ⟨y, hy⟩ ↦ ⟨x*y, N.mul_mem hx hy⟩
|
||||
mul_assoc := fun ⟨x, _⟩ ⟨y, _⟩ ⟨z, _⟩ ↦ SetCoe.ext (mul_assoc x y z)
|
||||
one := ⟨1, N.one_mem⟩
|
||||
one_mul := fun ⟨x, _⟩ ↦ SetCoe.ext (one_mul x)
|
||||
mul_one := fun ⟨x, _⟩ ↦ SetCoe.ext (mul_one x)
|
||||
|
||||
|
||||
class SubmonoidClass₁ (S : Type) (M : Type) [Monoid M] [SetLike S M] : Prop where
|
||||
mul_mem : ∀ (s : S) {a b : M}, a ∈ s → b ∈ s → a * b ∈ s
|
||||
one_mem : ∀ s : S, 1 ∈ s
|
||||
|
||||
instance [Monoid M] : SubmonoidClass₁ (Submonoid₁ M) M where
|
||||
mul_mem := Submonoid₁.mul_mem
|
||||
one_mem := Submonoid₁.one_mem
|
||||
|
||||
|
||||
instance [Monoid M] : Inf (Submonoid₁ M) :=
|
||||
⟨fun S₁ S₂ ↦
|
||||
{ carrier := S₁ ∩ S₂
|
||||
one_mem := ⟨S₁.one_mem, S₂.one_mem⟩
|
||||
mul_mem := fun ⟨hx, hx'⟩ ⟨hy, hy'⟩ ↦ ⟨S₁.mul_mem hx hy, S₂.mul_mem hx' hy'⟩ }⟩
|
||||
|
||||
|
||||
example [Monoid M] (N P : Submonoid₁ M) : Submonoid₁ M := N ⊓ P
|
||||
|
||||
|
||||
def Submonoid.Setoid [CommMonoid M] (N : Submonoid M) : Setoid M where
|
||||
r := fun x y ↦ ∃ w ∈ N, ∃ z ∈ N, x*w = y*z
|
||||
iseqv := {
|
||||
refl := fun x ↦ ⟨1, N.one_mem, 1, N.one_mem, rfl⟩
|
||||
symm := fun ⟨w, hw, z, hz, h⟩ ↦ ⟨z, hz, w, hw, h.symm⟩
|
||||
trans := by
|
||||
sorry
|
||||
}
|
||||
|
||||
instance [CommMonoid M] : HasQuotient M (Submonoid M) where
|
||||
quotient' := fun N ↦ Quotient N.Setoid
|
||||
|
||||
def QuotientMonoid.mk [CommMonoid M] (N : Submonoid M) : M → M ⧸ N := Quotient.mk N.Setoid
|
||||
|
||||
instance [CommMonoid M] (N : Submonoid M) : Monoid (M ⧸ N) where
|
||||
mul := Quotient.map₂' (· * ·) (by
|
||||
sorry
|
||||
)
|
||||
mul_assoc := by
|
||||
sorry
|
||||
one := QuotientMonoid.mk N 1
|
||||
one_mul := by
|
||||
sorry
|
||||
mul_one := by
|
||||
sorry
|
|
@ -0,0 +1,351 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Algebra.BigOperators.Ring
|
||||
import Mathlib.Data.Real.Basic
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
|
||||
class One₁ (α : Type) where
|
||||
/-- The element one -/
|
||||
one : α
|
||||
|
||||
|
||||
#check One₁.one -- One₁.one {α : Type} [self : One₁ α] : α
|
||||
|
||||
@[class] structure One₂ (α : Type) where
|
||||
/-- The element one -/
|
||||
one : α
|
||||
|
||||
#check One₂.one
|
||||
|
||||
|
||||
example (α : Type) [One₁ α] : α := One₁.one
|
||||
|
||||
example (α : Type) [One₁ α] := (One₁.one : α)
|
||||
|
||||
@[inherit_doc]
|
||||
notation "𝟙" => One₁.one
|
||||
|
||||
example {α : Type} [One₁ α] : α := 𝟙
|
||||
|
||||
example {α : Type} [One₁ α] : (𝟙 : α) = 𝟙 := rfl
|
||||
|
||||
|
||||
class Dia₁ (α : Type) where
|
||||
dia : α → α → α
|
||||
|
||||
infixl:70 " ⋄ " => Dia₁.dia
|
||||
|
||||
|
||||
class Semigroup₁ (α : Type) where
|
||||
toDia₁ : Dia₁ α
|
||||
/-- Diamond is associative -/
|
||||
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)
|
||||
|
||||
|
||||
attribute [instance] Semigroup₁.toDia₁
|
||||
|
||||
example {α : Type} [Semigroup₁ α] (a b : α) : α := a ⋄ b
|
||||
|
||||
|
||||
class Semigroup₂ (α : Type) extends Dia₁ α where
|
||||
/-- Diamond is associative -/
|
||||
dia_assoc : ∀ a b c : α, a ⋄ b ⋄ c = a ⋄ (b ⋄ c)
|
||||
|
||||
example {α : Type} [Semigroup₂ α] (a b : α) : α := a ⋄ b
|
||||
|
||||
class DiaOneClass₁ (α : Type) extends One₁ α, Dia₁ α where
|
||||
/-- One is a left neutral element for diamond. -/
|
||||
one_dia : ∀ a : α, 𝟙 ⋄ a = a
|
||||
/-- One is a right neutral element for diamond -/
|
||||
dia_one : ∀ a : α, a ⋄ 𝟙 = a
|
||||
|
||||
|
||||
|
||||
set_option trace.Meta.synthInstance true in
|
||||
example {α : Type} [DiaOneClass₁ α] (a b : α) : Prop := a ⋄ b = 𝟙
|
||||
|
||||
|
||||
class Monoid₁ (α : Type) extends Semigroup₁ α, DiaOneClass₁ α
|
||||
|
||||
|
||||
class Monoid₂ (α : Type) where
|
||||
toSemigroup₁ : Semigroup₁ α
|
||||
toDiaOneClass₁ : DiaOneClass₁ α
|
||||
|
||||
|
||||
example {α : Type} [Monoid₁ α] :
|
||||
(Monoid₁.toSemigroup₁.toDia₁.dia : α → α → α) = Monoid₁.toDiaOneClass₁.toDia₁.dia := rfl
|
||||
|
||||
|
||||
/- Monoid₂.mk {α : Type} (toSemigroup₁ : Semigroup₁ α) (toDiaOneClass₁ : DiaOneClass₁ α) : Monoid₂ α -/
|
||||
#check Monoid₂.mk
|
||||
|
||||
/- Monoid₁.mk {α : Type} [toSemigroup₁ : Semigroup₁ α] [toOne₁ : One₁ α] (one_dia : ∀ (a : α), 𝟙 ⋄ a = a) (dia_one : ∀ (a : α), a ⋄ 𝟙 = a) : Monoid₁ α -/
|
||||
#check Monoid₁.mk
|
||||
|
||||
|
||||
#check Monoid₁.toSemigroup₁
|
||||
#check Monoid₁.toDiaOneClass₁
|
||||
|
||||
|
||||
class Inv₁ (α : Type) where
|
||||
/-- The inversion function -/
|
||||
inv : α → α
|
||||
|
||||
@[inherit_doc]
|
||||
postfix:max "⁻¹" => Inv₁.inv
|
||||
|
||||
class Group₁ (G : Type) extends Monoid₁ G, Inv G where
|
||||
inv_dia : ∀ a : G, a⁻¹ ⋄ a = 𝟙
|
||||
|
||||
|
||||
lemma left_inv_eq_right_inv₁ {M : Type} [Monoid₁ M] {a b c : M} (hba : b ⋄ a = 𝟙) (hac : a ⋄ c = 𝟙) : b = c := by
|
||||
rw [← DiaOneClass₁.one_dia c, ← hba, Semigroup₁.dia_assoc, hac, DiaOneClass₁.dia_one b]
|
||||
|
||||
|
||||
export DiaOneClass₁ (one_dia dia_one)
|
||||
export Semigroup₁ (dia_assoc)
|
||||
export Group₁ (inv_dia)
|
||||
|
||||
|
||||
example {M : Type} [Monoid₁ M] {a b c : M} (hba : b ⋄ a = 𝟙) (hac : a ⋄ c = 𝟙) : b = c := by
|
||||
rw [← one_dia c, ← hba, dia_assoc, hac, dia_one b]
|
||||
|
||||
|
||||
lemma inv_eq_of_dia [Group₁ G] {a b : G} (h : a ⋄ b = 𝟙) : a⁻¹ = b :=
|
||||
left_inv_eq_right_inv₁ (inv_dia a) h
|
||||
|
||||
lemma dia_inv [Group₁ G] (a : G) : a ⋄ a⁻¹ = 𝟙 :=
|
||||
by rw [← inv_dia a⁻¹, inv_eq_of_dia (inv_dia a)]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class AddSemigroup₃ (α : Type) extends Add α where
|
||||
/-- Addition is associative -/
|
||||
add_assoc₃ : ∀ a b c : α, a + b + c = a + (b + c)
|
||||
|
||||
@[to_additive AddSemigroup₃]
|
||||
class Semigroup₃ (α : Type) extends Mul α where
|
||||
/-- Multiplication is associative -/
|
||||
mul_assoc₃ : ∀ a b c : α, a * b * c = a * (b * c)
|
||||
|
||||
class AddMonoid₃ (α : Type) extends AddSemigroup₃ α, AddZeroClass α
|
||||
|
||||
@[to_additive AddMonoid₃]
|
||||
class Monoid₃ (α : Type) extends Semigroup₃ α, MulOneClass α
|
||||
|
||||
attribute [to_additive existing] Monoid₃.toMulOneClass
|
||||
|
||||
export Semigroup₃ (mul_assoc₃)
|
||||
export AddSemigroup₃ (add_assoc₃)
|
||||
|
||||
whatsnew in
|
||||
@[to_additive]
|
||||
lemma left_inv_eq_right_inv' {M : Type} [Monoid₃ M] {a b c : M} (hba : b * a = 1) (hac : a * c = 1) : b = c := by
|
||||
rw [← one_mul c, ← hba, mul_assoc₃, hac, mul_one b]
|
||||
|
||||
#check left_neg_eq_right_neg'
|
||||
|
||||
class AddCommSemigroup₃ (α : Type) extends AddSemigroup₃ α where
|
||||
add_comm : ∀ a b : α, a + b = b + a
|
||||
|
||||
@[to_additive AddCommSemigroup₃]
|
||||
class CommSemigroup₃ (α : Type) extends Semigroup₃ α where
|
||||
mul_comm : ∀ a b : α, a * b = b * a
|
||||
|
||||
class AddCommMonoid₃ (α : Type) extends AddMonoid₃ α, AddCommSemigroup₃ α
|
||||
|
||||
@[to_additive AddCommMonoid₃]
|
||||
class CommMonoid₃ (α : Type) extends Monoid₃ α, CommSemigroup₃ α
|
||||
|
||||
class AddGroup₃ (G : Type) extends AddMonoid₃ G, Neg G where
|
||||
neg_add : ∀ a : G, -a + a = 0
|
||||
|
||||
@[to_additive AddGroup₃]
|
||||
class Group₃ (G : Type) extends Monoid₃ G, Inv G where
|
||||
inv_mul : ∀ a : G, a⁻¹ * a = 1
|
||||
|
||||
|
||||
attribute [simp] Group₃.inv_mul AddGroup₃.neg_add
|
||||
|
||||
|
||||
|
||||
@[to_additive]
|
||||
lemma inv_eq_of_mul [Group₃ G] {a b : G} (h : a * b = 1) : a⁻¹ = b :=
|
||||
left_inv_eq_right_inv' (Group₃.inv_mul a) h
|
||||
|
||||
|
||||
@[to_additive (attr := simp)]
|
||||
lemma Group₃.mul_inv {G : Type} [Group₃ G] {a : G} : a * a⁻¹ = 1 := by
|
||||
rw [← inv_mul a⁻¹, inv_eq_of_mul (inv_mul a)]
|
||||
|
||||
@[to_additive]
|
||||
lemma mul_left_cancel₃ {G : Type} [Group₃ G] {a b c : G} (h : a * b = a * c) : b = c := by
|
||||
simpa [← mul_assoc₃] using congr_arg (a⁻¹ * ·) h
|
||||
|
||||
@[to_additive]
|
||||
lemma mul_right_cancel₃ {G : Type} [Group₃ G] {a b c : G} (h : b*a = c*a) : b = c := by
|
||||
simpa [mul_assoc₃] using congr_arg (· * a⁻¹) h
|
||||
|
||||
class AddCommGroup₃ (G : Type) extends AddGroup₃ G, AddCommMonoid₃ G
|
||||
|
||||
@[to_additive AddCommGroup₃]
|
||||
class CommGroup₃ (G : Type) extends Group₃ G, CommMonoid₃ G
|
||||
|
||||
|
||||
|
||||
class Ring₃ (R : Type) extends AddGroup₃ R, Monoid₃ R, MulZeroClass R where
|
||||
/-- Multiplication is left distributive over addition -/
|
||||
left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c
|
||||
/-- Multiplication is right distributive over addition -/
|
||||
right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c
|
||||
|
||||
instance {R : Type} [Ring₃ R] : AddCommGroup₃ R :=
|
||||
{ Ring₃.toAddGroup₃ with
|
||||
add_comm := by
|
||||
intro a b
|
||||
have : a + (a + b + b) = a + (b + a + b) := calc
|
||||
a + (a + b + b) = (a + a) + (b + b) := by simp [add_assoc₃, add_assoc₃]
|
||||
_ = (1 * a + 1 * a) + (1 * b + 1 * b) := by simp
|
||||
_ = (1 + 1) * a + (1 + 1) * b := by simp [Ring₃.right_distrib]
|
||||
_ = (1 + 1) * (a + b) := by simp [Ring₃.left_distrib]
|
||||
_ = 1 * (a + b) + 1 * (a + b) := by simp [Ring₃.right_distrib]
|
||||
_ = (a + b) + (a + b) := by simp
|
||||
_ = a + (b + a + b) := by simp [add_assoc₃]
|
||||
exact add_right_cancel₃ (add_left_cancel₃ this) }
|
||||
|
||||
instance : Ring₃ ℤ where
|
||||
add := (· + ·)
|
||||
add_assoc₃ := add_assoc
|
||||
zero := 0
|
||||
zero_add := by simp
|
||||
add_zero := by simp
|
||||
neg := (- ·)
|
||||
neg_add := by simp
|
||||
mul := (· * ·)
|
||||
mul_assoc₃ := mul_assoc
|
||||
one := 1
|
||||
one_mul := by simp
|
||||
mul_one := by simp
|
||||
zero_mul := by simp
|
||||
mul_zero := by simp
|
||||
left_distrib := Int.mul_add
|
||||
right_distrib := Int.add_mul
|
||||
|
||||
class LE₁ (α : Type) where
|
||||
/-- The Less-or-Equal relation. -/
|
||||
le : α → α → Prop
|
||||
|
||||
@[inherit_doc] infix:50 " ≤₁ " => LE₁.le
|
||||
|
||||
class Preorder₁ (α : Type)
|
||||
extends LE₁ α where
|
||||
le_refl : ∀ a : α, a ≤₁ a
|
||||
le_trans : ∀ a b c : α, a ≤₁ b → b ≤₁ c → a ≤₁ c
|
||||
|
||||
class PartialOrder₁ (α : Type)
|
||||
extends Preorder₁ α where
|
||||
le_antisymm : ∀ a b : α, a ≤₁ b → b ≤₁ a → a = b
|
||||
|
||||
class OrderedCommMonoid₁ (α : Type)
|
||||
extends PartialOrder₁ α, CommMonoid₃ α where
|
||||
mul_of_le : ∀ a b : α, a ≤₁ b → ∀ c : α, c * a ≤₁ c * b
|
||||
|
||||
instance : OrderedCommMonoid₁ ℕ where
|
||||
le := (· ≤ ·)
|
||||
le_refl := fun _ ↦ le_rfl
|
||||
le_trans := fun _ _ _ ↦ le_trans
|
||||
le_antisymm := fun _ _ ↦ le_antisymm
|
||||
mul := (· * ·)
|
||||
mul_assoc₃ := mul_assoc
|
||||
one := 1
|
||||
one_mul := one_mul
|
||||
mul_one := mul_one
|
||||
mul_comm := mul_comm
|
||||
mul_of_le := fun _ _ h c ↦ Nat.mul_le_mul_left c h
|
||||
|
||||
class SMul₃ (α : Type) (β : Type) where
|
||||
/-- Scalar multiplication -/
|
||||
smul : α → β → β
|
||||
|
||||
infixr:73 " • " => SMul₃.smul
|
||||
|
||||
|
||||
class Module₁ (R : Type) [Ring₃ R] (M : Type) [AddCommGroup₃ M] extends SMul₃ R M where
|
||||
zero_smul : ∀ m : M, (0 : R) • m = 0
|
||||
one_smul : ∀ m : M, (1 : R) • m = m
|
||||
mul_smul : ∀ (a b : R) (m : M), (a * b) • m = a • b • m
|
||||
add_smul : ∀ (a b : R) (m : M), (a + b) • m = a • m + b • m
|
||||
smul_add : ∀ (a : R) (m n : M), a • (m + n) = a • m + a • n
|
||||
|
||||
instance selfModule (R : Type) [Ring₃ R] : Module₁ R R where
|
||||
smul := fun r s ↦ r*s
|
||||
zero_smul := zero_mul
|
||||
one_smul := one_mul
|
||||
mul_smul := mul_assoc₃
|
||||
add_smul := Ring₃.right_distrib
|
||||
smul_add := Ring₃.left_distrib
|
||||
|
||||
def nsmul₁ [Zero M] [Add M] : ℕ → M → M
|
||||
| 0, _ => 0
|
||||
| n + 1, a => a + nsmul₁ n a
|
||||
|
||||
def zsmul₁ {M : Type*} [Zero M] [Add M] [Neg M] : ℤ → M → M
|
||||
| Int.ofNat n, a => nsmul₁ n a
|
||||
| Int.negSucc n, a => -nsmul₁ n.succ a
|
||||
|
||||
instance abGrpModule (A : Type) [AddCommGroup₃ A] : Module₁ ℤ A where
|
||||
smul := zsmul₁
|
||||
zero_smul := sorry
|
||||
one_smul := sorry
|
||||
mul_smul := sorry
|
||||
add_smul := sorry
|
||||
smul_add := sorry
|
||||
|
||||
#synth Module₁ ℤ ℤ -- abGrpModule ℤ
|
||||
|
||||
|
||||
class AddMonoid₄ (M : Type) extends AddSemigroup₃ M, AddZeroClass M where
|
||||
/-- Multiplication by a natural number. -/
|
||||
nsmul : ℕ → M → M := nsmul₁
|
||||
/-- Multiplication by `(0 : ℕ)` gives `0`. -/
|
||||
nsmul_zero : ∀ x, nsmul 0 x = 0 := by intros; rfl
|
||||
/-- Multiplication by `(n + 1 : ℕ)` behaves as expected. -/
|
||||
nsmul_succ : ∀ (n : ℕ) (x), nsmul (n + 1) x = x + nsmul n x := by intros; rfl
|
||||
|
||||
instance mySMul {M : Type} [AddMonoid₄ M] : SMul ℕ M := ⟨AddMonoid₄.nsmul⟩
|
||||
|
||||
instance (M N : Type) [AddMonoid₄ M] [AddMonoid₄ N] : AddMonoid₄ (M × N) where
|
||||
add := fun p q ↦ (p.1 + q.1, p.2 + q.2)
|
||||
add_assoc₃ := fun a b c ↦ by ext <;> apply add_assoc₃
|
||||
zero := (0, 0)
|
||||
zero_add := fun a ↦ by ext <;> apply zero_add
|
||||
add_zero := fun a ↦ by ext <;> apply add_zero
|
||||
|
||||
instance : AddMonoid₄ ℤ where
|
||||
add := (· + ·)
|
||||
add_assoc₃ := Int.add_assoc
|
||||
zero := 0
|
||||
zero_add := Int.zero_add
|
||||
add_zero := Int.add_zero
|
||||
nsmul := fun n m ↦ (n : ℤ) * m
|
||||
nsmul_zero := Int.zero_mul
|
||||
nsmul_succ := fun n m ↦ show (n + 1 : ℤ) * m = m + n * m
|
||||
by rw [Int.add_mul, Int.add_comm, Int.one_mul]
|
||||
|
||||
example (n : ℕ) (m : ℤ) : SMul.smul (self := mySMul) n m = n * m := rfl
|
||||
|
||||
class LT₁ (α : Type) where
|
||||
/-- The Less-Than relation -/
|
||||
lt : α → α → Prop
|
||||
|
||||
@[inherit_doc] infix:50 " <₁ " => LT₁.lt
|
||||
|
||||
class PreOrder₂ (α : Type) extends LE₁ α, LT₁ α where
|
||||
le_refl : ∀ a : α, a ≤₁ a
|
||||
le_trans : ∀ a b c : α, a ≤₁ b → b ≤₁ c → a ≤₁ c
|
||||
lt := fun a b ↦ a ≤₁ b ∧ ¬b ≤₁ a
|
||||
lt_iff_le_not_le : ∀ a b : α, a <₁ b ↔ a ≤₁ b ∧ ¬b ≤₁ a := by intros; rfl
|
|
@ -0,0 +1,129 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Topology.Instances.Real
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
|
||||
def isMonoidHom₁ [Monoid G] [Monoid H] (f : G → H) : Prop :=
|
||||
f 1 = 1 ∧ ∀ g g', f (g * g') = f g * f g'
|
||||
structure isMonoidHom₂ [Monoid G] [Monoid H] (f : G → H) : Prop where
|
||||
map_one : f 1 = 1
|
||||
map_mul : ∀ g g', f (g * g') = f g * f g'
|
||||
example : Continuous (id : ℝ → ℝ) := continuous_id
|
||||
@[ext]
|
||||
structure MonoidHom₁ (G H : Type) [Monoid G] [Monoid H] where
|
||||
toFun : G → H
|
||||
map_one : toFun 1 = 1
|
||||
map_mul : ∀ g g', toFun (g * g') = toFun g * toFun g'
|
||||
|
||||
instance [Monoid G] [Monoid H] : CoeFun (MonoidHom₁ G H) (fun _ ↦ G → H) where
|
||||
coe := MonoidHom₁.toFun
|
||||
|
||||
attribute [coe] MonoidHom₁.toFun
|
||||
|
||||
|
||||
example [Monoid G] [Monoid H] (f : MonoidHom₁ G H) : f 1 = 1 := f.map_one
|
||||
|
||||
@[ext]
|
||||
structure AddMonoidHom₁ (G H : Type) [AddMonoid G] [AddMonoid H] where
|
||||
toFun : G → H
|
||||
map_zero : toFun 0 = 0
|
||||
map_add : ∀ g g', toFun (g + g') = toFun g + toFun g'
|
||||
|
||||
instance [AddMonoid G] [AddMonoid H] : CoeFun (AddMonoidHom₁ G H) (fun _ ↦ G → H) where
|
||||
coe := AddMonoidHom₁.toFun
|
||||
|
||||
attribute [coe] AddMonoidHom₁.toFun
|
||||
|
||||
@[ext]
|
||||
structure RingHom₁ (R S : Type) [Ring R] [Ring S] extends MonoidHom₁ R S, AddMonoidHom₁ R S
|
||||
|
||||
|
||||
|
||||
class MonoidHomClass₁ (F : Type) (M N : Type) [Monoid M] [Monoid N] where
|
||||
toFun : F → M → N
|
||||
map_one : ∀ f : F, toFun f 1 = 1
|
||||
map_mul : ∀ f g g', toFun f (g * g') = toFun f g * toFun f g'
|
||||
|
||||
|
||||
def badInst [Monoid M] [Monoid N] [MonoidHomClass₁ F M N] : CoeFun F (fun _ ↦ M → N) where
|
||||
coe := MonoidHomClass₁.toFun
|
||||
|
||||
|
||||
class MonoidHomClass₂ (F : Type) (M N : outParam Type) [Monoid M] [Monoid N] where
|
||||
toFun : F → M → N
|
||||
map_one : ∀ f : F, toFun f 1 = 1
|
||||
map_mul : ∀ f g g', toFun f (g * g') = toFun f g * toFun f g'
|
||||
|
||||
instance [Monoid M] [Monoid N] [MonoidHomClass₂ F M N] : CoeFun F (fun _ ↦ M → N) where
|
||||
coe := MonoidHomClass₂.toFun
|
||||
|
||||
attribute [coe] MonoidHomClass₂.toFun
|
||||
|
||||
|
||||
instance (M N : Type) [Monoid M] [Monoid N] : MonoidHomClass₂ (MonoidHom₁ M N) M N where
|
||||
toFun := MonoidHom₁.toFun
|
||||
map_one := fun f ↦ f.map_one
|
||||
map_mul := fun f ↦ f.map_mul
|
||||
|
||||
instance (R S : Type) [Ring R] [Ring S] : MonoidHomClass₂ (RingHom₁ R S) R S where
|
||||
toFun := fun f ↦ f.toMonoidHom₁.toFun
|
||||
map_one := fun f ↦ f.toMonoidHom₁.map_one
|
||||
map_mul := fun f ↦ f.toMonoidHom₁.map_mul
|
||||
|
||||
|
||||
lemma map_inv_of_inv [Monoid M] [Monoid N] [MonoidHomClass₂ F M N] (f : F) {m m' : M} (h : m*m' = 1) :
|
||||
f m * f m' = 1 := by
|
||||
rw [← MonoidHomClass₂.map_mul, h, MonoidHomClass₂.map_one]
|
||||
|
||||
example [Monoid M] [Monoid N] (f : MonoidHom₁ M N) {m m' : M} (h : m*m' = 1) : f m * f m' = 1 :=
|
||||
map_inv_of_inv f h
|
||||
|
||||
example [Ring R] [Ring S] (f : RingHom₁ R S) {r r' : R} (h : r*r' = 1) : f r * f r' = 1 :=
|
||||
map_inv_of_inv f h
|
||||
|
||||
|
||||
|
||||
class MonoidHomClass₃ (F : Type) (M N : outParam Type) [Monoid M] [Monoid N] extends
|
||||
FunLike F M (fun _ ↦ N) where
|
||||
map_one : ∀ f : F, f 1 = 1
|
||||
map_mul : ∀ (f : F) g g', f (g * g') = f g * f g'
|
||||
|
||||
instance (M N : Type) [Monoid M] [Monoid N] : MonoidHomClass₃ (MonoidHom₁ M N) M N where
|
||||
coe := MonoidHom₁.toFun
|
||||
coe_injective' := MonoidHom₁.ext
|
||||
map_one := MonoidHom₁.map_one
|
||||
map_mul := MonoidHom₁.map_mul
|
||||
|
||||
|
||||
@[ext]
|
||||
structure OrderPresHom (α β : Type) [LE α] [LE β] where
|
||||
toFun : α → β
|
||||
le_of_le : ∀ a a', a ≤ a' → toFun a ≤ toFun a'
|
||||
|
||||
@[ext]
|
||||
structure OrderPresMonoidHom (M N : Type) [Monoid M] [LE M] [Monoid N] [LE N] extends
|
||||
MonoidHom₁ M N, OrderPresHom M N
|
||||
|
||||
class OrderPresHomClass (F : Type) (α β : outParam Type) [LE α] [LE β]
|
||||
extends FunLike F α (fun _ ↦ β) where
|
||||
le_of_le : ∀ (f : F) a a', a ≤ a' → f a ≤ f a'
|
||||
|
||||
instance (α β : Type) [LE α] [LE β] : OrderPresHomClass (OrderPresHom α β) α β where
|
||||
coe := OrderPresHom.toFun
|
||||
coe_injective' := OrderPresHom.ext
|
||||
le_of_le := OrderPresHom.le_of_le
|
||||
|
||||
instance (α β : Type) [LE α] [Monoid α] [LE β] [Monoid β] :
|
||||
OrderPresHomClass (OrderPresMonoidHom α β) α β where
|
||||
coe := fun f ↦ f.toOrderPresHom.toFun
|
||||
coe_injective' := OrderPresMonoidHom.ext
|
||||
le_of_le := fun f ↦ f.toOrderPresHom.le_of_le
|
||||
|
||||
instance (α β : Type) [LE α] [Monoid α] [LE β] [Monoid β] :
|
||||
MonoidHomClass₃ (OrderPresMonoidHom α β) α β
|
||||
where
|
||||
coe := fun f ↦ f.toOrderPresHom.toFun
|
||||
coe_injective' := OrderPresMonoidHom.ext
|
||||
map_one := fun f ↦ f.toMonoidHom₁.map_one
|
||||
map_mul := fun f ↦ f.toMonoidHom₁.map_mul
|
|
@ -0,0 +1,127 @@
|
|||
import MIL.Common
|
||||
import Mathlib.GroupTheory.QuotientGroup
|
||||
|
||||
set_option autoImplicit true
|
||||
|
||||
|
||||
@[ext]
|
||||
structure Submonoid₁ (M : Type) [Monoid M] where
|
||||
/-- The carrier of a submonoid. -/
|
||||
carrier : Set M
|
||||
/-- The product of two elements of a submonoid belongs to the submonoid. -/
|
||||
mul_mem {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier
|
||||
/-- The unit element belongs to the submonoid. -/
|
||||
one_mem : 1 ∈ carrier
|
||||
|
||||
/-- Submonoids in `M` can be seen as sets in `M`. -/
|
||||
instance [Monoid M] : SetLike (Submonoid₁ M) M where
|
||||
coe := Submonoid₁.carrier
|
||||
coe_injective' := Submonoid₁.ext
|
||||
|
||||
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) : 1 ∈ N := N.one_mem
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) (α : Type) (f : M → α) := f '' N
|
||||
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) (x : N) : (x : M) ∈ N := x.property
|
||||
|
||||
|
||||
instance SubMonoid₁Monoid [Monoid M] (N : Submonoid₁ M) : Monoid N where
|
||||
mul := fun x y ↦ ⟨x*y, N.mul_mem x.property y.property⟩
|
||||
mul_assoc := fun x y z ↦ SetCoe.ext (mul_assoc (x : M) y z)
|
||||
one := ⟨1, N.one_mem⟩
|
||||
one_mul := fun x ↦ SetCoe.ext (one_mul (x : M))
|
||||
mul_one := fun x ↦ SetCoe.ext (mul_one (x : M))
|
||||
|
||||
|
||||
example [Monoid M] (N : Submonoid₁ M) : Monoid N where
|
||||
mul := fun ⟨x, hx⟩ ⟨y, hy⟩ ↦ ⟨x*y, N.mul_mem hx hy⟩
|
||||
mul_assoc := fun ⟨x, _⟩ ⟨y, _⟩ ⟨z, _⟩ ↦ SetCoe.ext (mul_assoc x y z)
|
||||
one := ⟨1, N.one_mem⟩
|
||||
one_mul := fun ⟨x, _⟩ ↦ SetCoe.ext (one_mul x)
|
||||
mul_one := fun ⟨x, _⟩ ↦ SetCoe.ext (mul_one x)
|
||||
|
||||
|
||||
class SubmonoidClass₁ (S : Type) (M : Type) [Monoid M] [SetLike S M] : Prop where
|
||||
mul_mem : ∀ (s : S) {a b : M}, a ∈ s → b ∈ s → a * b ∈ s
|
||||
one_mem : ∀ s : S, 1 ∈ s
|
||||
|
||||
instance [Monoid M] : SubmonoidClass₁ (Submonoid₁ M) M where
|
||||
mul_mem := Submonoid₁.mul_mem
|
||||
one_mem := Submonoid₁.one_mem
|
||||
|
||||
@[ext]
|
||||
structure Subgroup₁ (G : Type) [Group G] extends Submonoid₁ G where
|
||||
/-- The inverse of an element of a subgroup belongs to the subgroup. -/
|
||||
inv_mem {a} : a ∈ carrier → a⁻¹ ∈ carrier
|
||||
|
||||
|
||||
/-- Subgroups in `M` can be seen as sets in `M`. -/
|
||||
instance [Group G] : SetLike (Subgroup₁ G) G where
|
||||
coe := fun H ↦ H.toSubmonoid₁.carrier
|
||||
coe_injective' := Subgroup₁.ext
|
||||
|
||||
instance [Group G] (H : Subgroup₁ G) : Group H :=
|
||||
{ SubMonoid₁Monoid H.toSubmonoid₁ with
|
||||
inv := fun x ↦ ⟨x⁻¹, H.inv_mem x.property⟩
|
||||
mul_left_inv := fun x ↦ SetCoe.ext (mul_left_inv (x : G)) }
|
||||
|
||||
class SubgroupClass₁ (S : Type) (G : Type) [Group G] [SetLike S G]
|
||||
extends SubmonoidClass₁ S G : Prop where
|
||||
inv_mem : ∀ (s : S) {a : G}, a ∈ s → a⁻¹ ∈ s
|
||||
|
||||
instance [Group G] : SubmonoidClass₁ (Subgroup₁ G) G where
|
||||
mul_mem := fun H ↦ H.toSubmonoid₁.mul_mem
|
||||
one_mem := fun H ↦ H.toSubmonoid₁.one_mem
|
||||
|
||||
instance [Group G] : SubgroupClass₁ (Subgroup₁ G) G :=
|
||||
{ (inferInstance : SubmonoidClass₁ (Subgroup₁ G) G) with
|
||||
inv_mem := Subgroup₁.inv_mem }
|
||||
|
||||
|
||||
instance [Monoid M] : Inf (Submonoid₁ M) :=
|
||||
⟨fun S₁ S₂ ↦
|
||||
{ carrier := S₁ ∩ S₂
|
||||
one_mem := ⟨S₁.one_mem, S₂.one_mem⟩
|
||||
mul_mem := fun ⟨hx, hx'⟩ ⟨hy, hy'⟩ ↦ ⟨S₁.mul_mem hx hy, S₂.mul_mem hx' hy'⟩ }⟩
|
||||
|
||||
|
||||
example [Monoid M] (N P : Submonoid₁ M) : Submonoid₁ M := N ⊓ P
|
||||
|
||||
|
||||
def Submonoid.Setoid [CommMonoid M] (N : Submonoid M) : Setoid M where
|
||||
r := fun x y ↦ ∃ w ∈ N, ∃ z ∈ N, x*w = y*z
|
||||
iseqv := {
|
||||
refl := fun x ↦ ⟨1, N.one_mem, 1, N.one_mem, rfl⟩
|
||||
symm := fun ⟨w, hw, z, hz, h⟩ ↦ ⟨z, hz, w, hw, h.symm⟩
|
||||
trans := by
|
||||
rintro a b c ⟨w, hw, z, hz, h⟩ ⟨w', hw', z', hz', h'⟩
|
||||
refine ⟨w*w', N.mul_mem hw hw', z*z', N.mul_mem hz hz', ?_⟩
|
||||
rw [← mul_assoc, h, mul_comm b, mul_assoc, h', ← mul_assoc, mul_comm z, mul_assoc]
|
||||
}
|
||||
|
||||
instance [CommMonoid M] : HasQuotient M (Submonoid M) where
|
||||
quotient' := fun N ↦ Quotient N.Setoid
|
||||
|
||||
def QuotientMonoid.mk [CommMonoid M] (N : Submonoid M) : M → M ⧸ N := Quotient.mk N.Setoid
|
||||
|
||||
instance [CommMonoid M] (N : Submonoid M) : Monoid (M ⧸ N) where
|
||||
mul := Quotient.map₂' (· * ·) (by
|
||||
rintro a₁ b₁ ⟨w, hw, z, hz, ha⟩ a₂ b₂ ⟨w', hw', z', hz', hb⟩
|
||||
refine ⟨w*w', N.mul_mem hw hw', z*z', N.mul_mem hz hz', ?_⟩
|
||||
rw [mul_comm w, ← mul_assoc, mul_assoc a₁, hb, mul_comm, ← mul_assoc, mul_comm w, ha,
|
||||
mul_assoc, mul_comm z, mul_assoc b₂, mul_comm z', mul_assoc]
|
||||
)
|
||||
mul_assoc := by
|
||||
rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
|
||||
apply Quotient.sound
|
||||
dsimp only
|
||||
rw [mul_assoc]
|
||||
apply @Setoid.refl M N.Setoid
|
||||
one := QuotientMonoid.mk N 1
|
||||
one_mul := by
|
||||
rintro ⟨a⟩ ; apply Quotient.sound ; dsimp only ; rw [one_mul] ; apply @Setoid.refl M N.Setoid
|
||||
mul_one := by
|
||||
rintro ⟨a⟩ ; apply Quotient.sound ; dsimp only ; rw [mul_one] ; apply @Setoid.refl M N.Setoid
|
|
@ -0,0 +1,291 @@
|
|||
import Mathlib.GroupTheory.Sylow
|
||||
import Mathlib.GroupTheory.Perm.Cycle.Concrete
|
||||
import Mathlib.GroupTheory.Perm.Subgroup
|
||||
import Mathlib.GroupTheory.PresentedGroup
|
||||
|
||||
import MIL.Common
|
||||
|
||||
example {M : Type*} [Monoid M] (x : M) : x*1 = x := mul_one x
|
||||
|
||||
example {M : Type*} [AddCommMonoid M] (x y : M) : x + y = y + x := add_comm x y
|
||||
|
||||
example {M N : Type*} [Monoid M] [Monoid N] (x y : M) (f : M →* N) : f (x * y) = f x * f y :=
|
||||
f.map_mul x y
|
||||
|
||||
example {M N : Type*} [AddMonoid M] [AddMonoid N] (f : M →+ N) : f 0 = 0 :=
|
||||
f.map_zero
|
||||
|
||||
example {M N P : Type*} [AddMonoid M] [AddMonoid N] [AddMonoid P]
|
||||
(f : M →+ N) (g : N →+ P) : M →+ P := g.comp f
|
||||
|
||||
example {G : Type*} [Group G] (x : G) : x * x⁻¹ = 1 := mul_inv_self x
|
||||
|
||||
example {G : Type*} [Group G] (x y z : G) : x * (y * z) * (x*z)⁻¹ * (x * y * x⁻¹)⁻¹ = 1 := by
|
||||
group
|
||||
|
||||
example {G : Type*} [AddCommGroup G] (x y z : G) : z + x + (y - z - x) = y := by
|
||||
abel
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (x y : G) (f : G →* H) : f (x * y) = f x * f y :=
|
||||
f.map_mul x y
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (x : G) (f : G →* H) : f (x⁻¹) = (f x)⁻¹ :=
|
||||
f.map_inv x
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (f : G → H) (h : ∀ x y, f (x * y) = f x * f y) :
|
||||
G →* H :=
|
||||
MonoidHom.mk' f h
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (f : G ≃* H) :
|
||||
f.trans f.symm = MulEquiv.refl G :=
|
||||
f.self_trans_symm
|
||||
|
||||
noncomputable example {G H : Type*} [Group G] [Group H]
|
||||
(f : G →* H) (h : Function.Bijective f) :
|
||||
G ≃* H :=
|
||||
MulEquiv.ofBijective f h
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) {x y : G} (hx : x ∈ H) (hy : y ∈ H) :
|
||||
x * y ∈ H :=
|
||||
H.mul_mem hx hy
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) {x : G} (hx : x ∈ H) :
|
||||
x⁻¹ ∈ H :=
|
||||
H.inv_mem hx
|
||||
|
||||
example : AddSubgroup ℚ where
|
||||
carrier := Set.range ((↑) : ℤ → ℚ)
|
||||
add_mem' := by
|
||||
rintro _ _ ⟨n, rfl⟩ ⟨m, rfl⟩
|
||||
use n + m
|
||||
simp
|
||||
zero_mem' := by
|
||||
use 0
|
||||
simp
|
||||
neg_mem' := by
|
||||
rintro _ ⟨n, rfl⟩
|
||||
use -n
|
||||
simp
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) : Group H := inferInstance
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) : Group {x : G // x ∈ H} := inferInstance
|
||||
|
||||
example {G : Type*} [Group G] (H H' : Subgroup G) :
|
||||
((H ⊓ H' : Subgroup G) : Set G) = (H : Set G) ∩ (H' : Set G) := rfl
|
||||
|
||||
example {G : Type*} [Group G] (H H' : Subgroup G) :
|
||||
((H ⊔ H' : Subgroup G) : Set G) = Subgroup.closure ((H : Set G) ∪ (H' : Set G)) := by
|
||||
rw [Subgroup.sup_eq_closure]
|
||||
|
||||
example {G : Type*} [Group G] (x : G) : x ∈ (⊤ : Subgroup G) := trivial
|
||||
|
||||
example {G : Type*} [Group G] (x : G) : x ∈ (⊥ : Subgroup G) ↔ x = 1 := Subgroup.mem_bot
|
||||
|
||||
def conjugate {G : Type*} [Group G] (x : G) (H : Subgroup G) : Subgroup G where
|
||||
carrier := {a : G | ∃ h, h ∈ H ∧ a = x * h * x⁻¹}
|
||||
one_mem' := by
|
||||
dsimp
|
||||
sorry
|
||||
inv_mem' := by
|
||||
dsimp
|
||||
sorry
|
||||
mul_mem' := by
|
||||
dsimp
|
||||
sorry
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (G' : Subgroup G) (f : G →* H) : Subgroup H :=
|
||||
Subgroup.map f G'
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (H' : Subgroup H) (f : G →* H) : Subgroup G :=
|
||||
Subgroup.comap f H'
|
||||
|
||||
#check Subgroup.mem_map
|
||||
#check Subgroup.mem_comap
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (f : G →* H) (g : G) :
|
||||
g ∈ MonoidHom.ker f ↔ f g = 1 :=
|
||||
f.mem_ker
|
||||
|
||||
example {G H : Type*} [Group G] [Group H] (f : G →* H) (h : H) :
|
||||
h ∈ MonoidHom.range f ↔ ∃ g : G, f g = h :=
|
||||
f.mem_range
|
||||
|
||||
section exercises
|
||||
variable {G H : Type*} [Group G] [Group H]
|
||||
|
||||
open Subgroup
|
||||
|
||||
example (φ : G →* H) (S T : Subgroup H) (hST : S ≤ T) : comap φ S ≤ comap φ T :=by
|
||||
sorry
|
||||
|
||||
example (φ : G →* H) (S T : Subgroup G) (hST : S ≤ T) : map φ S ≤ map φ T :=by
|
||||
sorry
|
||||
|
||||
variable {K : Type*} [Group K]
|
||||
|
||||
-- Remember you can use the `ext` tactic to prove an equality of subgroups.
|
||||
example (φ : G →* H) (ψ : H →* K) (U : Subgroup K) :
|
||||
comap (ψ.comp φ) U = comap φ (comap ψ U) := by
|
||||
sorry
|
||||
|
||||
-- Pushing a subgroup along one homomorphism and then another is equal to
|
||||
-- pushing it forward along the composite of the homomorphisms.
|
||||
example (φ : G →* H) (ψ : H →* K) (S : Subgroup G) :
|
||||
map (ψ.comp φ) S = map ψ (S.map φ) := by
|
||||
sorry
|
||||
|
||||
end exercises
|
||||
|
||||
attribute [local instance 10] setFintype Classical.propDecidable
|
||||
|
||||
open Fintype
|
||||
|
||||
example {G : Type*} [Group G] [Fintype G] (G' : Subgroup G) : card G' ∣ card G :=
|
||||
⟨G'.index, mul_comm G'.index _ ▸ G'.index_mul_card.symm⟩
|
||||
|
||||
open Subgroup
|
||||
|
||||
example {G : Type*} [Group G] [Fintype G] (p : ℕ) {n : ℕ} [Fact p.Prime]
|
||||
(hdvd : p ^ n ∣ card G) : ∃ K : Subgroup G, card K = p ^ n :=
|
||||
Sylow.exists_subgroup_card_pow_prime p hdvd
|
||||
|
||||
lemma eq_bot_iff_card {G : Type*} [Group G] {H : Subgroup G} [Fintype H] :
|
||||
H = ⊥ ↔ card H = 1 := by
|
||||
suffices (∀ x ∈ H, x = 1) ↔ ∃ x ∈ H, ∀ a ∈ H, a = x by
|
||||
simpa [eq_bot_iff_forall, card_eq_one_iff]
|
||||
sorry
|
||||
|
||||
#check card_dvd_of_le
|
||||
|
||||
lemma inf_bot_of_coprime {G : Type*} [Group G] (H K : Subgroup G) [Fintype H] [Fintype K]
|
||||
(h : (card H).Coprime (card K)) : H ⊓ K = ⊥ := by
|
||||
sorry
|
||||
open Equiv
|
||||
|
||||
example {X : Type*} [Finite X] : Subgroup.closure {σ : Perm X | Perm.IsCycle σ} = ⊤ :=
|
||||
Perm.closure_isCycle
|
||||
|
||||
#simp [mul_assoc] c[1, 2, 3] * c[2, 3, 4]
|
||||
|
||||
section FreeGroup
|
||||
|
||||
inductive S | a | b | c
|
||||
|
||||
open S
|
||||
|
||||
def myElement : FreeGroup S := (.of a) * (.of b)⁻¹
|
||||
|
||||
def myMorphism : FreeGroup S →* Perm (Fin 5) :=
|
||||
FreeGroup.lift fun | .a => c[1, 2, 3]
|
||||
| .b => c[2, 3, 1]
|
||||
| .c => c[2, 3]
|
||||
|
||||
|
||||
def myGroup := PresentedGroup {.of () ^ 3} deriving Group
|
||||
|
||||
def myMap : Unit → Perm (Fin 5)
|
||||
| () => c[1, 2, 3]
|
||||
|
||||
lemma compat_myMap :
|
||||
∀ r ∈ ({.of () ^ 3} : Set (FreeGroup Unit)), FreeGroup.lift myMap r = 1 := by
|
||||
rintro _ rfl
|
||||
simp
|
||||
|
||||
def myNewMorphism : myGroup →* Perm (Fin 5) := PresentedGroup.toGroup compat_myMap
|
||||
|
||||
end FreeGroup
|
||||
|
||||
noncomputable section GroupActions
|
||||
|
||||
example {G X : Type*} [Group G] [MulAction G X] (g g': G) (x : X) :
|
||||
g • (g' • x) = (g * g') • x :=
|
||||
(mul_smul g g' x).symm
|
||||
|
||||
example {G X : Type*} [AddGroup G] [AddAction G X] (g g' : G) (x : X) :
|
||||
g +ᵥ (g' +ᵥ x) = (g + g') +ᵥ x :=
|
||||
(add_vadd g g' x).symm
|
||||
|
||||
open MulAction
|
||||
|
||||
example {G X : Type*} [Group G] [MulAction G X] : G →* Equiv.Perm X :=
|
||||
toPermHom G X
|
||||
|
||||
def CayleyIsoMorphism (G : Type*) [Group G] : G ≃* (toPermHom G G).range :=
|
||||
Equiv.Perm.subgroupOfMulAction G G
|
||||
|
||||
example {G X : Type*} [Group G] [MulAction G X] :
|
||||
X ≃ (ω : orbitRel.Quotient G X) × (orbit G (Quotient.out' ω)) :=
|
||||
MulAction.selfEquivSigmaOrbits G X
|
||||
|
||||
example {G X : Type*} [Group G] [MulAction G X] (x : X) :
|
||||
orbit G x ≃ G ⧸ stabilizer G x :=
|
||||
MulAction.orbitEquivQuotientStabilizer G x
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) : G ≃ (G ⧸ H) × H :=
|
||||
groupEquivQuotientProdSubgroup
|
||||
|
||||
variable {G : Type*} [Group G]
|
||||
|
||||
lemma conjugate_one (H : Subgroup G) : conjugate 1 H = H := by
|
||||
sorry
|
||||
|
||||
instance : MulAction G (Subgroup G) where
|
||||
smul := conjugate
|
||||
one_smul := by
|
||||
sorry
|
||||
mul_smul := by
|
||||
sorry
|
||||
|
||||
end GroupActions
|
||||
|
||||
noncomputable section QuotientGroup
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) [H.Normal] : Group (G ⧸ H) := inferInstance
|
||||
|
||||
example {G : Type*} [Group G] (H : Subgroup G) [H.Normal] : G →* G ⧸ H :=
|
||||
QuotientGroup.mk' H
|
||||
|
||||
example {G : Type*} [Group G] (N : Subgroup G) [N.Normal] {M : Type*}
|
||||
[Group M] (φ : G →* M) (h : N ≤ MonoidHom.ker φ) : G ⧸ N →* M :=
|
||||
QuotientGroup.lift N φ h
|
||||
|
||||
example {G : Type*} [Group G] {M : Type*} [Group M] (φ : G →* M) :
|
||||
G ⧸ MonoidHom.ker φ →* MonoidHom.range φ :=
|
||||
QuotientGroup.quotientKerEquivRange φ
|
||||
|
||||
example {G G': Type*} [Group G] [Group G']
|
||||
{N : Subgroup G} [N.Normal] {N' : Subgroup G'} [N'.Normal]
|
||||
{φ : G →* G'} (h : N ≤ Subgroup.comap φ N') : G ⧸ N →* G' ⧸ N':=
|
||||
QuotientGroup.map N N' φ h
|
||||
|
||||
example {G : Type*} [Group G] {M N : Subgroup G} [M.Normal]
|
||||
[N.Normal] (h : M = N) : G ⧸ M ≃* G ⧸ N := QuotientGroup.quotientMulEquivOfEq h
|
||||
|
||||
section
|
||||
variable {G : Type*} [Group G] {H K : Subgroup G}
|
||||
|
||||
open MonoidHom
|
||||
|
||||
#check card_pos -- The nonempty argument will be automatically inferred for subgroups
|
||||
#check Subgroup.index_eq_card
|
||||
#check Subgroup.index_mul_card
|
||||
#check Nat.eq_of_mul_eq_mul_right
|
||||
|
||||
lemma aux_card_eq [Fintype G] (h' : card G = card H * card K) : card (G⧸H) = card K := by
|
||||
sorry
|
||||
variable [H.Normal] [K.Normal] [Fintype G] (h : Disjoint H K) (h' : card G = card H * card K)
|
||||
|
||||
#check bijective_iff_injective_and_card
|
||||
#check ker_eq_bot_iff
|
||||
#check restrict
|
||||
#check ker_restrict
|
||||
|
||||
def iso₁ [Fintype G] (h : Disjoint H K) (h' : card G = card H * card K) : K ≃* G⧸H := by
|
||||
sorry
|
||||
def iso₂ : G ≃* (G⧸K) × (G⧸H) := by
|
||||
sorry
|
||||
#check MulEquiv.prodCongr
|
||||
|
||||
def finalIso : G ≃* H × K :=
|
||||
sorry
|
|
@ -0,0 +1,223 @@
|
|||
import Mathlib.RingTheory.Ideal.QuotientOperations
|
||||
import Mathlib.RingTheory.Localization.Basic
|
||||
import Mathlib.RingTheory.DedekindDomain.Ideal
|
||||
import Mathlib.Analysis.Complex.Polynomial
|
||||
import Mathlib.Data.ZMod.Quotient
|
||||
import MIL.Common
|
||||
|
||||
noncomputable section
|
||||
|
||||
example {R : Type*} [CommRing R] (x y : R) : (x + y)^2 = x^2 + y^2 + 2*x*y := by ring
|
||||
|
||||
example (x y : ℕ) : (x + y)^2 = x^2 + y^2 + 2*x*y := by ring
|
||||
|
||||
example (x : ℤˣ) : x = 1 ∨ x = -1 := Int.units_eq_one_or x
|
||||
|
||||
example {M : Type*} [Monoid M] (x : Mˣ) : (x : M)*x⁻¹ = 1 := Units.mul_inv x
|
||||
|
||||
example {M : Type*} [Monoid M] : Group Mˣ := inferInstance
|
||||
|
||||
example {R S : Type*} [Ring R] [Ring S] (f : R →+* S) (x y : R) :
|
||||
f (x + y) = f x + f y := f.map_add x y
|
||||
|
||||
example {R S : Type*} [Ring R] [Ring S] (f : R →+* S) : Rˣ →* Sˣ :=
|
||||
Units.map f
|
||||
|
||||
example {R : Type*} [Ring R] (S : Subring R) : Ring S := inferInstance
|
||||
|
||||
example {R : Type*} [CommRing R] (I : Ideal R) : R →+* R⧸I :=
|
||||
Ideal.Quotient.mk I
|
||||
|
||||
example {R : Type*} [CommRing R] {a : R} {I : Ideal R} :
|
||||
Ideal.Quotient.mk I a = 0 ↔ a ∈ I :=
|
||||
Ideal.Quotient.eq_zero_iff_mem
|
||||
|
||||
example {R S : Type*} [CommRing R] [CommRing S] (I : Ideal R) (f : R →+* S)
|
||||
(H : I ≤ RingHom.ker f) : R ⧸ I →+* S :=
|
||||
Ideal.Quotient.lift I f H
|
||||
|
||||
example {R S : Type*} [CommRing R] [CommRing S](f : R →+* S) :
|
||||
R ⧸ RingHom.ker f ≃+* f.range :=
|
||||
RingHom.quotientKerEquivRange f
|
||||
|
||||
section
|
||||
variable {R : Type*} [CommRing R] {I J : Ideal R}
|
||||
|
||||
example : I + J = I ⊔ J := rfl
|
||||
|
||||
example {x : R} : x ∈ I + J ↔ ∃ a ∈ I, ∃ b ∈ J, a + b = x := by
|
||||
simp [Submodule.mem_sup]
|
||||
|
||||
example : I * J ≤ J := Ideal.mul_le_left
|
||||
|
||||
example : I * J ≤ I := Ideal.mul_le_right
|
||||
|
||||
example : I * J ≤ I ⊓ J := Ideal.mul_le_inf
|
||||
|
||||
end
|
||||
|
||||
example {R S : Type*} [CommRing R] [CommRing S] (I : Ideal R) (J : Ideal S) (f : R →+* S)
|
||||
(H : I ≤ Ideal.comap f J) : R ⧸ I →+* S ⧸ J :=
|
||||
Ideal.quotientMap J f H
|
||||
|
||||
example {R : Type*} [CommRing R] {I J : Ideal R} (h : I = J) : R ⧸ I ≃+* R ⧸ J :=
|
||||
Ideal.quotEquivOfEq h
|
||||
|
||||
example {R : Type*} [CommRing R] {ι : Type*} [Fintype ι] (f : ι → Ideal R)
|
||||
(hf : ∀ i j, i ≠ j → IsCoprime (f i) (f j)) : (R ⧸ ⨅ i, f i) ≃+* Π i, R ⧸ f i :=
|
||||
Ideal.quotientInfRingEquivPiQuotient f hf
|
||||
|
||||
open BigOperators PiNotation
|
||||
|
||||
example {ι : Type*} [Fintype ι] (a : ι → ℕ) (coprime : ∀ i j, i ≠ j → (a i).Coprime (a j)) :
|
||||
ZMod (∏ i, a i) ≃+* ∀ i, ZMod (a i) :=
|
||||
ZMod.prodEquivPi a coprime
|
||||
|
||||
section
|
||||
variable {ι R : Type*} [CommRing R]
|
||||
open Ideal Quotient Function
|
||||
|
||||
#check Pi.ringHom
|
||||
#check ker_Pi_Quotient_mk
|
||||
|
||||
/-- The homomorphism from ``R ⧸ ⨅ i, I i`` to ``Π i, R ⧸ I i`` featured in the Chinese
|
||||
Remainder Theorem. -/
|
||||
def chineseMap (I : ι → Ideal R) : (R ⧸ ⨅ i, I i) →+* Π i, R ⧸ I i :=
|
||||
sorry
|
||||
|
||||
lemma chineseMap_mk (I : ι → Ideal R) (x : R) :
|
||||
chineseMap I (Quotient.mk _ x) = fun i : ι ↦ Ideal.Quotient.mk (I i) x :=
|
||||
sorry
|
||||
|
||||
lemma chineseMap_mk' (I : ι → Ideal R) (x : R) (i : ι) :
|
||||
chineseMap I (mk _ x) i = mk (I i) x :=
|
||||
sorry
|
||||
|
||||
#check injective_lift_iff
|
||||
|
||||
lemma chineseMap_inj (I : ι → Ideal R) : Injective (chineseMap I) := by
|
||||
sorry
|
||||
|
||||
#check IsCoprime
|
||||
#check isCoprime_iff_add
|
||||
#check isCoprime_iff_exists
|
||||
#check isCoprime_iff_sup_eq
|
||||
#check isCoprime_iff_codisjoint
|
||||
|
||||
#check Finset.mem_insert_of_mem
|
||||
#check Finset.mem_insert_self
|
||||
|
||||
theorem isCoprime_Inf {I : Ideal R} {J : ι → Ideal R} {s : Finset ι}
|
||||
(hf : ∀ j ∈ s, IsCoprime I (J j)) : IsCoprime I (⨅ j ∈ s, J j) := by
|
||||
classical
|
||||
simp_rw [isCoprime_iff_add] at *
|
||||
induction s using Finset.induction with
|
||||
| empty =>
|
||||
simp
|
||||
| @insert i s _ hs =>
|
||||
rw [Finset.iInf_insert, inf_comm, one_eq_top, eq_top_iff, ← one_eq_top]
|
||||
set K := ⨅ j ∈ s, J j
|
||||
calc
|
||||
1 = I + K := sorry
|
||||
_ = I + K*(I + J i) := sorry
|
||||
_ = (1+K)*I + K*J i := sorry
|
||||
_ ≤ I + K ⊓ J i := sorry
|
||||
lemma chineseMap_surj [Fintype ι] {I : ι → Ideal R}
|
||||
(hI : ∀ i j, i ≠ j → IsCoprime (I i) (I j)) : Surjective (chineseMap I) := by
|
||||
classical
|
||||
intro g
|
||||
choose f hf using fun i ↦ Ideal.Quotient.mk_surjective (g i)
|
||||
have key : ∀ i, ∃ e : R, mk (I i) e = 1 ∧ ∀ j, j ≠ i → mk (I j) e = 0 := by
|
||||
intro i
|
||||
have hI' : ∀ j ∈ ({i} : Finset ι)ᶜ, IsCoprime (I i) (I j) := by
|
||||
sorry
|
||||
sorry
|
||||
choose e he using key
|
||||
use mk _ (∑ i, f i*e i)
|
||||
sorry
|
||||
|
||||
noncomputable def chineseIso [Fintype ι] (f : ι → Ideal R)
|
||||
(hf : ∀ i j, i ≠ j → IsCoprime (f i) (f j)) : (R ⧸ ⨅ i, f i) ≃+* ∀ i, R ⧸ f i :=
|
||||
{ Equiv.ofBijective _ ⟨chineseMap_inj f, chineseMap_surj hf⟩,
|
||||
chineseMap f with }
|
||||
|
||||
end
|
||||
|
||||
example {R A : Type*} [CommRing R] [Ring A] [Algebra R A] (r r' : R) (a : A) :
|
||||
(r + r') • a = r • a + r' • a :=
|
||||
add_smul r r' a
|
||||
|
||||
example {R A : Type*} [CommRing R] [Ring A] [Algebra R A] (r r' : R) (a : A) :
|
||||
(r * r') • a = r • r' • a :=
|
||||
mul_smul r r' a
|
||||
|
||||
section Polynomials
|
||||
open Polynomial
|
||||
|
||||
example {R : Type*} [CommRing R] : R[X] := X
|
||||
|
||||
example {R : Type*} [CommRing R] (r : R) := X - C r
|
||||
|
||||
example {R : Type*} [CommRing R] (r : R) : (X + C r) * (X - C r) = X^2 - C (r ^ 2) := by
|
||||
rw [C.map_pow]
|
||||
ring
|
||||
|
||||
example {R : Type*} [CommRing R](r:R) : (C r).coeff 0 = r := by simp
|
||||
|
||||
example {R : Type*} [CommRing R] : (X^2 + 2*X + C 3 : R[X]).coeff 1 = 2 := by simp
|
||||
|
||||
example {R : Type*} [Semiring R] [NoZeroDivisors R] {p q : R[X]} :
|
||||
degree (p * q) = degree p + degree q :=
|
||||
Polynomial.degree_mul
|
||||
|
||||
example {R : Type*} [Semiring R] [NoZeroDivisors R] {p q : R[X]} (hp : p ≠ 0) (hq : q ≠ 0) :
|
||||
natDegree (p * q) = natDegree p + natDegree q :=
|
||||
Polynomial.natDegree_mul hp hq
|
||||
|
||||
example {R : Type*} [Semiring R] [NoZeroDivisors R] {p q : R[X]} :
|
||||
natDegree (comp p q) = natDegree p * natDegree q :=
|
||||
Polynomial.natDegree_comp
|
||||
|
||||
example {R : Type*} [CommRing R] (P: R[X]) (x : R) := P.eval x
|
||||
|
||||
example {R : Type*} [CommRing R] (r : R) : (X - C r).eval r = 0 := by simp
|
||||
|
||||
example {R : Type*} [CommRing R] (P : R[X]) (r : R) : IsRoot P r ↔ P.eval r = 0 := Iff.rfl
|
||||
|
||||
example {R : Type*} [CommRing R] [IsDomain R] (r : R) : (X - C r).roots = {r} :=
|
||||
roots_X_sub_C r
|
||||
|
||||
example {R : Type*} [CommRing R] [IsDomain R] (r : R) (n : ℕ):
|
||||
((X - C r)^n).roots = n • {r} :=
|
||||
by simp
|
||||
|
||||
example : aeval Complex.I (X^2 + 1 : ℝ[X]) = 0 := by simp
|
||||
|
||||
open Complex Polynomial
|
||||
|
||||
example : aroots (X^2 + 1 : ℝ[X]) ℂ = {Complex.I, -I} := by
|
||||
suffices roots (X ^ 2 + 1 : ℂ[X]) = {I, -I} by simpa [aroots_def]
|
||||
have factored : (X ^ 2 + 1 : ℂ[X]) = (X - C I) * (X - C (-I)) := by
|
||||
rw [C_neg]
|
||||
linear_combination show (C I * C I : ℂ[X]) = -1 by simp [← C_mul]
|
||||
have p_ne_zero : (X - C I) * (X - C (-I)) ≠ 0 := by
|
||||
intro H
|
||||
apply_fun eval 0 at H
|
||||
simp [eval] at H
|
||||
simp only [factored, roots_mul p_ne_zero, roots_X_sub_C]
|
||||
rfl
|
||||
|
||||
-- Mathlib knows about D'Alembert-Gauss theorem: ``ℂ`` is algebraically closed.
|
||||
example : IsAlgClosed ℂ := inferInstance
|
||||
|
||||
#check (Complex.ofReal : ℝ →+* ℂ)
|
||||
|
||||
example : (X^2 + 1 : ℝ[X]).eval₂ Complex.ofReal Complex.I = 0 := by simp
|
||||
|
||||
open MvPolynomial
|
||||
|
||||
def circleEquation : MvPolynomial (Fin 2) ℝ := X 0 ^ 2 + X 1 ^ 2 - 1
|
||||
|
||||
example : MvPolynomial.eval ![0, 1] circleEquation = 0 := by simp [circleEquation]
|
||||
|
||||
end Polynomials
|
|
@ -0,0 +1,166 @@
|
|||
import Mathlib.GroupTheory.Sylow
|
||||
import Mathlib.GroupTheory.Perm.Cycle.Concrete
|
||||
import Mathlib.GroupTheory.Perm.Subgroup
|
||||
import Mathlib.GroupTheory.PresentedGroup
|
||||
|
||||
import MIL.Common
|
||||
|
||||
def conjugate {G : Type*} [Group G] (x : G) (H : Subgroup G) : Subgroup G where
|
||||
carrier := {a : G | ∃ h, h ∈ H ∧ a = x * h * x⁻¹}
|
||||
one_mem' := by
|
||||
dsimp
|
||||
use 1
|
||||
constructor
|
||||
exact H.one_mem
|
||||
group
|
||||
inv_mem' := by
|
||||
dsimp
|
||||
rintro - ⟨h, h_in, rfl⟩
|
||||
use h⁻¹, H.inv_mem h_in
|
||||
group
|
||||
mul_mem' := by
|
||||
dsimp
|
||||
rintro - - ⟨h, h_in, rfl⟩ ⟨k, k_in, rfl⟩
|
||||
use h*k, H.mul_mem h_in k_in
|
||||
group
|
||||
|
||||
section exercises
|
||||
variable {G H : Type*} [Group G] [Group H]
|
||||
|
||||
open Subgroup
|
||||
|
||||
example (φ : G →* H) (S T : Subgroup H) (hST : S ≤ T) : comap φ S ≤ comap φ T :=by
|
||||
intro x hx
|
||||
rw [mem_comap] at * -- Lean does not need this line
|
||||
exact hST hx
|
||||
|
||||
example (φ : G →* H) (S T : Subgroup G) (hST : S ≤ T) : map φ S ≤ map φ T :=by
|
||||
intro x hx
|
||||
rw [mem_map] at * -- Lean does not need this line
|
||||
rcases hx with ⟨y, hy, rfl⟩
|
||||
use y, hST hy
|
||||
|
||||
variable {K : Type*} [Group K]
|
||||
|
||||
-- Remember you can use the `ext` tactic to prove an equality of subgroups.
|
||||
example (φ : G →* H) (ψ : H →* K) (U : Subgroup K) :
|
||||
comap (ψ.comp φ) U = comap φ (comap ψ U) := by
|
||||
-- The whole proof could be ``rfl``, but let's decompose it a bit.
|
||||
ext x
|
||||
simp only [mem_comap]
|
||||
rfl
|
||||
|
||||
-- Pushing a subgroup along one homomorphism and then another is equal to
|
||||
-- pushing it forward along the composite of the homomorphisms.
|
||||
example (φ : G →* H) (ψ : H →* K) (S : Subgroup G) :
|
||||
map (ψ.comp φ) S = map ψ (S.map φ) := by
|
||||
ext x
|
||||
simp only [mem_map]
|
||||
constructor
|
||||
· rintro ⟨y, y_in, hy⟩
|
||||
exact ⟨φ y, ⟨y, y_in, rfl⟩, hy⟩
|
||||
· rintro ⟨y, ⟨z, z_in, hz⟩, hy⟩
|
||||
use z, z_in
|
||||
calc ψ.comp φ z = ψ (φ z) := rfl
|
||||
_ = ψ y := by congr
|
||||
_ = x := hy
|
||||
|
||||
end exercises
|
||||
|
||||
attribute [local instance 10] setFintype Classical.propDecidable
|
||||
|
||||
open Fintype
|
||||
open Subgroup
|
||||
|
||||
lemma eq_bot_iff_card {G : Type*} [Group G] {H : Subgroup G} [Fintype H] :
|
||||
H = ⊥ ↔ card H = 1 := by
|
||||
suffices (∀ x ∈ H, x = 1) ↔ ∃ x ∈ H, ∀ a ∈ H, a = x by
|
||||
simpa [eq_bot_iff_forall, card_eq_one_iff]
|
||||
constructor
|
||||
· intro h
|
||||
use 1, H.one_mem
|
||||
· rintro ⟨y, -, hy'⟩ x hx
|
||||
calc x = y := hy' x hx
|
||||
_ = 1 := (hy' 1 H.one_mem).symm
|
||||
|
||||
lemma inf_bot_of_coprime {G : Type*} [Group G] (H K : Subgroup G) [Fintype H] [Fintype K]
|
||||
(h : (card H).Coprime (card K)) : H ⊓ K = ⊥ := by
|
||||
have D₁ : card (H ⊓ K : Subgroup G) ∣ card H := card_dvd_of_le inf_le_left
|
||||
have D₂ : card (H ⊓ K : Subgroup G) ∣ card K := card_dvd_of_le inf_le_right
|
||||
exact eq_bot_iff_card.2 (Nat.eq_one_of_dvd_coprimes h D₁ D₂)
|
||||
|
||||
noncomputable section GroupActions
|
||||
|
||||
variable {G : Type*} [Group G]
|
||||
|
||||
lemma conjugate_one (H : Subgroup G) : conjugate 1 H = H := by
|
||||
ext x
|
||||
simp [conjugate]
|
||||
|
||||
instance : MulAction G (Subgroup G) where
|
||||
smul := conjugate
|
||||
one_smul := by
|
||||
exact conjugate_one
|
||||
mul_smul := by
|
||||
intro x y H
|
||||
ext z
|
||||
constructor
|
||||
· rintro ⟨h, h_in, rfl⟩
|
||||
use y*h*y⁻¹
|
||||
constructor
|
||||
· use h
|
||||
· group
|
||||
· rintro ⟨-, ⟨h, h_in, rfl⟩, rfl⟩
|
||||
use h, h_in
|
||||
group
|
||||
|
||||
end GroupActions
|
||||
|
||||
noncomputable section QuotientGroup
|
||||
|
||||
section
|
||||
variable {G : Type*} [Group G] {H K : Subgroup G}
|
||||
|
||||
open MonoidHom
|
||||
|
||||
#check card_pos -- The nonempty argument will be automatically inferred for subgroups
|
||||
#check Subgroup.index_eq_card
|
||||
#check Subgroup.index_mul_card
|
||||
#check Nat.eq_of_mul_eq_mul_right
|
||||
|
||||
lemma aux_card_eq [Fintype G] (h' : card G = card H * card K) : card (G⧸H) = card K := by
|
||||
have := calc
|
||||
card (G ⧸ H) * card H = card G := by rw [← H.index_eq_card, H.index_mul_card]
|
||||
_ = card K * card H := by rw [h', mul_comm]
|
||||
|
||||
exact Nat.eq_of_mul_eq_mul_right card_pos this
|
||||
|
||||
variable [H.Normal] [K.Normal] [Fintype G] (h : Disjoint H K) (h' : card G = card H * card K)
|
||||
|
||||
#check bijective_iff_injective_and_card
|
||||
#check ker_eq_bot_iff
|
||||
#check restrict
|
||||
#check ker_restrict
|
||||
|
||||
def iso₁ [Fintype G] (h : Disjoint H K) (h' : card G = card H * card K) : K ≃* G⧸H := by
|
||||
apply MulEquiv.ofBijective ((QuotientGroup.mk' H).restrict K)
|
||||
rw [bijective_iff_injective_and_card]
|
||||
constructor
|
||||
· rw [← ker_eq_bot_iff, (QuotientGroup.mk' H).ker_restrict K]
|
||||
simp [h]
|
||||
· symm
|
||||
exact aux_card_eq h'
|
||||
|
||||
def iso₂ : G ≃* (G⧸K) × (G⧸H) := by
|
||||
apply MulEquiv.ofBijective <| (QuotientGroup.mk' K).prod (QuotientGroup.mk' H)
|
||||
rw [bijective_iff_injective_and_card]
|
||||
constructor
|
||||
· rw [← ker_eq_bot_iff, ker_prod]
|
||||
simp [h.symm.eq_bot]
|
||||
· rw [card_prod, aux_card_eq h', aux_card_eq (mul_comm (card H) _▸ h'), h']
|
||||
|
||||
def finalIso : G ≃* H × K :=
|
||||
(iso₂ h h').trans ((iso₁ h.symm (mul_comm (card H) _ ▸ h')).prodCongr (iso₁ h h')).symm
|
||||
|
||||
end
|
||||
end QuotientGroup
|
|
@ -0,0 +1,83 @@
|
|||
import Mathlib.RingTheory.Ideal.QuotientOperations
|
||||
import Mathlib.RingTheory.Localization.Basic
|
||||
import Mathlib.RingTheory.DedekindDomain.Ideal
|
||||
import Mathlib.Analysis.Complex.Polynomial
|
||||
import Mathlib.Data.ZMod.Quotient
|
||||
import MIL.Common
|
||||
|
||||
noncomputable section
|
||||
|
||||
open BigOperators PiNotation
|
||||
|
||||
section
|
||||
variable {ι R : Type*} [CommRing R]
|
||||
open Ideal Quotient Function
|
||||
|
||||
#check Pi.ringHom
|
||||
#check ker_Pi_Quotient_mk
|
||||
|
||||
/-- The homomorphism from ``R ⧸ ⨅ i, I i`` to ``Π i, R ⧸ I i`` featured in the Chinese
|
||||
Remainder Theorem. -/
|
||||
def chineseMap (I : ι → Ideal R) : (R ⧸ ⨅ i, I i) →+* Π i, R ⧸ I i :=
|
||||
Ideal.Quotient.lift (⨅ i, I i) (Pi.ringHom fun i : ι ↦ Ideal.Quotient.mk (I i))
|
||||
(by simp [← RingHom.mem_ker, ker_Pi_Quotient_mk])
|
||||
|
||||
lemma chineseMap_mk (I : ι → Ideal R) (x : R) :
|
||||
chineseMap I (Quotient.mk _ x) = fun i : ι ↦ Ideal.Quotient.mk (I i) x :=
|
||||
rfl
|
||||
|
||||
lemma chineseMap_mk' (I : ι → Ideal R) (x : R) (i : ι) :
|
||||
chineseMap I (mk _ x) i = mk (I i) x :=
|
||||
rfl
|
||||
|
||||
lemma chineseMap_inj (I : ι → Ideal R) : Injective (chineseMap I) := by
|
||||
rw [chineseMap, injective_lift_iff, ker_Pi_Quotient_mk]
|
||||
|
||||
theorem isCoprime_Inf {I : Ideal R} {J : ι → Ideal R} {s : Finset ι}
|
||||
(hf : ∀ j ∈ s, IsCoprime I (J j)) : IsCoprime I (⨅ j ∈ s, J j) := by
|
||||
classical
|
||||
simp_rw [isCoprime_iff_add] at *
|
||||
induction s using Finset.induction with
|
||||
| empty =>
|
||||
simp
|
||||
| @insert i s _ hs =>
|
||||
rw [Finset.iInf_insert, inf_comm, one_eq_top, eq_top_iff, ← one_eq_top]
|
||||
set K := ⨅ j ∈ s, J j
|
||||
calc
|
||||
1 = I + K := (hs fun j hj ↦ hf j (Finset.mem_insert_of_mem hj)).symm
|
||||
_ = I + K*(I + J i) := by rw [hf i (Finset.mem_insert_self i s), mul_one]
|
||||
_ = (1+K)*I + K*J i := by ring
|
||||
_ ≤ I + K ⊓ J i := by gcongr ; apply mul_le_left ; apply mul_le_inf
|
||||
|
||||
|
||||
lemma chineseMap_surj [Fintype ι] {I : ι → Ideal R}
|
||||
(hI : ∀ i j, i ≠ j → IsCoprime (I i) (I j)) : Surjective (chineseMap I) := by
|
||||
classical
|
||||
intro g
|
||||
choose f hf using fun i ↦ Ideal.Quotient.mk_surjective (g i)
|
||||
have key : ∀ i, ∃ e : R, mk (I i) e = 1 ∧ ∀ j, j ≠ i → mk (I j) e = 0 := by
|
||||
intro i
|
||||
have hI' : ∀ j ∈ ({i} : Finset ι)ᶜ, IsCoprime (I i) (I j) := by
|
||||
intros j hj
|
||||
exact hI _ _ (by simpa [ne_comm, isCoprime_iff_add] using hj)
|
||||
rcases isCoprime_iff_exists.mp (isCoprime_Inf hI') with ⟨u, hu, e, he, hue⟩
|
||||
replace he : ∀ j, j ≠ i → e ∈ I j := by simpa using he
|
||||
refine ⟨e, ?_, ?_⟩
|
||||
· simp [eq_sub_of_add_eq' hue, map_sub, eq_zero_iff_mem.mpr hu]
|
||||
rfl
|
||||
· exact fun j hj ↦ eq_zero_iff_mem.mpr (he j hj)
|
||||
choose e he using key
|
||||
use mk _ (∑ i, f i*e i)
|
||||
ext i
|
||||
rw [chineseMap_mk', map_sum, Fintype.sum_eq_single i]
|
||||
· simp [(he i).1, hf]
|
||||
· intros j hj
|
||||
simp [(he j).2 i hj.symm]
|
||||
|
||||
noncomputable def chineseIso [Fintype ι] (f : ι → Ideal R)
|
||||
(hf : ∀ i j, i ≠ j → IsCoprime (f i) (f j)) : (R ⧸ ⨅ i, f i) ≃+* ∀ i, R ⧸ f i :=
|
||||
{ Equiv.ofBijective _ ⟨chineseMap_inj f, chineseMap_surj hf⟩,
|
||||
chineseMap f with }
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Topology.Instances.Real
|
||||
|
||||
open Set Filter Topology
|
||||
|
||||
def principal {α : Type*} (s : Set α) : Filter α
|
||||
where
|
||||
sets := { t | s ⊆ t }
|
||||
univ_sets := sorry
|
||||
sets_of_superset := sorry
|
||||
inter_sets := sorry
|
||||
|
||||
example : Filter ℕ :=
|
||||
{ sets := { s | ∃ a, ∀ b, a ≤ b → b ∈ s }
|
||||
univ_sets := sorry
|
||||
sets_of_superset := sorry
|
||||
inter_sets := sorry }
|
||||
|
||||
def Tendsto₁ {X Y : Type*} (f : X → Y) (F : Filter X) (G : Filter Y) :=
|
||||
∀ V ∈ G, f ⁻¹' V ∈ F
|
||||
|
||||
def Tendsto₂ {X Y : Type*} (f : X → Y) (F : Filter X) (G : Filter Y) :=
|
||||
map f F ≤ G
|
||||
|
||||
example {X Y : Type*} (f : X → Y) (F : Filter X) (G : Filter Y) :
|
||||
Tendsto₂ f F G ↔ Tendsto₁ f F G :=
|
||||
Iff.rfl
|
||||
|
||||
#check (@Filter.map_mono : ∀ {α β} {m : α → β}, Monotone (map m))
|
||||
|
||||
#check
|
||||
(@Filter.map_map :
|
||||
∀ {α β γ} {f : Filter α} {m : α → β} {m' : β → γ}, map m' (map m f) = map (m' ∘ m) f)
|
||||
|
||||
example {X Y Z : Type*} {F : Filter X} {G : Filter Y} {H : Filter Z} {f : X → Y} {g : Y → Z}
|
||||
(hf : Tendsto₁ f F G) (hg : Tendsto₁ g G H) : Tendsto₁ (g ∘ f) F H :=
|
||||
sorry
|
||||
|
||||
variable (f : ℝ → ℝ) (x₀ y₀ : ℝ)
|
||||
|
||||
#check comap ((↑) : ℚ → ℝ) (𝓝 x₀)
|
||||
|
||||
#check Tendsto (f ∘ (↑)) (comap ((↑) : ℚ → ℝ) (𝓝 x₀)) (𝓝 y₀)
|
||||
|
||||
section
|
||||
variable {α β γ : Type*} (F : Filter α) {m : γ → β} {n : β → α}
|
||||
|
||||
#check (comap_comap : comap m (comap n F) = comap (n ∘ m) F)
|
||||
|
||||
end
|
||||
|
||||
example : 𝓝 (x₀, y₀) = 𝓝 x₀ ×ˢ 𝓝 y₀ :=
|
||||
nhds_prod_eq
|
||||
|
||||
#check le_inf_iff
|
||||
|
||||
example (f : ℕ → ℝ × ℝ) (x₀ y₀ : ℝ) :
|
||||
Tendsto f atTop (𝓝 (x₀, y₀)) ↔
|
||||
Tendsto (Prod.fst ∘ f) atTop (𝓝 x₀) ∧ Tendsto (Prod.snd ∘ f) atTop (𝓝 y₀) :=
|
||||
sorry
|
||||
|
||||
example (x₀ : ℝ) : HasBasis (𝓝 x₀) (fun ε : ℝ ↦ 0 < ε) fun ε ↦ Ioo (x₀ - ε) (x₀ + ε) :=
|
||||
nhds_basis_Ioo_pos x₀
|
||||
|
||||
example (u : ℕ → ℝ) (x₀ : ℝ) :
|
||||
Tendsto u atTop (𝓝 x₀) ↔ ∀ ε > 0, ∃ N, ∀ n ≥ N, u n ∈ Ioo (x₀ - ε) (x₀ + ε) := by
|
||||
have : atTop.HasBasis (fun _ : ℕ ↦ True) Ici := atTop_basis
|
||||
rw [this.tendsto_iff (nhds_basis_Ioo_pos x₀)]
|
||||
simp
|
||||
|
||||
example (P Q : ℕ → Prop) (hP : ∀ᶠ n in atTop, P n) (hQ : ∀ᶠ n in atTop, Q n) :
|
||||
∀ᶠ n in atTop, P n ∧ Q n :=
|
||||
hP.and hQ
|
||||
|
||||
example (u v : ℕ → ℝ) (h : ∀ᶠ n in atTop, u n = v n) (x₀ : ℝ) :
|
||||
Tendsto u atTop (𝓝 x₀) ↔ Tendsto v atTop (𝓝 x₀) :=
|
||||
tendsto_congr' h
|
||||
|
||||
example (u v : ℕ → ℝ) (h : u =ᶠ[atTop] v) (x₀ : ℝ) :
|
||||
Tendsto u atTop (𝓝 x₀) ↔ Tendsto v atTop (𝓝 x₀) :=
|
||||
tendsto_congr' h
|
||||
|
||||
#check eventually_of_forall
|
||||
#check Eventually.mono
|
||||
#check Eventually.and
|
||||
|
||||
example (P Q R : ℕ → Prop) (hP : ∀ᶠ n in atTop, P n) (hQ : ∀ᶠ n in atTop, Q n)
|
||||
(hR : ∀ᶠ n in atTop, P n ∧ Q n → R n) : ∀ᶠ n in atTop, R n := by
|
||||
apply (hP.and (hQ.and hR)).mono
|
||||
rintro n ⟨h, h', h''⟩
|
||||
exact h'' ⟨h, h'⟩
|
||||
|
||||
example (P Q R : ℕ → Prop) (hP : ∀ᶠ n in atTop, P n) (hQ : ∀ᶠ n in atTop, Q n)
|
||||
(hR : ∀ᶠ n in atTop, P n ∧ Q n → R n) : ∀ᶠ n in atTop, R n := by
|
||||
filter_upwards [hP, hQ, hR] with n h h' h''
|
||||
exact h'' ⟨h, h'⟩
|
||||
|
||||
#check mem_closure_iff_clusterPt
|
||||
#check le_principal_iff
|
||||
#check neBot_of_le
|
||||
|
||||
example (u : ℕ → ℝ) (M : Set ℝ) (x : ℝ) (hux : Tendsto u atTop (𝓝 x))
|
||||
(huM : ∀ᶠ n in atTop, u n ∈ M) : x ∈ closure M :=
|
||||
sorry
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
import MIL.Common
|
||||
import Mathlib.Topology.Instances.Real
|
||||
import Mathlib.Analysis.NormedSpace.BanachSteinhaus
|
||||
|
||||
open Set Filter
|
||||
open Topology Filter
|
||||
|
||||
variable {X : Type*} [MetricSpace X] (a b c : X)
|
||||
|
||||
#check (dist a b : ℝ)
|
||||
#check (dist_nonneg : 0 ≤ dist a b)
|
||||
#check (dist_eq_zero : dist a b = 0 ↔ a = b)
|
||||
#check (dist_comm a b : dist a b = dist b a)
|
||||
#check (dist_triangle a b c : dist a c ≤ dist a b + dist b c)
|
||||
|
||||
-- Note the next three lines are not quoted, their purpose is to make sure those things don't get renamed while we're looking elsewhere.
|
||||
#check EMetricSpace
|
||||
#check PseudoMetricSpace
|
||||
#check PseudoEMetricSpace
|
||||
|
||||
example {u : ℕ → X} {a : X} :
|
||||
Tendsto u atTop (𝓝 a) ↔ ∀ ε > 0, ∃ N, ∀ n ≥ N, dist (u n) a < ε :=
|
||||
Metric.tendsto_atTop
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] {f : X → Y} :
|
||||
Continuous f ↔
|
||||
∀ x : X, ∀ ε > 0, ∃ δ > 0, ∀ x', dist x' x < δ → dist (f x') (f x) < ε :=
|
||||
Metric.continuous_iff
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] {f : X → Y} (hf : Continuous f) :
|
||||
Continuous fun p : X × X ↦ dist (f p.1) (f p.2) := by continuity
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] {f : X → Y} (hf : Continuous f) :
|
||||
Continuous fun p : X × X ↦ dist (f p.1) (f p.2) :=
|
||||
continuous_dist.comp ((hf.comp continuous_fst).prod_mk (hf.comp continuous_snd))
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] {f : X → Y} (hf : Continuous f) :
|
||||
Continuous fun p : X × X ↦ dist (f p.1) (f p.2) := by
|
||||
apply Continuous.dist
|
||||
exact hf.comp continuous_fst
|
||||
exact hf.comp continuous_snd
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] {f : X → Y} (hf : Continuous f) :
|
||||
Continuous fun p : X × X ↦ dist (f p.1) (f p.2) :=
|
||||
(hf.comp continuous_fst).dist (hf.comp continuous_snd)
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] {f : X → Y} (hf : Continuous f) :
|
||||
Continuous fun p : X × X ↦ dist (f p.1) (f p.2) :=
|
||||
hf.fst'.dist hf.snd'
|
||||
|
||||
example {f : ℝ → X} (hf : Continuous f) : Continuous fun x : ℝ ↦ f (x ^ 2 + x) :=
|
||||
sorry
|
||||
|
||||
example {X Y : Type*} [MetricSpace X] [MetricSpace Y] (f : X → Y) (a : X) :
|
||||
ContinuousAt f a ↔ ∀ ε > 0, ∃ δ > 0, ∀ {x}, dist x a < δ → dist (f x) (f a) < ε :=
|
||||
Metric.continuousAt_iff
|
||||
|
||||
variable (r : ℝ)
|
||||
|
||||
example : Metric.ball a r = { b | dist b a < r } :=
|
||||
rfl
|
||||
|
||||
example : Metric.closedBall a r = { b | dist b a ≤ r } :=
|
||||
rfl
|
||||
|
||||
example (hr : 0 < r) : a ∈ Metric.ball a r :=
|
||||
Metric.mem_ball_self hr
|
||||
|
||||
example (hr : 0 ≤ r) : a ∈ Metric.closedBall a r :=
|
||||
Metric.mem_closedBall_self hr
|
||||
|
||||
example (s : Set X) : IsOpen s ↔ ∀ x ∈ s, ∃ ε > 0, Metric.ball x ε ⊆ s :=
|
||||
Metric.isOpen_iff
|
||||
|
||||
example {s : Set X} : IsClosed s ↔ IsOpen (sᶜ) :=
|
||||
isOpen_compl_iff.symm
|
||||
|
||||
example {s : Set X} (hs : IsClosed s) {u : ℕ → X} (hu : Tendsto u atTop (𝓝 a))
|
||||
(hus : ∀ n, u n ∈ s) : a ∈ s :=
|
||||
hs.mem_of_tendsto hu (eventually_of_forall hus)
|
||||
|
||||
example {s : Set X} : a ∈ closure s ↔ ∀ ε > 0, ∃ b ∈ s, a ∈ Metric.ball b ε :=
|
||||
Metric.mem_closure_iff
|
||||
|
||||
example {u : ℕ → X} (hu : Tendsto u atTop (𝓝 a)) {s : Set X} (hs : ∀ n, u n ∈ s) :
|
||||
a ∈ closure s :=
|
||||
sorry
|
||||
|
||||
example {x : X} {s : Set X} : s ∈ 𝓝 x ↔ ∃ ε > 0, Metric.ball x ε ⊆ s :=
|
||||
Metric.nhds_basis_ball.mem_iff
|
||||
|
||||
example {x : X} {s : Set X} : s ∈ 𝓝 x ↔ ∃ ε > 0, Metric.closedBall x ε ⊆ s :=
|
||||
Metric.nhds_basis_closedBall.mem_iff
|
||||
|
||||
example : IsCompact (Set.Icc 0 1 : Set ℝ) :=
|
||||
isCompact_Icc
|
||||
|
||||
example {s : Set X} (hs : IsCompact s) {u : ℕ → X} (hu : ∀ n, u n ∈ s) :
|
||||
∃ a ∈ s, ∃ φ : ℕ → ℕ, StrictMono φ ∧ Tendsto (u ∘ φ) atTop (𝓝 a) :=
|
||||
hs.tendsto_subseq hu
|
||||
|
||||
example {s : Set X} (hs : IsCompact s) (hs' : s.Nonempty) {f : X → ℝ}
|
||||
(hfs : ContinuousOn f s) :
|
||||
∃ x ∈ s, ∀ y ∈ s, f x ≤ f y :=
|
||||
hs.exists_forall_le hs' hfs
|
||||
|
||||
example {s : Set X} (hs : IsCompact s) (hs' : s.Nonempty) {f : X → ℝ}
|
||||
(hfs : ContinuousOn f s) :
|
||||
∃ x ∈ s, ∀ y ∈ s, f y ≤ f x :=
|
||||
hs.exists_forall_ge hs' hfs
|
||||
|
||||
example {s : Set X} (hs : IsCompact s) : IsClosed s :=
|
||||
hs.isClosed
|
||||
|
||||
example {X : Type*} [MetricSpace X] [CompactSpace X] : IsCompact (univ : Set X) :=
|
||||
isCompact_univ
|
||||
|
||||
#check IsCompact.isClosed
|
||||
|
||||
example {X : Type*} [MetricSpace X] {Y : Type*} [MetricSpace Y] {f : X → Y} :
|
||||
UniformContinuous f ↔
|
||||
∀ ε > 0, ∃ δ > 0, ∀ {a b : X}, dist a b < δ → dist (f a) (f b) < ε :=
|
||||
Metric.uniformContinuous_iff
|
||||
|
||||
example {X : Type*} [MetricSpace X] [CompactSpace X]
|
||||
{Y : Type*} [MetricSpace Y] {f : X → Y}
|
||||
(hf : Continuous f) : UniformContinuous f :=
|
||||
sorry
|
||||
|
||||
example (u : ℕ → X) :
|
||||
CauchySeq u ↔ ∀ ε > 0, ∃ N : ℕ, ∀ m ≥ N, ∀ n ≥ N, dist (u m) (u n) < ε :=
|
||||
Metric.cauchySeq_iff
|
||||
|
||||
example (u : ℕ → X) :
|
||||
CauchySeq u ↔ ∀ ε > 0, ∃ N : ℕ, ∀ n ≥ N, dist (u n) (u N) < ε :=
|
||||
Metric.cauchySeq_iff'
|
||||
|
||||
example [CompleteSpace X] (u : ℕ → X) (hu : CauchySeq u) :
|
||||
∃ x, Tendsto u atTop (𝓝 x) :=
|
||||
cauchySeq_tendsto_of_complete hu
|
||||
|
||||
open BigOperators
|
||||
|
||||
open Finset
|
||||
|
||||
theorem cauchySeq_of_le_geometric_two' {u : ℕ → X}
|
||||
(hu : ∀ n : ℕ, dist (u n) (u (n + 1)) ≤ (1 / 2) ^ n) : CauchySeq u := by
|
||||
rw [Metric.cauchySeq_iff']
|
||||
intro ε ε_pos
|
||||
obtain ⟨N, hN⟩ : ∃ N : ℕ, 1 / 2 ^ N * 2 < ε := by sorry
|
||||
use N
|
||||
intro n hn
|
||||
obtain ⟨k, rfl : n = N + k⟩ := le_iff_exists_add.mp hn
|
||||
calc
|
||||
dist (u (N + k)) (u N) = dist (u (N + 0)) (u (N + k)) := sorry
|
||||
_ ≤ ∑ i in range k, dist (u (N + i)) (u (N + (i + 1))) := sorry
|
||||
_ ≤ ∑ i in range k, (1 / 2 : ℝ) ^ (N + i) := sorry
|
||||
_ = 1 / 2 ^ N * ∑ i in range k, (1 / 2 : ℝ) ^ i := sorry
|
||||
_ ≤ 1 / 2 ^ N * 2 := sorry
|
||||
_ < ε := sorry
|
||||
|
||||
|
||||
open Metric
|
||||
|
||||
example [CompleteSpace X] (f : ℕ → Set X) (ho : ∀ n, IsOpen (f n)) (hd : ∀ n, Dense (f n)) :
|
||||
Dense (⋂ n, f n) := by
|
||||
let B : ℕ → ℝ := fun n ↦ (1 / 2) ^ n
|
||||
have Bpos : ∀ n, 0 < B n
|
||||
sorry
|
||||
/- Translate the density assumption into two functions `center` and `radius` associating
|
||||
to any n, x, δ, δpos a center and a positive radius such that
|
||||
`closedBall center radius` is included both in `f n` and in `closedBall x δ`.
|
||||
We can also require `radius ≤ (1/2)^(n+1)`, to ensure we get a Cauchy sequence later. -/
|
||||
have :
|
||||
∀ (n : ℕ) (x : X),
|
||||
∀ δ > 0, ∃ y : X, ∃ r > 0, r ≤ B (n + 1) ∧ closedBall y r ⊆ closedBall x δ ∩ f n :=
|
||||
by sorry
|
||||
choose! center radius Hpos HB Hball using this
|
||||
intro x
|
||||
rw [mem_closure_iff_nhds_basis nhds_basis_closedBall]
|
||||
intro ε εpos
|
||||
/- `ε` is positive. We have to find a point in the ball of radius `ε` around `x`
|
||||
belonging to all `f n`. For this, we construct inductively a sequence
|
||||
`F n = (c n, r n)` such that the closed ball `closedBall (c n) (r n)` is included
|
||||
in the previous ball and in `f n`, and such that `r n` is small enough to ensure
|
||||
that `c n` is a Cauchy sequence. Then `c n` converges to a limit which belongs
|
||||
to all the `f n`. -/
|
||||
let F : ℕ → X × ℝ := fun n ↦
|
||||
Nat.recOn n (Prod.mk x (min ε (B 0)))
|
||||
fun n p ↦ Prod.mk (center n p.1 p.2) (radius n p.1 p.2)
|
||||
let c : ℕ → X := fun n ↦ (F n).1
|
||||
let r : ℕ → ℝ := fun n ↦ (F n).2
|
||||
have rpos : ∀ n, 0 < r n := by sorry
|
||||
have rB : ∀ n, r n ≤ B n := by sorry
|
||||
have incl : ∀ n, closedBall (c (n + 1)) (r (n + 1)) ⊆ closedBall (c n) (r n) ∩ f n := by
|
||||
sorry
|
||||
have cdist : ∀ n, dist (c n) (c (n + 1)) ≤ B n := by sorry
|
||||
have : CauchySeq c := cauchySeq_of_le_geometric_two' cdist
|
||||
-- as the sequence `c n` is Cauchy in a complete space, it converges to a limit `y`.
|
||||
rcases cauchySeq_tendsto_of_complete this with ⟨y, ylim⟩
|
||||
-- this point `y` will be the desired point. We will check that it belongs to all
|
||||
-- `f n` and to `ball x ε`.
|
||||
use y
|
||||
have I : ∀ n, ∀ m ≥ n, closedBall (c m) (r m) ⊆ closedBall (c n) (r n) := by sorry
|
||||
have yball : ∀ n, y ∈ closedBall (c n) (r n) := by sorry
|
||||
sorry
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue