【问题标题】:Four Professions prolog puzzle四个职业序幕谜题
【发布时间】:2015-05-17 08:13:04
【问题描述】:

我正在尝试解决序言中的一个难题,我只做了一部分,我不知道如何完成它。 这就是问题所在:

考虑四个姓氏为 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")

【问题讨论】:

  • 我解决了:BakerFatherJob = CarpenterSonJob, FarmerSonJob = "Baker", . 这很容易。
  • 不,那是错误的。变量CarpenterSonJob 持有一个名叫Carpenter 的人的儿子的工作,他不是木匠。 T 找到“木匠的儿子”,你需要找到一个工作是木匠的父亲(你已经这样做了,顺便说一句),抓住他的名字,找到一个同名的儿子,然后那是你的“木匠之子”!

标签: prolog zebra-puzzle


【解决方案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)],

修改您的代码以同时命名工作人员:

      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”是一个名字(否则我们会与下一条规则相矛盾)。而且他一定是个父亲(为什么?),所以他的工作是BakerFatherJob。木匠的名字(同样,必须是父亲——为什么?)不是“木匠”——这是规则所禁止的。我们将他命名为OlderCarpenterName。他的儿子同名:

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

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

      JobX = ... ,

农夫的儿子是个面包师。

现在你也可以这样做了。


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 2023-02-15
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 2019-05-01
    • 2018-05-01
    相关资源
    最近更新 更多