CLP(R) math

Above, we discussed how to do basic arithmetic with Flora, using the \is operator and built-in arithmetic functions like , +, and so on. This method is limited by the fact that all the arguments have to be ground, i.e. they cannot be variables.

Flora also contains a more sophisticated method of doing mathematics, called CLP(R) (Constraint Logic Programming with Reals) [1].

A CLP(R) formula goes inside curly brackets. Arguments can be variables. A CLP(R) formula does not necessarily bind arguments to values. It can also cause constraints to be maintained on the variables. Sunflower shows any constraints on result variables in the query results UI.

For example, if you issue the query {?x < 3}, you get a solution ?x = ?Var0, and constraints ?Var0 < 3.0.

If you issue the query {?x =< 3, ?x >= 3}, you get a solution ?x = 3.0, with no remaining constraints. Flora has resolved the constraints and determined the only possible value for ?x.

CLP(R) allows you to write rules that can be used in multiple “directions”, rather than having fixed input/output parameters. For example, consider the rule

kinetic_energy(?e,?m,?v) :-
  ?e \is ?m*?v**2/2.

which calculates kinetic energy (* is the exponentiation operator in Flora). This works fine, as long as we only provide numbers for ?m and ?v, and an unbound variable for ?e.

We can write the rule using CLP(R) instead:

kinetic_energy(?e,?m,?v) :-
  {?e = ?m*pow(?v,2)/2}.

(pow is the exponentiation operator used inside CLP(R); for some reason it’s not the same as for \is-expressions).

Now we can run queries like:

kinetic_energy(?e,3,2).
kinetic_energy(6,?m,2).
kinetic_energy(6,3,?v).

and we get as results:

?e = 6.0
?m = 3.0
?v = 2.0
?v = -2.0

Note the two solutions for ?v, which are due to the positive and negative square roots. If we only wanted the positive solution, we could add another condition to the rule:

kinetic_energy(?e,?m,?v) :-
  {?e = ?m*pow(?v,2)/2, ?v > 0}.

Note that we can also issue queries with more than one variable unbound, which will result in some remaining constraints on the variables. For example,

kinetic_energy(?e,?m,2).

which results in the solution ?e = ?Var3, ?m = ?Var4, constraint: ?Var4=0.5*?Var3.

Any remaining constraints on variables are kept as they are passed to other rules. Other rules can then further constrain or instantiate these variables.

This ability of CLP(R) to essentially solve equations in any direction allows you to write more declarative, reusable, and powerful rules. Therefore, always consider using CLP(R) expressions rather than \is-expressions.

[1]Several Prolog systems have the same feature. Flora’s support for CLP(R) is directly based on XSB’s implementation