事实量规则

时间:2019-02-27 15:05:51

标签: prolog

对于一个学校项目,我想在Prolog中创建计划制定者。我希望Prolog每天都做一个计划。每天需要一定数量的员工,而员工只能在某些日子工作。我希望Prolog制定一项计划,以计划每天合适的人数。为此,我编写了以下代码:

c.Spawner.cmd

但是,我无法让Prolog给出正确的结果,因为我查询以下Prolog可以为我提供所有选择,而与所需员工数量无关。

workingday_employeesneeded(monday, 2).
workingday_employeesneeded(tuesday, 1).
workingday_employeesneeded(wednesday, 2).

employee_availability(tom, monday).
employee_availability(thomas, monday).
employee_availability(timme, monday).
employee_availability(timo, monday).
employee_availability(tom, tuesday).

planning(Employee, Day) :-
    workingday_employeesneeded(Day, Amount),
    employee_availability(Employee, Day).

planning(Employee, Day) :-
    aggregate_all(count, planning(Employee, Day), Count),
    workingday_employeesneeded(Day, Amount),
    Count <= Amount.

你们能看到我在做什么吗?预先感谢!

编辑: 我认为在计划中每天列出员工列表可能会很方便。因此,我将代码编辑为以下内容(还修复了注释中指出的一些语法错误);

?- planning(X, Y).

X = tom,
Y = monday ;
X = thomas,
Y = monday ;
X = timme,
Y = monday ;
X = timo,
Y = monday ;
X = tom,
Y = tuesday ;
false.

以下问题仍然存在;如果可用的员工人数超过所需的人数,则该程序不会打印当天的计划,而只会选择前N名员工。

你们有解决这个问题的建议吗?

1 个答案:

答案 0 :(得分:1)

您的谓词失败了,因为首先使用findall/3,然后限制列表的长度。例如,对于monday,有4名员工可用,您找到的所有员工都与findall/3并存储到Employees中。然后,您检查列表的长度,列表将失败。要解决此问题,您需要找到所有可用的员工,然后找到所需长度的列表子集。因此您的代码将是:

subset([], []).
subset([E|Tail], [E|NTail]):-
  subset(Tail, NTail).
subset([_|Tail], NTail):-
  subset(Tail, NTail).

planning_on_day(Day, Employees) :-
    workingday_employeesneeded(Day, Amount),
    findall(E, employee_availability(E, Day), E),
    length(Employees,Amount),
    subset(E,Employees).

?- planning_on_day(monday,P).
P = [tom, thomas]
P = [tom, timme]
P = [tom, timo]
P = [thomas, timme]
P = [thomas, timo]
P = [timme, timo]
false

?- planning_on_day(tuesday,P).
P = [tom]
false

?- planning_on_day(wednesday,P).
false

然后,如果要查找本周的计划,则可以添加:

isDifferent(_, []).
isDifferent(X, [H | T]) :-
  X \= H,
  isDifferent(X, T).

allDifferent([]).
allDifferent([H | T]) :-
  isDifferent(H, T),
  allDifferent(T).

solve([],Plan,Plan):-
    flatten(Plan,P),
    allDifferent(P).
solve([Day|T],LT,Plan):-
    workingday_employeesneeded(Day, Amount),
    planning_on_day(Day,PlanD),
    length(A,Amount),
    subset(PlanD,A),
    append(LT,[PlanD],LT1),
    solve(T,LT1,Plan).

?- solve([monday,tuesday],[],L).
L = [[thomas, timme], [tom]]
L = [[thomas, timo], [tom]]
L = [[timme, timo], [tom]]