Prolog Logic/Einstein Puzzle

后端 未结 5 996
我寻月下人不归
我寻月下人不归 2021-01-29 01:26

The problem is

Brown, Clark, Jones and Smith are four substantial citizens who serve the community as architect, banker, doctor and lawyer, though not necessarily respe

5条回答
  •  一向
    一向 (楼主)
    2021-01-29 01:43

    you need to bind your variables to a domain before to use them, the easiest way is permutation/2:

        L = [   [brown,J1,C1,G1,I1,A1],
                [clark,J2,C2,G2,I2,A2],
                [jones,J3,C3,G3,I3,A3],
                [smith,J4,C4,G4,I4,A4]],
    
    permutation([1,2,3,4], [C1,C2,C3,C4]),
    permutation([1,2,3,4], [I1,I2,I3,I4]),
    permutation([1,2,3,4], [A1,A2,A3,A4]),
    permutation([1,2,3,4], [G1,G2,G3,G4]),
    permutation([banker,archit,doctor,lawyer], [J1,J2,J3,J4]),
    

    now the rules can be used

        % Brown is more conservative than Jones. Brown is less conservative than Smith.
        member([brown,_,CB,GB,IB,AB],L),
        member([jones,_,CJ,_,_,_],L),
        CB > CJ,
        member([smith,_,CS,_,_,_],L),
        CB < CS,
    

    efficiency wise, when you select (via member) a named member, 'fetch' all related variables at once (brown attributes' are used later). Also beware that referencing in different selection variables J1,C1, etc could lead to unwanted binding.

    A rule difficult to express is

        % Brown is a better golfer than those older than him.
    
        member([_,_,_,GO1,_,AO1],L),
        (AO1 > AB, GB > GO1 ; AO1 < AB),
        member([_,_,_,GO2,_,AO2],L),
        (AO2 > AB, GB > GO2 ; AO2 < AB),
        member([_,_,_,GO3,_,AO3],L),
        (AO3 > AB, GB > GO3 ; AO3 < AB),
    
        vardiff(GO1,GO2,GO3),
        vardiff(AO1,AO2,AO3),  % bug: AO1 was GO1
    

    where vardiff/3 is a simple convenience:

    vardiff(A,B,C) :- A\=B,A\=C,B\=C.
    

    Of course, if your Prolog has available, CLP(FD) is a much better choice.

提交回复
热议问题