This PR modifies the signature of the functions `Nat.fold`, `Nat.foldRev`, `Nat.any`, `Nat.all`, so that the function is passed the upper bound. This allows us to change runtime array bounds checks to compile time checks in many places.
56 lines
2.1 KiB
Text
56 lines
2.1 KiB
Text
/-
|
||
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Author: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import Init.Control.Basic
|
||
import Init.Data.Nat.Basic
|
||
import Init.Omega
|
||
|
||
namespace Nat
|
||
universe u v
|
||
|
||
@[inline] def forM {m} [Monad m] (n : Nat) (f : (i : Nat) → i < n → m Unit) : m Unit :=
|
||
let rec @[specialize] loop : ∀ i, i ≤ n → m Unit
|
||
| 0, _ => pure ()
|
||
| i+1, h => do f (n-i-1) (by omega); loop i (Nat.le_of_succ_le h)
|
||
loop n (by simp)
|
||
|
||
@[inline] def forRevM {m} [Monad m] (n : Nat) (f : (i : Nat) → i < n → m Unit) : m Unit :=
|
||
let rec @[specialize] loop : ∀ i, i ≤ n → m Unit
|
||
| 0, _ => pure ()
|
||
| i+1, h => do f i (by omega); loop i (Nat.le_of_succ_le h)
|
||
loop n (by simp)
|
||
|
||
@[inline] def foldM {α : Type u} {m : Type u → Type v} [Monad m] (n : Nat) (f : (i : Nat) → i < n → α → m α) (init : α) : m α :=
|
||
let rec @[specialize] loop : ∀ i, i ≤ n → α → m α
|
||
| 0, h, a => pure a
|
||
| i+1, h, a => f (n-i-1) (by omega) a >>= loop i (Nat.le_of_succ_le h)
|
||
loop n (by omega) init
|
||
|
||
@[inline] def foldRevM {α : Type u} {m : Type u → Type v} [Monad m] (n : Nat) (f : (i : Nat) → i < n → α → m α) (init : α) : m α :=
|
||
let rec @[specialize] loop : ∀ i, i ≤ n → α → m α
|
||
| 0, h, a => pure a
|
||
| i+1, h, a => f i (by omega) a >>= loop i (Nat.le_of_succ_le h)
|
||
loop n (by omega) init
|
||
|
||
@[inline] def allM {m} [Monad m] (n : Nat) (p : (i : Nat) → i < n → m Bool) : m Bool :=
|
||
let rec @[specialize] loop : ∀ i, i ≤ n → m Bool
|
||
| 0, _ => pure true
|
||
| i+1 , h => do
|
||
match (← p (n-i-1) (by omega)) with
|
||
| true => loop i (by omega)
|
||
| false => pure false
|
||
loop n (by simp)
|
||
|
||
@[inline] def anyM {m} [Monad m] (n : Nat) (p : (i : Nat) → i < n → m Bool) : m Bool :=
|
||
let rec @[specialize] loop : ∀ i, i ≤ n → m Bool
|
||
| 0, _ => pure false
|
||
| i+1, h => do
|
||
match (← p (n-i-1) (by omega)) with
|
||
| true => pure true
|
||
| false => loop i (Nat.le_of_succ_le h)
|
||
loop n (by simp)
|
||
|
||
end Nat
|