四个职业prolog拼图

时间:2015-05-17 08:13:04

标签: prolog zebra-puzzle

我正在尝试在prolog中解决一个难题而我只做了一部分,我无法弄清楚如何完成它。 这就是问题所在:

考虑四名姓Baker,Carpenter,Miller和Farmer的男子。假设这个群体代表的四个职业包括面包师,木匠,磨坊主和农民。进一步假设每个人的职业都与他们的姓氏不符。

这四个人中的每一个都有一个儿子。这四个儿子有面包师,木匠,磨坊主和农民的职业。再次假设每个人的职业都与他们的姓氏不符。

假设我们也知道以下事实:       没有儿子和他父亲有同样的职业。       贝克与木匠的儿子有着同样的职业。       农夫的儿子是面包师。

我无法弄清楚如何实施的部分是:

  Baker has the same profession as the carpenter's son.
  The farmer's son is a baker.

这是我到目前为止所遇到的部分问题的代码:

 DOMAINS
   father      = father(lastname,profession)
   son         = son(lastname2,profession2)
   list2       = son*
   list        = father*
   lastname    = string
   profession  = string
   lastname2    = string
   profession2    = string

PREDICATES
   nondeterm member(father, list)
   nondeterm member(son,list2)
    solution 
CLAUSES

   member(Item, [Item|_]).   
      member(Item,[_|Tail]) :-  member(Item,Tail).

   solution:- 

      List = [father("Baker" , BakerFatherJob),
              father("Carpenter" , CarpenterFatherJob),
              father("Miller" , MillerFatherJob),
              father("Farmer",FarmerFatherJob)],

      List2 = [son("Baker" , BakerSonJob),
              son("Carpenter" , CarpenterSonJob),
              son("Miller" , MillerSonJob),
              son("Farmer",FarmerSonJob)],


      member(father(_, "Baker"), List),
      member(father(_, "Carpenter"), List),
      member(father(_, "Miller"), List),
      member(father(_, "Farmer"), List),   

      member(son(_, "Baker"), List2),
      member(son(_, "Carpenter"), List2),
      member(son(_, "Miller"), List2),
      member(son(_, "Farmer"), List2),     




      BakerFatherJob<>BakerSonJob,
      CarpenterFatherJob<>CarpenterSonJob,
      MillerFatherJob<>MillerSonJob,
      FarmerFatherJob<>FarmerSonJob,

      BakerFatherJob <> "Baker",
      CarpenterFatherJob <> "Carpenter",
      MillerFatherJob <> "Miller",
      FarmerFatherJob <> "Farmer",

      BakerSonJob <> "Baker",
      CarpenterSonJob <> "Carpenter",
      MillerSonJob <> "Miller",
      FarmerSonJob <> "Farmer",




      write("Father Baker has job ", BakerFatherJob),nl,
      write("Father Carpenter has job ", CarpenterFatherJob), nl,
      write("Father Miller has job ", MillerFatherJob),nl,
      write("Father Farmer has job ", FarmerFatherJob),nl,
      write("                              "), nl,

      write("Son Baker has job ", BakerSonJob),nl,
      write("Son Carpenter has job ", CarpenterSonJob), nl,
      write("Son Miller has job ", MillerSonJob),nl,
      write("Son Farmer has job ", FarmerSonJob),nl,
      write("                              "), nl,


      fail.
   solution:- 
      write(" ALL SOLUTIONS HAVE BEEN FOUND")

1 个答案:

答案 0 :(得分:1)

现在你正在为人们的工作命名,

   solution:- 

      List = [father("Baker" ,     BakerFatherJob),
              father("Carpenter" , CarpenterFatherJob),
              father("Miller" ,    MillerFatherJob),
              father("Farmer",     FarmerFatherJob)],

      List2 = [son("Baker" ,     BakerSonJob),
               son("Carpenter" , CarpenterSonJob),
               son("Miller" ,    MillerSonJob),
               son("Farmer",     FarmerSonJob)],

修改您的代码以命名工作&#39;人:

      member( father( OlderBakerName,     "Baker"),     List),
      member( father( OlderCarpenterName, "Carpenter"), List),
      member( father( OlderMillerName,    "Miller"),    List),
      member( father( OlderFarmerName,    "Farmer"),    List),   

      member( son( YongerBakerName,     "Baker"),     List2),
      member( son( YongerCarpenterName, "Carpenter"), List2),
      member( son( YongerMillerName,    "Miller"),    List2),
      member( son( YongerFarmerName,    "Farmer"),    List2),  

此时分配了所有工作和人员的姓名。现在你可以写下你缺少的规则:

  贝克与木匠的儿子有着同样的职业。

&#34;贝克&#34;这是一个名字(或者我们与下一个规则相矛盾)。他必须是一个父亲(为什么?),所以他的工作是BakerFatherJob。木匠的名字(再次,必须是父亲 - 为什么?)是不是&#34; Carpenter&#34; - 规则禁止的。我们给他命名为OlderCarpenterName。他的儿子名字相同:

      member( son( ... , JobX ), List.... ),

我们知道这两项工作是一样的:

      JobX = ... ,
  

农夫的儿子是面包师。

现在你也可以这样做。

课程:为你的东西命名;使用描述性名称来缓解认知负担。