Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace recursive definitions of algebraic operations with axioms #41

Merged
merged 25 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions Game/MyNat/Addition.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import Game.MyNat.Definition

namespace MyNat

open MyNat

def add : MyNat → MyNat → MyNat
| a, zero => a
| a, MyNat.succ b => MyNat.succ (MyNat.add a b)
opaque add : MyNat → MyNat → MyNat

instance instAdd : Add MyNat where
add := MyNat.add
Expand All @@ -17,11 +13,12 @@ instance instAdd : Add MyNat where
`add_zero` is a `simp` lemma, because if you see `a + 0`
you usually want to simplify it to `a`.
-/
@[simp]
theorem add_zero (a : MyNat) : a + 0 = a := by rfl
@[simp, MyNat_decide]
axiom add_zero (a : MyNat) : a + 0 = a

/--
If `a` and `d` are natural numbers, then `add_succ a d` is the proof that
`a + succ d = succ (a + d)`.
-/
theorem add_succ (a d : MyNat) : a + (succ d) = succ (a + d) := by rfl
@[MyNat_decide]
axiom add_succ (a d : MyNat) : a + (succ d) = succ (a + d)
6 changes: 3 additions & 3 deletions Game/MyNat/DecidableEq.lean
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Game.MyNat.Addition-- makes simps work?
import Game.MyNat.PeanoAxioms
import Game.Levels.Algorithm.L07succ_ne_succ
import Mathlib.Tactic
import Game.Levels.Algorithm.L07succ_ne_succ -- succ_ne_succ
import Game.Tactic.decide -- modified decide tactic

namespace MyNat

instance instDecidableEq : DecidableEq MyNat
Expand Down
29 changes: 29 additions & 0 deletions Game/MyNat/DecidableTests.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Game.MyNat.DecidableEq
import Game.MyNat.Power

example : 4 = 4 := by
decide

example : 4 ≠ 5 := by
decide

example : (0 : ℕ) + 0 = 0 := by
decide

example : (2 : ℕ) + 2 = 4 := by
decide

example : (2 : ℕ) + 2 ≠ 5 := by
decide

example : (20 : ℕ) + 20 = 40 := by
decide

example : (2 : ℕ) * 2 = 4 := by
decide

example : (2 : ℕ) * 2 ≠ 5 := by
decide

example : (3 : ℕ) ^ 2 ≠ 37 := by
decide
19 changes: 12 additions & 7 deletions Game/MyNat/Definition.lean
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Game.Tactic.LabelAttr -- MyNat_decide attribute

/-- Our copy of the natural numbers called `MyNat`, with notation `ℕ`. -/
inductive MyNat where
| zero : MyNat
Expand All @@ -13,22 +15,25 @@ namespace MyNat
instance : Inhabited MyNat where
default := MyNat.zero

def myNatFromNat (x : Nat) : MyNat :=
@[MyNat_decide]
def ofNat (x : Nat) : MyNat :=
match x with
| Nat.zero => MyNat.zero
| Nat.succ b => MyNat.succ (myNatFromNat b)
| Nat.succ b => MyNat.succ (ofNat b)

def natFromMyNat (x : MyNat) : Nat :=
@[MyNat_decide]
def toNat (x : MyNat) : Nat :=
match x with
| MyNat.zero => Nat.zero
| MyNat.succ b => Nat.succ (natFromMyNat b)
| MyNat.succ b => Nat.succ (toNat b)

instance ofNat {n : Nat} : OfNat MyNat n where
ofNat := myNatFromNat n
instance instofNat {n : Nat} : OfNat MyNat n where
ofNat := ofNat n

instance : ToString MyNat where
toString p := toString (natFromMyNat p)
toString p := toString (toNat p)

@[MyNat_decide]
theorem zero_eq_0 : MyNat.zero = 0 := rfl

def one : MyNat := MyNat.succ 0
Expand Down
5 changes: 2 additions & 3 deletions Game/MyNat/LE.lean
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ def le (a b : ℕ) := ∃ (c : ℕ), b = a + c
-- notation
instance : LE MyNat := ⟨MyNat.le⟩

--@[leakage] theorem le_def' : MyNat.le = (≤) := rfl

theorem le_iff_exists_add (a b : ℕ) : a ≤ b ↔ ∃ (c : ℕ), b = a + c := Iff.rfl
-- We don't use this any more; I tell the users `≤` is *notation*
-- theorem le_iff_exists_add (a b : ℕ) : a ≤ b ↔ ∃ (c : ℕ), b = a + c := Iff.rfl

end MyNat
10 changes: 5 additions & 5 deletions Game/MyNat/Multiplication.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import Game.MyNat.Addition

namespace MyNat

def mul : MyNat → MyNat → MyNat
| _, 0 => 0
| a, b + 1 => (MyNat.mul a b) + a
opaque mul : MyNat → MyNat → MyNat

instance : Mul MyNat where
mul := MyNat.mul

theorem mul_zero (a : MyNat) : a * 0 = 0 := by rfl
@[MyNat_decide]
axiom mul_zero (a : MyNat) : a * 0 = 0

theorem mul_succ (a b : MyNat) : a * (succ b) = a * b + a := by rfl
@[MyNat_decide]
axiom mul_succ (a b : MyNat) : a * (succ b) = a * b + a
2 changes: 1 addition & 1 deletion Game/MyNat/PeanoAxioms.lean
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ theorem succ_inj (a b : ℕ) (h : succ a = succ b) : a = b := by

def is_zero : ℕ → Prop
| 0 => True
| succ n => False
| succ _ => False

lemma is_zero_zero : is_zero 0 = True := rfl
lemma is_zero_succ (n : ℕ) : is_zero (succ n) = False := rfl
Expand Down
17 changes: 6 additions & 11 deletions Game/MyNat/Power.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,16 @@ import Game.MyNat.Multiplication
namespace MyNat
open MyNat

def pow : ℕ → ℕ → ℕ
| _, zero => one
| m, (succ n) => pow m n * m
opaque pow : ℕ → ℕ → ℕ

-- notation `a ^ b` for `pow a b`
instance : Pow ℕ ℕ where
pow := pow

-- notation a ^ b := pow a b
@[MyNat_decide]
axiom pow_zero (m : ℕ) : m ^ 0 = 1

-- Important note: This here is the real `rfl`, not the weaker game version

example : (1 : ℕ) ^ 1 = 1 := by rfl

theorem pow_zero (m : ℕ) : m ^ 0 = 1 := by rfl

theorem pow_succ (m n : ℕ) : m ^ (succ n) = m ^ n * m := by rfl
@[MyNat_decide]
axiom pow_succ (m n : ℕ) : m ^ (succ n) = m ^ n * m

end MyNat
5 changes: 5 additions & 0 deletions Game/Tactic/LabelAttr.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Std.Tactic.LabelAttr
import Mathlib.Lean.Meta.Simp

/-- Simp set for `functor_norm` -/
register_simp_attr MyNat_decide
16 changes: 16 additions & 0 deletions Game/Tactic/decide.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Game.Tactic.LabelAttr
import Game.MyNat.Definition

-- to get numerals of type MyNat to reduce to MyNat.succ (MyNat.succ ...)
@[MyNat_decide]
theorem ofNat_succ : (OfNat.ofNat (Nat.succ n) : ℕ) = MyNat.succ (OfNat.ofNat n) := _root_.rfl


/- modified `decide` tactic which first runs a custom
simp call to reduce numerals like `1 + 1` to
`MyNat.succ (MyNat.succ MyNat.zero)
-/
macro "decide" : tactic => `(tactic|(
try simp only [MyNat_decide]
try decide
))
Loading