gpt4 book ai didi

Prolog:尝试解决一个难题!返回错误

转载 作者:行者123 更新时间:2023-12-02 08:55:00 26 4
gpt4 key购买 nike

我帖子末尾的代码应该回答以下难题:

Brown, Clark, Jones and Smith are 4 substantial citizens who serve their community as achitect, banker, doctor and lawyer, though not necessarily respectively. Brown, who is more conservative than Jones but more liberal than Smith, is a better golfer than the men who are YOUNGER than he is and has a larger income than the men who are OLDER than Clark. The banker, who earns more than the architect, is neither the youngest nor the oldest.

The doctor, who is a poorer golfer than the lawyer, is less conservative than the architect. As might be expected, the oldest man is the most conservative and has the largest income, and the youngest man is the best golfer. What is each man's profession?

代码:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% We represent each "person" with a six-tuple of the form
%
% [ name , profession , age , income , politics , golf ranking ]
%
% where name is either brown, clark, jones, or smith
% profession is either banker, lawyer, doctor, or architect
% age is a range 1 .. 4, with 1 being the youngest and 4 the oldest
% income is a range 1 .. 4, with 1 being the least and 4 the most
% politics is a range 1 .. 4, with 1 being conservative, 4 liberal
% golf ranking is a range 1 .. 4, 1 for the best rank, 4 for the worst
%
:- use_module(library(clpfd)).
solutions(L) :- L = [ [brown, _, _, _, _, _], [clark, _, _, _, _, _],
[jones, _, _, _, _, _], [smith, _, _, _, _, _] ],
clue1(L),
clue2(L),
clue3(L),
clue4(L),
constrained_profession(L),
constrained_age(L),
constrained_income(L),
constrained_politics(L),
constrained_golf_rank(L).

%
% clue #1
% brown, who is more conservateive than jones but
% more liberal than smith, is a better golfer than
% the men who are younger than he is and has a larger
% income than the men who are older than clark
%

clue1(L) :- member(P1,L), member(P2,L), member(P3,L),
P1 = [brown, _, A1, _, L1, G1],
P2 = [jones, _, _, _, L2, _],
P3 = [smith, _, _, _, L3, _],
liberaler( P2, P1 ),
liberaler( P1, P3 ),
not( clue1_helper_a(L) ),
not( clue1_helper_b(L) ).

% for all men younger than brown he is a better golfer ===>
% it is not the case that there exists a man younger than brown
% such that brown is not a better golfer than him.
% The "is not the case" is taken care of in clue1.

clue1_helper_a(L) :- member(P1,L), P1 = [brown, _, A1, _, L1, G1],
member(PU,L), PU = [_, _, AU, _, _, GU],
younger(PU,P1),
not(golfier(P1, PU)).

% for all men older than clark, brown makes more money than they do ===>
% it is not the case that there exists a man older than clark such that
% brown does not make more money than him.
% The "is not the case" is taken care of in clue1.

clue1_helper_b(L) :- member(P1,L), P1 = [brown, _, _, _, _, _],
member(P2,L), P2 = [clark, _, _, _, _, _],
member(PU,L), PU = [_, _, _, _, _, _],
younger(P2,PU),
not(richer(P1, PU)).

%
% clue #2
% the banker, who earns more than the archiect, is
% neither the youngest nor the oldest
%

clue2(L) :- member(P1,L), member(P2,L),
P1 = [_, banker, A1, I1, _, _],
P2 = [_, architect, _, I2, _, _],
richer(P1,P2),
not( A1 = 1 ),
not( A1 = 4 ).

%
% clue #3
% the doctor, who is a pooer golfer than the lawyer, is
% less conservative than the architect.
%

clue3(L) :- member(P1, L), member(P2, L), member(P3,L),
P1 = [_,doctor, _, _, L1, G1],
P2 = [_,lawyer, _, _, _, G2],
P3 = [_,architect, _, _, L3, _],
golfier(P2,P1),
liberaler(P1,P3).

%
% clue #4
% as might be expected, the oldest man is the most
% conservative and has the largest income, and the
% youngest man is the best golfer.

clue4(L) :- member(P1,L), member(P2,L),
P1 = [_, _, 4, 4, 1, _],
P2 = [_, _, 1, _, _, 1].

%
% relations
%

younger(X,Y) :- X = [_, _, AX, _, _, _], Y = [_, _, AY, _, _, _], AX #< AY.

liberaler(X,Y) :- X = [_, _, _, _, LX, _], Y = [_, _, _, _, LY, _], LX #> LY.

golfier(X,Y) :- X = [_, _, _, _, _, GX], Y = [_, _, _, _, _, GY], GX #< GY.

richer(X,Y) :- X = [_, _, _, IX, _, _], Y = [_, _, _, IY, _, _], IX #> IY.

%
% constraints
%

constrained_profession(L) :-
member(P1,L), member(P2,L), member(P3,L), member(P4,L),
P1 = [_, banker, _, _, _, _],
P2 = [_, lawyer, _, _, _, _],
P3 = [_, doctor, _, _, _, _],
P4 = [_, architect, _, _, _, _].

