As a hint: you can aim to construct all expressions by exhautively searching over the expression space. Since X - (Y - Z)
is just X - Y + Z
, this is good news, since we can restrict us to left recursive expressions, like:
makepm([], ExpI, ExpI).
makepm([H|T], ExpI, ExpO) :-
makepm(T, +(ExpI, H), ExpO).
makepm([H|T], ExpI, ExpO) :-
makepm(T, -(ExpI, H), ExpO).
If as first element we take 1
, and we inject the rest of the list in the makepm/3
, we get:
?- makepm([12,34,23,11], 1, F).
F = 1+12+34+23+11 ;
F = 1+12+34+23-11 ;
F = 1+12+34-23+11 ;
F = 1+12+34-23-11 ;
F = 1+12-34+23+11 ;
F = 1+12-34+23-11 ;
F = 1+12-34-23+11 ;
F = 1+12-34-23-11 ;
F = 1-12+34+23+11 ;
F = 1-12+34+23-11 ;
F = 1-12+34-23+11 ;
F = 1-12+34-23-11 ;
F = 1-12-34+23+11 ;
F = 1-12-34+23-11 ;
F = 1-12-34-23+11 ;
F = 1-12-34-23-11.
What still needs to be done: the question is not perfectly clear about the fact if numbers can be left out, if that is the case, then you should write a predicate that first selects a subset of numbers. Then we can exhaustively enumerate all expressions which we create with makepm/3
, and then we need to verify, for example with the is/2
[swi-doc] predicate that the expression sums up to the requested value. If that is the case the predicate can succeed.