0

我正在通过旧考试并尝试检查我的工作。我附上了图片,但文字如下:

我们想扩展一个处理公司员工的程序。

对于每个部门,有一个事实department(Id, Manager, Groups)定义了部门Id的名称, ,其经理的姓名,Manager,以及构成该部门的工作组或其他部门的列表,Groups

对于每个工作组,都有一个事实 ,group(Id, Leader, Participant)定义Id了该组的唯一名称 , ,该组Leader的经理或领导者,以及一个Participant包含该组成员名称的列表 , 。

个人可以是一个或多个工作组的成员,或者“只是”经理。同一个人可以是多个小组/部门的领导或经理。领导者被认为是他们领导的工作组的一部分,而等级较高的经理不会自动成为任何工作组的成员。

例如,程序的数据库可能如下所示:

   department( management, knut_billkvist, [administration, factory] ).
   department( administration, lisa_larsson, [economy, staff] ).
   department( economy, ahmed_hassan, [billing, budget, project_office] ).
   department( staff, jenny_bengtsson, [recruitment, health, salaries] ).
   department( factory, rune_viking, [assembly, testing] ).

   group( billing, lotta_persson, [anna_nilsson,arne_johnsson] ).
   group( budget, lena_levin, [kurt_allgen, mona_malm] ).
   group( project_office, ahmed_hassan, [kurt_allgen, anna_nilsson] ).
   group( recruitment, lill_nilsson, [annie_cedrell, jonna_spjuth] ).
   group( salaries, bengt_karlsson, [gullbritt_svensson, siri_hallin] ).
   group( assembly, rune_runesson, [johnny_kraft] ).
   group( testing, allan_snygg, [edvin_karlsson, mohammed_tayed] ).

定义这些谓词!

  • coworker(Name, Department, Group)如果一个人 ,Name属于某个部门 ,Department和某个工作组 ,则为真的谓词Group, (none如果该人不属于任何工作组,则使用)。

  • leader(Name, GroupId)如果一个人Name是某个工作组的领导者,则谓词为真GroupId

  • manager(Name, Id)如果某人是某个部门的经理,Id或者名称为 的工作组的领导者,则谓词为真Id

请考虑个人通常可以直接成为工作组的成员,也可以隐含地成为多个级别的部门成员!

我的代码如下:

coworker(Name,Department,Group):-
    begot(Name,department(ID,Name,group),Group).

leader(Name,GroupID):-
    bagof(Name,Group(ID,Name,Participants),GroupId).

manager(Name,ID):-
    setof (Name,Department(ID,Name,Groups),ID)setof (Name,Group(Id,names,participants),GroupId).

我已按照以下建议修改了我的代码:

cowoker(Name,Department,Group) :-
   group(Group,Name,Manager).

leader(Name,GroupID) :-
   Group(_,Name,GroupID).

manager(Name,ID) :-
   department(_,Name,ID),
   Group(_,Name,GroupId).
4

1 回答 1

1

您的第一个问题是您对 Prolog 中的变量或标识符可以使用什么感到困惑。每个变量都必须以大写字母开头,并且每个标识符都不能以一个开头。所以代码Group(Id,Name,Participants)是错误的,因为Group以大写字母开头,并且department(Id,Name,group)是错误的,因为group应该大写。最重要的是,这条线很滑稽:setof (Name,Department(ID,Name,Groups),ID)setof ...

我认为您实际上不需要setof/3或回答这些问题中的任何bagof/3一个。我会给你一个,因为我可以说这是家庭作业,但它应该足以让你了解如何解决这个问题。findall/3

leader(Name, GroupId) :- 
    group(GroupId, Name, _).

你在这里用关系编程。之间的关系leader(Name, Group)是有一些组Group并且Name是领导者。这是我在定义中指定的leader/2。请注意,我没有对组中的人员列表做任何事情。我不需要它们来完成这项任务。这只是重新排列您已有的数据!它不必征税。

其他两个问题几乎一样简单。现在试试,不要让自己被二阶谓词所迷惑!我认为你不需要它们。

编辑:因为这不是作业,让我们看看我将如何做另外两个。

coworker/3有点名不副实;它没有告诉你任何关于一对工人的信息,只是每个人所在的组和部门。所以实现将使用member/2枚举人员,如下所示:

coworker(Name, Department, Group) :-
    department(Department, _, Groups),
    member(Group, Groups),
    group(Group, _, People),
    member(Name, People).

这实际上只是故事的 1/3。这个案例涵盖了最底层的人,但它不会涉及管理组或管理部门的人,因此存在于整个组层次结构之上,因此我们需要另外两个规则:

 coworker(Name, Department, none) :-
      department(Department, Name, _).
 coworker(Name, Department, Group) :-
      department(Department, _, Groups),
      member(Group, Groups),
      group(Group, Name, _).

感觉我们可以使用它来实现这一点,manager/2manager/2会丢弃有关他们是管理部门还是管理组的信息,因此如果不重做一些工作,我们就无法使用它来恢复这些信息。所以最好单独定义它,尽管它看起来像coworker/3重复的第二个和第三个子句:

 manager(Name, Department) :-
      department(Department, Name, _).
 manager(Name, Group) :-
      department(Department, _, Groups),
      member(Group, Groups),
      group(Group, Name, _).

你有它。

于 2016-01-14T18:23:50.347 回答