109 lines
3.3 KiB
Text
109 lines
3.3 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
|
||
-/
|
||
module
|
||
|
||
prelude
|
||
import Init.Control.Basic
|
||
import Init.Data.Nat.Basic
|
||
import Init.Omega
|
||
|
||
set_option linter.missingDocs true
|
||
|
||
namespace Nat
|
||
universe u v
|
||
|
||
/--
|
||
Executes a monadic action on all the numbers less than some bound, in increasing order.
|
||
|
||
Example:
|
||
````lean example
|
||
#eval Nat.forM 5 fun i _ => IO.println i
|
||
````
|
||
````output
|
||
0
|
||
1
|
||
2
|
||
3
|
||
4
|
||
````
|
||
-/
|
||
@[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)
|
||
|
||
/--
|
||
Executes a monadic action on all the numbers less than some bound, in decreasing order.
|
||
|
||
Example:
|
||
````lean example
|
||
#eval Nat.forRevM 5 fun i _ => IO.println i
|
||
````
|
||
````output
|
||
4
|
||
3
|
||
2
|
||
1
|
||
0
|
||
````
|
||
-/
|
||
@[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)
|
||
|
||
/--
|
||
Iterates the application of a monadic function `f` to a starting value `init`, `n` times. At each
|
||
step, `f` is applied to the current value and to the next natural number less than `n`, in
|
||
increasing order.
|
||
-/
|
||
@[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
|
||
|
||
/--
|
||
Iterates the application of a monadic function `f` to a starting value `init`, `n` times. At each
|
||
step, `f` is applied to the current value and to the next natural number less than `n`, in
|
||
decreasing order.
|
||
-/
|
||
@[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
|
||
|
||
/--
|
||
Checks whether the monadic predicate `p` returns `true` for all numbers less that the given bound.
|
||
Numbers are checked in increasing order until `p` returns false, after which no further are checked.
|
||
-/
|
||
@[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)
|
||
|
||
/--
|
||
Checks whether there is some number less that the given bound for which the monadic predicate `p`
|
||
returns `true`. Numbers are checked in increasing order until `p` returns true, after which
|
||
no further are checked.
|
||
-/
|
||
@[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
|