% requirement definition for Meeting Scheduler System (MSS) meeting_date_OK(Date,Location) :- exclusion_OK(Date), preference_OK(Date), location_OK(Date,Location), equipment_OK(Location), print('Date=',Date,' Location=',Location),!. meeting_date_OK(Date,_) :- print('Date=',Date,' not available'). nonpreference_meeting_date_OK(Date,Location) :- exclusion_OK(Date), location_OK(Date,Location), equipment_OK(Location), print('Date=',Date,' Location=',Location),!. nonpreference_meeting_date_OK(Date,_) :- print('Date=',Date,' not available'). exclusion_OK(Date) :- exclusion_list(EL), nonmember(Date,EL). preference_OK(Date) :- preference_list(PL), memberchk(Date,PL). location_OK(Date,Location) :- location_preference_list(LP), memberchk(Location,LP), location_availability(Location,AV), memberchk(Date,AV). equipment_OK(Location) :- equipment_list(EQ), equipment_at_location(Location, EAL), subset(EQ,EAL). exclusion_list(EL) :- findall(X,attendee_exclusion(Y,X),L), list_union(L,EL). preference_list(PL) :- findall(X,attendee_preference(Y,X),L), list_intersection(L,PL). location_preference_list(LP) :- findall(X,attendee_location_preference(Y,X),L), list_intersection(L,LP). equipment_list(QL):- findall(X,attendee_equipment(Y,X),L), list_union(L,QL). % set operations member(Element,[Element|_]). member(Element,[_|Rest]) :- member(Element,Rest). memberchk(Element, [Element|_]) :- !. memberchk(Element, [_|Rest]) :- memberchk(Element, Rest). nonmember(_,[]). nonmember(X,[H|T]) :- X /= H,nonmember(X,T). subset([], _). subset([Element|Residue], Set) :- memberchk(Element, Set), !, subset(Residue, Set). subtract([], _, []). subtract([Element|Residue], Set, Difference) :- memberchk(Element, Set), !, subtract(Residue, Set, Difference). subtract([Element|Residue], Set, [Element|Difference]) :- subtract(Residue, Set, Difference). union([], Set2, Set2). union([Element|Residue], Set, Union) :- memberchk(Element, Set), !, union(Residue, Set, Union). union([Element|Residue], Set, [Element|Union]) :- union(Residue, Set, Union). list_union([First|Rest],Out) :- union1(First,[],Rest,Out). union1(First,Second,[],Out) :- union(First,Second,Out). union1(First,Second,[Next|Rest1],Union) :- union(First,Second,Un), union1(Next,Un,Rest1,Union). intersect([],_,[]). intersect([Element|Residue], Set, Result) :- member(Element, Set),!, Result = [Element|Intersection],intersect(Residue,Set,Intersection). intersect([_|Rest],Set,Intersection) :- intersect(Rest,Set,Intersection). list_intersection([First|Rest],Out) :- intersection1(First,First,Rest,Out). intersection1(First,Second,[],Out) :- intersect(First,Second,Out). intersection1(First,Second,[Next|Rest1],Intersection) :- intersect(First,Second,Inter), intersection1(Next,Inter,Rest1,Intersection). % tests range_check(Start,End,Location) :- Start <= End, meeting_date_OK(Start,Location), N is Start + 1, range_check(N,End,Location). nonpreference_range_check(Start,End,Location) :- Start <= End, nonpreference_meeting_date_OK(Start,Location), N is Start + 1, nonpreference_range_check(N,End,Location). test_lists(EL,PL,LP,QL) :- exclusion_list(EL), preference_list(PL), location_preference_list(LP), equipment_list(QL). % test database meeting_initiator(secretary). attendee_exclusion(jim,[1,5,9]). attendee_exclusion(joe,[1,6,10]). attendee_preference(jim,[3,4]). attendee_preference(joe,[2,3,4]). attendee_equipment(jim,[projector]). attendee_equipment(joe,[video]). attendee_location_preference(jim,[london,paris,berlin]). attendee_location_preference(joe,[paris]). location_availability(paris,[1,2,3,4]). equipment_at_location(paris,[projector,video,telephone]).