/* Organize a day in Picat. Problem formulation: Slides on (finite domain) Constraint Logic Programming, page 38f Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => N = 4, TasksStr = ["Work","Mail","Shop","Bank"], Begins = new_list(N), Begins :: 9..17, Ends = new_list(N), Ends :: 9..17, durations(Durations), before_tasks(BeforeTasks), L = findall([Begins,Ends], $organize(Durations,BeforeTasks,Begins, Ends)), foreach([BB,EE] in L) foreach(Task in 1..N) S = TasksStr[Task], B = BB[Task], E = EE[Task], printf("%w: %2d .. %2d\n",S,B,E) end, nl end, nl. organize(Durations,BeforeTasks,Begins,Ends) => N = 4, % number of tasks foreach(I in 1..N) Ends[I] #= Begins[I] + Durations[I] end, % foreach(I in 1..N, J in I+1..N) % no_overlap(Begins,Durations,I,J) % end, % no_overlaps is better written during the built-in constraint % serialized: serialized(Begins,Durations), % and serialized is in turn a special case of cumulative: % Ones = [1 : I in 1..N], % cumulative(Begins,Durations,Ones, 1), % handle precendeces foreach([A,B] in BeforeTasks) Ends[A] #=< Begins[B] end, % Work >= 11 a clock Begins[1] #>= 11, Vars = Begins ++ Ends, solve(Vars). no_overlap(Begins,Durations,I,J) => (Begins[I] + Durations[I] #=< Begins[J]) #\/ (Begins[J] + Durations[J] #=< Begins[I]). % duration of the four tasks durations(Durations) => Durations = [4,1,2,1]. % precedences % [A,B] : task A must be completed before task B before_tasks(Before) => Before = [[4,3],[2,1]].