prolog基于网格的逻辑拼图卡住了

时间:2017-12-21 15:01:13

标签: prolog zebra-puzzle

这个谜题是这样的:在岛上有4座寺庙。每座寺庙都有一个名称,位置和建造日期。您将获得4条线索,以帮助您确定哪4种组合(名称,位置,日期)是正确的。我必须使用prolog来解决这个问题。

寺庙的名字是:hori_takesi,okabe honzo,sama takako和takahashi。地点是:funai,toyagi,uchida和usui。日期分别为1525年,1585年,1645年和1705年。

您将获得以下线索:

  1. 在内田的神社和建于1645年的寺庙中,有一个是萨马 takako和另一个是okabe honzo。
  2. 船井的寺庙建于takahashi之前
  3. 玩具寺是在臼井寺前120年建造的
  4. Hori takei wasa是在sama takako之后建造的
  5. 我创建了以下knowlegde base,它包含所有可能的组合。

    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).
    

    你要问prolog的问题是:?-solution(X)。这必须返回所有4个正确的组合。所以X是4个元素的列表,即太阳穴。

    溶液(X)。如果所有线索都是真的,那是真的。所以我做了以下事情:

    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).
    

    我不确定如何从这里开始。我得到的另一个提示是使用member / 2。但我不确定如何实现它。如果有人可以帮助我,请喜欢它。

3 个答案:

答案 0 :(得分: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.

答案 1 :(得分:0)

这是我对问题的回答。 我正在使用SICStus Prolog,而且我正在使用clpfd库。

:- use_module(library(clpfd)).

在有限域中,您必须将问题转换为整数。

因此我决定寺庙的名字是1..4。 地点和年份的顺序与问题中的顺序相同。

我在解决方案中包含了名称的顺序,因此,会有一些解决方案只是名称中的不同顺序。

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

策略是使用约束。解决方案必须满足必要条件。

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.

第一条线索:在内田的神社和建于1645年的寺庙,一个是sama takako,另一个是okabe honzo。

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

第二条线索:funai的寺庙是在takahashi之前建造的。 因此,我将获得funai位置的元素,5和takahashi,4,并将它们的值保存在N1和N2。然后我需要得到他们的约会。日期是寺庙的最后4个元素,因此我将把这些位置视为&gt;然后,我得到日期元素并具有相同的值N1和N2,并约束解决方案以满足线索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.

第三条线索:玩具寺是在臼井寺前120年建造的。 或者,根据我们的日期顺序,日期位置之间的差异为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.

第四条线索:Hori takei是在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.

答案 2 :(得分:0)

不打败老马,但这是基于swish的版本。这与OP版本非常相似。

:- 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)).

它在swish上呈现一个整齐的表格

enter image description here