Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用prolog解决查找在一个人手下工作的所有员工(包括间接员工)的问题。_Prolog - Fatal编程技术网

使用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
在这里确实更可取,在很多其他情况下也是如此!