Zulip Chat Archive

Stream: new members

Topic: Appropriate nondeterminism monad


Simeon Duwel (Mar 26 2025 at 19:51):

Hi all,

I'm having trouble implementing a nondeterministic search algorithm. For context, you can refer to this earlier post where I explain what I'm trying to do, or my new repository.

Concretely, the following algorithm works, but crashes on relatively small input sizes:

def mkTree' {len: Nat} (pOrder: POrder len) (depth: Nat := maxDepth len) : Many (SortingTree len) :=
  match pOrder.incompPairs with
    | [] => Many.one $ SortingTree.Leaf pOrder.toOrder
    | ps => match depth with
      | 0 => Many.none
      | depth' + 1 => Many.fromList ps >>= λ p  do
        let lt  mkTree' (pOrder.add p) depth';
        let gt  mkTree' (pOrder.add p.swap) depth';
        pure $ SortingTree.Branch p lt gt

and this is the only way I see to write this algorithm.

Is there a more suitable nondeterminism monad than the one described in Functional Programming With Lean's chapter on monads? I tried using MLList Thunk to little avail (I blew through stack space way too quickly anyway) and Nondet Id from Batteries ; but I think I don't know enough about how that works concretely to have implemented it correctly. Any pointers would be nice.

Aaron Liu (Mar 26 2025 at 20:43):

I think what you want is a depth-first search

Simeon Duwel (Mar 26 2025 at 20:45):

yes, I agree, and I thought Nondet's iterate method looked promising, but I'm feeling quite lost tbh...

Aaron Liu (Mar 26 2025 at 20:46):

Why not just write a depth-first search - have a stack State that you append to each time you search and pop from each time you backtrack

Aaron Liu (Mar 26 2025 at 20:46):

Make sure to make it tail recursive

Simeon Duwel (Mar 26 2025 at 20:48):

Wait State as in the state monad?

Simeon Duwel (Mar 26 2025 at 20:49):

or a custom State structure that holds the necessary information to backtrack

Aaron Liu (Mar 26 2025 at 20:51):

Your choice


Last updated: May 02 2025 at 03:31 UTC