Doing math in Prolog is different than the way other programming languages do it.
While Prolog in theory and design is a programming language without static types at times it is easier if one thinks of certain syntax as having a type. In this case one should think of arithmetic expressions as being typed.
The next thing to understand about Prolog is that to evaluate an arithmetic expression the predicate is/2 is needed/often used.
An example arithmetic expression 3 + 18 + 10
and using that with is/2
?- is(Sum, 3 + 18 + 10).
Sum = 31.
or more commonly in code as
?- Sum is 3 + 18 + 10.
Sum = 31.
Now is
is also infix operator
?- current_op(P,T,is).
P = 700,
T = xfx.
and since operators are rewritten as predicates when the code is loaded, they are converted from expressions (think string input) using operators into terms, think abstract syntax tree, E.g.
?- atom_to_term("3 + 18 + 10",Term,[]),write_canonical(Term).
+(+(3,18),10)
Term = 3+18+10.
and to evaluate the term is/2 is used, E.g.
?- atom_to_term("3 + 18 + 10",Term,[]),write_canonical(Term),is(Sum,Term).
+(+(3,18),10)
Term = 3+18+10,
Sum = 31.
Since your problem has some facts, a quick way to enter facts, predicates etc., at the top level is to just enter them directly into the user
module (Reserved Modules) , E.g.
?- [user].
|: mark(3).
|: mark(18).
|: mark(10).
|: % Press Ctrl-D to exit
% user://1 compiled 0.00 sec, 3 clauses
true.
and to verify the facts are there using listing/1, E.g.
?- listing(mark).
mark(3).
mark(18).
mark(10).
true.
To extract the values from the facts just use the fact functor, mark
with a variable for the argument(s), E.g.
?- mark(Value).
Value = 3 ;
Value = 18 ;
Value = 10.
and one can collect the values into a list easily with findall/3, E.g.
?- findall(Value,mark(Value),Values).
Values = [3, 18, 10].
While one can use foldl/4 with plus/3 to sum the values in the list, E.g.
?- findall(Value,mark(Value),Values),foldl(plus,Values,0,Sum).
Values = [3, 18, 10],
Sum = 31.
in production code you might find findall/3 used with sum_list/2, E.g.
?- findall(Value,mark(Value),Values),sum_list(Values,Sum).
Values = [3, 18, 10],
Sum = 31.
or aggregate/3, E.g.
?- aggregate(sum(Value),mark(Value),Sum).
Sum = 31.
In many cases I like to think of findall/3 like select for SQL queries, it pulls in the data then leaves open the door for accessing the returned list. aggregate/3 on the other hand does not allow for repeated access to the list but is nice if only one predicate is executed on the list, e.g. sum
.
I take that your question is a training problem and the use of higher order predicates is not allowed, so will leave the rest as an exercise, E.g. using recursion with base and recursive case predicates.