0

So as part of my work my code needs to print all the solutions to a query but without using the findall/3 predicate. I've done some reading around and there are ways involving adding the solutions to a list and so on. I tried doing this myself but to with no success; hence I was hoping someone may be able to show how I would print all the solutions without using findall.

The program code is as follows:

    solutions(Q, 100):-
        Q = [X, Y, S],
        between(2,50,X),
        between(2,50,Y),
        S is X+Y,
        Y > X,
        S =< 50.

The Q and the 100 are there because it's needed for another part of the program so ignore that for now. When I query using ?- solutions(Q, 100) I get the results [2,3,5], [2,4,6], [2,5,7] and so on but obviously I need to press ; to get each new result. I need all these to be displayed without the need to press ; and without using findall.

lurker
  • 56,987
  • 9
  • 69
  • 103
Elviii
  • 21
  • 6

2 Answers2

1

You can use a failure-driven loop. Try:

?- solutions(Q, 100), write(Q), nl, fail.
Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • While that does work fine they're strict about keeping the query of just solutions(Q, 100). So unfortunately I can't do this =[ – Elviii Mar 18 '14 at 22:59
  • @Elviii So just add `write(Q), nl, fail.` to the end of your `solutions` code. – Sergii Dymchenko Mar 19 '14 at 03:07
  • I can't do that either. They method they use to mark this work is through using another program that essentially checks i'm doing what they want me to be doing. This doesn't allow for failure-driven loops. Did some more looking around and found an accumulator may be an option. Do you think this would be best? Thanks! – Elviii Mar 19 '14 at 03:28
1

An assert-based solution (which is actually how findall was implemented in Prolog textbooks): Assume that solution/2 finds each single solution, as per your code. Now we use a fail-driven loop, as Paulo suggested, to build a list of solutions, using assert/1 to cache solutions.

solutions(_, N) :-
  solution(Q, N),
  (cache(Qs) -> retractall(cache(_)) ; Qs = []),
  assert(cache([Q|Qs])),
  fail.
solutions(Qs, _) :-
  retract(cache(Qs)).
Little Bobby Tables
  • 5,261
  • 2
  • 39
  • 49