Prolog Logic/爱因斯坦之谜 [英] Prolog Logic/Einstein Puzzle

查看:22
本文介绍了Prolog Logic/爱因斯坦之谜的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是

布朗、克拉克、琼斯和史密斯是四位重要的公民,他们以建筑师、银行家、医生和律师的身份为社区服务,尽管不一定分别.布朗比琼斯更保守,但比史密斯更自由,他的高尔夫球手比比他大的男人更好,收入也比比克拉克年轻的男人高

Brown, Clark, Jones and Smith are four substantial citizens who serve the community as architect, 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 older than he is and has a larger income than the men who are younger than Clark

挣得比建筑师多的银行家,既不是最年轻的,也不是最年长的.

The banker who earns more than the architect, is neither the youngest or 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

每个人的职业是什么?

我写过

jobs(L) :- L = [[brown,_,_,_,_,_],
           [clark,_,_,_,_,_],
           [jones,_,_,_,_,_],
           [smith,_,_,_,_,_]],
        % [name,job,conservative,golf,income,age]
        % conserative: 1 = least conservative, 4 = most conservative
        % golf: 1 = worst golfer, 4 = best golfer
        % income: 1 = least income, 4 = highest income
        % age: 1 = youngest, 4 = oldest

        % Brown is more conservative than Jones. Brown is less conservative than Smith.
        member([brown,_,C1,_,_,_],L),
        member([jones,_,C2,_,_,_],L),
        C1 > C2,
        member([smith,_,C3,_,_,_],L),
        C1 < C3,

        % Brown is a better golfer than those older than him.
        member([brown,_,_,G1,_,A1],L),
        member([_,_,_,G2,_,A2],L),
        G1 > G2, 
        A2 > A1,

        % Brown has a higher income than those younger than Clark.
        member([brown,_,_,_,I1,_],L),
        member([clark,_,_,_,_,A3],L),
        member([_,_,_,_,I2,A4],L),
        I1 > I2,
        A3 > A4,

        % Banker has a higher income than architect. Banker is neither youngest nor oldest.
        member([_,banker_,_,I3,A5],L),
        member([_,architect,_,_,I4,_],L),
        I3 > I4,
        (A5 = 2;A5 = 3),

        % Doctor is a worse golfer than lawyer. Doctor is less conservative than architect.
        member([_,doctor,C4,G3,_,_],L),
        member([_,lawyer,_,G4,_,_],L),
        member([_,architect,C5,_,_,_],L),
        G3 < G4,
        C4 < C5,

        % Oldest is most conservative and has highest income.
        member([_,_,4,_,4,4],L),

        % Youngest is the best golfer.
        member([_,_,_,4,_,1],L).

当我问它时

?- jobs(L).

我明白了

ERROR: >/2: Arguments are not sufficiently instantiated

我不确定这个错误是什么意思,我相信我已经翻译了所有的线索.

I'm not sure what the error means, I believe I've translated all the clues.

推荐答案

(继续 CapelliC 开辟的道路...)从域中选择并(更好的是,同时)应用规则通常是解决此类难题的方法.仔细尽快测试,以尽快消除错误的选择——但不会越早.

(continuing the trail blazed by CapelliC...) Selecting from domains and (better yet, while) applying the rules is usually the way to go in such puzzles. Carefully testing as soon as possible, to eliminate wrong choices as soon as possible -- but not sooner.

我们不能在算术上比较未知值,这就是错误的含义:> 比较两个已知的算术值,它的参数被实例化.但是如果一个 Prolog 逻辑变量还没有被实例化,这意味着它的值仍然是未知的.

We can't arithmetically compare unknown values, this is what the error means: > compares two known arithmetical values to which its arguments are instantiated. But if a Prolog logical variable is not yet instantiated it means that its value is still unknown.

约束逻辑编程 (CLP) 中,我们可以预先注册这样的约束,但不能在普通 Prolog 中.尽管许多现代 Prolog 中都有可用的 CLP 包或谓词.SWI Prolog 也有.但是在普通的 Prolog 代码中,我们必须小心.

In constraint logical programming (CLP) we can register such constraints upfront, -- but not in vanilla Prolog. Though many a modern Prolog has CLP packages or predicates available in them. SWI Prolog has it too. But in vanilla Prolog code, we must be careful.

mselect([A|As],S,Z):- select(A,S,S1), mselect(As,S1,Z).
mselect([],Z,Z).         % (* instantiate a domain by selecting from it *)

puzzle(L):- % (* [_,_,Conserv,Golf,Income,Age] *)
  L =      [ [brown,_,C1,G1,I1,A1],
             [clark,_,C2,_ ,I2,A2],
             [jones,_,C3,_ ,I3,A3],
             [smith,_,C4,_ ,I4,A4] ],

  L1 = [[_,_,4,_,4,4], [_,_,_,4,_,1]],           % (* 6,7 - oldest, youngest *)
  mselect( L1, L, L2),                           % (* L2: neither youngest nor oldest *)
  mselect( [A3,A4], [1,2,3,4], [A2,A1]), A2 > 1, % (* 3b. 1 < A2 < A1  *)
  select( C2, [1,2,3,4], [C3,C1,C4]),            % (* 1.  C3 < C1 < C4 *)

  select(    [_, banker, _ ,GB,IB,_ ], L2, [P3] ),
  mselect( [ [_, archct, CA,GA,IA,_ ],           % (* second view into the same matrix *)
             [_, doctor, CD,GD,ID,_ ] ], [P3|L1], 
           [ [_, lawyer, _ ,GL,IL,_ ] ]         ),
  CD < CA,                                       % (* 5b.          *)
  mselect( [ID,IL], [1,2,3,4], [IA,IB]),         % (* 4a.  IA < IB *)
  mselect( [GA,GB], [1,2,3,4], [GD,GL]),         % (* 5a.  GD < GL *)

  % (* 2. ( X in L : A1 < AX ) => G1 > GX  *)
  % (* 3. ( Y in L : AY < A2 ) => I1 > IY ... so, not(A1<A2)! i.e. % 3b. 1 < A2 < A1 *)
  forall( (member(X,L), last(X,AX), AX>A1), (nth1(4,X,GX), G1>GX) ),
  forall( (member(Y,L), last(Y,AY), A2>AY), (nth1(5,Y,IY), I1>IY) ).

测试:([_,_,Conserv,Golf,Income,Age])

7 ?- time(( puzzle(_X), maplist(writeln,_X),nl, false; true )).
[brown,banker,3,3,3,3]
[clark,doctor,1,1,1,2]
[jones,archct,2,4,2,1]
[smith,lawyer,4,2,4,4]

[brown,banker,3,3,3,3]
[clark,doctor,1,1,2,2]
[jones,archct,2,4,1,1]
[smith,lawyer,4,2,4,4]

[brown,banker,3,3,2,3]
[clark,doctor,1,1,3,2]
[jones,archct,2,4,1,1]
[smith,lawyer,4,2,4,4]

% (* 2,299 inferences, 0.000 CPU in 0.120 seconds (0% CPU, Infinite Lips) *)
true.

这实际上是一个解决方案,根据谜题的提问方式.

This is actually one solution, according to the way the puzzle question is asked.

这篇关于Prolog Logic/爱因斯坦之谜的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