使用 Prolog 定义部门和员工关系

Use Prolog to definition the departments and employees relationship

我正在努力完成旧考试并尝试检查我的作业。我附上了图片,但文字引用如下:

We want to extend a program for handling the staff of a company.

For each department there is a fact department(Id, Manager, Groups) that defines the name of the department, Id, the name of its manager, Manager, and a list of working groups or other departments which constitute the department, Groups.

For each working group there is a fact, group(Id, Leader, Participant), that defines Id, a unique name for the group, Leader, a manager or leader of the group, and a list, Participant, containing the names of the members of the group.

Individuals can be members of one or more working groups, or "just" managers. The same person can be leader or manager for multiple groups/departments. Leaders are considered to be part of the working group they lead, while managers higher up in the hierarchy are not automatically members in any working group.

E.g. the database of the program can look like this:

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

Define these predicates!

  • A predicate coworker(Name, Department, Group) which is true if a person, Name, belongs to a certain department, Department, and a certain working group, Group, (use none if the person doesn't belong to any working group).

  • A predicate leader(Name, GroupId) that is true if a person, Name, is a leader of a certain working group GroupId.

  • A predicate manager(Name, Id) that is true if a person is a manager for a certain department, Id or ledaer of a working group with the name Id.

Please consider that individuals can often be members of working groups directly, and they can also be implicit members of departments on several levels!

我的代码如下:

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

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

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

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

你正在用这里的关系编程。 leader(Name, Group)之间的关系是有某个组GroupName是leader。这是我在 leader/2 的定义中指定的内容。请注意,我没有对组中的人员列表进行任何操作。我不需要他们来完成这项任务。这只是重新排列您已有的数据!不必费力。

其他两个问题几乎一样简单。现在试试,不要让自己被 second-order 谓词搞糊涂了!我认为您不需要它们。

编辑: 因为这不是作业,让我们看看我会怎么做其他两个。

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

给你。