File: .lake/packages/batteries/Batteries/Control/Nondet/Basic.lean

full_name: Nondet
code: /--
`Nondet m α` is variation on `MLList m α` suitable for use with backtrackable monads `m`.

We think of `Nondet m α` as a nondeterministic value in `α`,
with the possible alternatives stored in a monadic lazy list.

Along with each `a : α` we store the backtrackable state, and ensure that monadic operations
on alternatives run with the appropriate state.

Operations on the nondeterministic value via `bind`, `mapM`, and `filterMapM`
run with the appropriate backtrackable state, and are responsible for updating the state themselves
(typically this doesn't need to be done explicitly,
but just happens as a side effect in the monad `m`).
-/
@[nolint unusedArguments]
structure Nondet (m : Type → Type) [MonadBacktrack σ m] (α : Type) : Type where
  /--
  Convert a non-deterministic value into a lazy list, keeping the backtrackable state.
  Be careful that monadic operations on the `MLList` will not respect this state!
  -/
  toMLList : MLList m (α × σ)
goal: Type

full_name: Nondet.toMLList
code: /--
`Nondet m α` is variation on `MLList m α` suitable for use with backtrackable monads `m`.

We think of `Nondet m α` as a nondeterministic value in `α`,
with the possible alternatives stored in a monadic lazy list.

Along with each `a : α` we store the backtrackable state, and ensure that monadic operations
on alternatives run with the appropriate state.

Operations on the nondeterministic value via `bind`, `mapM`, and `filterMapM`
run with the appropriate backtrackable state, and are responsible for updating the state themselves
(typically this doesn't need to be done explicitly,
but just happens as a side effect in the monad `m`).
-/
@[nolint unusedArguments]
structure Nondet (m : Type → Type) [MonadBacktrack σ m] (α : Type) : Type where
  /--
  Convert a non-deterministic value into a lazy list, keeping the backtrackable state.
  Be careful that monadic operations on the `MLList` will not respect this state!
  -/
  toMLList : MLList m (α × σ)
goal: MLList m (α × σ)

full_name: Nondet.nil
code: /-- The empty nondeterministic value. -/
def nil : Nondet m α 
goal: Nondet m α

full_name: Nondet.instInhabited
code: instance : Inhabited (Nondet m α) 
goal: Inhabited (Nondet m α)

full_name: Nondet.squash
code: /--
Squash a monadic nondeterministic value to a nondeterministic value.
-/
def squash (L : Unit → m (Nondet m α)) : Nondet m α 
goal: Nondet m α

full_name: Nondet.bind
code: /--
Bind a nondeterministic function over a nondeterministic value,
ensuring the function is run with the relevant backtrackable state at each value.
-/
partial def bind (L : Nondet m α) (f : α → Nondet m β) : Nondet m β 
goal: Nondet m β

full_name: Nondet.singletonM
code: /-- Convert any value in the monad to the singleton nondeterministic value. -/
def singletonM (x : m α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.singleton
code: /-- Convert a value to the singleton nondeterministic value. -/
def singleton (x : α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.instMonad
code: /-- `Nondet m` is a monad. -/
instance : Monad (Nondet m) 
goal: Monad (Nondet m)

full_name: Nondet.instAlternative
code: /-- `Nondet m` is an alternative monad. -/
instance : Alternative (Nondet m) 
goal: Alternative (Nondet m)

full_name: Nondet.instMonadLift
code: instance : MonadLift m (Nondet m) 
goal: MonadLift m (Nondet m)

full_name: Nondet.ofListM
code: /--
Lift a list of monadic values to a nondeterministic value.
We ensure that each monadic value is evaluated with the same backtrackable state.
-/
def ofListM (L : List (m α)) : Nondet m α 
goal: Nondet m α

full_name: Nondet.ofList
code: /--
Lift a list of values to a nondeterministic value.
(The backtrackable state in each will be identical:
whatever the state was when we first read from the result.)
-/
def ofList (L : List α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.mapM
code: /-- Apply a function which returns values in the monad to every alternative of a `Nondet m α`. -/
def mapM (f : α → m β) (L : Nondet m α) : Nondet m β 
goal: Nondet m β

full_name: Nondet.map
code: /-- Apply a function to each alternative in a `Nondet m α` . -/
def map (f : α → β) (L : Nondet m α) : Nondet m β 
goal: Nondet m β

full_name: Nondet.ofOptionM
code: /-- Convert a monadic optional value to a nondeterministic value. -/
def ofOptionM (x : m (Option α)) : Nondet m α 
goal: Nondet m α

full_name: Nondet.ofOption
code: /-- Convert an optional value to a nondeterministic value. -/
def ofOption (x : Option α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.filterMapM
code: /-- Filter and map a nondeterministic value using a monadic function which may return `none`. -/
def filterMapM (f : α → m (Option β)) (L : Nondet m α) : Nondet m β 
goal: Nondet m β

full_name: Nondet.filterMap
code: /-- Filter and map a nondeterministic value. -/
def filterMap (f : α → Option β) (L : Nondet m α) : Nondet m β 
goal: Nondet m β

full_name: Nondet.filterM
code: /-- Filter a nondeterministic value using a monadic predicate. -/
def filterM (p : α → m (ULift Bool)) (L : Nondet m α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.filter
code: /-- Filter a nondeterministic value. -/
def filter (p : α → Bool) (L : Nondet m α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.iterate
code: /--
All iterations of a non-deterministic function on an initial value.

(That is, depth first search.)
-/
partial def iterate (f : α → Nondet m α) (a : α) : Nondet m α 
goal: Nondet m α

full_name: Nondet.head
code: /--
Find the first alternative in a nondeterministic value, as a monadic value.
-/
def head [Alternative m] (L : Nondet m α) : m α 
goal: m α

full_name: Nondet.firstM
code: /--
Find the value of a monadic function on the first alternative in a nondeterministic value
where the function succeeds.
-/
def firstM [Alternative m] (L : Nondet m α) (f : α → m (Option β)) : m β 
goal: m β

full_name: Nondet.toMLList'
code: /--
Convert a non-deterministic value into a lazy list, by discarding the backtrackable state.
-/
def toMLList' (L : Nondet m α) : MLList m α 
goal: MLList m α

full_name: Nondet.toList
code: /--
Convert a non-deterministic value into a list in the monad, retaining the backtrackable state.
-/
def toList (L : Nondet m α) : m (List (α × σ)) 
goal: m (List (α × σ))

full_name: Nondet.toList'
code: /--
Convert a non-deterministic value into a list in the monad, by discarding the backtrackable state.
-/
def toList' (L : Nondet m α) : m (List α) 
goal: m (List α)

full_name: «instMonadBacktrackUnitId_.lake»
code: /-- The `Id` monad is trivially backtrackable, with state `Unit`. -/
-- This is useful so we can use `Nondet Id α` instead of `List α`
-- as the basic non-determinism monad.
instance : MonadBacktrack Unit Id 
goal: Lean.MonadBacktrack Unit Id