Merge pull request #15 from lenianiva/experiments/dsp

experiment: Draft-Sketch-Prove
This commit is contained in:
Leni Aniva 2024-10-05 22:30:47 -07:00 committed by GitHub
commit 009ae08894
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
163 changed files with 51139 additions and 237 deletions

View File

@ -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}}
}
```

150
SNAP.md Normal file
View File

@ -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

View File

@ -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")

View File

@ -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

36
examples/sketch.py Normal file
View File

@ -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)

View File

@ -1,3 +0,0 @@
import Mathlib
-- Ensure that Aesop is running

View File

@ -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

View File

@ -1 +0,0 @@
../../src/lean-toolchain

View File

@ -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
```

1
experiments/dsp/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/result

56
experiments/dsp/README.md Normal file
View File

@ -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)

View File

@ -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

View File

@ -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."
]
}

View File

@ -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."
}

View File

@ -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)."
}

View File

@ -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."
]
}
]

View File

@ -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"
]
}
]

View File

@ -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"
}
]

View File

@ -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"
}
]

View File

@ -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:

View File

@ -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)

View File

@ -1,3 +1,2 @@
/build
/lakefile.olean
/lake-packages/*

View File

@ -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?

View File

@ -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

View File

@ -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
.

View File

@ -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

View File

@ -0,0 +1,7 @@
#
## Appendix
### Questions:
Q:

View File

@ -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

View File

@ -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!

View File

@ -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

View File

@ -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."
}

View File

@ -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": "..."
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
def hello := "world"

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
#eval "Hello, World!"

View File

@ -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]

View File

@ -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.

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 (GH) = 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 ≃* GH := by
sorry
def iso₂ : G ≃* (GK) × (GH) := by
sorry
#check MulEquiv.prodCongr
def finalIso : G ≃* H × K :=
sorry

View File

@ -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 →+* RI :=
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

View File

@ -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 (GH) = 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 ≃* GH := 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 ≃* (GK) × (GH) := 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

View File

@ -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

View File

@ -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

View File

@ -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