Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remarks to exercises in chapter 6 #4

Closed
mrkkrp opened this issue Jan 25, 2015 · 2 comments
Closed

Remarks to exercises in chapter 6 #4

mrkkrp opened this issue Jan 25, 2015 · 2 comments

Comments

@mrkkrp
Copy link

mrkkrp commented Jan 25, 2015

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
Copy link
Author

mrkkrp commented Jan 26, 2015

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.

@mrkkrp mrkkrp closed this as completed Jan 26, 2015
@dragonwasrobot
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants