1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8%
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License.
13%
14% The Original Code is  The ECLiPSe Constraint Logic Programming System.
15% The Initial Developer of the Original Code is  Cisco Systems, Inc.
16% Portions created by the Initial Developer are
17% Copyright (C) 1995-2006 Cisco Systems, Inc.  All Rights Reserved.
18%
19% Contributor(s):
20%
21% END LICENSE BLOCK
22% ----------------------------------------------------------------------
23% System:	ECLiPSe Constraint Logic Programming System
24% Version:	$Id: scheduler.pl,v 1.1 2006/09/23 01:54:05 snovello Exp $
25% ----------------------------------------------------------------------
26
27% $Id: scheduler.pl,v 1.1 2006/09/23 01:54:05 snovello Exp $
28
29:- module_interface(scheduler).
30
31:- lib(fd).
32:- lib(structures).
33:- lib(forall).
34
35:- export
36    schedule/3,
37    interval_activity/5,
38    discrete_resource/3,
39    alt_res_set/3,
40    starts_after_end/2,
41    set_capacity_max/4,
42    close_resource/1,
43    isc/2,
44    requires/2, requires/3,
45    set_not_possible/2,
46    consumes/2, consumes/3.
47
48:- op(750, xfx, isc).
49:- op(700, xfx, starts_after_end).
50:- op(700, xfx, set_not_possible).
51:- op(700, xfx, consumes).
52:- op(700, xfx, requires).
53:- op(700, xfx, --->).
54
55
56:- export format_scheduler/2.
57:- define_macro(activity/4, format_scheduler/2, [write]).
58:- define_macro(schedule/5, format_scheduler/2, [write]).
59
60:- export tr_isc/2.
61:- define_macro(isc/2, tr_isc/2, [goal]).
62
63:- begin_module(scheduler).
64
65:- import setarg/3 from sepia_kernel.
66
67:- define_struct(activity(handle, start, end, duration)).
68:- define_struct(schedule(handle, timemin, timemax, activities, resources)).
69
70format_scheduler(activity(_H, Start, End, Duration), Start-Duration--->End).
71format_scheduler(schedule with [timemin:Min, timemax:Max], schedule(Min..Max)).
72
73:- external(c_schedule/3, c_schedule),
74   external(c_interval_activity/5, c_interval_activity),
75   external(c_discrete_resource/3, c_discrete_resource),
76   external(c_schedule_add/3, c_schedule_add),
77   external(c_alt_res_set/3, c_alt_res_set),
78   external(c_schedule_set/2, c_schedule_set).
79
80% Type checking
81code_type(ilc('DiscreteResource'), resource(cap(discrete(_)))).
82code_type(ilc('CapResource'), resource(cap(_))).
83code_type(ilc('Resource'), resource(_)).
84code_type(ilc('AltResSet'), alt_res_set).
85code_type(ilc('AltResConstraint'), constraint(alr_res)).
86code_type(ilc('ResourceConstraint'), constraint(resource)).
87
88:- define_macro(ilc/1, code_type/2, []).
89
90
91
92% Initialization of a schedule ---------------------------------------------
93schedule(Min, Max, schedule(S, Min, Max, [], [])) :-
94  integer(Min), integer(Max), !,
95  c_schedule(Min, Max, S).
96schedule(Min, Max, S) :-
97  error(4, schedule(Min, Max, S)).
98
99% Backtrackable statements---------------------------------------------------
100schedule_add(C, Constraint) :-
101  getval(ilog_handle, H),
102  c_schedule_add(H, C, Constraint).
103
104schedule_set(C) :-
105  getval(ilog_handle, H),
106  c_schedule_set(H, C).
107
108% interval_activity(+S, +Start, +End, +Duration, -A)
109interval_activity(Schedule, Start, End, Duration, Activity) :-
110  Schedule = schedule(S, Min, Max, Activities, _Resources),
111  [Start, End, Duration] :: Min..Max,
112  dvar_domain(Start, StartI),
113  dvar_domain(End, EndI),
114  dvar_domain(Duration, DurationI),
115  c_interval_activity(S, StartI, EndI, DurationI, A),
116  Activity = activity(A, Start, End, Duration),
117  setarg(activities of schedule, Schedule, [Activity | Activities]).
118
119
120discrete_resource(Schedule, Capacity, Resource) :-
121  integer(Capacity),
122  Schedule = schedule with [handle:S, resources:Rs],
123  c_discrete_resource(S, Capacity, R),
124  Resource = resource(R, ilc('DiscreteResource')),
125  setarg(resources of schedule, Schedule, [Resource | Rs]).
126
127alt_res_set(schedule with handle:S, Resources, Resource) :-
128  ( foreach(resource(R, Type), Resources), foreach(R, Rs)
129  do
130    check_resource_type(Type)
131  ),
132  c_alt_res_set(S, Rs, ARS),
133  Resource = resource(ARS, ilc('AltResSet')).
134
135check_resource_type(ilc('Resource')) :- -?-> true.
136
137% Constraints ---------------------------------------------------------------
138tr_isc(X isc Y, Goal) :-
139  Y =.. [P | As], append(As, [X], Args), Goal =.. [P | Args].
140
141A1  starts_after_end A2 :-
142  starts_after_end(A1, A2, _).
143
144starts_after_end(activity with handle:A1, activity with handle:A2, Constraint) :-
145  !,
146  schedule_add(starts_after_end(A1, A2, 0), Cstr),
147  Constraint = constraint(Cstr, ilc('PrecedenceConstraint')).
148starts_after_end(activity with handle:A1, (activity with handle:A2)+Delay, Constraint) :-
149  integer(Delay),
150  schedule_add(starts_after_end(A1, A2, Delay), Cstr),
151  Constraint = constraint(Cstr, ilc('PrecedenceConstraint')).
152
153
154set_capacity_max(resource(Handle, ilc('DiscreteResource')), TimeMin, TimeMax, Capacity) :-
155  -?->
156  integer(TimeMax), integer(TimeMax), integer(Capacity),
157  schedule_set(set_capacity_max(Handle, TimeMin, TimeMax, Capacity)).
158
159
160A1 consumes C :- consumes(A1, C, _).
161
162consumes(activity with handle:A, Capacity of resource(Resource, ilc('CapResource')), Constraint) :-
163  -?->
164  integer(Capacity),
165  !,
166  schedule_add(consumes(A, Resource, Capacity, cap), Cstr),
167  Constraint = constraint(Cstr, ilc('ResourceConstraint')).
168
169consumes(activity with handle:A, Capacity of resource(Resource, ilc('AltResSet')), Constraint) :-
170  -?->
171  integer(Capacity),
172  schedule_add(consumes(A, Resource, Capacity, ars), Cstr),
173  Constraint = constraint(Cstr, ilc('AltResConstraint')).
174
175
176
177A1 requires C :- requires(A1, C, _).
178
179requires(activity with handle:A, Capacity of resource(Resource, ResourceType), Constraint) :-
180  -?->
181  integer(Capacity),
182  !,
183  do_requires(A, Resource, Capacity, Constraint, ResourceType).
184requires(activity with handle:A, resource(Resource, ResourceType), Constraint) :-
185  do_requires(A, Resource, 1, Constraint, ResourceType).
186
187do_requires(A, Resource, Capacity, Constraint, ilc('CapResource')) :-
188  -?->
189  schedule_add(requires(A, Resource, Capacity, cap), Cstr),
190  Constraint = constraint(Cstr, ilc('ResourceConstraint')).
191do_requires(A, Resource, Capacity, Constraint, ilc('AltResSet')) :-
192  -?->
193  schedule_add(requires(A, Resource, Capacity, ars), Cstr),
194  Constraint = constraint(Cstr, ilc('AltResConstraint')).
195
196
197
198close_resource(resource(R, ilc('Resource'))) :-
199  -?->
200  schedule_set(close_resource(R)).
201
202constraint(C, ilc('AltResConstraint')) set_not_possible resource(R, ilc('Resource')) :-
203  -?->
204  schedule_set(set_not_possible(C, R)).
205