1

I have this scenario wherein I get a linear equation in the Prolog query like below:

?- myquery( 3X + 5Y = 10, Result).

So my query has an equation 3X + 5Y = 10, which in general assumes the form AX + BY = C, where A=3, B=5 and C=10.

Now, in my prolog program, I am trying to define a predicate that can take in the expression mentioned in the query above. That is, I somehow want to get A, B and C values and also the operator involved (in the above case the plus operator) stored and then used on the logic that I define withing the program. I am wondering how this can be done.

To be more generic, the question is how do I identify the constants and the operator involved in an equation that is passed on through the goal/query?

repeat
  • 18,496
  • 4
  • 54
  • 166
kallakafar
  • 725
  • 3
  • 11
  • 27
  • what implementation of prolog are you using? it appears that in swi-prolog you cannot have an argument of the form you described (3X + 5Y = 10) – Thanos Tintinidis Feb 04 '12 at 18:30
  • I am looking for eclipse prolog, but anything should be fine, I just need to get the concepts right. – kallakafar Feb 04 '12 at 18:41

4 Answers4

2

SWI-Prolog has a constraint library clp(Q,R) that solve at symbolic level these equations:

[debug]  ?- [library(clpq)].
% library(clpq) compiled into clpq 0,27 sec, 992 clauses
true.

?- {3 * X + 5 * Y = 10}.
{Y=2-3 rdiv 5*X}.

Eclipse will surely have something more advanced. These libraries aren't simple, tough...

Of interest to you, the Prolog syntax is used, as a host language, so the usual builtins could be applied for identify vars, constants, and the like.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
1

You can for example use term inspection predicates: arg/3, functor/3, var/1, (=..)/2 etc.

mat
  • 40,498
  • 3
  • 51
  • 78
  • Umm.. could you please elaborate on how to get 3 stored in A1, x as A2, 5 as B1, Y as B2 and 10 as C (from the example I have given in main question)..? I'm still struggling on how to use arg (or for that matter functor/3, var/1 etc..) for the example I have cited. Thanks! – kallakafar Feb 04 '12 at 18:20
1

The following transcript may prove illuminating:

32 ?- Term = (3*_X + 5*_Y = 10), functor(Term,F,A).

Term = 3*_G527+5*_G530=10
F = =
A = 2 

33 ?- Term = (3*_X + 5*_Y = 10), arg(Arg,Term,Val).

Term = 3*_G459+5*_G462=10
Arg = 1
Val = 3*_G459+5*_G462 ; % user pressed ';' interactively

Term = 3*_G459+5*_G462=10
Arg = 2
Val = 10 ; % user pressed ';' interactively

No
35 ?- Term = (3*_X + 5*_Y = 10), arg(1,Term,Val1), functor(Val1,F1,A1),
      arg(2,Val1,Val12).

Term = 3*_G693+5*_G696=10
Val1 = 3*_G693+5*_G696
F1 = +
A1 = 2
Val12 = 5*_G696 

The last query reads: for Term as given, 1st arg of Term is Val1, the functor of Val1 is F1 with arity A1 (meaning, it has A1 args - subparts - itself), and 2nd arg of the term in Val1 is stored under Val12 name. To clarify, any symbolic data in Prolog is in the form of fff(aa,bb,cc,...) where fff is some name, called functor, and the "arguments" in that expression can be accessed through the arg call.

That means that the original expression (3*_X + 5*_Y = 10) is actually stored in Prolog as '='( '+'( '*'(3,_X), '*'(5,_Y)), 10). When you get to the atomic parts (functors with arity 0), you can check them further:

47 ?- arg(1,(3*X),V), functor(V,F,A), number(V).

X = _G441
V = 3
F = 3
A = 0 

Yes

EDIT: to answer your other question (from the comments):

1 ?- (3*_X + 5*_Y = 10) = (A*X + B*Y = C).

A = 3
X = _G412
B = 5
Y = _G415
C = 10 

Yes

If you insist on not writing out the multiplication sign * explicitly, you will have to represent your terms as strings, and to analyze that string. That would be a much more involved task.

EDIT: another thing to try is =.. predicate, called "Univ":

4 ?- (3*_X + 5*_Y = 10) =.. X.

X = [=, 3*_G454+5*_G457, 10] 

Yes
5 ?- (3*_X + 5*_Y = 10) =.. X, X=[X1,X2,X3], X2 =.. Y.

X = [=, 3*_G545+5*_G548, 10]
X1 = =
X2 = 3*_G545+5*_G548
X3 = 10
Y = [+, 3*_G545, 5*_G548] 

Yes
Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • Thanks for the edit.. I seem to get the logic now. Let me try it out. – kallakafar Feb 05 '12 at 10:49
  • @kallakafar btw in case you didn't know that, here in Stackoverflow you can *accept* an answer if/which you think answers your question, by clicking on big empty green check-mark (V-shaped) next to it. It will give some reputation points (15 ?) to the author. Also, it is possible to "up-vote" an answer, which gives it 10 reputation points. Part of the SO experience. :) – Will Ness Feb 05 '12 at 11:16
  • yep, i did try to upvote this answer, but then it said i need to have 15 points myself to do that, which unfortunately i dont. i didnt mark it as answered so that i can try it out myself, and maybe post followup questions. :) i will, once i am done..for sure! thanks, Will. – kallakafar Feb 05 '12 at 13:07
  • @kallakafar I've added some more example code to the answer, check it out. :) – Will Ness Feb 05 '12 at 19:43
  • Thank You, @Will Ness. I am still trying your solutions out,but I think I have got your point. I will update this post if I have anymore questions. Thanks! – kallakafar Feb 06 '12 at 01:50
0

You might want to take a look at examples of symbolic differentiation implemented using term rewrite rules; they handle such expressions.

Here's a chapter (minus 1 page) from the book Clause and Effect that you might find useful: Clause and Effect - Chapter Six: Term Rewriting

Another from The art of Prolog: advanced programming techniques 23 An equation solver

Programming in Prolog also has a section (7.11) on symbolic differentiation.

Roman
  • 1,179
  • 6
  • 7