@Kha It seems the recent parser modifications created some unexpected problems. I didn't investigate them. I am "lost" in the elaborator and dependent pattern matching land. 1) We can't write anymore ``` f [1, 2, 3] |>.run' 0 = Except.ok () ``` We have to use parentheses and the error message is weird :( ``` (f [1, 2, 3] |>.run' 0) = Except.ok () ``` 2) I had to add comments to `macro.lean`, I didn't find a workaround for one of the rules. BTW, I had to add a bunch of `:term` for fixing the other rules, and the error messages were counterintuitive.
44 lines
1.6 KiB
Text
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]
|