Built-in relations
On their own, built-in numbers and strings act no different than other uninterpreted constants, but they can be manipulated in special ways.
Equality and inequality comparisons
It’s possible to compare integers by writing premises of the form t1 >= t2
,
t1 > t2
, t1 <= t2
, or t1 < t2
. These premises will only succeed if
both terms are numbers or both terms are strings.
p 1. p 3. p 8. p "p". p "q". p "z". p (pair 3 1). p nothing. q X Y :- p X, p Y, X < Y.
Explore this example on dusa.rocks
On the other hand, equality premises t1 == t2
and inequality premises
t1 != t2
can compare any two terms: 1 != "p"
is true, so this example will
derive q 1 "p"
and q "p" 1
.
p 1. p "n". p "z". p (pair 3 1). q X Y :- p X, p Y, X != Y. r X Y :- p X, p Y, X == Y.
Explore this example on dusa.rocks
A special and powerful way of using inequality uses wildcards to allow you to
check whether a known term doesn’t match some pattern, so this program
will derive only the facts q 1
, q "n"
, and q "z"
.
p 1. p "n". p "z". p (pair 3 1). p (pair "n" 1). q X :- p X, X != pair _ _.
Explore this example on dusa.rocks
Other built-in relations
Other built-in functionality for manipulating strings and numbers can be
accessed by writing #builtin
declarations. For every number n >= 0
,
the NAT_SUCC
relation relates the number n
to the number n+1
. For every
set of integers n
and m
, the INT_MINUS
relation relates the numbers n
and m
to the number n-m
.
INT_MINUS minus NAT_SUCC s p 4. p 1. q Z :- p X, p Y, minus X Y is Z. r Z :- p X, s X is Z.
Explore this example on dusa.rocks
Some builtins can be run backwards: if you know the value of the relation,
then you can use the relation to learn a premise. This means that INT_MINUS
is redundant with INT_PLUS
, because instead of writing minus X Y is Z
when
you know X
and Y
but not Z
, you could write plus Y Z is X
. For the
STRING_CONCAT
builtin, this allows for some simple string manipulation:
STRING_CONCAT concat p "bananana". p Y :- p X, concat Y "na" is X.
Explore this example on dusa.rocks
The STRING_CONCAT
function can even be run backwards with multiple unknown
values.
STRING_CONCAT concat p Prefix Postfix :- concat Prefix "na" Postfix is "bananana".
Explore this example on dusa.rocks
Some builtins can also be given a variable number of arguments.
INT_PLUS plus p 100. p 20. p 9. q (plus X Y Z) :- p X, p Y, p Z. r (plus X Y) :- p X, p Y.
Explore this example on dusa.rocks
All built-in identifiers
BOOLEAN_TRUE
- takes no arguments, returns the Boolean constanttrue
BOOLEAN_FALSE
- takes no arguments, returns the Boolean constantfalse
NAT_ZERO
- takes no arguments, returns the integer0
(which you could also just write as0
)NAT_SUCC
- takes one argument, relates nonnegative integers to their successors. Can be run backwards: works if either the argument or value is known ahead of time.INT_PLUS
- takes any positive number of arguments and relates integers to their sum. Can be run backwards: works if either all arguments are known, or if the value and all but one argument are known.INT_MINUS
- takes exactly two arguments and relates integers to their difference. Can be run backwards: works if either all arguments are known, or if the value and all but one argument are known.INT_TIMES
- takes any positive number of arguments and relates integers to their product. Cannot be run backwards.STRING_CONCAT
- takes any positive number of arguments and relates strings to their concatenation. Can be run backwards: works if either all arguments are known, or if the value is known.