初级Prolog逻辑难题

初级Prolog逻辑难题,prolog,Prolog,请容忍我,我知道这显然非常简单。我只是不能把我的头绕在序言上。我有一个逻辑问题: 在最近的奥运会上,100米预赛受到了密切监控 每位参赛者必须参加两场比赛,以便确定平均名次 在两场比赛中,只有一名选手在同一个地方跑完全程 艾伦从来都不是最后一个。查尔斯总是打败达伦。布莱恩至少有一个 第一名。艾伦在至少一场比赛中得了第三名。都是达伦 查尔斯获得了第二名。这两个结果是什么 回答:比赛1:布莱恩,查尔斯,艾伦,达伦。第二场:查尔斯,达伦,艾伦, 布莱恩 这是我到目前为止所想到的,但我无法找出“至少”和

请容忍我,我知道这显然非常简单。我只是不能把我的头绕在序言上。我有一个逻辑问题:

在最近的奥运会上,100米预赛受到了密切监控

每位参赛者必须参加两场比赛,以便确定平均名次

在两场比赛中,只有一名选手在同一个地方跑完全程

艾伦从来都不是最后一个。查尔斯总是打败达伦。布莱恩至少有一个 第一名。艾伦在至少一场比赛中得了第三名。都是达伦 查尔斯获得了第二名。这两个结果是什么

回答:比赛1:布莱恩,查尔斯,艾伦,达伦。第二场:查尔斯,达伦,艾伦, 布莱恩

这是我到目前为止所想到的,但我无法找出“至少”和其他更复杂的条件

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).
任何帮助或智慧之言都将不胜感激

我用SWI+CLPFD解决了这个问题。 代表“至少”, 我用了
\/

:-使用_模块(库(clpfd))。
求解(结果):-
消旋结果=[Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2],
外消旋体结果为1..4,
所有不同的([Alan1,Chales1,Brian1,Darren1]),
一切都不同([Alan2,Chales2,Brian2,Darren2]),
%在两场比赛中,只有一名选手在同一个地方跑完全程。
(Alan1#=Alan2)#alan相同,
(Chales1#=Chales2)#chalesame,
布里安,
(Darren1=Darren2)DarrenSame,
总和([AlanSame,ChalesSame,BrianSame,DarrenSame],#=1),
%艾伦从来都不是最后一个。
Alan1#\=4,
Alan2#\=4,
%艾伦在至少一场比赛中得了第三名。
(Alan1=3)\/(Alan2=3),
%查尔斯总是打败达伦。
挑战,
挑战2,
%布莱恩至少获得了一个第一名。
(Brian1=1)\/(Brian2=1),
%达伦和查尔斯都获得了第二名。
(Darren1#=2)#\/(Darren2#=2),
(挑战1=2)\/(挑战2=2),
标记([ffc],结果)。
?求解([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。
也许还有别的解决办法

第1场: 查尔斯 戴伦 艾伦 布莱恩

第二场: 布瑞恩 查尔斯 艾伦 达伦

。。。抱歉,刚刚更换了race1和race2。

我用SWI+CLPFD解决了问题。 代表“至少”, 我用了
\/

:-使用_模块(库(clpfd))。
求解(结果):-
消旋结果=[Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2],
外消旋体结果为1..4,
所有不同的([Alan1,Chales1,Brian1,Darren1]),
一切都不同([Alan2,Chales2,Brian2,Darren2]),
%在两场比赛中,只有一名选手在同一个地方跑完全程。
(Alan1#=Alan2)#alan相同,
(Chales1#=Chales2)#chalesame,
布里安,
(Darren1=Darren2)DarrenSame,
总和([AlanSame,ChalesSame,BrianSame,DarrenSame],#=1),
%艾伦从来都不是最后一个。
Alan1#\=4,
Alan2#\=4,
%艾伦在至少一场比赛中得了第三名。
(Alan1=3)\/(Alan2=3),
%查尔斯总是打败达伦。
挑战,
挑战2,
%布莱恩至少获得了一个第一名。
(Brian1=1)\/(Brian2=1),
%达伦和查尔斯都获得了第二名。
(Darren1#=2)#\/(Darren2#=2),
(挑战1=2)\/(挑战2=2),
标记([ffc],结果)。
?求解([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。
也许还有别的解决办法

第1场: 查尔斯 戴伦 艾伦 布莱恩

第二场: 布瑞恩 查尔斯 艾伦 达伦

。。。抱歉,刚刚更换了race1和race2。

我是这样做的:

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,[_]).
我是这样做的:

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,[_]).