Pig
Pig

Reputation: 2122

Prolog: solving multi-variable arithmetics

I am having trouble writing a Prolog predicate that returns the variable values for some arithmetic.

For example, the function should return what x and y can be from the equation: 12 = 3x + 2y.

Currently my code can only work the other way around:

foo(S,X,Y) :- 
   S is 3*X+2*Y.

Any ideas?

Upvotes: 2

Views: 1244

Answers (2)

repeat
repeat

Reputation: 18726

Depending on the modeling domain you're in, use one of the following:

  • for integers

  • for arbitrary precision rational numbers

  • for limited-precision "real numbers", typically approximated by floating-point values

  • for Boolean values


Here's how you can handle integers with :

:- use_module(library(clpfd)).

foo(S,X,Y) :- 
   S #= 3*X+2*Y.

Let's look at some sample queries!

First up: ground queries.

?- foo(1,23,-34).
true.

?- foo(1,23,-2).
false.

Next up: some queries with one-variable.

?- foo(X,1,2).
X = 7.

?- foo(1,X,2).
X = -1.

?- foo(1,23,X).
X = -34.

?- foo(1,2,X).
false.

Then, a query with one variable used in multiple places:

?- foo(X,X,X).
X = 0.

At last: some more general queries.

?- foo(S,X,2).
S#=3*X+4.

?- foo(S,X,Y).
S#=3*X+2*Y.

For arbitrary-precision rational numbers, use :

:- use_module(library(clpq)).

?- foo(X,X,X).
X = 0.

?- foo(1,2,X).          % a similar query failed with clp(FD)
X = -5 rdiv 2.          % arbitrary-precision solution

?- foo(S,X,Y).
{Y=1 rdiv 2*S-3 rdiv 2*X}.

For relations over floating-point numbers, use :

:- use_module(library(clpr)).

foo(S,X,Y) :- 
   { S = 3*X+2*Y }.

Sample queries:

?- foo(1,2,X).          % a similar query failed with clp(FD)
X = -2.5 ;              % and had an arbitrary-precision solution with clp(Q)
false.

?- foo(X,X,X).
X = 0.0 ;
false.

Upvotes: 2

user502187
user502187

Reputation:

You could go along using the var/1 predicate to check whether an argument is output:

foo(S, X, Y) :- var(X), !, X is (S-2*Y)/3.
foo(S, X, Y) :- var(Y), !, Y is (S-3*X)/2.
foo(S, X, Y) :- S is 3*X+2*Y.

Here is an example run with SWI-Prolog:

?- foo(S, 1, 2).
S = 7.
?- foo(7, X, 2).
X = 1.
?- foo(7, 1, Y).
Y = 2.

Best Regards

Upvotes: 0

Related Questions