0

The puzzle goes like this: on an island there are 4 temples. Each temple has a name, location and date it was build. You get 4 clues to help you determine which 4 combinations (name, location, date) are correct. I have to solve this using prolog.

The names of the temples are: hori_takesi, okabe honzo, sama takako and takahashi. The locations are: funai, toyagi, uchida and usui. The dates are 1525, 1585, 1645 and 1705.

You are given the following clues:

  1. Of the shrine in Uchida and the temple built in 1645, one is sama takako and the other is okabe honzo.
  2. The temple in Funai was built before takahashi
  3. The temple in toyagi was built 120 years before the temple in usui
  4. Hori takesi wasa built after sama takako

I created the following knowlegde base which holds all possible combinations.

temple(hori_takesi, Location, Y).
temple(okabe_honzo, Location, Y).
temple(sama_takako, Location, Y).
temple(takahashi, Location, Y).

temple(Name, funai, Y).
temple(Name, toyagi, Y).
temple(Name, uchida, Y).
temple(Name, usui, Y).

temple(Shrine, Location, 1525).
temple(Shrine, Location, 1585).
temple(Shrine, Location, 1645).
temple(Shrine, Location, 1705).

The query you gonna ask prolog is: ?-solution(X). This has to return all 4 correct combinations. So X is a list of 4 elements namely the temples.

solution(X). Is true if all clues are true. So I did the following:

clue1(X) :- temple(Name, uchida, Y), Y\= 1645
clue2(X) :- temple(Name, funai, Y), temple(Shrine, takahashi, Y1), Y < Y1.
clue3(X) :- temple(Name, toyagi Y), temple(Shrine, usui, Y1). Y1 is Y + 120.
clue4(X) :- temple(hori_takesi, Loc, Y), temple(sama_takako, Loc, Y1) Y > Y1.
solution(X) :- clue1(X), clue2(X), clue3(X), clue4(X).

I'm not sure on how to proceed onwarts from here. Another tip i got is to use member/2. But im not sure on how to implement it. Love it if someone can help me.

false
  • 10,264
  • 13
  • 101
  • 209
  • 1
    You should use clpfd library to solve this problem – damianodamiano Dec 21 '17 at 17:59
  • 1
    @damianodamiano: before to study advanced tools, better OP learn the basics. CLP(FD) it's a [leaking abstraction](https://en.wikipedia.org/wiki/Leaky_abstraction), you cannot use it without knowing what's going on in your predicates... – CapelliC Dec 22 '17 at 10:49
  • In the question title, you indicate a fundamental detail that's missing from your attempt. You should model a *grid* with a single predicate, where variables get a chance to play together. Every clue will work on some subset of grid rows, since each row represents an entity. – CapelliC Dec 22 '17 at 11:06

3 Answers3

1

SWI Prolog,

:- use_module(library(clpfd)).

