Skip to main content

Class: IntervalVar

Interval (task) variable for scheduling. Has start, end, length, and optional presence.

Remarks​

Interval variable is a task, action, operation, or any other interval with a start and an end. The start and the end of the interval are unknowns that the solver has to find. They could be accessed as integer expressions using IntervalVar.start and IntervalVar.end. or using Model.start and Model.end. In addition to the start and the end of the interval, the interval variable has a length (equal to end - start) that can be accessed using IntervalVar.length or Model.length.

The interval variable can be optional. In this case, the solver can decide to make the interval absent, which is usually interpreted as the fact that the interval doesn't exist, the task/action was not executed, or the operation was not performed. When the interval variable is absent, its start, end, and length are also absent. A boolean expression that represents the presence of the interval variable can be accessed using IntervalVar.presence and Model.presence.

Interval variables can be created using the function Model.intervalVar. By default, interval variables are present (not optional). To create an optional interval, specify optional: true in the arguments of the function.

Examples​

In the following example we create three present interval variables x, y and z and we make sure that they don't overlap. Then, we minimize the maximum of the end times of the three intervals (the makespan):

let model = new CP.Model;
let x = model.intervalVar({ length: 10, name: "x" });
let y = model.intervalVar({ length: 10, name: "y" });
let z = model.intervalVar({ length: 10, name: "z" });
model.noOverlap([x, y, z]);
model.max([x.end(), y.end(), z.end()]).minimize();
let result = await model.solve();

In the following example, there is a task X that could be performed by two different workers A and B. The interval variable X represents the task. It is not optional because the task X is mandatory. Interval variable XA represents the task X when performed by worker A and similarly XB represents the task X when performed by worker B. Both XA and XB are optional because it is not known beforehand which worker will perform the task. The constraint IntervalVar.alternative links X, XA and XB together and ensures that only one of XA and XB is present and that X and the present interval are equal.

let model = new CP.Model;
let X = model.intervalVar({ length: 10, name: "X" });
let XA = model.intervalVar({ name: "XA", optional: true });
let XB = model.intervalVar({ name: "XB", optional: true });
model.alternative(X, [XA, XB]);
let result = await model.solve();

Variables XA and XB can be used elsewhere in the model, e.g. to make sure that each worker is assigned to at most one task at a time:

// Tasks of worker A don't overlap:
model.noOverlap([... , XA, ...]);
// Tasks of worker B don't overlap:
model.noOverlap([... , XB, ...]);

Extends​

Accessors​

endMax​

Get Signature​

get endMax(): number

The maximum end time of the interval variable.

Remarks​

Gets or sets the maximum end time of the interval variable.

The initial value is set during construction by Model.intervalVar.

Note: This property reflects the interval's domain in the model (before the solve), not in the solution.

The value must be in the range IntervalMin to IntervalMax.

See​

IntervalVar.endMin, IntervalVar.startMax, IntervalVar.lengthMax.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task = model.intervalVar({ length: 10, name: "task" });

task.endMax = 100;
console.log(task.endMax); // 100
Returns​

number

Set Signature​

set endMax(value: number): void

Parameters​
ParameterType
valuenumber
Returns​

void


endMin​

Get Signature​

get endMin(): number

The minimum end time of the interval variable.

Remarks​

Gets or sets the minimum end time of the interval variable.

The initial value is set during construction by Model.intervalVar.

Note: This property reflects the interval's domain in the model (before the solve), not in the solution.

The value must be in the range IntervalMin to IntervalMax.

See​

IntervalVar.endMax, IntervalVar.startMin, IntervalVar.lengthMin.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task = model.intervalVar({ length: 10, name: "task" });

console.log(task.endMin); // 10 (startMin + length)

task.endMin = 20;
console.log(task.endMin); // 20
Returns​

number

Set Signature​

set endMin(value: number): void

Parameters​
ParameterType
valuenumber
Returns​

void


lengthMax​

Get Signature​

get lengthMax(): number

The maximum length of the interval variable.

Remarks​

Gets or sets the maximum length of the interval variable.

The initial value is set during construction by Model.intervalVar.

Note: This property reflects the interval's domain in the model (before the solve), not in the solution.

The value must be in the range 0 to LengthMax.

See​

IntervalVar.lengthMin, IntervalVar.startMax, IntervalVar.endMax.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task = model.intervalVar({ length: 10, name: "task" });

