3 ms·
I am not sure this really is "amb" in all its glory. The incredible power of amb comes from the fact that some of the computations involved may be crashing or d
by theaeolist 7y ago
I am not sure this really is "amb" in all its glory. The incredible power of amb comes from the fact that some of the computations involved may be crashing or diverging. Crashes or non-termination are avoided by amb in favour of the successful computations. Otherwise is just the nondeterminism monad.
- colanderman 7y agoC/POSIX permits a simple (albeit wildly inefficient) implementation that handles crashing: #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> // Return an integer in the range [0, n) which // causes execution to succeed. unsigned amb(const unsigned n) { if (n == 0) _exit(42); for (unsigned i = 0; i < n - 1; ++i) { const pid_t child = fork(); if (child < 0) abort(); if (child == 0) return i; int wstatus; if (waitpid(child, &wstatus, 0) < 0) abort(); if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) _exit(0); } return n - 1; } You could of course parallelize this to handle nontermination, at the expensive of potentially many concurrent processes for a high n. You can make other fun time-traveling functions following the above pattern. My favorite I call the "Groundhog Day" function, or "Cause and Effect" for Star Trek fans: when first called, it returns zero; if the program later fails, it is restarted from that function call, which returns the exit code. (I'm not really sure how useful this is.)
- giornogiovanna 7y agoHow does amb "in all its glory" handle an endless loop? Any solution I can think of seems prohibitively expensive.