:- use_module(library(bounds)). enumerate_teams([], _, []). enumerate_teams([R|Rs], N0, [N0-Team|Rest]) :- R =.. [_|Team], N1 is N0 + 1, enumerate_teams(Rs, N1, Rest). all_args([], _, []). all_args([T|Ts], Arg, [A|As]) :- arg(Arg, T, A), all_args(Ts, Arg, As). % constraints0/3: generate match structure constraints0([], _, _). constraints0([M|Ms], NumTeams, MaxGoals) :- M = ((T1-T2) = (G1-G2)), [T1,T2] in 1..NumTeams, [G1,G2] in 0..MaxGoals, T1 #< T2, G1 #\= G2, constraints0(Ms, NumTeams, MaxGoals). % constraints1/2: make everything sum up correctly constraints1([], _). constraints1([T|Ts], Matches) :- T = TeamID-[_Team,Played,Dealt,Taken], matches_count_team(Matches, TeamID, 0, Played), matches_count_dealt(Matches, TeamID, 0, Dealt), matches_count_taken(Matches, TeamID, 0, Taken), constraints1(Ts, Matches). matches_count_team([], _, N, N). matches_count_team([((T1-T2)=_)|Ms], TeamID, N0, N) :- T1 #= TeamID #=> N1, T2 #= TeamID #=> N2, N3 #= N0 + N1 + N2, matches_count_team(Ms, TeamID, N3, N). matches_count_dealt([], _, N, N). matches_count_dealt([(T1-T2)=(G1-G2)|Ms], TeamID, N0, N) :- T1 #= TeamID #=> N1 #= N0 + G1, T1 #\= TeamID #=> N1 #= N0, T2 #= TeamID #=> N2 #= N1 + G2, T2 #\= TeamID #=> N2 #= N1, matches_count_dealt(Ms, TeamID, N2, N). matches_count_taken([], _, N, N). matches_count_taken([(T1-T2)=(G1-G2)|Ms], TeamID, N0, N) :- T1 #= TeamID #=> N1 #= N0 + G2, T1 #\= TeamID #=> N1 #= N0, T2 #= TeamID #=> N2 #= N1 + G1, T2 #\= TeamID #=> N2 #= N1, matches_count_taken(Ms, TeamID, N2, N). matches_variables([]) --> []. matches_variables([(T1-T2)=(G1-G2)|Ms]) --> [T1,T2,G1,G2], matches_variables(Ms). subst_ids([], _, []). subst_ids([(T1-T2)=(G1-G2)|Ms], Teams, [(T11-T22)=(G1-G2)|Rest]) :- nth1(T1, Teams, _-[T11|_]), nth1(T2, Teams, _-[T22|_]), subst_ids(Ms, Teams, Rest). soccer(Results, Matches) :- all_args(Results, 2, Games), sumlist(Games, NumGames1), enumerate_teams(Results, 1, Teams), NumGames is NumGames1 // 2, %format("games played: ~w\n", [NumGames]), all_args(Results, 3, GoalsDealt), all_args(Results, 4, GoalsTaken), append(GoalsDealt, GoalsTaken, AllGoals0), sort(AllGoals0, AllGoals), last(AllGoals, MaxGoals), %format("max goals: ~w\n", [MaxGoals]), length(Matches0, NumGames), length(Results, NumTeams), constraints0(Matches0, NumTeams, MaxGoals), constraints1(Teams, Matches0), matches_variables(Matches0, Variables, []), once(label(Variables)), subst_ids(Matches0, Teams, Matches).