0

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

寺庙的名称是:hori_takesi、okabe honzo、sama takako 和 takahashi。地点是:船内,toyagi,uchida和usui。日期是 1525、1585、1645 和 1705。

你会得到以下线索:

  1. 内田神社和建于 1645 年的寺庙,一个是高子大人,另一个是冈部本藏。
  2. 船内的寺庙建于高桥之前
  3. 枥木寺建于臼井寺前120年
  4. Hori Takesi wasa 在 sama takako 之后建造

我创建了以下知识库,其中包含所有可能的组合。

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。但我不确定如何实现它。如果有人可以帮助我,我会喜欢它。

4

3 回答 3

1

SWI 序言,

:- 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.
于 2018-04-05T13:55:48.743 回答
0

没有打败一匹死马,但这是一个基于swish的版本。这与 OPs 版本非常相似。

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

它在嗖嗖声中呈现出一张整洁的桌子

在此处输入图像描述

于 2019-12-03T12:31:36.977 回答
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,另一个是冈部本藏。

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

第二条线索:府内的寺庙建于高桥之前。因此,我将在 funai 位置 5 和高桥位置 4 中获取元素,并将它们的值保存在 N1 和 N2 中。然后我需要得到他们的日期。日期是 Temples 的最后 4 个元素,所以我将位置限制为 > 8。然后我得到日期元素并且具有相同的值 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.

第三条线索:toyagi的寺庙建于usui寺庙的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.

第四条线索:堀竹是在高子大人之后建造的

clue4(Temples):-
    element(1, Temples, N1),
    element(3, Temples, N2),
    Y1 #> 8,
    Y2 #> 8,
    element(Y1, Temples, N1),
    element(Y2, Temples, N2),
    Y1 #> Y2.
于 2017-12-22T14:08:14.730 回答