四种职业序言谜题

Four Professions prolog 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")

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

   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( 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),  

此时所有的工作和人名都已分配。现在您可以写下您遗漏的规则:

Baker has the same profession as the carpenter's son.

"Baker" 这是一个名称(否则我们会与下一条规则相矛盾)。而且他一定是个父亲(为什么?),所以他的工作是BakerFatherJob。木匠的名字(同样,必须是父亲 -- 为什么?)是 而不是 "Carpenter" -- 这是规则所禁止的。我们给他取名 OlderCarpenterName。他的儿子同名:

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

而且我们知道这两个工作是一样的:

      JobX = ... ,

The farmer's son is a baker.

现在你也可以这样做了。


教训:给你的东西命名;使用描述性名称来减轻认知负担。