Prolog clause being recalled every time value retrieved from clause is accessed

Viewed 39

Please bear with me because I am new to logic programming. I am writing a Prolog clause that should succeed if another clause--get_cards_by_suit/3--returns a list with only a single element. However, it seems that whenever I use the returned list, the clause get_cards_by_suit is called again on its own. I have no idea why this is happening, and I've spent hours trying to figure this out.

Here is the clause I'm having trouble with:

find_strongest_card(CardPile, TrumpSuit, StrongestCard, Reason) :-
   %if there is one and only one trump suit cards in the pile, then that card is the strongest card
   get_cards_by_suit(CardPile, TrumpSuit, AllTrumpCardsInCardPile),
   write(AllTrumpCardsInCardPile), nl,
   %if there is only one card in the pile/list, then clause succeeds
   AllTrumpCardsInCardPile = [StrongestCard],
   Reason = card_is_trump_suit.

And here is the get_cards_by_suit clause:

get_cards_by_suit([], _, []).

get_cards_by_suit([FirstCard | RemainingCards], Suit, CardsOfGivenSuit) :-
   get_card_suit(FirstCard, FirstCardSuit),
   FirstCardSuit = Suit,
   CardsOfGivenSuit = [FirstCard | OtherCardsOfGivenSuit],
   get_cards_by_suit(RemainingCards, Suit, OtherCardsOfGivenSuit).

get_cards_by_suit([_ | RemainingCards], Suit, CardsOfGivenSuit) :-
   get_cards_by_suit(RemainingCards, Suit, CardsOfGivenSuit).

In the find_strongest_card clause, I included a write statement that prints the value returned by get_cards_by_suit to show how the clause is being repeated.

Here is the output when I make the following query: Query:

find_strongest_card([0, 1, 2, 3, 5, 4, 5, 13, 11, 12, 17, 16, 15, 13], clubs, Card, Reason).

Here is the output:

[0,1,2,3,5,4,5]
[0,1,2,3,5,4]
[0,1,2,3,5,5]
[0,1,2,3,5]
[0,1,2,3,4,5]
[0,1,2,3,4]
[0,1,2,3,5]
[0,1,2,3]
[0,1,2,5,4,5]
[0,1,2,5,4]
[0,1,2,5,5]
[0,1,2,5]
[0,1,2,4,5]
[0,1,2,4]
[0,1,2,5]
[0,1,2]
[0,1,3,5,4,5]
[0,1,3,5,4]
[0,1,3,5,5]
[0,1,3,5]
[0,1,3,4,5]
[0,1,3,4]
[0,1,3,5]
[0,1,3]
[0,1,5,4,5]
[0,1,5,4]
[0,1,5,5]
[0,1,5]
[0,1,4,5]
[0,1,4]
[0,1,5]
[0,1]
[0,2,3,5,4,5]
[0,2,3,5,4]
[0,2,3,5,5]
[0,2,3,5]
[0,2,3,4,5]
[0,2,3,4]
[0,2,3,5]
[0,2,3]
[0,2,5,4,5]
[0,2,5,4]
[0,2,5,5]
[0,2,5]
[0,2,4,5]
[0,2,4]
[0,2,5]
[0,2]
[0,3,5,4,5]
[0,3,5,4]
[0,3,5,5]
[0,3,5]
[0,3,4,5]
[0,3,4]
[0,3,5]
[0,3]
[0,5,4,5]
[0,5,4]
[0,5,5]
[0,5]
[0,4,5]
[0,4]
[0,5]
[0]
Card = 0,
Reason = card_is_trump_suit

The output I would expected would be that the clause fails, since get_cards_by_suit is supposed to return a list with multiple elements, and not just one.

What am I missing?

Edit: Here is some additional info:

This is the get_card_suit/2 clause, as used in get_cards_by_suit/3 :

get_card_suit(Card, clubs) :-
   mod(Card, 24) < 6.

get_card_suit(Card, diamonds) :-
   mod(Card, 24) >= 6,
   mod(Card, 24) < 2 * 6.

get_card_suit(Card, hearts) :-
   mod(Card, 24) >= 2 * 6,
   mod(Card, 24) < 3 * 6.

get_card_suit(Card, spades) :-
   mod(Card, 24) >= 3 * 6,
   mod(Card, 24) < 4 * 6.

I also tested something else out. I replaced the get_cards_by_suit/3 definition with the following:

get_cards_by_suit(List, Suit, [4, 5, 6, 7, 7]) :-
   write(List), nl.

When I use the query the find_strongest_card clause again (but removing the write(AllTrumpCardsInCardPile) command, I get the following output:

[0,1,2,3,5,4,5,13,11,12,17,16,15,13]
false.

However, when I add the original definitions of the get_cards_by_suit/3 clause behind the one I created for testing (as shown below), I again get a similar error get_cards_by_suit/3 definition:

get_cards_by_suit(List, Suit, [4, 5, 6, 7, 7]) :-
   write(List), nl.

get_cards_by_suit([], _, []).

get_cards_by_suit([FirstCard | RemainingCards], Suit, CardsOfGivenSuit) :-
   get_card_suit(FirstCard, FirstCardSuit),
   FirstCardSuit = Suit,
   CardsOfGivenSuit = [FirstCard | OtherCardsOfGivenSuit],
   get_cards_by_suit(RemainingCards, Suit, OtherCardsOfGivenSuit).

get_cards_by_suit([_ | RemainingCards], Suit, CardsOfGivenSuit) :-
   get_cards_by_suit(RemainingCards, Suit, CardsOfGivenSuit).

The output this time is:

[0,1,2,3,5,4,5,13,11,12,17,16,15,13]
[1,2,3,5,4,5,13,11,12,17,16,15,13]
[2,3,5,4,5,13,11,12,17,16,15,13]
[3,5,4,5,13,11,12,17,16,15,13]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[3,5,4,5,13,11,12,17,16,15,13]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[2,3,5,4,5,13,11,12,17,16,15,13]
[3,5,4,5,13,11,12,17,16,15,13]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[3,5,4,5,13,11,12,17,16,15,13]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,4,5,13,11,12,17,16,15,13]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[4,5,13,11,12,17,16,15,13]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[5,13,11,12,17,16,15,13]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
[13,11,12,17,16,15,13]
[11,12,17,16,15,13]
[12,17,16,15,13]
[17,16,15,13]
[16,15,13]
[15,13]
[13]
[]
Card = 0,
Reason = card_is_trump_suit 

Really strange. I appreciate any help

1 Answers

In get_cards_by_suit/3, the unification FirstCardSuit = Suit is used as a "guard" to decide whether to continue (because we have the right suit) or break off (because FirstCardSuit is not of Suit). If we break off we contine with the 4rd clause: get_cards_by_suit([_ | RemainingCards], Suit, CardsOfGivenSuit).

However if we don't break off, Prolog will keep the (wrong) alternative get_cards_by_suit([_ | RemainingCards], Suit, CardsOfGivenSuit) open and try it later, too. You have to tell it to discard that alternative.

Add a cut ! after the guard FirstCardSuit = Suit: FirstCardSuit = Suit,!,..., thus committing to this alternative. The third clause will not be tried later.

Related