30pewpew
30pewpew

Reputation: 91

Recursion query that checks if X exists in a Prolog database

I'm trying to create a query exists(X) that returns true if X exists in a prolog database.

Prolog Database

store(best_smoothies, [alan,john,mary],
      [ smoothie(berry, [orange, blueberry, strawberry], 2),
        smoothie(tropical, [orange, banana, mango, guava], 3),
        smoothie(blue, [banana, blueberry], 3) ]).
store(all_smoothies, [keith,mary],
      [ smoothie(pinacolada, [orange, pineapple, coconut], 2),
        smoothie(green, [orange, banana, kiwi], 5),
        smoothie(purple, [orange, blueberry, strawberry], 2),
        smoothie(smooth, [orange, banana, mango],1) ]).
store(smoothies_galore, [heath,john,michelle],
      [ smoothie(combo1, [strawberry, orange, banana], 2),
        smoothie(combo2, [banana, orange], 5),
        smoothie(combo3, [orange, peach, banana], 2),
        smoothie(combo4, [guava, mango, papaya, orange],1),
        smoothie(combo5, [grapefruit, banana, pear],1) ]).

My attempt

exists(X) :- store(_,_,S), isIn(X,S).

isIn(X, [smoothie(X,_,_)|[]]).
isIn(X, [smoothie(N,_,_)|T]) :- isIn(X,T).

Surprisingly it only returns true for blue, smooth and combo5. Is there something wrong with my recursion? (I don't think so since it was able to read blue, smooth and all the way down to combo5)

Output that I'm getting

?- exists(combo1).
false

?- exists(X).
X = blue;
X = smooth;
X = combo5;
false

Appreciate any help on this. Many thanks!

EDIT: Revised Attempt

exists(X) :- store(_,_,S), isIn(X,S).

isIn(X, [smoothie(X,_,_)]).
isIn(X, [smoothie(N,_,_)|T]) :- isIn(X,T).

EDIT: Fixed

exists(X) :- store(_,_,S), isIn(X,S).

isIn(X, [smoothie(X,_,_)|_]).
isIn(X, [smoothie(N,_,_)|T]) :- isIn(X,T).

Upvotes: 2

Views: 163

Answers (1)

Will Ness
Will Ness

Reputation: 71065

[smoothie(X,_,_) | []] is the same as [smoothie(X,_,_)].

isIn( X, S ) is equivalent to

isIn( X, S ) :-
  last(  S, smoothie(X,_,_) ).

which explains you observations.

Upvotes: 1

Related Questions