For my program I need to make a list of lists, with each sublist containing 2 numbers, X and Y along with the sum and product of these 2 numbers.
So far I have the following:
genList(95, X,[]):-!.
genList(N, X,[[X,Y,Sum,Product]|Xs]):-
Y is N+1,
Sum is X+Y,
Sum<101,
Product is X*Y,
N1 is N+1,
genList(N1, X,Xs).
This works just fine for my test case of genList(5,5,Q).
However, I’m having trouble making it work for any starting number.
The goal is to find every pair of numbers where sum<= 100. So running through the above for one starting value, X would find every pair 1 < X < Y, where sum<=100, and running through it with all numbers 2-N would give a complete list of possible pairs.
For those interested, the problem I’m working through is the sum/product problem, described here (Second on the page)
If anyone could help with this it would be greatly appreciated!
Also, no built in prolog predicates are able to be used, hence the complicated way of doing this rather than with a findall.
A small extract of the output produced by this predicated is as follows:
[[5,6,11,30],[5,7,12,35],[5,8,13,40],[5,9,14,45],[5,10,15,50],[5,11,16,55],[5,12,17,60],[5,13,18,65],[5,14,19,70],[5,15,20,75],[5,16,21,80],[5,17,22,85],[5,18,23,90],[5,19,24,95],[5,20,25,100],[5,21,26,105],[5,22,27,110], …
EDIT:
Ok, so after some editing, here is the latest version of my code.
I think it’s very close, but there’s still something not quite right.
It cycles through number pairs, but requires the use of “;” to view all the answers, which isn’t what I want. Additionally, it returns false after all the answers are exhausted. I just can’t figure it out.
Also, it gives a complete answer in the middle, but then removes a sublist each time until I’m left with only the last set of pairs.
E.g. genList(0,48,48,Q). gives me:
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496]]
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[48,50,98,2400],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[49,50,99,2450],[49,51,100,2499]]
[[49,50,99,2450],[49,51,100,2499]]
false.
As you can see, a sublist gets removed each time, I just can’t see why!
You can exploit Prolog backtracking here. Just state what you want. For example you could say:
Xto be between1and100.Yto be between1andmin(100 - X, X).Let’s look at what a
validPair/1predicate would look like:You can just call it with
and browse results with
;, or build a list of all the matching pairs withfindall/3.Edit: even with recursion, we can keep our statements:
Xto be between1and100.Yto be between1andmin(100 - X, X).So, an idea to do it would be to set up a worker predicate:
then set up the base case:
and in the worker predicate, to implement the statements we made with some conditions: