1) 最接近/最简单的方法是检查您选择的课程是否严格按照顺序比前一个课程大。
例如,通过添加一个额外的谓词,该谓词还包括组合中的上一门课程。
%%makeListPrev(PreviousTakenCourse, ResultCombinationOfCourses, NrOfCoursesToAdd)
makeListPrev(_,[], 0).
makeListPrev(course(Tprev,Ttime,Troom),[course(Teacher,Time,Room)|Rest], N) :-
N > 0,
teacher(Teacher),
classtime(Time),
classroom(Room),
course(Tprev,Ttime,Troom) @< course(Teacher,Time,Room), %% enforce unique combinations
is(M,minus(N,1)),
makeListPrev(course(Teacher,Time,Room),Rest,M).
通过这种方式,您可以通过始终采用字典顺序最小的方式来消除同一组合的所有重复排列。
例如,如果您有 4 门课程:
(a,b,c,d)
(a,b,d,c) % d can't be before c
(a,c,b,d) % c can't be before b
...
2) 另一种很容易解决此问题的方法是首先创建所有可能课程的列表。然后依次取出N的所有可能组合。
scheduler(L) :-
%% Find all possible courses
findall(course(Teacher,Time,Room),(teacher(Teacher),classtime(Time),classroom(Room)),Courses),
makeList(Courses,4,L),
different(L).
makeList([],0,[]) :- !. %% list completed
makeList([H|T],N,[H|Res]) :- %% list including H
M is N-1,
makeList(T,M,Res).
makeList([_|T], N, Res) :- makeList(T, N, Res). %% list without H