class Dusa
The main entrypoint to the Dusa JavaScript API is the Dusa class.
Creating a Dusa instance
Dusa()
constructor
A Dusa instance is created by passing a Dusa program to the constructor.
If the program has errors, an error in the DusaCompileError
class will be thrown.
Solving a Dusa instance
Dusa programs can’t be directly queried: they must first be solved. There are
several different ways to direct Dusa to generate solutions, all of which
provide access to DusaSolution
objects.
sample()
method and solution
getter
Often all you need is to find a single solution (or to know that at least one
solution exists). The sample()
method just returns a single solution, and
will potentially return a different solution every time it is called. The
solution
getter will generate a sample the first time it is accessed and
will then remember that sample; from then on accessing dusa.solution
will
always return the same solution until new facts are asserted.
Explore this example on val.town
If no solutions exist, the solution
getter will return null
.
Explore this example on val.town
If there are multiple solutions, the solution
getter will pick one solution,
and will always return that one.
Explore this example on val.town
Getting a solution iterator with solve()
The solve()
function returns a extended
JavaScript iterator
that will, upon successive calls to next()
, return each solution for the
Dusa program. The iterator works in an arbitrary order: this program will
either print "one"
and then "two"
or else it will print "two"
and then
"one"
.
Explore this example on val.town
The iterator returned by solve
has a couple of extra methods. Trying to
return the next solution is a process that could run forever; the advance()
method takes an optional argument limit
and then will run at most limit
steps, returning true
if next()
can return without any extra computation.
The stats()
method reports how much work has been done by the iterator so
far, and all()
returns all remaining solutions as an array.
Using for...of
loops
Dusa classes themselves are also Iterable
— they implement the
[Symbol.iterator]
method and so can be used in for..of
loops:
Explore this example on val.town
Each time you invoke the iterator dusa
is accessed, search is re-run,
potentially returning solutions in a different order.
Modifying a Dusa instance
The Dusa implementation doesn’t support adding and removing rules after a
Dusa
class instance has been created, but it does support adding additional
facts, which can be just as powerful. This can be useful for applications
where the actual set of facts isn’t known ahead of time, but the desired
analysis on those facts is known.
assert() method
The assert
method of a Dusa instance takes an arbitrary number of arguments,
each one a Fact, and adds them to the database.