Logic Puzzle in Prolog - using lists

后端 未结 2 940
情深已故
情深已故 2020-12-21 13:03

I am trying to solve the following problem in Prolog, and I think I have coded it right, but my queries simply return false. Any advice on what to change? The problem is as

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-21 13:37

    First, it seems that the problem statement needs some review - in particular point 4.

    What you have here is a logical puzzle. Thus you really need to stick to the logical part of Prolog. However, in your code I see (\==)/2 and (==)/2 which both do not fully realize the logical relations they pretend to represent. Instead, use dif/2 and (=)/2 respectively.

    But even after replacing those, things are not much better, your program still fails. However, with a pure definition you have a chance to localize the problem. Your problem is that bagels(Sols) fails. Thus, the current definition is too specialized, too narrow. So I will try to generalize it by removing some of your requirements. To this end, I will add * in front of some of your goals. I will generalize them such that the resulting program still fails.

    What is left is a generalization that shows you where you will have to modify your program. Otherwise, the error will persist.

    Edit: I have highlighted what looks particularly odd to me: Two men drinking amaretto.

    :- op(950, fy, *).
    *_.
    
    bagels(Sol):-
       Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
       member([brad,X,plain,_,_], Sol),
          dif(X,wheat),
       member([walt,_,_,small,_], Sol),
       member([_,_,_,medium1,hazelnut], Sol),
       * member([_,_,peanut_butter,medium2,_], Sol),
       member([_,onion,Y,Z,french_vanilla], Sol),
          * dif(Y,butter),
          dif(Z,small),
       member([joe,Ja,Jb,Jc,Jd], Sol),
          * dif(Ja,wheat), * dif(Jb,egg_bacon),
          dif(Jc,large),
          Jd=amaretto,
       * member([La,Lb,Lc,large,Ld], Sol),
          * dif(La,joe), * dif(Lb,wheat), * dif(Lc,egg_bacon), * dif(Ld,amaretto),
       member([Aa,Ab,Ac,Ad,amaretto], Sol),
          dif(Aa,joe),
          * dif(Ab,wheat), * dif(Ac,egg_bacon), * dif(Ad,large),
       member([Wa,wheat,Wb,Wc,Wd], Sol),
          * dif(Wa, joe), * dif(Wb, egg_bacon),
          dif(Wc, large),
          dif(Wd, amaretto),
       member([Ea,Eb,egg_bacon,Ec,Ed], Sol),
          * dif(Ea, joe),
          dif(Eb, wheat),
          * dif(Ec, large),
          dif(Ed, amaretto),
       member([rick,R,_,_,columbian], Sol),
          * dif(R,blueberry),
       * member([A,cheddar,_,_,amaretto], Sol),
          * dif(A,walt),
       member([_,B,cream_cheese,large,_], Sol),
          * dif(B,blueberry),
       * member([C,sesame,butter,_,_], Sol),
          * dif(C, carlos),
       * member([_,_,_,other,_], Sol),
       * member([_,_,_,_,other], Sol).
    

    Still, you might be unhappy: Why is there so much code left? The reason for this is that you forgot to state some general observations in the beginning. In particular that they wanted all a different topping. With that information the program fragment shrinks down to just the lines highlighted. However, one has to start with the following goals using library(lambda).

    bagels(Sol):-
       Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
        maplist(Sol+\P^member([P|_], Sol),
              [brad,walt,joe,rick,carlos]),
        maplist(Sol+\D^member([_,_,_,_,D], Sol),
              [amaretto,french_vanilla,hazelnut,columbian,other]),
        ...
    

提交回复
热议问题