lean4-htt/tests/lean/run/exp.lean
Leonardo de Moura ad3b0b4a2c feat: nary generalize tactic
This commit also fixes a bug when using multiple targets with the
`induction` and `cases` tactics.
2021-08-30 16:31:39 -07:00

44 lines
1.6 KiB
Text

inductive Expr : Type
| const (n : Nat)
| plus (e₁ e₂ : Expr)
| mul (e₁ e₂ : Expr)
deriving BEq, Inhabited, Repr, DecidableEq
def Expr.eval : Expr → Nat
| const n => n
| plus e₁ e₂ => eval e₁ + eval e₂
| mul e₁ e₂ => eval e₁ * eval e₂
def Expr.times : Nat → Expr → Expr
| k, const n => const (k*n)
| k, plus e₁ e₂ => plus (times k e₁) (times k e₂)
| k, mul e₁ e₂ => mul (times k e₁) e₂
theorem eval_times (k : Nat) (e : Expr) : (e.times k |>.eval) = k * e.eval := by
induction e with simp [Expr.times, Expr.eval]
| plus e₁ e₂ ih₁ ih₂ => simp [ih₁, ih₂, Nat.left_distrib]
| mul _ _ ih₁ ih₂ => simp [ih₁, Nat.mul_assoc]
def Expr.reassoc : Expr → Expr
| const n => const n
| plus e₁ e₂ =>
let e₁' := e₁.reassoc
let e₂' := e₂.reassoc
match e₂' with
| plus e₂₁ e₂₂ => plus (plus e₁' e₂₁) e₂₂
| _ => plus e₁' e₂'
| mul e₁ e₂ =>
let e₁' := e₁.reassoc
let e₂' := e₂.reassoc
match e₂' with
| mul e₂₁ e₂₂ => mul (mul e₁' e₂₁) e₂₂
| _ => mul e₁' e₂'
theorem eval_reassoc (e : Expr) : e.reassoc.eval = e.eval := by
induction e with simp [Expr.reassoc]
| plus e₁ e₂ ih₁ ih₂ =>
generalize h : Expr.reassoc e₂ = e₂'
cases e₂' <;> rw [h] at ih₂ <;> simp [Expr.eval] at * <;> rw [← ih₂, ih₁]; rw [Nat.add_assoc]
| mul e₁ e₂ ih₁ ih₂ =>
generalize h : Expr.reassoc e₂ = e₂'
cases e₂' <;> rw [h] at ih₂ <;> simp [Expr.eval] at * <;> rw [← ih₂, ih₁]; rw [Nat.mul_assoc]