【问题标题】:prolog grid-based logic puzzle stuckprolog 基于网格的逻辑难题卡住了
【发布时间】:2017-12-21 15:01:13
【问题描述】:

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

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

给你以下线索:

  1. 内田神社和建于1645年的寺庙中,一位是大人 takako,另一个是okabe honzo。
  2. 船内寺建于高桥之前
  3. toyagi 寺比臼井寺早 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。但我不确定如何实现它。如果有人可以帮助我,我会很高兴。

【问题讨论】:

  • 你应该使用 clpfd 库来解决这个问题
  • @damianodamiano:在学习高级工具之前,更好的OP学习基础知识。 CLP(FD) 它是一个leaking abstraction,你不能在不知道你的谓词发生了什么的情况下使用它......
  • 在问题标题中,您指出了尝试中缺少的基本细节。您应该使用单个谓词对 grid 建模,其中变量有机会一起发挥作用。每条线索都适用于网格行的某个子集,因为每一行都代表一个实体。

标签: prolog zebra-puzzle


【解决方案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.

【讨论】:

    【解决方案2】:

    这是我对这个问题的回答。 我正在使用 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年的寺庙,一个是高子大人,另一个是冈部本藏。

    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.
    

    【讨论】:

    • @CapelliC 你为什么说它被滥用了?
    • 我希望强大的工具能够减少解决问题的工作量,甚至是玩具问题。您的代码很长,我在理解它时遇到了问题(例如,在线索 4/1 中, Y1#>8 的目的是什么?)。所以我认为你的回答只会让朱利叶斯感到困惑。
    • @CapelliC 将下一个元素限制为日期,最后 4 个元素是日期,我将对其进行编辑。
    【解决方案3】:

    不是死马,但这是基于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)).
    

    它会在 swish 上呈现一张整洁的桌子

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2011-06-10
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      相关资源
      最近更新 更多