Search code examples
prolog

prolog questions.. fails to invoke predicate


I am trying to understand why duck2 is not called.. Should I cover all cases of the two list being empty, non empty.


duck([H|T], something ) :- 

    write("*"),
    write("?"),
    duck2([H|T], T, something_else),
    write("Over").

duck2([], [], something_else) :- write("AllDone").

duck2([H|T], [H1,T1], something_else) :-
    write("I am here").

trace gives this..

Call: (16) duck([dog, eats], [eats], something) ? creep
   Call: (17) write("*") ? creep
*
   Exit: (17) write("*") ? creep
   Call: (17) write("?") ? creep
?
   Exit: (17) write("?") ? creep
   Call: (17) duck2([dog, eats], [eats], something_else) ? creep
   Fail: (17) duck2([dog, eats], [eats], something_else) ? creep
   Fail: (16) duck([dog, eats], [eats], something) ? creep

Solution

  • duck2([H|T], [H1,T1], something_else) :-
    
    % spaced out to line up with the below trace
                duck2([H|T],       [H1,T1], something_else) :-
    Call: (17) `duck2([dog, eats], [eats],  something_else)` ? creep
    

    [H1, T1] is a list of two items and [eats] is a list of one item; if you try and unify them, they don't unify:

    ?- [H1, T1] = [eats].
    false
    

    so the call fails.

    Should I cover all cases

    Well, at least cover enough cases to make the code work. All cases is up to you.