|
| 1 | +/-! |
| 2 | +Tests around the special case of well-founded recursion on Nat. |
| 3 | +-/ |
| 4 | + |
| 5 | +namespace T1 |
| 6 | + |
| 7 | +def foo : List α → Nat |
| 8 | + | [] => 0 |
| 9 | + | _::xs => 1 + (foo xs) |
| 10 | +termination_by xs => xs.length |
| 11 | + |
| 12 | +-- Closed terms should evaluate |
| 13 | + |
| 14 | +example : foo ([] : List Unit) = 0 := rfl |
| 15 | +example : foo ([] : List Unit) = 0 := by decide |
| 16 | +example : foo ([] : List Unit) = 0 := by decide +kernel |
| 17 | +example : foo [1,2,3,4,5] = 5 := rfl |
| 18 | +example : foo [1,2,3,4,5] = 5 := by decide |
| 19 | +example : foo [1,2,3,4,5] = 5 := by decide +kernel |
| 20 | + |
| 21 | +-- Open terms should not (these wouldn't even without the provisions with `WellFounded.Nat.eager`, |
| 22 | +-- the fuel does not line up) |
| 23 | + |
| 24 | +example : foo (x::xs) = 1 + foo xs := by (fail_if_success rfl); simp [foo] |
| 25 | +example : foo (x::y::z::xs) = 1+ (1+(1+ foo xs)) := by (fail_if_success rfl); simp [foo] |
| 26 | + |
| 27 | +end T1 |
| 28 | + |
| 29 | +-- Variant where the fuel does not line up |
| 30 | + |
| 31 | +namespace T2 |
| 32 | +def foo : List α → Nat |
| 33 | + | [] => 0 |
| 34 | + | _::xs => 1 + (foo xs) |
| 35 | +termination_by xs => 2 * xs.length |
| 36 | + |
| 37 | +example : foo ([] : List Unit) = 0 := rfl |
| 38 | +example : foo ([] : List Unit) = 0 := by decide |
| 39 | +example : foo ([] : List Unit) = 0 := by decide +kernel |
| 40 | +example : foo [1,2,3,4,5] = 5 := rfl |
| 41 | +example : foo [1,2,3,4,5] = 5 := by decide |
| 42 | +example : foo [1,2,3,4,5] = 5 := by decide +kernel |
| 43 | + |
| 44 | +-- Open terms should not (these wouldn't even without the provisions, the fuel does not line up) |
| 45 | + |
| 46 | +example : foo (x::xs) = 1 + foo xs := by (fail_if_success rfl); simp [foo] |
| 47 | +example : foo (x::y::z::xs) = 1+ (1 + ( 1+ foo xs)) := by (fail_if_success rfl); simp [foo] |
| 48 | + |
| 49 | +end T2 |
| 50 | + |
| 51 | +-- Idiom to switch to `WellFounded.fix` |
| 52 | + |
| 53 | +namespace T3 |
| 54 | +def foo : List α → Nat |
| 55 | + | [] => 0 |
| 56 | + | _::xs => 1 + (foo xs) |
| 57 | +termination_by xs => (xs.length, 0) |
| 58 | + |
| 59 | +example : foo ([] : List Unit) = 0 := by (fail_if_success rfl); simp [foo] |
| 60 | +example : foo ([] : List Unit) = 0 := by (fail_if_success decide); simp [foo] |
| 61 | +example : foo ([] : List Unit) = 0 := by (fail_if_success decide +kernel); simp [foo] |
| 62 | +example : foo [1,2,3,4,5] = 5 := by (fail_if_success rfl); simp [foo] |
| 63 | +example : foo [1,2,3,4,5] = 5 := by (fail_if_success decide); simp [foo] |
| 64 | +example : foo [1,2,3,4,5] = 5 := by (fail_if_success decide +kernel); simp [foo] |
| 65 | + |
| 66 | +-- Open terms should not (these wouldn't even without the provisions, the fuel does not line up) |
| 67 | + |
| 68 | +example : foo (x::xs) = 1 + foo xs := by (fail_if_success rfl); simp [foo] |
| 69 | +example : foo (x::y::z::xs) = 1+ (1 + ( 1+ foo xs)) := by (fail_if_success rfl); simp [foo] |
| 70 | + |
| 71 | +end T3 |
0 commit comments