constrained_age(L) :-
member(P1,L), member(P2,L), member(P3,L), member(P4,L),
P1 = [_, _, 1, _, _, _],
P2 = [_, _, 2, _, _, _],
P3 = [_, _, 3, _, _, _],
P4 = [_, _, 4, _, _, _].

constrained_income(L) :-
member(P1,L), member(P2,L), member(P3,L), member(P4,L),
P1 = [_, _, _, 1, _, _],
P2 = [_, _, _, 2, _, _],
P3 = [_, _, _, 3, _, _],
P4 = [_, _, _, 4, _, _].

constrained_politics(L) :-
member(P1,L), member(P2,L), member(P3,L), member(P4,L),
P1 = [_, _, _, _, 1, _],
P2 = [_, _, _, _, 2, _],
P3 = [_, _, _, _, 3, _],
P4 = [_, _, _, _, 4, _].

constrained_golf_rank(L) :-
member(P1,L), member(P2,L), member(P3,L), member(P4,L),
P1 = [_, _, _, _, _, 1],
P2 = [_, _, _, _, _, 2],
P3 = [_, _, _, _, _, 3],
P4 = [_, _, _, _, _, 4].

% end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

但是,当我运行它时,它返回 false!

?- solutions(L).
false.

有人可以帮我吗?

最佳答案

我不会为您解决整个问题,但我想解释一个可以让您快速缩小此类问题范围的通用方法。

回顾一下,我们有以下主要谓词:

solutions(L) :-        L = [ [brown, _, _, _, _, _], [clark, _, _, _, _, _],              [jones, _, _, _, _, _], [smith, _, _, _, _, _] ],        clue1(L),        clue2(L),        clue3(L),        clue4(L),        constrained_profession(L),        constrained_age(L),        constrained_income(L),        constrained_politics(L),        constrained_golf_rank(L).

即使对于最常见的查询,它也会意外失败,其中所有参数都是新变量:

?- solutions(L).false.

为什么会失败?与 GUPU 一样,我将使用 ,通过使用以下定义来概括目标:

:- op(950, fy, *).
*_.

如果您在程序中包含此内容,则可以在目标前面使用 (*)/1 来“删除它们”。这最多可以使生成的程序更加通用

例如,让我们现在概括所有目标(我使用删除线文本来指示目标不再限制解决方案,因为它已概括):

solutions(L) :-        * L = [ [brown, _, _, _, _, _], [clark, _, _, _, _, _],    [jones, _, _, _, _, _], [smith, _, _, _, _, _] ],        * clue1(L),        * clue2(L),        * clue3(L),        * clue4(L),        * constrained_profession(L),        * constrained_age(L),        * constrained_income(L),        * constrained_politics(L),        * constrained_golf_rank(L).

现在查询成功:

?- solutions(L).true.

但是,该程序现在显然太笼统。现在的重点是:我们可以有选择地重新引入目标(=约束)来定位导致程序意外失败的错误。

例如,我选择第一个目标和 clue2/1 目标,并删除它们前面的 (*)/1:

solutions(L) :-        L = [ [brown, _, _, _, _, _], [clark, _, _, _, _, _],              [jones, _, _, _, _, _], [smith, _, _, _, _, _] ],        * clue1(L),        clue2(L),        * clue3(L),        * clue4(L),        * constrained_profession(L),        * constrained_age(L),        * constrained_income(L),        * constrained_politics(L),        * constrained_golf_rank(L).

现在,我们再次拥有:

?- solutions(L).false.

由此,您知道 clue2/1 一定包含错误。这是因为任何进一步的目标最多只能使谓词变得更加具体,并且它们无法消除该目标的失败。

让我们重新考虑一下clue2/1的定义:

clue2(L) :- member(P1,L), member(P2,L),            P1 = [_, banker, A1, I1, _, _],            P2 = [_, architect, _, I2, _, _],            richer(P1,P2),            not( A1 = 1 ),            not( A1 = 4 ).

这里的错误在于使用了非单调谓词not/1,它错误地删除了这种情况下的解决方案。检查一下,即使对于非常一般的查询,我们也从这个谓词中得不到答案:

?- length(Ls, 4), clue2(Ls).false.

该怎么办?答案:

Instead of not/1 or (\+)/1, use constraints to express disequalities.

约束是真实的关系,可以在所有方向上使用,即使它的部分或全部参数是自由变量!

根据您的情况,请使用 dif/2,或者在本例中使用 CLP(FD) 约束 (#\=)/2 表示两个整数不同:

clue2(L) :-        member(P1,L), member(P2,L),        P1 = [_, banker, A1, I1, _, _],        P2 = [_, architect, _, I2, _, _],        richer(P1,P2),        A1 #\= 1,        A1 #\= 4.

通过这个简单的更改,谓词现在可以生成答案,并且缩小范围的程序对于最一般的查询成功

通过系统地应用这种声明式调试技术,您可以纠正其他谓词中剩余的错误。我将其作为练习。

关于Prolog:尝试解决一个难题!返回错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40536677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com