Last active
January 27, 2022 15:10
-
-
Save hyphenrf/dad2bbf63d959c9440648e37a02a6e33 to your computer and use it in GitHub Desktop.
nondeterministic choice implemented in different languages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# OPTIONS_FRONTEND -Wno-overlapping #-} | |
import AllSolutions | |
insert :: a -> [a] -> [a] -- warning: overlapping patterns = ndet | |
insert x xs = x : xs | |
insert x (y:ys) = y : insert x ys | |
perm :: [a] -> [a] | |
perm [] = [] | |
perm (x:xs) = insert x (perm xs) | |
sorted :: Ord a => [a] -> Bool | |
sorted [] = True | |
sorted [_] = True | |
sorted (x : ys@(y:_)) = x <= y && sorted ys | |
unisort :: Ord a => [a] -> [a] | |
unisort xs | sorted ch = ch | |
where ch = perm xs | |
main :: IO () | |
main = do | |
-- a <- getAllValues $ perm [1, 2, 3] | |
b <- getAllValues $ unisort [3, 1, 2] -- only 1 satisfiable solution | |
-- nondeterminism completely removed | |
-- using AllSolutions for monadic intf | |
-- print a | |
print b |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
infixr 00 (?) | |
infixr 60 (::) | |
effect amb | |
ctl (?)(l : a, r : a) : a | |
ctl fail() : a | |
val solutions = | |
handler | |
return(x) -> [x] | |
ctl fail() -> [] | |
ctl (?)(l, r) -> resume(l) ++ resume(r) | |
fun tests() | |
// FIXME | |
/* this can be solved with using true/false for amb, then short-circuiting or thunking. | |
either way we never execute the nested continuations more than once.. | |
but this kind of solution makes for a bad heavy-handed API compared to first-class logic langs */ | |
"Search space will be duplicated, unlike in logic langs". | |
assert( solutions { 1 ? 2 ? 3 } == [1,2,1,3] ) | |
fun main() solutions { | |
[1,2,3].unisort | |
} | |
fun unisort(xs) | |
val choice = xs.perm | |
if choice.sorted | |
then choice | |
else fail() | |
fun perm(xs) match(xs) | |
[] -> [] | |
Cons(y,ys) -> ys.perm.insert(y) | |
fun sorted(xs : list<int>) match (xs) | |
[] -> True | |
[_] -> True | |
Cons(x, ys as Cons(y, _)) -> | |
x <= y && sorted(ys) | |
fun insert(xs, x) match(xs) | |
[] -> [x] | |
Cons(y, ys) -> | |
x :: xs ? y :: ys.insert(x) | |
fun (::)(x, xs) Cons(x, xs) | |
fun (==)(xs, ys) zipwith(xs, ys, (==)).all(id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% swipl -g main | |
insert(X, XS, [X|XS]). | |
insert(X, [Y|YS], [Y|ZS]) :- insert(X, YS, ZS). | |
perm([], []). | |
perm([X|XS], YS) :- perm(XS, ZS), insert(X, ZS, YS). | |
sorted([]). | |
sorted([_]). | |
sorted([X,Y|YS]) :- X =< Y, sorted([Y|YS]). | |
unisort(XS, ZS) :- perm(XS, ZS), sorted(ZS). | |
main :- unisort([2,1,3], Out), write(Out). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment