Logical Problem


Prolog language is an excellent tool to solve problems that need inference based on facts and rules. Examples of problems of this case are the logical problems we see in puzzle magazines. Lets see one of these problems and its solution in Prolog.

Portuguese version.

Relax with Logic


The five women in this puzzle are used to relax solving one or two logical problems per day, although they have a very busy life. One of these days they stopped to relax in different places and times. Using the tips bellow, relate the women, their jobs, and tell what time and place they stopped to solve their logical problems.


1- The student started her day with a logical problem session at 9h in the morning.
2- Benta had a break later than the autonomous woman.
3- Mara solved her problems in the garden, earlier than the director of a big company (who is not Odete).
4- Marcela work as a cosmetic seller; she had a break immediately before Odete.
5- One of the women, but not Odete, exercised her capacity during the breakfast in the snack bar.
6- Rute chose the lunch time to relax, starting at 13h o'clock.
7- The bank manager brought her logical problems to the park. One person went to a restaurant at 18h o'clock to relax solving logical problems.

The names, jobs, times and places are mutually exclusive:
Names: Benta, Mara, Marcela, Odete and Rute
Jobs: director, manager, autonomous, seller and student.
Times: 8h, 9h, 13h, 16h and 18h.
Places: snackbar, restaurant, garden, kitchen and park.

(*) Magazine Problemas de Lógica, Coquetel, n. 90, p. 20 (ISSN 1517-0837).

Prolog Solution


Well, if you want the answer of this problem you must implement the code bellow and run it in a Prolog interpreter - or buy the magazine! :)

One way to solve it is using lists and restricting the possibilities of solutions for every tip you consider. The data structure of this program is basically a 5 elements list, that is ordered, one for each person:
[ListaBenta, ListaMara, ListaMarcela, ListaOdete, ListaRute]=Lista
Every one of this elements is another sublist with 3 characteristics, also ordered. For example, ListaBenta or any other, contain:
[Job, Time, Place]=ListaBenta

The program starts calling the predicate resolve(X) that generates a list X with all possible valid combinations without repetition, given by the predicate solucao(X).

After X contain all possible solutions, every predicate itemN(X) will eliminate from that list the solutions that are incompatible with the information they carry.

After considering all items, the list X will have only one possible solution to the problem.

Complete code of the Prolog Solution


Save this code bellow with the name: job-time-place.pl. For linux systems, make it executable (chmod +x job-time-place.pl) and run it like a script.

Download source code:
Portugese version:
English version:

Source code:

#!/usr/bin/pl -t solve(X) -q -f none -s
 
%Prof. Dr. Ruben Carlo Benante (benante @ gmail.com)
%Solution to a logic problem using PROLOG language
%Magazine Problemas de logica, Coquetel, n. 90, p. 20 (ISSN 1517-0837)
%File: job-time-place.pl
 
 
% == Relax with Logic ==
% 
%The five women in this puzzle are used to relax solving one or two
%logical problems per day, although they have a very busy life.
%One of these days they stopped to relax in different places and times.
%Using the tips bellow, relate the women, their jobs, and tell what time
%and place they stopped to solve their logical problems.
% 
% 1- The student started her day with a logical problem session at 9h in the morning.
% 2- Benta had a break later than the autonomous woman.
% 3- Mara solved her problems in the garden, earlier than the director of a big
%company (who is not Odete).
% 4- Marcela work as a cosmetic seller; she had a break immediately before Odete.
% 5- One of the women, but not Odete, exercised her capacity during the breakfast
%in the snack bar.
% 6- Rute chose the lunch time to relax, starting at 13h o'clock.
% 7- The bank manager brought her logical problems to the park. One person went
%to a restaurant at 18h o'clock to relax solving logical problems.
% 
% The names, jobs, times and places are mutually exclusive:
% **Names**: Benta, Mara, Marcela, Odete and Rute
% **Jobs**: director, manager, autonomous, seller and student.
% **Times**: 8h, 9h, 13h, 16h and 18h.
% **Places**: snackbar, restaurant, garden, kitchen and park.
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chance this part to solve another problem
 
indexname(name).
indexa(benta).     %a
indexb(mara).      %b
indexc(marcela).   %c
indexd(odete).     %d
indexe(rute).      %e
 
car1name(job).
car1(director).
car1(manager).
car1(autonomous).
car1(seller).
car1(student).
 
car2name(time).
car2(8).
car2(9).
car2(13).
car2(16).
car2(18).
 
car3name(place).
car3(snackbar).
car3(restaurant).
car3(garden).
car3(kitchen).
car3(park).
 
%list of names x 5= [Lbenta,Lmara,Lmarcela,Lodete,Lrute]
%each list of names contain a list of characteristics x 3=[job, time, place]
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%begin of the tips:
 
%student did at 9h
item1(Lists) :-
    member(Lsomeone,Lists),
    [student,9,_]=Lsomeone.
 
%Benta did after autonomous
item2(Lists) :-
    [Lbenta,_,_,_,_]=Lists,
    member(Lsomeone,Lists),
    [autonomous,TimeAutonomous,_]=Lsomeone,
    not(Lbenta=Lsomeone),
    [_,TimeBenta,_]=Lbenta,
    TimeBenta > TimeAutonomous.
 
%Mara did in the garden
item3([_,[_,_,garden],_,_,_]).
 
%Mara did earlier than director
item4(Lists) :-
    [_,Lmara,_,_,_]=Lists,
    [JobMara,TimeMara,_]=Lmara,
    member(Lsomeone,Lists),
    not(Lsomeone=Lmara),
    [director,TimeDirector,_]=Lsomeone,
    not(JobMara=director),
    TimeMara < TimeDirector.
 
%Odete is not a director
item5([_,_,_,Lodete,_]) :-
    not([director,_,_]=Lodete).
 
%Marcela works as seller
item6([_,_,[seller,_,_],_,_]).
 
%Marcela did immediately before Odete
item7(Lists) :-
    [_,_,Lmarcela,Lodete,_]=Lists,
    [_,TimeMarcela,_]=Lmarcela,
    [_,TimeOdete,_]=Lodete,
    TimeMarcela=8,
    TimeOdete=9.
 
%or
item7(Lists) :-
    [_,_,Lmarcela,Lodete,_]=Lists,
    [_,TimeMarcela,_]=Lmarcela,
    [_,TimeOdete,_]=Lodete,
    TimeMarcela=9,
    TimeOdete=13.
 
%or
item7(Lists) :-
    [_,_,Lmarcela,Lodete,_]=Lists,
    [_,TimeMarcela,_]=Lmarcela,
    [_,TimeOdete,_]=Lodete,
    TimeMarcela=13,
    TimeOdete=16.
 
%or
item7(Lists) :-
    [_,_,Lmarcela,Lodete,_]=Lists,
    [_,TimeMarcela,_]=Lmarcela,
    [_,TimeOdete,_]=Lodete,
    TimeMarcela=16,
    TimeOdete=18.
 
%Odete was not in the snackbar
item8([_,_,_,[_,_,LugarOdete],_]) :-
    not(LugarOdete=snackbar).
 
%Rute did at 13h
item9([_,_,_,_,[_,13,_]]).
 
%manager did in the park
item10(Lists) :-
    member([manager,_,park],Lists).
 
%someone in the restaurant started at 18h
item11(Lists) :-
    member([_,18,restaurant],Lists).
 
item12(_).
item13(_).
item14(_).
item15(_).
item16(_).
item17(_).
item18(_).
item19(_).
item20(_).
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Do not change bellow !!!
 
solutions([[Car1a, Car2a, Car3a],[Car1b, Car2b, Car3b],[Car1c, Car2c, Car3c],
[Car1d, Car2d, Car3d],[Car1e, Car2e, Car3e]]) :-
            car1(Car1a),
            car1(Car1b),
            not(Car1a=Car1b),
            car1(Car1c),
            not(Car1a=Car1c),
            not(Car1b=Car1c),
            car1(Car1d),
            not(Car1a=Car1d),
            not(Car1b=Car1d),
            not(Car1c=Car1d),
            car1(Car1e),
            not(Car1a=Car1e),
            not(Car1b=Car1e),
            not(Car1c=Car1e),
            not(Car1d=Car1e),
            car2(Car2a),
            car2(Car2b),
            not(Car2a=Car2b),
            car2(Car2c),
            not(Car2a=Car2c),
            not(Car2b=Car2c),
            car2(Car2d),
            not(Car2a=Car2d),
            not(Car2b=Car2d),
            not(Car2c=Car2d),
            car2(Car2e),
            not(Car2a=Car2e),
            not(Car2b=Car2e),
            not(Car2c=Car2e),
            not(Car2d=Car2e),
            car3(Car3a),
            car3(Car3b),
            not(Car3a=Car3b),
            car3(Car3c),
            not(Car3a=Car3c),
            not(Car3b=Car3c),
            car3(Car3d),
            not(Car3a=Car3d),
            not(Car3b=Car3d),
            not(Car3c=Car3d),
            car3(Car3e),
            not(Car3a=Car3e),
            not(Car3b=Car3e),
            not(Car3c=Car3e),
            not(Car3d=Car3e).
 
solve([[Car1a, Car2a, Car3a],[Car1b, Car2b, Car3b],[Car1c, Car2c, Car3c],
[Car1d, Car2d, Car3d],[Car1e, Car2e, Car3e]]) :-
    X=[[Car1a, Car2a, Car3a],[Car1b, Car2b, Car3b],[Car1c, Car2c, Car3c],
[Car1d, Car2d, Car3d],[Car1e, Car2e, Car3e]],
    solutions(X),
    item1(X),
    item2(X),
    item3(X),
    item4(X),
    item5(X),
    item6(X),
    item7(X),
    item8(X),
    item9(X),
    item10(X),
    item11(X),
    item12(X),
    item13(X),
    item14(X),
    item15(X),
    item16(X),
    item17(X),
    item18(X),
    item19(X),
    item20(X),
    indexa(Ia),
    indexb(Ib),
    indexc(Ic),
    indexd(Id),
    indexe(Ie),
    indexname(Indexname),
    car1name(Car1name),
    car2name(Car2name),
    car3name(Car3name),
    writef('%w %w %w %w\n',[Indexname, Car1name, Car2name, Car3name]),
    writef('%w %w %w %w\n',[Ia, Car1a, Car2a, Car3a]),
    writef('%w %w %w %w\n',[Ib, Car1b, Car2b, Car3b]),
    writef('%w %w %w %w\n',[Ic, Car1c, Car2c, Car3c]),
    writef('%w %w %w %w\n',[Id, Car1d, Car2d, Car3d]),
    writef('%w %w %w %w\n',[Ie, Car1e, Car2e, Car3e]).