I'm working with Terms and Signatures (first-order predicate logic) in Prolog.
I've been given the signature (∅, Z, {add(2), sub(2), mult(2)})
. So there's no variables, the constants are integers, and the functions are "add", "sub" and "mult".
The goal is to write the predicate "calc/2", which takes a term (given the signature above) and calculates it according the usual definition of addition, subtraction and multiplication of integers. Example:
?- calc( add(sub(8,2), mult(4,-3)), N).
N = -6
(since ((8 − 2) + (4 ∗ −3)) = −6)
The problem is similar and related to this question, but one big difference is that I need to avoid using the =.. operator to find the name of the functions. Instead, I want to take advantage of the fact that Prolog uses pattern matching on a rule's parameters, which is what I'm completely stuck on. Another thing to note is that "add", "sub", and "mult" are not supposed to be predicates.
My first solution using the =.. operator was (with the help of the answer from the thread linked above):
op(+, add).
op(-, sub).
op(*, mult).
calc(Term, N) :-
calc2(Term, Expr),
N is Expr.
calc2(N,N) :- integer(N).
calc2(Term, Expr) :-
Term =.. [Op_str, Comp1, Comp2],
op(Op, Op_str),
calc2(Comp1, Expr1),
calc2(Comp2, Expr2),
Expr =.. [Op, Expr1, Expr2].
But since this^ isn't the type of solution I'm looking for it doesn't really help much with my issue.
I can pretty easily perform single calculations (like calc(add(1,2), N)
), but I struggle with anything more complicated than that.