solve(Place, Year):-
    Place = [Funai, Toyagi, Uchida, Usui],
    Year = [Y1525, Y1585, Y1645, Y1705],
    Hori #= 1,
    Okabe #= 2,
    Sama #= 3,
    Takahashi #= 4,
    init_dom(1..4,Place),
    init_dom(1..4,Year),

    % clue1
    % Of the shrine in Uchida and the temple built in 1645, one is sama takako and the other is okabe honzo.
    (Uchida #= Sama #/\ Y1645 #= Okabe) #\ (Y1645 #= Sama #/\ Uchida #= Okabe),

    %clue 2
    %The temple in Funai was built before takahashi
    element(A, Year, Funai),
    element(B, Year, Takahashi),
    A #< B,

    %clue 3
    %The temple in toyagi was built 120 years before the temple in usui
    element(C, Year, Toyagi),
    element(D, Year, Usui),
    D - C #= 2,

    %clue 4
    %Hori takesi was built after sama takako
    element(E, Year, Hori),
    element(F, Year, Sama),
    E #> F,

    labeling([], Place),
    labeling([], Year).


init_dom(R, L) :-
    all_distinct(L),
    L ins R.

% solve(X,Y). to show indexes of Place and Year.
jkj yuio
  • 2,543
  • 5
  • 32
  • 49
0

Here's my answer to the problem. I'm using SICStus Prolog, and I'm using the clpfd library.

:- use_module(library(clpfd)).

In finite domain you have to translate your problem to integers.

As such I decided that the name of the temples will be 1..4. Locations and Years will be in the same order as in the question.

I included the order of the names in the solutions, as such, there will be solutions that are just a different order in the names.

names([hori_takesi, okabe_honzo, sama_takako, takahashi]).
locations([funai, toyagi, uchida, usui]).
years([1525, 1585, 1645, 1705]).

The strategy is to use constrains. The solution will have to meet the requisites.

solver(Temples):-
    years(Years),
    length(Temples, 12),
    domain(Temples, 1, 4),
    global_cardinality(Temples, [1-3, 2-3, 3-3, 4-3]),
    optim(Temples),
    clue1(Temples),
    clue2(Temples),
    clue3(Temples),
    clue4(Temples),
    labeling([], Temples),
    write(Temples).

optim(Temples):-
    element(1, Temples, N1),
    element(2, Temples, N2),
    element(3, Temples, N3),
    element(4, Temples, N4),
    all_distinct([N1, N2, N3, N4]),
    10 #= N1 + N2 + N3 + N4,
    element(5, Temples, N5),
    element(6, Temples, N6),
    element(7, Temples, N7),
    element(8, Temples, N8),
    all_distinct([N5, N6, N7, N8]),
    10 #= N5 + N6 + N7 + N8,
    element(9, Temples, N9),
    element(10, Temples, N10),
    element(11, Temples, N11),
    element(12, Temples, N12),
    all_distinct([N9, N10, N11, N12]),
    10 #= N9 + N10 + N11 + N12.

First clue: Of the shrine in Uchida and the temple built in 1645, one is sama takako and the other is okabe honzo.

clue1(Temples):-
    element(7, Temples, N1),
    element(11, Temples, N2),
    (N1 #= 3 #/\ N2 #= 2)
    #\/ (N2 #= 3 #/\ N1 #= 2).

Second clue: The temple in funai was built before takahashi. So I'll get the element in funai position, 5, and in takahashi, 4, and save their values at N1 and N2. Then I need to get their dates. The dates are the last 4 elements of Temples, so I'll contrains the positions to be > 8. Then I get the elements that are dates and have the same values N1 and N2, and constrain the solutions to satisfy the clue Y2 > Y1.

clue2(Temples):-
    element(5, Temples, N1),
    element(4, Temples, N2),
    Y1 #> 8,
    Y2 #> 8,
    element(Y1, Temples, N1),
    element(Y2, Temples, N2),
    Y2 #> Y1.

Third clue: The temple in toyagi was built 120 years before the temple in usui. Or, with our order of dates, the difference between the dates position is 2.

clue3(Temples):-
    element(6, Temples, N1),
    element(8, Temples, N2),
    Y1 #> 8,
    Y2 #> 8,
    element(Y1, Temples, N1),
    element(Y2, Temples, N2),
    abs(Y1 - Y2) #= 2.

Fourth clue: Hori takesi was built after sama takako

clue4(Temples):-
    element(1, Temples, N1),
    element(3, Temples, N2),
    Y1 #> 8,
    Y2 #> 8,
    element(Y1, Temples, N1),
    element(Y2, Temples, N2),
    Y1 #> Y2.
Diogo Cruz
  • 66
  • 12
  • 1
    @CapelliC why do you say it is misused? – Diogo Cruz Dec 23 '17 at 15:17
  • I expect from powerful tools that t hey *reduce* the effort to solve problems, even toy ones. You code is very long, and I have problems understanding it (for instance, in clue4/1, what's the purpose of Y1#>8 ?). So I think your answer can only confuse Julius. – CapelliC Dec 23 '17 at 15:25
  • 1
    @CapelliC it's to constrain the next element to be a date, the last 4 elements are the dates, i'll edit that. – Diogo Cruz Dec 27 '17 at 20:07
0

Not beating a dead horse but here's a version based on swish. This is very similar to the OPs version.

:- use_module(library(clpfd)).
:- use_rendering(table,
         [header(h('Name','Date','Location'))]).


%   Of the shrine in Uchida and the temple built in 1645, one is sama takako and the other is okabe honzo.
%   The temple in Funai was built before takahashi
%   The temple in toyagi was built 120 years before the temple in usui
%   Hori takesi wasa built after sama takako



temples(Ts):-
    length(Ts,4),
    member(h(hori_takesi, _, _), Ts),
    member(h(okabe_honzo, _, _), Ts),
    member(h(sama_takako, _, _), Ts),
    member(h(takahashi, _, _), Ts),
    member(h(_, funai, _), Ts),
    member(h(_, toyagi, _), Ts),
    member(h(_, uchida, _), Ts),
    member(h(_, usui, _), Ts),
    member(h(_, _, 1525), Ts),
    member(h(_, _, 1585), Ts),
    member(h(_, _, 1645), Ts),
    member(h(_, _, 1705), Ts),
    member(h(takahashi, _, X), Ts), member(h(_, funai, Y), Ts), Y #< X,
    member(h(_, toyagi, Z), Ts), member(h(_, usui, W), Ts), Z + 120 #= W,
    member(h(sama_takako, _, U), Ts), member(h(hori_takesi, _, V), Ts), V #> U,
    (member(h(sama_takako,uchida,_), Ts),member(h(okabe_honzo,_,1645), Ts),\+member(h(okabe_honzo,uchida,_),Ts),\+member(h(sama_takako,_,1645), Ts));(\+member(h(sama_takako,uchida,_), Ts),\+member(h(okabe_honzo,_,1645), Ts),member(h(okabe_honzo,uchida,_),Ts),member(h(sama_takako,_,1645), Ts)).

It renders a neat table on swish

enter image description here

sudhackar
  • 264
  • 2
  • 13