| import Lean.Elab.Command | |
| /-! | |
| # Tests for `let_fun x := v; b` notation | |
| -/ | |
| /-! | |
| Checks that types can be inferred and that default instances work with `let_fun`. | |
| -/ | |
| #check | |
| let_fun f x := x * 2 | |
| let_fun x := 1 | |
| let_fun y := x + 1 | |
| f (y + x) | |
| /-! | |
| Checks that `simp` can do zeta reduction of `let_fun`s | |
| -/ | |
| example (a b : Nat) (h1 : a = 0) (h2 : b = 0) : (let_fun x := a + 1; x + x) > b := by | |
| simp (config := { zeta := false }) [h1] | |
| trace_state | |
| simp (config := { decide := true }) [h2] | |
| /-! | |
| Checks that the underlying encoding for `let_fun` can be overapplied. | |
| This still pretty prints with `let_fun` notation. | |
| -/ | |
| #check (show Nat → Nat from id) 1 | |
| /-! | |
| Checks that zeta reduction still occurs even if the `let_fun` is applied to an argument. | |
| -/ | |
| example (a b : Nat) (h : a > b) : (show Nat → Nat from id) a > b := by | |
| simp | |
| trace_state | |
| exact h | |
| /-! | |
| Checks that the type of a `let_fun` can depend on the value. | |
| -/ | |
| #check let_fun n := 5 | |
| (⟨[], Nat.zero_le n⟩ : { as : List Bool // as.length ≤ n }) | |
| /-! | |
| Check that `let_fun` is reducible. | |
| -/ | |
| #check (rfl : (let_fun n := 5; n) = 5) | |
| /-! | |
| Exercise `isDefEqQuick` for `let_fun`. | |
| -/ | |
| #check (rfl : (let_fun _n := 5; 2) = 2) | |
| /-! | |
| Check that `let_fun` responds to WHNF's `zeta` option. | |
| -/ | |
| open Lean Elab Term in | |
| elab "#whnfCore " z?:(&"noZeta")? t:term : command => Command.runTermElabM fun _ => do | |
| let e ← withSynthesize <| Term.elabTerm t none | |
| let e ← Meta.whnfCore e {zeta := z?.isNone} | |
| logInfo m!"{e}" | |
| #whnfCore let_fun n := 5; n | |
| #whnfCore noZeta let_fun n := 5; n |