:- use_module(library(lists),[select/3]). palmtree(LongestVisit) :- setof(Tree,palm(Tree),Trees), setof(Duration-Visit,visit(Trees,Duration,Visit),AllVisits), AllVisits = [_-LongestVisit|_]. visit(Trees,Duration,Visit) :- permute(Trees,Visit), time_from_well(Visit,0,Duration). time_from_well([],Duration,FinalDuration) :- FinalDuration is -Duration. time_from_well([T|Trees],Duration,FinalDuration) :- palm2well(T,Time), Duration1 is Duration + Time, bucket(FullBucket), palm_needs(T,Cap), NewBucket is FullBucket - Cap, NewBucket > -1, time_from_tree(Trees,T,NewBucket,Duration1,FinalDuration). time_from_tree([],Tree,_,DurationIn,DurationOut) :- palm2well(Tree,Time), DurationOut is DurationIn + Time. time_from_tree([T|Trees],Tree,Bucket,Duration,FinalDuration) :- ( Bucket == 0 -> palm2well(Tree,Time), Duration1 is Duration + Time, time_from_well([T|Trees],Duration1,FinalDuration) ; palm_needs(T,Cap), NewBucket is Bucket - Cap, NewBucket >= 0, p2p(T,Tree,Time), Duration1 is Duration + Time, time_from_tree(Trees,T,NewBucket,Duration1,FinalDuration) ). palm(X) :- palm2palm(X,_,_) ; palm2palm(_,X,_) ; palm2well(X,_). p2p(X,Y,T) :- once((palm2palm(X,Y,T) ; palm2palm(Y,X,T))). permute([],[]). permute([X|R],O) :- permute(R,RP), select(X,O,RP).