console.log(task.lengthMax); // 10

task.lengthMax = 20;
console.log(task.lengthMax); // 20
Returns​

number

Set Signature​

set lengthMax(value: number): void

Parameters​
ParameterType
valuenumber
Returns​

void


lengthMin​

Get Signature​

get lengthMin(): number

The minimum length of the interval variable.

Remarks​

Gets or sets the minimum length of the interval variable.

The initial value is set during construction by Model.intervalVar.

Note: This property reflects the interval's domain in the model (before the solve), not in the solution.

The value must be in the range 0 to LengthMax.

See​

IntervalVar.lengthMax, IntervalVar.startMin, IntervalVar.endMin.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task = model.intervalVar({ length: 10, name: "task" });

console.log(task.lengthMin); // 10

task.lengthMin = 5;
console.log(task.lengthMin); // 5
Returns​

number

Set Signature​

set lengthMin(value: number): void

Parameters​
ParameterType
valuenumber
Returns​

void


name​

Get Signature​

get name(): string | undefined

The name assigned to this model element.

Remarks​

The name is optional and primarily useful for debugging purposes. When set, it helps identify the element in solver logs, error messages, and when inspecting solutions.

Names can be assigned to any model element including variables, expressions, and constraints.

Example​
import * as CP from "optalcp";

const model = new CP.Model();

// Name a variable at creation
const task = model.intervalVar({ length: 10, name: "assembly" });

// Or set name later
const x = model.intVar({ min: 0, max: 100 });
x.name = "quantity";

console.log(task.name); // "assembly"
console.log(x.name); // "quantity"
Returns​

string | undefined

Set Signature​

set name(value: string): void

Parameters​
ParameterType
valuestring
Returns​

void

Inherited from​

ModelElement.name


optional​

Get Signature​

get optional(): boolean

Whether the interval variable is optional.

Remarks​

Gets or sets whether the interval variable is optional:

  • True / true: The interval is optional - the solver decides whether it is present or absent in the solution.
  • False / false: The interval is present - it must be scheduled in the solution.

