Dusa @ POPL 2025
The POPL 2025 talk on finite-choice logic programming and Dusa links to this page. Here are some of the examples in the talk and how to run them.
Stop or continue
The โstop or continueโ program shown in the talk can almost be cut-and-pasted into Dusa: the only changes are that free variables need to be uppercased, and that Dusa does not have an infix addition.
The simplest path is just to replace N+1 with s N, and use Dusaโs
Prolog-style structured terms instead of built-in numbers:
run 0 is { "๐", "๐" }. run (s N) is { "๐", "๐" } :- run N is "๐".
You can explore this example on dusa.rocks, but beware: you really want to hit โpauseโ relatively quickly before you start generating very large examples.
Your other option is to use Dusaโs built-in addition.
INT_PLUS plus run 0 is { "๐", "๐" }. run (plus N 1) is { "๐", "๐" } :- run N is "๐".
You can explore this example on dusa.rocks as well: it is a little less eager to crash your browser.
Command-line execution
If you have npx command line utility
installed, you can run either of these examples by putting them in a file
called run.dusa and, on the command line, running
npx dusa run.dusa -n10The -n10 argument tells the dusa command-line utility to generate ten
solutions.
Map generation
The central generation program example from the talk is this one:
reach "๐ ". reach R2 :- reach R1, next_to R1 R2, terrain R2 is "๐ณ". terrain R is {"โฐ๏ธ", "๐ณ", "๐"} :- region R. terrain R2 is {"๐ณ", "๐"} :- terrain R1 is "๐", next_to R1 R2.
This code doesnโt actually do much unless we populate the region and
next_to relations. We could do that by adding a bunch of facts, but itโs
nicer to write a program to generate all the regions. These rules create
26 regions, home and every space on a 5x5 grid:
dim 1. dim 2. dim 3. dim 4. dim 5. region "๐ ". region (coord X Y) :- dim X, dim Y.
To populate the next-to relation, we place home adjacent to the upper-left
corner of the map, use an auxillary delta relation along with the built-in
addition operation to place every other region adjacent to the region to
its right and to the region below it. Finally, we force the relation to be
transitive.
INT_PLUS plus delta 0 1. delta 1 0. next_to "๐ " (coord 1 1). next_to (coord X Y) (coord (plus X DX) (plus Y DY)) :- delta DX DY, dim X, dim Y, dim (plus X DX), dim (plus Y DY). next_to X Y :- next_to Y X.
The result is the example shown in the in-browser animation during the talk. Explore this example on dusa.rocks.
Additional constraints
We can add additional constraints, for example requiring that the lower-right
region be reachable. This uses a new kind of rule, a #demand constraint,
that is described in the paperโs appendix and documented here.
reach (coord 5 5).
Another aesthetic preference might be to ensure that thereโs exactly one contiguous ocean in every example. This is easily handled by a variant of the canonical-representative-selection algorithm from Section 3.2 in the paper.
representative X is? X :- terrain X is "๐". representative Y is Z :- next_to X Y, representative X is Z, terrain Y is "๐". representative _ is _. representative _ is X, representative _ is Y, X != Y.