0

I want to make an arithmetic solver in Prolog that can have +,-,*,^ operations on numbers >= 2. It should also be possible to have a variable x in there. The input should be a prefix expression in a list.

I have made a program that parses an arithmetic expression in prefix format into a syntax tree. So that:

?- parse([+,+,2,9,*,3,x],Tree).
Tree = plus(plus(num(2), num(9)), mul(num(3), var(x))) .

(1) At this stage, I want to extend this program to be able to solve it for a given x value. This should be done by adding another predicate evaluate(Tree, Value, Solution) which given a value for the unknown x, calculates the solution.

Example:

?- parse([*, 2, ^, x, 3],Tree), evaluate(Ast, 2, Solution).
Tree = mul(num(2), pow(var(x), num(3))) ,
Solution = 16.

I'm not sure how to solve this problem due to my lack of Prolog skills, but I need a way of setting the var(x) to num(2) like in this example (because x = 2). Maybe member in Prolog can be used to do this. Then I have to solve it using perhaps is/2

Edit: My attempt to solving it. Getting error: 'Undefined procedure: evaluate/3 However, there are definitions for: evaluate/5'

evaluate(plus(A,B),Value,Sol) --> evaluate(A,AV,Sol), evaluate(B,BV,Sol), Value is AV+BV.
evaluate(mul(A,B),Value,Sol) --> evaluate(A,AV,Sol), evaluate(B,BV,Sol), Value is AV*BV.
evaluate(pow(A,B),Value,Sol) --> evaluate(A,AV,Sol), evaluate(B,BV,Sol), Value is AV^BV.
evaluate(num(Num),Value,Sol) --> number(Num).
evaluate(var(x),Value,Sol) --> number(Value).

(2) I'd also want to be able to express it in postfix form. Having a predicate postfixform(Tree, Postfixlist)

Example:

?- parse([+, *, 2, x, ^, x, 5 ],Tree), postfix(Tree,Postfix).
Tree = plus(mul(num(2), var(x)), pow(var(x), num(5))) ,
Postfix = [2, x, *, x, 5, ^, +].

Any help with (1) and (2) would be highly appreciated!

false
  • 10,264
  • 13
  • 101
  • 209
knordbo
  • 552
  • 3
  • 7
  • The first part: is answered here: http://stackoverflow.com/questions/19793480/prolog-parsing. – false Nov 11 '13 at 21:42
  • @false Yes, thanks! I used your approach to implement the first part, but I'm stuck in my approach for (1) and (2). Any ideas? – knordbo Nov 11 '13 at 21:45
  • The last part is: http://stackoverflow.com/questions/13131640/remove-ambiguity-in-abstract-syntax-in-other-to-write-dcg-parser-prolog/13143803#13143803 – false Nov 11 '13 at 21:45
  • The part in the middle is not that clear. Do you permit several variables? – false Nov 11 '13 at 21:47
  • @false Thanks again. No, only one variable x. So in evaluate(Tree, Value, Solution), Value will always correspond to the value of x. – knordbo Nov 11 '13 at 22:01
  • So you need a different interface: You need to be able to indicate several variables at once. – false Nov 11 '13 at 22:07
  • I was considering this approach. http://ktiml.mff.cuni.cz/~bartak/prolog/arithmetics.html In my example it would be `eval_v(plus(A,B),CV,Vars):-eval_v(A,AV,Vars),eval_v(B,BV,Vars),CV is AV+BV. eval_v(mul(A,B),CV,Vars):-eval_v(A,AV,Vars),eval_v(B,BV,Vars),CV is AV*BV. eval_v(pow(A,B),CV,Vars):-eval_v(A,AV,Vars),eval_v(B,BV,Vars),CV is AV^BV. eval_v(Num,Num,Vars):-number(Num). eval_v(Var,Value,Vars):-atom(Var),member(Var/Value,Vars)` but there seems to be something wrong with it. Any idea? – knordbo Nov 11 '13 at 22:30
  • You are putting too much into a single question. – false Nov 11 '13 at 23:04
  • Sorry for that. Have a look at my attempt at solving it. I edited the main question. – knordbo Nov 11 '13 at 23:23
  • This site works if you ask a clear question. Not everything at once. See: http://stackoverflow.com/help – false Nov 11 '13 at 23:56

1 Answers1

1

You don't need to use a grammar for this, as you are doing. You should use normal rules.

This is the pattern you need to follow.

evaluate(plus(A,B),Value,Sol) :- 
   evaluate(A, Value, A2),
   evaluate(B, Value, B2),
   Sol is A2+B2.

And

evaluate(num(X),_Value,Sol) :- Sol = X.
evaluate(var(x),Value,Sol) :- Sol = Value.
Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
  • Thanks a lot! I tried normal rules as well, but I did a typo 'Value is ...' instead of 'Sol is ...' Now it's working fine! – knordbo Nov 13 '13 at 13:46
  • Of course! Could you have a look at my other problem with my implementation? http://stackoverflow.com/questions/19959722/prolog-numbers-greater-than-x Thanks! – knordbo Nov 13 '13 at 16:56