Prolog 事实数量规则

Prolog 事实数量规则,prolog,Prolog,对于一个学校项目,我想用Prolog做一个计划制定者。我想让Prolog为每天做一个计划。每天都需要一定数量的员工,员工只能在特定的日期工作。我想让Prolog制定一个计划,每天安排适当数量的人。为此,我编写了以下代码: workingday_employeesneeded(monday, 2). workingday_employeesneeded(tuesday, 1). workingday_employeesneeded(wednesday, 2). employee_availabi

对于一个学校项目,我想用Prolog做一个计划制定者。我想让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.
你们能看出我做错了什么吗?提前谢谢

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

以下问题仍然存在;如果有超过需要的员工,该计划不会打印当天的计划,而只挑选前N名员工


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

简单地说,谓词失败是因为首先使用
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]]

两条独立的规划规则?另外,
你希望
有哪些答案?-在计划日(星期一,Xs)进行规划。
?@重复
Xs=[tom,thomas]还有其他答案吗?排列呢?
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]]