dragonwasrobot / learn-prolog-now-exercises

My solutions to the exercises and practical sessions of the book 'Learn Prolog Now!' by Patrick Blackburn, Johan Bos, and Kristina Striegnitz.
288 stars 81 forks source link

Remarks to exercises in chapter 6 #4

Closed mrkkrp closed 9 years ago

mrkkrp commented 9 years ago

I'm learning Prolog, and I don't claim that I am a guru, but take a look at this solution (exercise 6.1):

grab(R,0,A) :- reverse(A,R).
grab([H|T],N,A) :-
    N1 is N - 1,
    grab(T,N1,[H|A]).

doubled(L) :-
    length(L,Len),
    Len mod 2 =:= 0,
    Dbl is Len div 2,
    grab(L,Dbl,[]).

It is based on observation that only lists that have even length can be 'doubled'. Next, I use helper rule grab, that takes first N elements (half of all elements in our case) of a list forming temporary accumulator. In base case the accumulator is reversed and compared to the rest of the list. Use trace (although you may know how to use real profiler), and see for yourself that it makes way less calls.


It's also really strange that you need equal predicate. As far as I know Prolog can pattern match on entire lists, so:

palindrome(L) :- reverse(L,L).

Where reverse is standard function (it's accumulator based internally).


6.3.1. Why not to use _? It doesn't cause 'singleton variable' warning (in SWI-Prolog):

second(X, [_,X|_]).

6.4 Your toptail seems to be overcomplicated, maybe it's better to substitute it with something like this:

toptail([_|T],R) :- append(R,[_],T).

? Please try it and you will see that all conditions of the task are satisfied.


Here is a funny solution for 5:

swapfl([H1|T1],[H2|T2]) :-
    reverse(T1,[H2|X]),
    reverse(T2,[H1|X]).

Exercise 6.6. In this solution you write:

house(blue,japanese,Xc).
house(red,english,snail).
house(Za,spanish,jaguar).

How do you know that Japanese lives in the blue house? There is no such fact in the text of the riddle. The same applies to the fact that Englishman keeps a snail. The riddle says that Englishman lives in red house, that's all. In definition of street you somehow know order in which all the 'properties' are placed on the street. Sorry, but your solution is simply not valid. It's not a solution, it's a speculation.

Here is the proper solution:

zebra(X) :- %% zebra(X,[H0,H1,H2]) :-
    member(house(red, english, _), [H0,H1,H2]),
    member(house(_, spanish, jaguar), [H0,H1,H2]),
    sublist([house(_, _, snail), house(_, japanese, _)], [H0,H1,H2]),
    sublist([house(_, _, snail), house(blue, _, _)], [H0,H1,H2]),
    member(house(_, X, zebra), [H0,H1,H2]).

Try zebra(X,L). query (uncomment second variant of the definition), and you will see that Japanse keeps zebra, there are two possible streets that logically satisfy given conditions:

?- zebra(X,L).
X = japanese,
L = [house(red, english, snail), house(blue, japanese, zebra), 
house(_G35, spanish, jaguar)] ;
X = japanese,
L = [house(_G35, spanish, jaguar), house(red, english, snail), 
house(blue, japanese, zebra)] ;
false.

Feel free to improve your solutions (you may also not mention me as co-author, just correct the solutions, so people could see proper solutions and improve their Prolog skills), but if you don't want to improve them, tell me and I will create my own repository of solutions. I shall check all your solutions as I progress through the book.


Best, -- Mark

mrkkrp commented 9 years ago

Solutions to exercises in the practical session (those that actually solved) have room for improvement too.

I will not explain lots of details here, as this place is not appropriate for this, but it's important to say that your solution of set is overcomplicated. You don't need to reverse set, because in theory of sets, there is no particular order in a set.

Also, your set hangs if I try to get more solutions using semicolon ; (SWI-Prolog), think about it.

Also, a number of functions that are introduced in the book are standard and they are present in most (all?) Prolog implementations: reverse, append, member, etc. You don't need to redefine them in every file.

All in all, although you've done considerable work writing all the stuff, I think that your solutions are rather misleading for those who learn the language. I should admit that I have to close this issue, as you have ignored it and obviously to correct all the exercises you have to do a lot of work. I cannot ask you to do it, as you probably have better things to do in your spare time. I think forking makes no sense in this case, so I have to write all the solutions from scratch.

dragonwasrobot commented 9 years ago

I appreciate the input though it should hopefully be obvious from the description and commit log that the repository contains my (at times incomplete and flawed) solutions to the exercises and I probably haven't touched them for 4 years (except for when I put them online), so they should be treated with proper caution.