% seznam
% [a] = [X|Xs] % neprázdný seznam
% [a, b] = [X, Y] % dvouprkový seznam
% Xs = [_,_|_] %% vyžaduje alespoň dvouprvkový seznam

% person declaration
person(david).
person(thomas).
person(stella).
person(emma).

% name declaration
male(david).
male(thomas).
female(stella).
female(emma).

% food declartion
food(dumplings).
food(pasta).
food(soup).
food(trout).

% drink declaration
drink(beer).
drink(cider).
drink(ice_tea).
drink(wine).

% sitting order definition
sitting_opposite(X, Y) :- male(X), male(Y), X \= Y.
sitting_opposite(X, Y) :- female(X), female(Y), X \= Y.

person_list([Name, Food, Drink]) :-
    person(Name),
    food(Food),
    drink(Drink).

solve_(L) :-
    % rule n.1
    member(person_list([Name1,_,cider]), L),
    member(person_list([Name2,trout,_]), L),
    sitting_opposite(Name1, Name2),
    % rule n.2
    % hard-wired

    % rule n.3
    % hard-wired

    % rule n.4
    member(person_list([Name3,pasta,_]), L),
    member(person_list([Name4,_,beer]), L),
    sitting_opposite(Name3, Name4),
    % rule n.5
    member(person_list([david,_,DavidDrink]), L),
    DavidDrink \= ice_tea,
    % rule n.6
    member(person_list([emma,_, wine]), L),
    % rule n.7
    member(person_list([stella, StellaFood, _]), L),
    StellaFood \= dumplings.


solve(Dumplings, Pasta, Soup, Trout) :-
    solve_([
        person_list([Dumplings, dumplings, beer]), 
        person_list([Pasta, pasta, _]),
        person_list([Soup, soup, cider]),
        person_list([Trout, trout, _])
        ]),
        Dumplings \= Pasta,
        Dumplings \= Soup,
        Dumplings \= Trout,
        Pasta \= Soup,
        Pasta \= Trout,
        Soup \= Trout.