lean4-htt/tests/lean/run/binrec.lean
Kim Morrison 3a457e6ad6
chore: use #guard_msgs in run tests (#4175)
Many of our tests in `tests/lean/run/` produce output from `#eval` (or
`#check`) statements, that is then ignored.

This PR tries to capture all the useful output using `#guard_msgs`. I've
only done a cursory check that the output is still sane --- there is a
chance that some "unchecked" tests have already accumulated regressions
and this just cements them!

In the other direction, I did identify two rotten tests:
* a minor one in `setStructInstNotation.lean`, where a comment says `Set
Nat`, but `#check` actually prints `?_`. Weird?
* `CompilerProbe.lean` is generating empty output, apparently indicating
that something is broken, but I don't know the signficance of this file.

In any case, I'll ask about these elsewhere.

(This started by noticing that a recent `grind` test file had an
untested `trace_state`, and then got carried away.)
2024-05-16 00:38:31 +00:00

64 lines
1.8 KiB
Text

def Nat.bit (b : Bool) (n : Nat) : Nat :=
cond b (2*n+1) (2*n)
theorem Nat.bit_div_even (h : n % 2 = 0) : bit false (n / 2) = n := by
simp [bit]
have := Nat.div_add_mod n 2
simp [h] at this
assumption
theorem Nat.bit_div_odd (h : n % 2 ≠ 0) : bit true (n / 2) = n := by
have h : n % 2 = 1 := by
have := mod_lt n (by decide : 2 > 0)
revert h this
generalize n%2 = k
match k with
| 0 => decide
| 1 => decide
| n+2 => intros; contradiction
simp [bit]
have := Nat.div_add_mod n 2
simp [h] at this
assumption
theorem Nat.div2_lt (h : n ≠ 0) : n / 2 < n := by
match n with
| 1 => decide
| 2 => decide
| 3 => decide
| n+4 =>
rw [div_eq, if_pos]
refine succ_lt_succ (Nat.lt_trans ?_ (lt_succ_self _))
exact @div2_lt (n+2) (by simp_arith)
simp_arith
@[specialize]
def Nat.binrec
(motive : Nat → Sort u)
(base : Unit → motive 0)
(ind : (b : Bool) → (n : Nat) → (Unit → motive n) → motive (bit b n))
(n : Nat) : motive n :=
if h₁ : n = 0 then
h₁ ▸ base ()
else if h₂ : n % 2 = 0 then
bit_div_even h₂ ▸ ind false (n / 2) (fun _ => binrec motive base ind (n / 2))
else
bit_div_odd h₂ ▸ ind true (n / 2) (fun _ => binrec motive base ind (n / 2))
termination_by n
decreasing_by all_goals exact Nat.div2_lt h₁
theorem Nat.binind
(motive : Nat → Prop)
(base : motive 0)
(ind : (b : Bool) → (n : Nat) → motive n → motive (bit b n))
(n : Nat) : motive n :=
binrec motive (fun _ => base) (fun b n ih => ind b n (ih ())) n
set_option trace.compiler.ir.result true in
def Nat.toBit (n : Nat) : List Bool :=
binrec (fun _ => List Bool)
(fun _ => [])
(fun b n ih => b :: ih ())
n
#guard Nat.toBit 18 == [false, true, false, false, true]