zurück
:- use_module(library(fd)).
anzahlTage(AnzTage) :-
findall(TagID, tag(TagID, _), TagesListe),
length(TagesListe, AnzTage).
anzahlZeiten(AnzZeiten) :-
findall(ZeitID, zeit(ZeitID, _), ZeitenListe),
length(ZeitenListe, AnzZeiten).
anzahlRaeume(AnzRaeume) :-
findall(RaumID, raum(RaumID, _, _, _), RaumListe),
length(RaumListe, AnzRaeume).
mkProbVar(VerID, ProblemVar) :-
ProblemVar=raumTagZeit(Raum, Tag, Zeit, VerID),
anzahlRaeume(AnzRaeume),
anzahlTage(AnzTage),
anzahlZeiten(AnzZeiten),
AnzRaeume0 is AnzRaeume-1,
AnzTage0 is AnzTage-1,
AnzZeiten0 is AnzZeiten-1,
Raum::0..AnzRaeume0,
Tag::0..AnzTage0,
Zeit::0..AnzZeiten0.
% mkProblemVars(Veranstaltungen, ProblemVars)
mkProblemVars([], []).
mkProblemVars([VerID|VRest], [ProblemVar|PRest]) :-
mkProbVar(VerID, ProblemVar),
mkProblemVars(VRest, PRest).
teilMenge([], Menge2).
teilMenge([Kopf1|Rest1], Menge2) :-
member(Kopf1, Menge2),
teilMenge(Rest1, Menge2).
zaehleTeilnehmer([], 0).
zaehleTeilnehmer([Teilnehmer|TRest], Anzahl) :-
teilnehmer(Teilnehmer, TeilnehmerAnz),
zaehleTeilnehmer(TRest, AnzRest),
Anzahl is TeilnehmerAnz + AnzRest.
holeGueltigeRaeume([], _, []).
holeGueltigeRaeume([RaumID|RRest], VerID, GueltigeRaeume) :-
veranstaltung(VerID, Teilnehmer, _),
raum(RaumID, Groesse, _, _),
zaehleTeilnehmer(Teilnehmer, AnzTeilnehmer),
Groesse < AnzTeilnehmer,
holeGueltigeRaeume(RRest, VerID, GueltigeRaeume).
holeGueltigeRaeume([RaumID|RRest], VerID, GueltigeRaeume) :-
veranstaltung(VerID, Teilnehmer, VerRessourcen),
raum(RaumID, Groesse, RaumRessourcen, _),
zaehleTeilnehmer(Teilnehmer, AnzTeilnehmer),
Groesse >= AnzTeilnehmer,
not(teilMenge(VerRessourcen, RaumRessourcen)),
holeGueltigeRaeume(RRest, VerID, GueltigeRaeume).
holeGueltigeRaeume([RaumID|RRest], VerID, [RaumID0|GueltigeRaeume]) :-
veranstaltung(VerID, Teilnehmer, VerRessourcen),
raum(RaumID, Groesse, RaumRessourcen, _),
zaehleTeilnehmer(Teilnehmer, AnzTeilnehmer),
Groesse >= AnzTeilnehmer,
teilMenge(VerRessourcen, RaumRessourcen),
RaumID0 is RaumID - 1,
holeGueltigeRaeume(RRest, VerID, GueltigeRaeume).
raumConstr([]).
raumConstr([raumTagZeit(Raum, _, _, VerID)|PRest]) :-
findall(RaumID, raum(RaumID, _, _, _), RaumListe),
holeGueltigeRaeume(RaumListe, VerID, GueltigeRaeume),
Raum::GueltigeRaeume,
raumConstr(PRest).
mkDiffVars([], []).
mkDiffVars([raumTagZeit(Raum, Tag, Zeit, _)|Rest], [DiffVar|DVRest]) :-
anzahlTage(AnzTage),
anzahlZeiten(AnzZeiten),
AnzTageUndZeiten is AnzTage * AnzZeiten,
(AnzTageUndZeiten * Raum + AnzZeiten * Tag + Zeit) #= DiffVar,
mkDiffVars(Rest, DVRest).
raumClashConstr(ProblemVars) :-
mkDiffVars(ProblemVars, DiffVars),
alldistinct(DiffVars).
schnittMenge([], Menge2) :- fail.
schnittMenge([Kopf|Rest], Menge2) :-
member(Kopf, Menge2).
schnittMenge([Kopf|Rest], Menge2) :-
schnittMenge(Rest, Menge2).
holeSchnittVar(_, [], []).
holeSchnittVar(Teilnehmer, [PVar|PRest], SchnittVar) :-
PVar=raumTagZeit(Raum, Tag, Zeit, VerID),
veranstaltung(VerID, VerTeilnehmer, _),
not(schnittMenge(Teilnehmer, VerTeilnehmer)),
holeSchnittVar(Teilnehmer, PRest, SchnittVar).
holeSchnittVar(Teilnehmer, [PVar|PRest], [PVar|SchnittVar]) :-
PVar=raumTagZeit(Raum, Tag, Zeit, VerID),
veranstaltung(VerID, VerTeilnehmer, _),
schnittMenge(Teilnehmer, VerTeilnehmer),
holeSchnittVar(Teilnehmer, PRest, SchnittVar).
verhindereTeilnehmerClash(_, []).
verhindereTeilnehmerClash(PVar, [SchnittVar|SVRest]) :-
PVar=raumTagZeit(_, Tagi, Zeiti, _),
SchnittVar=raumTagZeit(_, Tagj, Zeitj, _),
anzahlZeiten(AnzZeiten),
(AnzZeiten * Tagi + Zeiti) #\= (AnzZeiten * Tagj + Zeitj),
verhindereTeilnehmerClash(PVar, SVRest).
teilnehmerClashConstr([]).
teilnehmerClashConstr([PVar|PRest]) :-
PVar = raumTagZeit(_, _, _, VerID),
veranstaltung(VerID, Teilnehmer, _),
holeSchnittVar(Teilnehmer, PRest, SchnittVars),
verhindereTeilnehmerClash(PVar, SchnittVars),
teilnehmerClashConstr(PRest).
labeling([]).
labeling([PVar|PVRest]) :-
PVar = raumTagZeit(Raum, Tag, Zeit, VerID),
indomain(Raum),
indomain(Tag),
indomain(Zeit),
labeling(PVRest).
ausgabe2(ProblemVars, Ausgabe) :-
open(Ausgabe, write, Stream),
ausgabe22(ProblemVars, Stream),
close(Stream).
ausgabe22([],_).
ausgabe22([PVar|PVars], Stream) :-
PVar=raumTagZeit(Raum, Tag, Zeit, VerID),
Raum0 is Raum + 1,
Tag0 is Tag + 1,
Zeit0 is Zeit + 1,
print(Stream, 'loesung('),
print(Stream, VerID),
print(Stream, ', '),
print(Stream, Raum0),
print(Stream, ', '),
print(Stream, Tag0),
print(Stream, ', '),
print(Stream, Zeit0),
print(Stream, ').'),
nl(Stream),
ausgabe22(PVars, Stream).
stundenplan(Wissensbasis, Ausgabe) :-
print('Wissensbasis laden ...'),
compile(Wissensbasis),
print('Problemvariablen erstellen ...'),
nl,
findall(VerID, veranstaltung(VerID, _, _), Veranstaltungen),
mkProblemVars(Veranstaltungen, ProblemVars),
print('Raeume constrainen ...'),
nl,
raumConstr(ProblemVars),
print('Raum clash constrainen ...'),
nl,
raumClashConstr(ProblemVars),
print('Teilnehmer clash constrainen ...'),
nl,
teilnehmerClashConstr(ProblemVars),
print('labeling ...'),
nl,
labeling(ProblemVars),
print('Heureka !!!'),
ausgabe2(ProblemVars, Ausgabe).