0

Does anyone know how I could implement I predicate doing what this one does but without "findall"? Thank you a lot.

domains
    oferta =  rebaixat ; normal
    element = string
        list = element*
database
    producte (string, integer, oferta)
predicates
    nondeterm reduced2(list)

clauses

    producte("Enciam",2,rebaixat). 
    producte("Peix",5,normal).
    producte("Llet",1,rebaixat). 
    producte("Formatge",5,normal).

         reduced2(Vals):-
            findall(Val, producte(Val,_,rebaixat),Vals).
Goal
    write("Amb findall"),nl,
    reduced2(List).
mkll
  • 41
  • 9
  • Your requirement seems arbitrary. Can you explain why `findall` is out? – Robert Harvey Jan 09 '12 at 16:17
  • Frankly, they are requirements of my homework. But I'm lost in here. – mkll Jan 09 '12 at 16:21
  • Sorry I'm totally new at stackoverflow. I hardly knoq how it works. I'm getting used to it. – mkll Jan 09 '12 at 16:24
  • I added the Visual Prolog tag. In general to create a list of solutions generated by backtracking (without using findall/3) requires using the dynamic database. The point is that backtracking will not "undo" asserts or retracts, so you can create a repeat/fail loop that revises a list stored in a dynamic fact. You might want to try your hand at this approach before asking for a more detailed answer. – hardmath Jan 09 '12 at 17:09
  • 1
    If you go back to your previous question: http://stackoverflow.com/questions/8746877/prolog-little-exercise-on-facts you will find that Mog provided an answer that used a "list comprehension" (sorry, can't think of better term) syntax instead of findall/3. Is there a problem with his answer? – ccoakley Jan 09 '12 at 17:13
  • Well "List = [ Price || producte(_, Price, _) ]," doesn't work on Visual Prolog. At least, on mine. Thanks – mkll Jan 09 '12 at 17:40
  • 1
    Possible duplicate of [SWI-Prolog: gathering all solutions without findall](http://stackoverflow.com/questions/22492633/swi-prolog-gathering-all-solutions-without-findall) –  Oct 12 '15 at 11:56

1 Answers1

0

I don't know much about Visual Prolog, but I will try to give a general answer. It depends on whether you want to find a findall/3 replacement for a specific case or in general, though.

In the specific case, you can use an accumulator. In your case, this would be a list into which the values are added as you find them. Something like:

acc(In, List) :-
   ... % do something to generate possible next value
   ... % test if value is already in list In
   !,
   Out = [Val|In], % adds to the head, but is faster than using append
   acc(Out, List).
acc(List, List).

I.e., when you can't find another possible value, you return the list of values that you found. Note that this may be slow if you have to accumulate a lot of values and generating the next possible value is done via backtracking. Also, this will not let you generate duplicates, so it's not an exact replacement for findall/3.

If you want a general replacement for findall/3, where you can specify a goal and a variable or term that will contain the instance to be accumulated, then you won't get around using some sort of non-logical global variable. After finding the next value, you add it to what's been stored in the global variable, and cause backtracking. If generating the next value fails, you retrieve the content of the global variable and return it.

twinterer
  • 2,416
  • 1
  • 15
  • 13
  • by the way, how would you control to read facts from "readterm" as many as the user wished until he(the user) decides to press only "enter"? Thank you so much. That regards another problem I'm having. – mkll Jan 09 '12 at 18:01
  • I don't like to downvote the answer, but I would be surprised if it works. IMHO, the alternative to findall should be a failure driven loop, or a forward read loop. – CapelliC Jan 11 '12 at 17:00
  • Is it the specific or the general replacement that you doubt? The specific one, which is only meant to collect all unique values for some specific goal, I tested. The call would be `?-acc([],L).` Note that I never claimed it to be a feature-by-feature replacement for `findall/3`. The general replacement is indeed a failure-driven loop, but you need non-logical storage for intermediate results or you'll lose them on backtracking. – twinterer Jan 12 '12 at 07:02