To force an interval to be absent, make it optional and constrain its presence to be false: model.enforce(~x.presence()) (Python), model.enforce(x.presence().not()) (TypeScript), or model.Enforce(!x.Presence()) (C#).

Note: This property reflects the presence status in the model (before the solve), not in the solution.

See​

IntervalVar.startMin, IntervalVar.endMin, IntervalVar.lengthMin.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task1 = model.intervalVar({ length: 10, name: "task1" });
const task2 = model.intervalVar({ length: 10, optional: true, name: "task2" });

console.log(task1.optional); // false (present by default)
console.log(task2.optional); // true (optional)

// Make task1 optional
task1.optional = true;
console.log(task1.optional); // true
Returns​

boolean

Set Signature​

set optional(value: boolean): void

Parameters​
ParameterType
valueboolean
Returns​

void


startMax​

Get Signature​

get startMax(): number

The maximum start time of the interval variable.

Remarks​

Gets or sets the maximum start time of the interval variable.

The initial value is set during construction by Model.intervalVar.

Note: This property reflects the interval's domain in the model (before the solve), not in the solution.

The value must be in the range IntervalMin to IntervalMax.

See​

IntervalVar.startMin, IntervalVar.endMax, IntervalVar.lengthMax.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task = model.intervalVar({ length: 10, name: "task" });

task.startMax = 100;
console.log(task.startMax); // 100
Returns​

number

Set Signature​

set startMax(value: number): void

Parameters​
ParameterType
valuenumber
Returns​

void


startMin​

Get Signature​

get startMin(): number

The minimum start time of the interval variable.

Remarks​

Gets or sets the minimum start time of the interval variable.

The initial value is set during construction by Model.intervalVar.

Note: This property reflects the interval's domain in the model (before the solve), not in the solution.

The value must be in the range IntervalMin to IntervalMax.

See​

IntervalVar.startMax, IntervalVar.endMin, IntervalVar.lengthMin.

Example​
import * as CP from "optalcp";

const model = new CP.Model();
const task = model.intervalVar({ length: 10, name: "task" });

console.log(task.startMin); // 0 (default)

task.startMin = 5;
console.log(task.startMin); // 5
Returns​

number

Set Signature​

set startMin(value: number): void

Parameters​
ParameterType
valuenumber
Returns​

void

Constructors​

Constructor​

new IntervalVar(): IntervalVar

Returns​

IntervalVar

Inherited from​

ModelElement.constructor

Methods​

alternative()​

alternative(options: IntervalVar[]): Constraint

Creates alternative constraints for the interval variable and provided options.

Parameters​

ParameterTypeDescription
optionsIntervalVar[]The interval variables to choose from.

Returns​

Constraint

The alternative constraint.

Remarks​

The alternative constraint requires that exactly one of the options intervals is present when self is present. The selected option must have the same start, end, and length as self. If self is absent, all options must be absent.

This is useful for modeling choices, such as assigning a task to one of several machines, where each option represents the task executed on a different machine.

This constraint is equivalent to Model.alternative with self as the main interval.


end()​

end(): IntExpr

Creates an integer expression for the end time of the interval variable.

Returns​

IntExpr

The resulting integer expression

Remarks​

If the interval variable is absent, then the resulting expression is also absent.

Example​

In the following example, we constrain interval variable y to start after the end of x with a delay of at least 10. In addition, we constrain the length of x to be less or equal to the length of y.

let model = new CP.Model;
let x = model.intervalVar({ name: "x", ... });
let y = model.intervalVar({ name: "y", ... });
model.enforce(x.end().plus(10).le(y.start()));
model.enforce(x.length().le(y.length()));

When x or y is absent then value of both constraints above is absent and therefore they are satisfied.

See​

Model.end is equivalent function on Model.


endAtEnd()​

endAtEnd(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.end().plus(delay).eq(successor.end()))

In other words, end of predecessor plus delay must be equal to end of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


endAtStart()​

endAtStart(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.end().plus(delay).eq(successor.start()))

In other words, end of predecessor plus delay must be equal to start of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


endBeforeEnd()​

endBeforeEnd(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.end().plus(delay).le(successor.end()))

In other words, end of predecessor plus delay must be less than or equal to end of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


endBeforeStart()​

endBeforeStart(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.end().plus(delay).le(successor.start()))

In other words, end of predecessor plus delay must be less than or equal to start of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


endOr()​

endOr(absentValue: number): IntExpr

Creates an integer expression for the end time of the interval variable. If the interval is absent, then its value is absentValue.

Parameters​

ParameterTypeDescription
absentValuenumberThe value to use when the interval is absent.

Returns​

IntExpr

The resulting integer expression

Remarks​

This function is equivalent to interval.end().guard(absentValue).

See​


forbidEnd()​

forbidEnd(func: IntStepFunction): Constraint

Constrains the end of an interval variable to not coincide with zero segments of a step function.

Parameters​

ParameterTypeDescription
funcIntStepFunctionThe step function whose zero segments define forbidden end times.

Returns​

Constraint

The constraint forbidding the end point.

Remarks​

This function is equivalent to:

model.enforce(func.eval(interval.end()).ne(0))

I.e., the function value at the end of the interval variable cannot be zero.

Example​

import * as CP from "optalcp";

const model = new CP.Model();

// A 1-hour delivery task
const delivery = model.intervalVar({ length: 1, name: "delivery" });

// Allowed end times: 1 = allowed, 0 = forbidden
const allowedEnds = model.stepFunction([
[0, 0], // Before 9h: forbidden
[9, 1], // 9h: business opens, allowed
[12, 0], // 12h: lunch break, forbidden
[13, 1], // 13h: lunch ends, allowed
[17, 0], // 17h: business closes, forbidden
]);

// Delivery cannot end when allowedEnds is 0
delivery.forbidEnd(allowedEnds);
model.minimize(delivery.end());

const result = await model.solve();
// Delivery ends at 9 (starts at 8, ends at earliest allowed time)

See​


forbidExtent()​

forbidExtent(func: IntStepFunction): Constraint

This function prevents the specified interval variable from overlapping with segments of the step function where the value is zero.

Parameters​

ParameterTypeDescription
funcIntStepFunctionThe step function.

Returns​

Constraint

The constraint forbidding the extent (entire interval).

Remarks​

This function prevents the specified interval variable from overlapping with segments of the step function where the value is zero. I.e., if [s,e)[s, e) is a segment of the step function where the value is zero, then the interval variable either ends before ss (interval.end()≤s\mathtt{interval.end()} \le s) or starts after ee (e≤interval.start()e \le \mathtt{interval.start()}).

Example​

import * as CP from "optalcp";

const model = new CP.Model();

// A 3-hour production run
const production = model.intervalVar({ length: 3, name: "production" });

// Machine availability: 1 = available, 0 = under maintenance
const availability = model.stepFunction([
[0, 1], // Initially available
[8, 0], // 8h: maintenance starts
[10, 1], // 10h: maintenance ends
]);

// Production cannot overlap periods where availability is 0
production.forbidExtent(availability);
model.minimize(production.end());

const result = await model.solve();
// Production runs [0, 3) - finishes before maintenance window

See​


forbidStart()​

forbidStart(func: IntStepFunction): Constraint

Constrains the start of an interval variable to not coincide with zero segments of a step function.

Parameters​

ParameterTypeDescription
funcIntStepFunctionThe step function whose zero segments define forbidden start times.

Returns​

Constraint

The constraint forbidding the start point.

Remarks​

This function is equivalent to:

model.enforce(func.eval(interval.start()).ne(0))

I.e., the function value at the start of the interval variable cannot be zero.

Example​

import * as CP from "optalcp";

const model = new CP.Model();

// A 2-hour task on a machine
const task = model.intervalVar({ length: 2, name: "task" });

// Allowed start times: 1 = allowed, 0 = forbidden
// Morning shift 6-14h, but break at 10-11h when no new task can start
const allowedStarts = model.stepFunction([
[0, 0], // Before 6h: forbidden
[6, 1], // 6h: shift starts, allowed
[10, 0], // 10h: break, forbidden
[11, 1], // 11h: break ends, allowed
[14, 0], // 14h: shift ends, forbidden
]);

// Task cannot start when allowedStarts is 0
task.forbidStart(allowedStarts);
model.minimize(task.start());

const result = await model.solve();
// Task starts at 6 (earliest allowed start time)

See​


length()​

length(): IntExpr

Creates an integer expression for the duration (end - start) of the interval variable.

Returns​

IntExpr

The resulting integer expression

Remarks​

If the interval variable is absent, then the resulting expression is also absent.

Example​

In the following example, we constrain interval variable y to start after the end of x with a delay of at least 10. In addition, we constrain the length of x to be less or equal to the length of y.

let model = new CP.Model;
let x = model.intervalVar({ name: "x", ... });
let y = model.intervalVar({ name: "y", ... });
model.enforce(x.end().plus(10).le(y.start()));
model.enforce(x.length().le(y.length()));

When x or y is absent then value of both constraints above is absent and therefore they are satisfied.

See​

Model.length is equivalent function on Model.


lengthOr()​

lengthOr(absentValue: number): IntExpr

Creates an integer expression for the duration (end - start) of the interval variable. If the interval is absent, then its value is absentValue.

Parameters​

ParameterTypeDescription
absentValuenumberThe value to use when the interval is absent.

Returns​

IntExpr

The resulting integer expression

Remarks​

This function is equivalent to interval.length().guard(absentValue).

See​


position()​

position(sequence: SequenceVar): IntExpr

Creates an expression equal to the position of the interval on the sequence.

Parameters​

ParameterTypeDescription
sequenceSequenceVarThe sequence variable.

Returns​

IntExpr

The resulting integer expression

Remarks​

Returns an integer expression representing the 0-based position of this interval in the given sequence. The position reflects the order in which intervals appear after applying the SequenceVar.noOverlap constraint.

If this interval is absent, the position expression is also absent.

This method is equivalent to Model.position with self as the interval.


presence()​

presence(): BoolExpr

Creates a Boolean expression which is true if the interval variable is present.

Returns​

BoolExpr

A Boolean expression that is true if the interval variable is present in the solution.

Remarks​

The resulting expression is never absent: it is true if the interval variable is present and false if the interval variable is absent.

This function is the same as Model.presence, see its documentation for more details.

Example​

In the following example, interval variables x and y must have the same presence status. I.e. they must either be both present or both absent.

const model = new CP.Model();
const x = model.intervalVar({ name: "x", optional: true, length: 10 });
const y = model.intervalVar({ name: "y", optional: true, length: 10 });
model.enforce(x.presence().eq(y.presence()));

See​

Model.presence is the equivalent function on Model.


pulse()​

pulse(height: number | IntExpr): CumulExpr

Creates cumulative function (expression) pulse for the interval variable and specified height.

Parameters​

ParameterTypeDescription
heightnumber | IntExprThe height value.

Returns​

CumulExpr

The resulting cumulative expression

Remarks​

Limitation: The height must be non-negative. Pulses with negative height are not supported.

This function is the same as Model.pulse.

Example​

let task = model.intervalVar({name: "task", length: 10});
let pulse = task.pulse(5);

See​

Model.pulse for detailed documentation and examples.


span()​

span(covered: IntervalVar[]): Constraint

Constrains the interval variable to span (cover) a set of other interval variables.

Parameters​

ParameterTypeDescription
coveredIntervalVar[]The set of interval variables to cover.

Returns​

Constraint

The span constraint.

Remarks​

The span constraint ensures that self exactly covers all present intervals in covered. Specifically, self starts at the minimum start time and ends at the maximum end time of the present covered intervals. If all covered intervals are absent, self must also be absent.

This is useful for modeling composite tasks or projects where a parent interval represents the overall duration of multiple sub-tasks.

This constraint is equivalent to Model.span with self as the spanning interval.


start()​

start(): IntExpr

Creates an integer expression for the start time of the interval variable.

Returns​

IntExpr

The resulting integer expression

Remarks​

If the interval variable is absent, then the resulting expression is also absent.

Example​

In the following example, we constrain interval variable y to start after the end of x with a delay of at least 10. In addition, we constrain the length of x to be less or equal to the length of y.

let model = new CP.Model;
let x = model.intervalVar({ name: "x", ... });
let y = model.intervalVar({ name: "y", ... });
model.enforce(x.end().plus(10).le(y.start()));
model.enforce(x.length().le(y.length()));

When x or y is absent then value of both constraints above is absent and therefore they are satisfied.

See​

Model.start is equivalent function on Model.


startAtEnd()​

startAtEnd(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.start().plus(delay).eq(successor.end()))

In other words, start of predecessor plus delay must be equal to end of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


startAtStart()​

startAtStart(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.start().plus(delay).eq(successor.start()))

In other words, start of predecessor plus delay must be equal to start of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


startBeforeEnd()​

startBeforeEnd(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.start().plus(delay).le(successor.end()))

In other words, start of predecessor plus delay must be less than or equal to end of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


startBeforeStart()​

startBeforeStart(successor: IntervalVar, delay?: number | IntExpr): Constraint

Creates a precedence constraint between two interval variables.

Parameters​

ParameterTypeDefault valueDescription
successorIntervalVarundefinedThe successor interval variable.
delaynumber | IntExpr0The minimum delay between intervals.

Returns​

Constraint

The precedence constraint.

Remarks​

Assuming that the current interval is predecessor, the constraint is the same as:

model.enforce(predecessor.start().plus(delay).le(successor.start()))

In other words, start of predecessor plus delay must be less than or equal to start of successor.

When one of the two interval variables is absent, then the constraint is satisfied.

See​


startOr()​

startOr(absentValue: number): IntExpr

Creates an integer expression for the start time of the interval variable. If the interval is absent, then its value is absentValue.

Parameters​

ParameterTypeDescription
absentValuenumberThe value to use when the interval is absent.

Returns​

IntExpr

The resulting integer expression

Remarks​

This function is equivalent to interval.start().guard(absentValue).

See​


stepAtEnd()​

stepAtEnd(height: number | IntExpr): CumulExpr

Creates cumulative function (expression) that changes value at end of the interval variable by the given height.

Parameters​

ParameterTypeDescription
heightnumber | IntExprThe height value.

Returns​

CumulExpr

The resulting cumulative expression

Remarks​

Creates cumulative function (expression) that changes value at end of the interval variable by the given height.

This function is the same as Model.stepAtEnd.

Example​

let task = model.intervalVar({name: "task", length: 10});
let step = task.stepAtEnd(5);

See​


stepAtStart()​

stepAtStart(height: number | IntExpr): CumulExpr

Creates cumulative function (expression) that changes value at start of the interval variable by the given height.

Parameters​

ParameterTypeDescription
heightnumber | IntExprThe height value.

Returns​

CumulExpr

The resulting cumulative expression

Remarks​

Creates cumulative function (expression) that changes value at start of the interval variable by the given height.

This function is the same as Model.stepAtStart.

Example​

let task = model.intervalVar({name: "task", length: 10});
let step = task.stepAtStart(5);

See​