%implementation of the second step of ACC '98 get_pattern_sets(PatternSet):- %Patterns is the set of all 38 legal patterns findall(P, get_patterns(P), Patterns), %Home, Away, and Bye are the corresponding matrices from the Patterns. get_home(Patterns, Home), get_away(Patterns, Away), get_bye(Patterns, Bye), %X represents the indexes of the selected patterns in a legal pattern set. X = [_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_], X in [0,1], sum(X) #= 9, %make sure every day there are 4 teams that play home. transpose(Home, HT), day_constraints(HT, X, 4), %make sure every day there are 4 teams that play away. transpose(Away, AT), day_constraints(AT, X, 4), %make sure every day there is 1 team that has a bye. transpose(Bye, BT), day_constraints(BT, X, 1), %make sure that patterns that are not compatible are not put in a pattern set. numlist(1,38,PatternIndex), foreach(PatternIndex, foreach(PatternIndex, compatible_constraints(Patterns, X))), labeling(X), make_pattern(Home, X, HomePattern), make_pattern(Away, X, AwayPattern), make_pattern(Bye, X, ByePattern), PatternSet = [HomePattern, AwayPattern, ByePattern]. %writeln(PatternSet). %selects from Matrice, the rows for which the corresponding elements of colum X are 1. make_pattern(Matrice, X, Pattern):-make_pattern(Matrice, X, Pattern, []). make_pattern([], _, Pattern, Pattern). make_pattern([Row|Matrice], [X|Xs], Pattern, Acc):- (X == 1, !, RowElem = [Row], append(Acc, RowElem, Acc1); Acc1 = Acc), make_pattern(Matrice, Xs, Pattern, Acc1). %from a Patterns structure selects the Home pattern (the first column) get_home(Patterns, Home):- get_home(Patterns, Home, []). get_home([], Home, Home). get_home([P|Patterns], Home, Acc):- P = [H, _A, _B], H_List = [H], append(Acc, H_List, Acc1), get_home(Patterns, Home, Acc1). %from a Patterns structure selects the Away pattern (the second column) get_away(Patterns, Away):- get_away(Patterns, Away, []). get_away([], Away, Away). get_away([P|Patterns], Away, Acc):- P = [_H, A, _B], A_List = [A], append(Acc, A_List, Acc1), get_away(Patterns, Away, Acc1). %from a Patterns structure selects the Bye pattern (the third column) get_bye(Patterns, Bye):- get_bye(Patterns, Bye, []). get_bye([], Bye, Bye). get_bye([P|Patterns], Bye, Acc):- P = [_H, _A, B], B_List = [B], append(Acc, B_List, Acc1), get_bye(Patterns, Bye, Acc1). %for each day, the selected rows (selector X) sum to Sum day_constraints([], _, _). day_constraints([Row|Matrix], X, Sum):- scalar_product(X, Row, #=, Sum), day_constraints(Matrix, X, Sum). %Result is Matrice with added column List add_column(Matrice, List, Result):- add_column(Matrice, List, Result, []). add_column([], [], Result, Result). add_column([Row|Matrice], [X|List], Result, Acc):- ElemList = [X], append( Row, ElemList, Row1), RowList = [Row1], append(Acc, RowList, Acc1), add_column(Matrice, List, Result, Acc1). %If pattern A and pattern B are not compatible (there is no possible meeting date for corresponding teams), %a constraint is added to not allow Pattern A and B to be chosen simultaneously. compatible_constraints(Patterns, X, A, B):- (A < B, %writeln(A), %writeln(B), nth(A, Patterns, PatternA), nth(B, Patterns, PatternB), PatternA = [HomeA, AwayA, _], PatternB = [HomeB, AwayB, _], not_compatible(HomeA, AwayB), not_compatible(HomeB, AwayA) -> nth(A, X, Xa), nth(B, X, Xb), Xa + Xb #< 2; true ). %two patterns are not compatible if for every day, two teams following this patterns cannot meet. not_compatible([], []). not_compatible([A|As], [B|Bs]):- ((A = 0) ; (B =0)), not_compatible(As, Bs).