使用Prolog来定义部门和员工之间的关系

时间:2016-01-14 17:49:17

标签: prolog prolog-dif

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

  

我们希望扩展一个处理公司员工的计划。

     

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

     

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

     

个人可以是一个或多个工作组的成员,或者只是"只是"经理。同一个人可以是多个团体/部门的领导者或经理。领导者被认为是他们领导的工作组的一部分,而层级中较高层的经理并不是任何工作组的自动成员。

     

E.g。程序的数据库可能如下所示:

   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).

1 个答案:

答案 0 :(得分:1)

您的第一个问题是您对Prolog中可用于变量或标识符的内容有些疑惑。每个变量必须以大写字母开头,每个标识符不得以开头。因此代码Group(Id,Name,Participants)是错误的,因为Group以大写字母开头,department(Id,Name,group)错误,因为group应该大写。最重要的是,这一行只是zany:setof (Name,Department(ID,Name,Groups),ID)setof ...

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

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

你在这里用关系编程。 leader(Name, Group)之间的关系是有一些组GroupName是领导者。这就是我在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/2实现此功能但manager/2会丢弃有关他们是管理部门还是组的信息,因此我们无法使用它来恢复该信息而无需重做一些工作。因此,单独定义它可能更好,尽管它看起来像coworker/3重复的第二和第三个条款:

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

你有它。