使用prolog解决查找在一个人手下工作的所有员工(包括间接员工)的问题。
如果我有员工条目,其中显示了员工的姓名以及该员工直接下属的所有人员,例如:使用prolog解决查找在一个人手下工作的所有员工(包括间接员工)的问题。,prolog,Prolog,如果我有员工条目,其中显示了员工的姓名以及该员工直接下属的所有人员,例如: employee(joe, []). employee(billy, []). employee(mike, [joe, billy]). employee(megan, [mike]). employee(tom, [joe, megan]). employee(bob, [billy]). employee(kate, [tom, bob, joe]). 我如何获得一份所有直接或间接在给
employee(joe, []).
employee(billy, []).
employee(mike, [joe, billy]).
employee(megan, [mike]).
employee(tom, [joe, megan]).
employee(bob, [billy]).
employee(kate, [tom, bob, joe]).
我如何获得一份所有直接或间接在给定员工手下工作的人员的名单
就像我进去一样:
bossof(megan, Output).
为了让所有人都在megan手下工作,它给了我一个输出:
Output = [mike, joe, billy].
到目前为止,我一直在尝试以这种方式递归进行:
bossof(X, A) :- getloweremployees(employee(X,Y), A).
getloweremployees([],_).
getloweremployees([H|T], A) :- A = append([H], getloweremployees(employee(H,Z),B), getloweremployees(T, C)).
但它只是给了我一个虚假的输出。让我困惑的主要部分是找出如何分解列表来尝试每一条数据
任何提示都将不胜感激。如果您要求您的事实与原始帖子中所述一致,那么您可以定义以下规则,以确定特定“老板”的员工: 如果
老板
是员工
的老板,那么哪个会成功:
| ?- boss_of(megan, Output).
Output = mike ? ;
Output = joe ? ;
Output = billy
yes
| ?-
然后使用findall/3
收集所有响应:
boss_of_all(Boss, Employees) :-
findall(E, boss_of(Boss, E), Employees).
作为测试查询:
| ?- boss_of_all(megan, Employees).
Employees = [mike,joe,billy]
yes
| ?-
就个人而言,我会将你的事实命名为employees/2
,而不是employees/2
,因为这些事实会产生某个老板的所有员工,而不仅仅是一名。在Prolog中建立逻辑一致的命名约定(就像在任何语言中一样)将有助于使程序更易于理解和设计。
然而,作为一种替代方法,我认为将员工事实表示为个人老板/员工关系更简单、更灵活、更规范
employee(mike, billy).
employee(mike, joe).
employee(megan, mike).
employee(tom, joe).
employee(tom, megan).
employee(bob, billy).
employee(kate, tom).
employee(kate, bob).
employee(kate, joe).
根据这些事实,您将有一个查询,例如:
| ?- employee(mike, X).
X = billy ? ;
X = joe
yes
因此,Prolog将回溯以获得每个解决方案(mike的员工)。您的事实(带有列表参数)可以通过一个简单的谓词从中派生:
employees(X, Employees) :- findall(E, employee(X, E), Employees).
这样,以下查询将以当前事实数据库的方式进行操作:
| ?- employees(tom, Employees).
Employees = [joe,megan]
yes
| ?-
考虑到所有这些,如果以下任一项为真,则可以说B
是E
的老板:
B
是E
X
是B
的员工,X
是E
这些可表示为:
boss_of(B, E) :- employee(B, E).
boss_of(B, E) :- employee(B, X), boss_of(X, E).
上面的第一个解决方案演示了/2的
boss_的行为。如果X
是Y
的boss,则谓词boss\u为(X,Y)
。如果你真的需要在列表中收集这些结果,你可以定义boss\u of_all/2
,正如第一个解决方案中所示。如果你要求你的事实与原始帖子中所述的一样,那么你可以定义以下规则来确定给定“boss”的员工:
如果老板
是员工
的老板,那么哪个会成功:
| ?- boss_of(megan, Output).
Output = mike ? ;
Output = joe ? ;
Output = billy
yes
| ?-
然后使用findall/3
收集所有响应:
boss_of_all(Boss, Employees) :-
findall(E, boss_of(Boss, E), Employees).
作为测试查询:
| ?- boss_of_all(megan, Employees).
Employees = [mike,joe,billy]
yes
| ?-
就个人而言,我会将你的事实命名为employees/2
,而不是employees/2
,因为这些事实会产生某个老板的所有员工,而不仅仅是一名。在Prolog中建立逻辑一致的命名约定(就像在任何语言中一样)将有助于使程序更易于理解和设计。
然而,作为一种替代方法,我认为将员工事实表示为个人老板/员工关系更简单、更灵活、更规范
employee(mike, billy).
employee(mike, joe).
employee(megan, mike).
employee(tom, joe).
employee(tom, megan).
employee(bob, billy).
employee(kate, tom).
employee(kate, bob).
employee(kate, joe).
根据这些事实,您将有一个查询,例如:
| ?- employee(mike, X).
X = billy ? ;
X = joe
yes
因此,Prolog将回溯以获得每个解决方案(mike的员工)。您的事实(带有列表参数)可以通过一个简单的谓词从中派生:
employees(X, Employees) :- findall(E, employee(X, E), Employees).
这样,以下查询将以当前事实数据库的方式进行操作:
| ?- employees(tom, Employees).
Employees = [joe,megan]
yes
| ?-
考虑到所有这些,如果以下任一项为真,则可以说B
是E
的老板:
B
是E
X
是B
的员工,X
是E
这些可表示为:
boss_of(B, E) :- employee(B, E).
boss_of(B, E) :- employee(B, X), boss_of(X, E).
上面的第一个解决方案演示了/2的boss_的行为。如果X
是Y
的boss,则谓词boss\u为(X,Y)
。如果您真的需要在列表中收集这些结果,您可以定义boss\u of_all/2
,正如上面在第一个解决方案中所示。递归方法可以是:
boss_employees(Boss, Employees) :-
employee(Boss, Direct),
findall(L, ( member(D, Direct), boss_employees(D, L) ), Lt),
flatten([Direct, Lt], Sub),
sort(Sub, Employees).
我们可以使用append/2代替flant/2,因为嵌套总是1级
...
append([Direct|Lt], Sub),
...
递归方法可以是:
boss_employees(Boss, Employees) :-
employee(Boss, Direct),
findall(L, ( member(D, Direct), boss_employees(D, L) ), Lt),
flatten([Direct, Lt], Sub),
sort(Sub, Employees).
我们可以使用append/2代替flant/2,因为嵌套总是1级
...
append([Direct|Lt], Sub),
...
Prolog谓词与函数不同,因此getloweremployees(employee(X,Y),A)。
完全不符合您的想法。Prolog谓词与函数不同,因此getloweremployees(Employees(X,Y),A)。
完全不符合您的想法。我喜欢替代编码!如果我只需要间接下属怎么办?老板直接参与事实的案例不应显示。@JoséAlgarra你可以将(B,E)的Boss\u:-employee(B,E)。
更改为(B,E)的Boss\u:-employee(B,X),employee(X,E)。
我喜欢这种替代编码!如果我只需要间接下属怎么办?老板直接参与事实的案例不应显示。@JoséAlgarra您可以将(B,E)的Boss_:-employee(B,E)。
更改为(B,E)的Boss_:-employee(B,X),employee(X,E)。
append/2
确实更可取,而且在很多其他情况下也是如此append/2
在这里确实更可取,在很多其他情况下也是如此!