Reputation: 1
I'm fairly new to Prolog and I want to create a predicate that behaves as follows
calculate(add(1, sub(4,1)),Result).
Result = 4.
This is doing: 1 + (4 - 1) = 4
I'm familiar with predicates but I don't know where to start in terms of being able to write an add//2 predicate/operator.
Any help or suggestions are much appreciated.
Upvotes: 0
Views: 67
Reputation: 18663
With a small change on the representation of numbers, we can write a nice solution. The change is to represent the number N
as number(N)` to avoid a defaulty representation (meaning, "it's a number by default if it's not an operation):
calculate(number(Number), Number).
calculate(add(Expression1, Expression2), Result) :-
calculate(Expression1, Result1),
calculate(Expression2, Result2),
Result is Result1 + Result2.
calculate(sub(Expression1, Expression2), Result) :-
calculate(Expression1, Result1),
calculate(Expression2, Result2),
Result is Result1 - Result2.
Sample call:
| ?- calculate(add(number(1), sub(number(4), number(1))), Result).
Result = 4
yes
Upvotes: 2
Reputation: 15316
You are still thinking in terms of functions
z = f(x,y)
: "f(x,y) returns (is replaced by/ is reduced to) value z ..."
Predicates relate values to other values:
p_f(x,y,z)
: "predicate p_ makes a relation/connection/links values (x,y,z) such that z = f(x,y)"
So to pipeline evaluation (mathematical notation (g°f)(x,y) )
g(f(x,y))
you have to write (not respecting the Prolog convention that 'variables' are written in uppercase here):
p_f(x,y,a),p_g(a,b)
And think in terms of information flowing into this expression through p_f(x,y,_)
, getting transferred to p_g/2
via p_f(_,_,a), p_g(a,_)
and flowing out of the expression via p_g(a,b)
.
And p_f/3 or p_g/2 will fail (return false, not in any of their arguments, but as a whole) if they are unable to relate their arguments and there will be no result.
Using predicates has the advantage that for p_f(x,y) you can request x if y is known, y if x is known, or pairs of valid (x,y) (as long as that is computationally possible and the predicate has been correctly coded). Or for a predicate add/3
:
See also: Prolog ~ Splitting a number into a list
Upvotes: 2