Skip to content

Commit bc75bbc

Browse files
lecture
1 parent 4dceaf6 commit bc75bbc

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

PfsProgs25/Unit13/MetaSolve.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ elab "list_eg" : term => do
142142

143143
#check mkSort
144144

145+
/-
146+
⊢ Type u → Type v → Type (max u v)
147+
-/
145148
#check Prod
146149

147150
def prodExpr? (e: Expr) :

PfsProgs25/Unit13/NatLE.lean

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import Lean
2+
import PfsProgs25.Unit13.MetaSolve
3+
open Lean Meta Elab Term Tactic
4+
5+
/-!
6+
# Transitivity for `LE` on `Nat`
7+
8+
We *rewrite* inequalities for natural numbers using transitivity. Namely, if the goal is `a ≤ b` and we have `a ≤ c`, we can rewrite the goal to `c ≤ b` and similarly for `c ≤ b` and for just `a ≤ b`.
9+
-/
10+
/-
11+
Nat.le_trans {n m k : ℕ} : n ≤ m → m ≤ k → n ≤ k
12+
-/
13+
#check Nat.le_trans
14+
15+
/-
16+
natLeExpr? (e : Expr) : MetaM (Option (Expr × Expr))
17+
-/
18+
#check natLeExpr?
19+
20+
elab "nat_le_trans" t:term : tactic =>
21+
withMainContext do
22+
match ← natLeExpr? <| ← getMainTarget with
23+
| none => throwError "Goal not an LE expression"
24+
| some (a, b) =>
25+
let h ← Tactic.elabTerm t none
26+
match ← natLeExpr? <| ← inferType h with
27+
| none => throwError "Hypothesis not an LE expression"
28+
| some (c, d) =>
29+
let checkLeft ← isDefEq a c
30+
let checkRight ← isDefEq b d
31+
if checkLeft && checkRight then
32+
closeMainGoal `nat_le_trans h
33+
else
34+
if checkLeft then
35+
-- the new goal is `d ≤ b` and
36+
-- the original goal follows from `h` and the new goal
37+
let newGoalType ← mkAppM ``Nat.le #[d, b]
38+
let newGoal ← mkFreshExprMVar newGoalType
39+
let goal ← getMainGoal
40+
let pf ← mkAppM ``Nat.le_trans #[h, newGoal]
41+
goal.assign pf
42+
replaceMainGoal [newGoal.mvarId!]
43+
else if checkRight then
44+
-- the new goal is `a ≤ c` and
45+
-- the original goal follows from `h` and the new goal
46+
let newGoalType ← mkAppM ``Nat.le #[a, c]
47+
let newGoal ← mkFreshExprMVar newGoalType
48+
let goal ← getMainGoal
49+
let pf ← mkAppM ``Nat.le_trans #[newGoal, h]
50+
goal.assign pf
51+
replaceMainGoal [newGoal.mvarId!]
52+
else
53+
throwError "Could not rewrite as neither ends match"
54+
55+
example (a: Nat)(h : a ≤ 3): a ≤ 4 := by
56+
nat_le_trans h
57+
simp
58+
59+
60+
example (a: Nat)(h : 2 ≤ a): 0 ≤ a := by
61+
nat_le_trans h
62+
simp

0 commit comments

Comments
 (0)