初学者Prolog逻辑拼图

时间:2018-02-27 01:01:31

标签: prolog

忍受我,我知道这显然是超级简单的。我似乎无法绕过序幕。我有这个逻辑问题:

在最近的节日中,对100米高温进行了密切监控。

每位参赛者必须参加两场比赛才能确定平均场地。

两场比赛中只有一名选手在同一个地方完成比赛。

艾伦永远不会持久。查尔斯总是击败达伦。布莱恩至少有一个 第一名。艾伦在至少一场比赛中获得第三名。达伦都是 查尔斯获得了第二名。这两个结果是什么?

答案:第1场比赛:Brian,Charles,Alan,Darren。第2场比赛:查尔斯,达伦,艾伦, 布赖恩。

这是我到目前为止所提出的,但我无法弄清楚"至少"和其他更复杂的条件。

place(one).
place(two).
place(three).
place(four).

/* Place (constants): one, two, three, four.

Names (variables): Alan_1, Brian_1, Charles_1, Darren_1
Names (variables): Alan_2, Brian_2, Charles_2, Darren_2
*/

higher(one,two).
higher(one,three).
higher(one,four).
higher(two,three).
higher(two,four).
higher(three,four).

is_higher(X,Y):- higher(X,Y).
is_higher(X,Y):- higher(X,Z), is_higher(Z,Y).


is_different(S,T,U,V,W,X,Y,Z):- W\=X,W\=Y,W\=Z,X\=Y,X\=Z,Y\=Z,W\=S,W\=T,
            W\=U,W\=V,S\=T,T\=U,U\=V,S\=U,S\=V,T\=V,
            T\=W,T\=X,T\=Y,T\=Z,U\=W,U\=X,U\=Y,U\=Z,
            V\=X,V\=Y,V\=Z.


solution(Alan_1, Brian_1, Charles_1, Darren_1, Alan_2, Brian_2, Charles_2, 
Darren_2):-
place(Alan_1), place(Brian_1), place(Charles_1), place(Darren_1), 
place(Alan_2), place(Brian_2), place(Charles_2), place(Darren_2),
Alan_1\=four, Alan_2\=four, higher(Charles_1, Darren_1), higher(Charles_2, 
Darren_2),

is_different(Alan_1, Brian_1, Charles_1, Darren_1, Alan_2, Brian_2, 
Charles_2, Darren_2).

/*  Query */

% solution(Alan_1, Brian_1, Charles_1, Darren_1, Alan_2, Brian_2, Charles_2, 
Darren_2).

任何帮助或智慧的话都会受到超级赞赏。

2 个答案:

答案 0 :(得分:2)

我用SWI + CLPFD解决了。 为了表示"至少", 我使用了#\/

:-use_module(library(clpfd)). solve(RaceResult):- RaceResult = [Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2], RaceResult ins 1..4, all_different([Alan1,Chales1,Brian1,Darren1]), all_different([Alan2,Chales2,Brian2,Darren2]), % Only one runner finished in the same place in both races. (Alan1 #= Alan2) #<==> AlanSame, (Chales1 #= Chales2) #<==> ChalesSame, (Brian1 #= Brian2) #<==> BrianSame, (Darren1 #= Darren2) #<==> DarrenSame, sum([AlanSame,ChalesSame,BrianSame,DarrenSame], #=, 1), % Alan was never last. Alan1 #\= 4, Alan2 #\= 4, % Alan finished third in at least one of the races. (Alan1 #= 3 ) #\/ (Alan2 #= 3), % Charles always beat Darren. Chales1 #< Darren1, Chales2 #< Darren2, % Brian had at least one first place. (Brian1 #= 1 ) #\/ (Brian2 #= 1), % Both Darren and Charles had a second place. (Darren1 #= 2) #\/ (Darren2 #= 2), (Chales1 #= 2) #\/ (Chales2 #= 2), labeling([ffc],RaceResult). ?- solve([Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2]). Alan1 = Alan2, Alan2 = 3, Chales1 = Brian2, Brian2 = 1, Chales2 = Darren1, Darren1 = 2, Brian1 = Darren2, Darren2 = 4 ; Alan1 = Alan2, Alan2 = 3, Chales1 = Darren2, Darren2 = 2, Chales2 = Brian1, Brian1 = 1, Brian2 = Darren1, Darren1 = 4.
:-use_module(library(clpfd)). solve(RaceResult):- RaceResult = [Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2], RaceResult ins 1..4, all_different([Alan1,Chales1,Brian1,Darren1]), all_different([Alan2,Chales2,Brian2,Darren2]), % Only one runner finished in the same place in both races. (Alan1 #= Alan2) #<==> AlanSame, (Chales1 #= Chales2) #<==> ChalesSame, (Brian1 #= Brian2) #<==> BrianSame, (Darren1 #= Darren2) #<==> DarrenSame, sum([AlanSame,ChalesSame,BrianSame,DarrenSame], #=, 1), % Alan was never last. Alan1 #\= 4, Alan2 #\= 4, % Alan finished third in at least one of the races. (Alan1 #= 3 ) #\/ (Alan2 #= 3), % Charles always beat Darren. Chales1 #< Darren1, Chales2 #< Darren2, % Brian had at least one first place. (Brian1 #= 1 ) #\/ (Brian2 #= 1), % Both Darren and Charles had a second place. (Darren1 #= 2) #\/ (Darren2 #= 2), (Chales1 #= 2) #\/ (Chales2 #= 2), labeling([ffc],RaceResult). ?- solve([Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2]). Alan1 = Alan2, Alan2 = 3, Chales1 = Brian2, Brian2 = 1, Chales2 = Darren1, Darren1 = 2, Brian1 = Darren2, Darren2 = 4 ; Alan1 = Alan2, Alan2 = 3, Chales1 = Darren2, Darren2 = 2, Chales2 = Brian1, Brian1 = 1, Brian2 = Darren1, Darren1 = 4.

也许有另一种解决方案?

Race1: Chales 达伦 艾伦 布赖恩

RACE2: 布赖恩 Chales 艾伦 达伦

...抱歉只是替换了race1和race2。

答案 1 :(得分:0)

我是这样做的:

puzzle :-
    Races = [[_,_,_,_],[_,_,_,_]],
    Races = [R1,R2],
    (first(brian,R1);first(brian,R2);(first(brian,R1),first(brian,R2))),
    (third(alan,R1);third(alan,R2);(third(alan,R1),third(alan,R2))),
    ((second(darren,R1),second(charles,R2));(second(darren,R2),second(charles,R1))),
    member(brian,R1),
    member(charles,R1),
    member(brian,R2),
    member(charles,R2),
    member(alan,R1),
    member(darren,R1),
    member(alan,R2),
    member(darren,R2),
    before(charles,darren,R1),
    before(charles,darren,R2),
    never_last(alan,Races),
    only_one_same(Races),
    write(Races),nl.

zip_equal([],[],[]).
zip_equal([R|R1s],[R|R2s],[R|Rs]) :- !, zip_equal(R1s,R2s,Rs).
zip_equal([_|R1s],[_|R2s],Rs) :- !, zip_equal(R1s,R2s,Rs).

never_last(X,[[A1,B1,C1,_],[A2,B2,C2,_]]) :- member(X,[A1,B1,C1]), member(X,[A2,B2,C2]).

before(X,Y,[X|Rs]) :- !, member(Y,Rs).
before(X,Y,[_|Rs]) :- before(X,Y,Rs).

first(X,[X,_,_,_]).
second(X,[_,X,_,_]).
third(X,[_,_,X,_]).

only_one_same([R1s,R2s]) :- zip_equal(R1s,R2s,[_]).