# Class: Model

*Model* captures the problem to be solved. It contains variables,
constraints and objective function.

To create an optimization model, you need to first create a *Model* object.
Then you can use the methods of the *Model* to create variables (e.g. intervalVar), the objective function (minimize or maximize)
and constraints (e.g. constraint or noOverlap).
Note that a boolean expression becomes a constraint only by passing it to
the function constraint otherwise it is not enforced.

To solve a model, pass it to function solve or to Solver class.

### Available modeling elements

#### Variables

Interval variables can be created by function intervalVar.

#### Basic integer expressions

- startOf: start of an interval variable (optional integer expression).
- startOr: start of an interval variable or a constant when it is
*absent*. - endOf: end of an interval variable (optional integer expression).
- endOr: end of an interval variable or a constant when it is
*absent*. - lengthOf: length of an interval variable (optional integer expression).
- lengthOr: length of an interval variable or a constant when it is
*absent*. - guard: replaces
*absent*value by a constant.

#### Integer arithmetics

- plus: addition.
- minus: subtraction.
- neg: negation (changes sign).
- times: multiplication.
- div: division (rounds to zero).
- abs: absolute value.
- min2: minimum of two integer expressions.
- min: minimum of an array of integer expressions.
- max2: maximum of two integer expressions.
- max: maximum of an array of integer expressions.
- sum: sum of an array of integer expressions.

#### Comparison operators for integer expressions

- eq: equality.
- ne: inequality.
- lt: less than.
- le: less than or equal to.
- gt: greater than.
- ge: greater than or equal to.
- identity: constraints two integer expressions to be equal including the presence status.

#### Boolean operators

#### Functions returning BoolExpr

- presenceOf: whether the argument is
*present*or*absent*. - inRange: whether an integer expression is within the given range

#### Basic constraints on interval variables

- alternative: an alternative between multiple interval variables.
- span: span (cover) of a set of interval variables.
- endBeforeEnd, endBeforeStart, startBeforeEnd, startBeforeStart, endAtStart, startAtEnd: precedence constraints.

#### Disjunction (noOverlap)

- sequenceVar: sequence variable over a set of interval variables.
- noOverlap: constraints a set of interval variables to not overlap (possibly with transition times).

#### Basic cumulative expressions

- pulse: changes value during the interval variable.
- stepAtStart: changes value at the start of the interval variable.
- stepAtEnd: changes value at the end of the interval variable.
- stepAt: changes value at a given time.

#### Combining cumulative expressions

- cumulNeg: negation.
- cumulPlus: addition.
- cumulMinus: subtraction.
- cumulSum: sum of multiple expressions.

#### Constraints on cumulative expressions

#### Objective

`Example`

Our goal is to schedule a set of tasks such that it is finished as soon as possible (i.e. the makespan is minimized). Each task has a fixed duration and it cannot be interrupted. Moreover, each tasks needs a certain number of workers to be executed and the total number of workers is limited. The input data are generated randomly.

`import * as CP from '@scheduleopt/optalcp';`

// Constants for random problem generation:

const nbTasks = 100;

const nbWorkers = 5;

const maxDuration = 100;

// Start by creating the model:

let model = new CP.Model();

// For each task we will have an interval variable and a cumulative expression:

let tasks : CP.IntervalVar[] = [];

let workerUsage: CP.CumulExpr[] = [];

// Loop over the tasks:

for (let i = 0; i < nbTasks; i++) {

// Generate random task length:

const taskLength = 1 + Math.floor(Math.random() * (maxDuration - 1));

// Create the interval variable for the task:

let task = model.intervalVar({ name: "Task" + (i + 1), length: taskLength });

// And store it in the array:

tasks.push(task);

// Generate random number of workers needed for the task:

const workersNeeded = 1 + Math.floor(Math.random() * (nbWorkers - 1));

// Create the pulse that increases the number of workers used during the task:

workerUsage.push(task.pulse(workersNeeded));

}

// Limit the sum of the pulses to the number of workers available:

model.cumulSum(workerUsage).cumulLe(nbWorkers);

// From an array of tasks, create an array of their ends:

let ends = tasks.map(t => t.end());

// And minimize the maximum of the ends:

model.max(ends).minimize();

try {

// Solve the model with the provided parameters:

let result = await CP.solve(model, {

timeLimit: 3, // Stop after 3 seconds

nbWorkers: 4, // Use for CPU threads

});

if (result.nbSolutions == 0)

console.log("No solution found.");

else {

const solution = result.bestSolution!;

// Note that in evaluation version of the solver, the variable values //

the solution are masked, i.e. they are all _absent_ (`null` in JavaScript).

// Objective value is not masked though.

console.log("Solution found with makespan " + solution.getObjective());

for (let task of tasks) {

let start = solution.getStart(task);

if (start !== null)

console.log("Task " + task.getName() + " starts at " + );

else

console.log("Task " + task.getName() + " is absent (not scheduled).")

}

}

} catch (e) {

// In case of error, CP.solve returns rejected promise.

// Therefore "await CP.solve" throws an exception.

console.log("Error: " + (e as Error).message);

}

`See`

## Constructors

### constructor

• **new Model**(`name?`

)

Creates a new empty model.

Naming the model is optional. The main purpose of the name is to distinguish between different models during benchmarking (see benchmark).

#### Parameters

Name | Type | Description |
---|---|---|

`name?` | `string` | Name of the model. |

## Methods

### abs

▸ **abs**(`arg`

): `IntExpr`

Creates an integer expression which is absolute value of `arg`

.

#### Parameters

Name | Type |
---|---|

`arg` | `number` | `IntExpr` |

#### Returns

`Remarks`

If `arg`

has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.abs.

### alternative

▸ **alternative**(`main`

, `options`

): `void`

Creates alternative constraint between interval variables.

#### Parameters

Name | Type | Description |
---|---|---|

`main` | `IntervalVar` | The main interval variable. |

`options` | `IntervalVar` [] | Array of optional interval variables to chose from. |

#### Returns

`void`

`Remarks`

Alternative constraint is a way to model various kind of alternative choices. For example, we can model a task that could be done by worker A, B, or C. To model such alternative, we use interval variable `main`

that represents the task regardless the chosen worker and three interval variables `options = [A, B, C]`

that represent the task when done by worker A, B, or C. Interval variables `A`

, `B`

and `C`

should be optional. This way, if e.g. option B is chosen, then `B`

will be *present* and equal to `main`

(they will start at the same time and end at the same time), the remaining options A and C will be *absent*.

We may also decide not to execute the `main`

task at all (if it is optional). Then `main`

will be *absent* and all options `A`

, `B`

and `C`

will be *absent* too.

#### Formal definition

The constraint `alternative(main, options)`

is satisfied in the following two cases:

- Interval
`main`

is*absent*and all`options[i]`

are*absent*too. - Interval
`main`

is*present*and exactly one of`options[i]`

is*present*(the remaining options are*absent*). Let`k`

be the index of the present option. Then`main.start() == options[k].start()`

and`main.end() == options[k].end()`

.

`Example`

Let's consider a task T that can be done by worker A, B, or C. The length of the task and a cost associated with it depends on the chosen worker:

- If done by worker A then its length is 10 and the cost is 5.
- If done by worker B then its length is 20 and the cost is 2.
- If done by worker C then its length is 3 and the cost is 10.

Each worker can execute only one task at a time. The remaining tasks are omitted in the model below though. The objective could be e.g. to minimize the total cost (also omitted in the model).

`let model = new CP.Model;`

let T = model.intervalVar({ name: "T" });

let T_A = model.intervalVar({ name: "T_A", optional: true, length: 10 });

let T_B = model.intervalVar({ name: "T_B", optional: true, length: 20 });

let T_C = model.intervalVar({ name: "T_C", optional: true, length: 3 });

// T_A, T_B and T_C are different ways to execute task T:

model.alternative(T, [T_A, T_B, T_C]);

// The cost depends on the chosen option:

let costOfT = model.sum([

T_A.presence().times(5),

T_B.presence().times(2),

T_C.presence().times(10)

]);

// Each worker A can perform only one task at a time:

model.noOverlap([T_A, ...]); // Worker A

model.noOverlap([T_B, ...]); // Worker B

model.noOverlap([T_C, ...]); // Worker C

// Minimize the total cost:

model.sum([costOfT, ...]).minimize();

### and

▸ **and**(`arg1`

, `arg2`

): `BoolExpr`

Logical *AND* of boolean expressions `arg1`

and `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `boolean` | `BoolExpr` |

`arg2` | `boolean` | `BoolExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as BoolExpr.and.

### constraint

▸ **constraint**(`constraint`

): `void`

Creates a constraint from a boolean expression that must be satisfied in the solution.

A constraint is satisfied if it is not *false*. In other words, a constraint is satisfied
if it is *true* or *absent*.

#### Parameters

Name | Type | Description |
---|---|---|

`constraint` | `boolean` | `BoolExpr` | The boolean expression to turn into a constraint. |

#### Returns

`void`

A constraint that must be satisfied in the solution.

`Remarks`

A boolean expression that is *not* turned into a constraint can have
arbitrary value in the solution.

`Example`

In the following example, we create a boolean expression `endsBefore50`

that checks whether the end of interval variable `x`

is before 50.
We don't turn it into a constraint yet:

`let model = new CP.Model();`

let x = model.intervalVar({ name: "x", length: 10, optional: true });

let endsBefore50 = x.end().le(50);

Because `endsBefore50`

is not a constraint, it can take arbitrary
value in a solution, in particular:

`endsBefore50`

is*true*if`x`

is present and its end is less than or equal to 50.`endsBefore50`

is*false*if`x`

is present and its end is greater than 50.`endsBefore50`

is*absent*if`x`

is absent.

Now we turn `endsBefore50`

into a constraint:

`model.constraint(endsBefore50);`

When `endsBefore50`

is a constraint, it can only be *true* or *absent* in
the solution. Therefore, cases 1 and 3 above can happen but case 2 cannot.

#### Difference between constraints and boolean expressions

Boolean expressions can take arbitrary value (*true*, *false*, or *absent*)
and can be combined into composed expressions (e.g. using and or
or).

Constraints can only be *true* or *absent* (in a solution) and cannot
be combined into composed expressions.

Some functions create constraints directly, e.g. noOverlap.
Then, it is not necessary to to pass them to function constraint.
It is also not possible to combine constraints into composed expressions
such as `or(noOverlap(..), noOverlap(..))`

.

### cumulGe

▸ **cumulGe**(`cumul`

, `minCapacity`

): `void`

Constrains cumulative function `cumul`

to be everywhere greater or equal to `minCapacity`

.

#### Parameters

Name | Type |
---|---|

`cumul` | `CumulExpr` |

`minCapacity` | `number` |

#### Returns

`void`

`Remarks`

This function can be used to specify the minimum limit of resource usage at any time. For example to make sure that there is never less than zero material on stock.
See stepAtStart for an example with `cumulGe`

.

`See`

- CumulExpr.cumulGe for the equivalent function on CumulExpr.
- cumulLe for the opposite constraint.

### cumulLe

▸ **cumulLe**(`cumul`

, `maxCapacity`

): `void`

Constrains cumulative function `cumul`

to be everywhere less or equal to `maxCapacity`

.

#### Parameters

Name | Type |
---|---|

`cumul` | `CumulExpr` |

`maxCapacity` | `number` |

#### Returns

`void`

`Remarks`

This function can be used to specify the maximum limit of resource usage at any time. For example to limit number of workers working simultaneously, limit the maximum amount of material on stock etc.
See pulse for an example with `cumulLe`

.

`See`

- CumulExpr.cumulLe for the equivalent function on CumulExpr.
- cumulGe for the opposite constraint.

### cumulMinus

▸ **cumulMinus**(`lhs`

, `rhs`

): `CumulExpr`

Subtraction of two cumulative expressions.

#### Parameters

Name | Type |
---|---|

`lhs` | `CumulExpr` |

`rhs` | `CumulExpr` |

#### Returns

`Remarks`

Computes subtraction of two cumulative functions.

#### Formal definition

Let `result = cumulMinus(lhs, rhs)`

. Then for any number `x`

in range IntervalMin..IntervalMax the value of `result`

at `x`

is equal to `lhs`

at `x`

minus `rhs`

at `x`

.

`cumulMinus(lhs, rhs)`

is the same as `cumulSum([lhs, cumulNeg(rhs)])`

.

`See`

- CumulExpr.cumulMinus for the equivalent function on CumulExpr.
- cumulSum, cumulPlus, cumulNeg for other ways to combine cumulative functions.

### cumulNeg

▸ **cumulNeg**(`arg`

): `CumulExpr`

Negation of a cumulative expression.

#### Parameters

Name | Type |
---|---|

`arg` | `CumulExpr` |

#### Returns

`Remarks`

Computes negation of a cumulative function. That is, the resulting function has the opposite values.

`See`

- CumulExpr.cumulNeg for the equivalent function on CumulExpr.
- cumulSum, cumulPlus, cumulMinus for other ways to combine cumulative functions.

### cumulPlus

▸ **cumulPlus**(`lhs`

, `rhs`

): `CumulExpr`

Addition of two cumulative expressions.

#### Parameters

Name | Type |
---|---|

`lhs` | `CumulExpr` |

`rhs` | `CumulExpr` |

#### Returns

`Remarks`

Computes addition of two cumulative functions.

#### Formal definition

Let `result = cumulPlus(lhs, rhs)`

. Then for any number `x`

in range IntervalMin..IntervalMax the value of `result`

at `x`

is equal to `lhs`

at `x`

plus `rhs`

at `x`

.

`cumulPlus(lhs, rhs)`

is the same as `cumulSum([lhs, rhs])`

.

`See`

- CumulExpr.cumulPlus for the equivalent function on CumulExpr.
- cumulSum, cumulMinus, cumulNeg for other ways to combine cumulative functions.

### cumulSum

▸ **cumulSum**(`array`

): `CumulExpr`

Sum of cumulative expressions.

#### Parameters

Name | Type |
---|---|

`array` | `CumulExpr` [] |

#### Returns

`Remarks`

Computes sum of cumulative functions. The sum can be used e.g. to combine contributions of individual tasks to total resource consumption.

`See`

cumulPlus, cumulMinus, cumulNeg for other ways to combine cumulative functions.

### div

▸ **div**(`arg1`

, `arg2`

): `IntExpr`

Creates an integer division of the two integer expressions, i.e. `arg1 div arg2`

. The division rounds towards zero.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.div.

### endAtEnd

▸ **endAtEnd**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.endAtEnd is equivalent function on IntervalVar.
- constraint
- start, end
- eq

### endAtStart

▸ **endAtStart**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.endAtStart is equivalent function on IntervalVar.
- constraint
- start, end
- eq

### endBeforeEnd

▸ **endBeforeEnd**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.endBeforeEnd is equivalent function on IntervalVar.
- constraint
- start, end
- le

### endBeforeStart

▸ **endBeforeStart**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.endBeforeStart is equivalent function on IntervalVar.
- constraint
- start, end
- le

### endOf

▸ **endOf**(`interval`

): `IntExpr`

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

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

#### Returns

`Remarks`

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

`Example`

In the following example we constraint interval variable `y`

to start after end of `y`

with a delay at least 10. In addition we constrain length of `x`

to be less or equal than length of `y`

.

`let model = new CP.Model;`

let x = model.intervalVar({ name: "x", ... });

let y = model.intervalVar({ name: "y", ... });

model.constraint(model.endOf(x).plus(10).le(model.startOf(y)));

model.constraint(model.lengthOf(x).le(model.lengthOf(y)));

When `x`

or `y`

is *absent* then value of both constraints above is *absent* and therefore they are satisfied.

`See`

- end is equivalent function on IntervalVar.
- Function endOr is a similar function that replaces value
*absent*by a constant.

### endOr

▸ **endOr**(`interval`

, `absentValue`

): `IntExpr`

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

.

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

`absentValue` | `number` |

#### Returns

`Remarks`

This function is equivalent to `endOf(interval).guard(absentValue)`

.

`See`

### eq

▸ **eq**(`arg1`

, `arg2`

): `BoolExpr`

Creates Boolean expression `arg1`

= `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.eq.

### ge

▸ **ge**(`arg1`

, `arg2`

): `BoolExpr`

Creates Boolean expression `arg1`

≥ `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks If`

one of the arguments has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.ge.

### getIntervalVars

▸ **getIntervalVars**(): `IntervalVar`

[]

Returns an array of all interval variables in the model.

#### Returns

### getName

▸ **getName**(): `undefined`

| `string`

Returns the name of the model. When no name was set, returns `undefined`

.

#### Returns

`undefined`

| `string`

### gt

▸ **gt**(`arg1`

, `arg2`

): `BoolExpr`

Creates Boolean expression `arg1`

> `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.gt.

### guard

▸ **guard**(`arg`

, `absentValue?`

): `IntExpr`

Creates an expression that replaces value *absent* by a constant.

#### Parameters

Name | Type | Default value |
---|---|---|

`arg` | `number` | `IntExpr` | `undefined` |

`absentValue` | `number` | `0` |

#### Returns

`Remarks The`

resulting expression is:

- equal to
`arg`

if`arg`

is*present* - and equal to
`absentValue`

otherwise (i.e. when`arg`

is*absent*).

The default value of `absentValue`

is 0.

The resulting expression is never *absent*.

Same as IntExpr.guard.

### identity

▸ **identity**(`arg1`

, `arg2`

): `void`

Constraints `arg1`

and `arg2`

to be identical, including their presence status.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`void`

`Remarks`

Identity is different than equality. For example, if `x`

is *absent*, then `eq(x, 0)`

is *absent*, but `identity(x, 0)`

is *false*.

Same as IntExpr.identity.

### implies

▸ **implies**(`arg1`

, `arg2`

): `BoolExpr`

Logical implication of two boolean expressions, that is `arg1`

implies `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `boolean` | `BoolExpr` |

`arg2` | `boolean` | `BoolExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as BoolExpr.implies.

### inRange

▸ **inRange**(`arg`

, `lb`

, `ub`

): `BoolExpr`

Creates Boolean expression `lb`

≤ `arg`

≤ `ub`

.

#### Parameters

Name | Type |
---|---|

`arg` | `number` | `IntExpr` |

`lb` | `number` |

`ub` | `number` |

#### Returns

`Remarks`

If `arg`

has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.inRange.

### intervalVar

▸ **intervalVar**(`params`

): `IntervalVar`

Creates a new interval variable and adds it to the model.

An interval variable represents an unknown interval (a task, operation,
action) that the solver assign a value in such a way to satisfy all
constraints. An interval variable has a start, end and length. In a
solution, *start <= end* and *length = end - start*.

The interval variable can be optional. In this case its value in a solution
could be *absent*, meaning that the task/operation is not performed.

#### Parameters

Name | Type | Description |
---|---|---|

`params` | `Object` | - |

`params.end?` | `number` | [number?, number?] | Constraints the end of the interval. |

`params.length?` | `number` | [number?, number?] | Constraints the length of the interval. |

`params.name?` | `string` | The name of the interval variable. The default is `undefined` . |

`params.optional?` | `boolean` | Whether the interval variable is optional (can take value absent). The default is `false` . |

`params.start?` | `number` | [number?, number?] | Constraints the start of the interval. |

#### Returns

The created interval variable.

`Remarks`

Parameters `params.start`

, `params.end`

and `params.length`

can be either a
number or a tuple of two numbers. If a number is given, it represents a
fixed value. If a tuple is given, it represents a range of possible values.
The default range for start, end and length is `0`

to `IntervalMax`

.
If a range is specified but one of the values is undefined (e.g. `start: [, 100]`

)
then the default value is used instead (in our case `0`

).

`Example`

`let model = new CP.Model();`

// Create a present interval variable with a fixed start but unknown length:

const x = model.intervalVar({ start: 0, length: [10, 20], name: "x" });

// Create an interval variable with a start and end ranges:

const y = model.intervalVar({ start: [0, 5], end: [10, 15], name: "y" });

// Create an optional interval variable with a length interval 5..10:

const z = model.intervalVar({ length: [5, 10], optional: true, name: "z" });

`See`

▸ **intervalVar**(`name?`

): `IntervalVar`

Creates a new present interval variable with the given name and adds it to the model.

#### Parameters

Name | Type | Description |
---|---|---|

`name?` | `string` | The name of the interval variable. |

#### Returns

The created interval variable.

`Remarks`

The default range for start, end and length is `0`

to `IntervalMax`

.

`Example`

`const model = new CP.Model();`

// Create an interval variable with a name:

const x = model.intervalVar("x");

// Create unnamed interval variable (the name will be undefined):

const interval2 = model.intervalVar();

`See`

- IntervalVar
- makeOptional, makePresent and makeAbsent for changing the presence of the interval.
- setStart, setStartMin and setStartMax for changing the start of the interval.
- setEnd, setEndMin and setEndMax for changing the end of the interval.
- setLength, setLengthMin and setLengthMax for changing the length of the interval.

### le

▸ **le**(`arg1`

, `arg2`

): `BoolExpr`

Creates Boolean expression `arg1`

≤ `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.le.

### lengthOf

▸ **lengthOf**(`interval`

): `IntExpr`

Creates an integer expression for the length of an interval variable.

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

#### Returns

`Remarks`

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

`Example`

In the following example we constraint interval variable `y`

to start after end of `y`

with a delay at least 10. In addition we constrain length of `x`

to be less or equal than length of `y`

.

`let model = new CP.Model;`

let x = model.intervalVar({ name: "x", ... });

let y = model.intervalVar({ name: "y", ... });

model.constraint(model.endOf(x).plus(10).le(model.startOf(y)));

model.constraint(model.lengthOf(x).le(model.lengthOf(y)));

When `x`

or `y`

is *absent* then value of both constraints above is *absent* and therefore they are satisfied.

`See`

- length is equivalent function on IntervalVar.
- Function lengthOr is a similar function that replaces value
*absent*by a constant.

### lengthOr

▸ **lengthOr**(`interval`

, `absentValue`

): `IntExpr`

Creates an integer expression for the length of the interval variable. If the interval is absent then its value is `absentValue`

.

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

`absentValue` | `number` |

#### Returns

`Remarks`

This function is equivalent to `lengthOf(interval).guard(absentValue)`

.

`See`

### lt

▸ **lt**(`arg1`

, `arg2`

): `BoolExpr`

Creates Boolean expression `arg1`

< `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.lt.

### max

▸ **max**(`args`

): `IntExpr`

Creates an integer expression for the maximum of the arguments.

#### Parameters

Name | Type |
---|---|

`args` | (`number` | `IntExpr` )[] |

#### Returns

`Remarks`

Absent arguments are ignored as if they were not specified in the input array `args`

. Maximum of an empty set (i.e. `max([])`

is *absent*. The maximum is *absent* also if all arguments are *absent*.

Note that binary function max2 handles absent values differently. For example, when `x`

is *absent* then:

`max2(x, 5)`

is*absent*.`max([x, 5])`

is 5.`max([x])`

is*absent*.

`Example`

A common use case is to compute *makespan* of a set of tasks, i.e. the time when the last task finishes. In the following example, we minimize the makespan of a set of tasks (other parts of the model are not included).

`let model = new CP.Model;`

let tasks: CP.IntervalVar[] = ...;

...

// Create an array of end times of the tasks:

let endTimes = tasks.map(task => task.end());

let makespan = model.max(endTimes);

model.minimize(makespan);

Notice that when a task is *absent* (not executed) then its end time is *absent*. And therefore the absent task is not included in the maximum.

`See`

- Binary max2.
- Function span constraints interval variable to start and end at minimum and maximum of the given set of intervals.

### max2

▸ **max2**(`arg1`

, `arg2`

): `IntExpr`

Creates an integer expression which is the maximum of `arg1`

and `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.max2. See Model.max for n-ary maximum.

### maximize

▸ **maximize**(`arg`

): `void`

Maximize the provided expression. I.e. search for a solution that achieves the maximal value of the expression.

#### Parameters

Name | Type |
---|---|

`arg` | `number` | `IntExpr` |

#### Returns

`void`

`Remarks`

Equivalent of function IntExpr.maximize.

`Example`

In the following model, we search for a solution that maximizes
the length of the interval variable `x`

:

`let model = new CP.Model();`

let x = model.intervalVar({ length: [10, 20], name: "x" });

model.maximize(x.length());

let result = await CP.solve(model);

`See`

### min

▸ **min**(`args`

): `IntExpr`

Creates an integer expression for the minimum of the arguments.

#### Parameters

Name | Type |
---|---|

`args` | (`number` | `IntExpr` )[] |

#### Returns

`Remarks`

Absent arguments are ignored as if they were not specified in the input array `args`

. Minimum of an empty set (i.e. `min([])`

is *absent*. The minimum is *absent* also if all arguments are *absent*.

Note that binary function min2 handles absent values differently. For example, when `x`

is *absent* then:

`min2(x, 5)`

is*absent*.`min([x, 5])`

is 5.`min([x])`

is*absent*.

`Example`

In the following example, we compute the time when the first task of `tasks`

starts, i.e. the minimum of the starting times.

`let model = new CP.Model;`

let tasks: CP.IntervalVar[] = ...;

...

// Create an array of start times of the tasks:

let startTimes = tasks.map(task => task.start());

let firstStartTime = model.min(startTimes);

Notice that when a task is *absent* (not executed) then its end time is *absent*. And therefore the absent task is not included in the minimum.

`See`

- Binary min2.
- Function span constraints interval variable to start and end at minimum and maximum of the given set of intervals.

### min2

▸ **min2**(`arg1`

, `arg2`

): `IntExpr`

Creates an integer expression which is the minimum of `arg1`

and `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.min2. See Model.min for n-ary minimum.

### minimize

▸ **minimize**(`arg`

): `void`

Minimize the provided expression. I.e. search for a solution that achieves the minimal value of the expression.

#### Parameters

Name | Type |
---|---|

`arg` | `number` | `IntExpr` |

#### Returns

`void`

`Remarks`

Equivalent of function IntExpr.minimize.

`Example`

In the following model, we search for a solution that minimizes the maximum
end of the two intervals `x`

and `y`

:

`let model = new CP.Model();`

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

let y = model.intervalVar({ length: 20, name: "y" });

model.minimize(model.max2(x.end(), y.end()));

let result = await CP.solve(model);

`See`

### minus

▸ **minus**(`arg1`

, `arg2`

): `IntExpr`

Creates a subtraction of the two integer expressions, i.e. `arg1 + arg2`

.@remarks

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.minus.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

### ne

▸ **ne**(`arg1`

, `arg2`

): `BoolExpr`

Creates Boolean expression `arg1`

≠ `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Use function constraint to create a constraint from this expression.

Same as IntExpr.ne.

### neg

▸ **neg**(`arg`

): `IntExpr`

Creates negation of the integer expression, i.e. `-arg`

.

#### Parameters

Name | Type |
---|---|

`arg` | `number` | `IntExpr` |

#### Returns

`Remarks`

If the value of `arg`

has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.neg.

### noOverlap

▸ **noOverlap**(`intervals`

, `transitions?`

): `void`

Constrain a set of interval variables to not overlap.

#### Parameters

Name | Type | Description |
---|---|---|

`intervals` | `IntervalVar` [] | An array of interval variables to constrain. |

`transitions?` | `number` [][] | A 2D square array of minimum transition times between the intervals. The size of the array must be equal to the number of interval variables. |

#### Returns

`void`

`Remarks`

This function constrains a set of interval variables to not overlap.
That is, for each pair of interval variables `x`

and `y`

, one of the
following must hold:

- Interval variable
`x`

or`y`

is*absent*. In this case, the absent interval is not scheduled (the task is not performed) and therefore it cannot overlap with any other interval. Only*optional*interval variables can be*absent*. - Interval variable
`x`

is before`y`

, that is,`x.end()`

is less than or equal to`y.start()`

. - Interval variable
`y`

is before`x`

, that is,`y.end()`

is less than or equal to`x.start()`

.

The function can also take a square array `transitions`

of minimum
transition times between the intervals. The transition time is the time
that must elapse between the end of the first interval and the start of the
second interval. The transition time cannot be negative. When transition
times are specified, the above conditions 2 and 3 are modified as follows:

`x.end() + transition[i][j]`

is less than or equal to`y.start()`

.`y.end() + transition[j][i]`

is less than or equal to`x.start()`

.

Where `i`

and `j`

are indices of `x`

and `y`

in the array of interval
variables.

Note that minimum transition times are enforced between all pairs of intervals, not only between direct neighbors.

Functionally this constraint is the same as SequenceVar.noOverlap and Model.noOverlap(SequenceVar, ...). The difference is that this function takes an array of interval variables as an argument instead of a sequence variable.

`Example`

The following example does not use transition times. For an example with transition times see SequenceVar.noOverlap.

Let's consider a set of tasks that must be performed by a single machine. The machine is able to handle only one task at a time. Each task is characterized by its length and a deadline. The goal is to schedule the tasks on the machine such that the number of missed deadlines is minimized.

`let tasks = [`

{ length: 10, deadline: 70 },

{ length: 20, deadline: 50 },

{ length: 15, deadline: 50},

{ length: 30, deadline: 100 },

{ length: 20, deadline: 120 },

{ length: 25, deadline: 90 },

{ length: 30, deadline: 80 },

{ length: 10, deadline: 40 },

{ length: 20, deadline: 60 },

{ length: 25, deadline: 150 },

];

let model = new CP.Model;

// An interval variable for each task. Begin with an empty array:

let taskVars: CP.IntervalVar[] = [];

// A boolean expression that is true if the task is late:

let isLate: CP.BoolExpr[] = [];

// Fill the arrays:

for (let i = 0; i < tasks.length; i++) {

let task = tasks[i];

let taskVar = model.intervalVar({ name: "Task" + i, length: task.length});

taskVars.push(taskVar);

isLate.push(model.ge(taskVar.end(), task.deadline));

}

// Tasks cannot overlap:

model.noOverlap(taskVars);

// Minimize the number of late tasks:

model.sum(isLate).minimize();

await CP.solve(model, { searchType: "FDS" });

▸ **noOverlap**(`sequence`

, `transitions?`

): `void`

Constrain a set of interval variables (forming a sequence variable) to not overlap.

#### Parameters

Name | Type | Description |
---|---|---|

`sequence` | `SequenceVar` | A sequence variable to constrain. The sequence is formed by set of interval variables. |

`transitions?` | `number` [][] | A 2D array of minimum transition times between the intervals. |

#### Returns

`void`

`Remarks`

This function is the same as noOverlap, only sequence variable is passed as an argument instead. See the documentation for noOverlap for details.

There is also Model.noOverlap(IntervalVar[], ...) that takes an array of interval variables instead of a sequence variable.

### not

▸ **not**(`arg`

): `BoolExpr`

Negation of the boolean expression `arg`

.

#### Parameters

Name | Type |
---|---|

`arg` | `boolean` | `BoolExpr` |

#### Returns

`Remarks`

If the argument has value *absent* then the resulting expression has also value *absent*.

Same as BoolExpr.not.

### or

▸ **or**(`arg1`

, `arg2`

): `BoolExpr`

Logical *OR* of boolean expressions `arg1`

and `arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `boolean` | `BoolExpr` |

`arg2` | `boolean` | `BoolExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as BoolExpr.or.

### plus

▸ **plus**(`arg1`

, `arg2`

): `IntExpr`

Creates an addition of the two integer expressions, i.e. `arg1 + arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.plus.

### presenceOf

▸ **presenceOf**(`arg`

): `BoolExpr`

Creates a boolean expression that is true if the given argument is present in the solution.

#### Parameters

Name | Type | Description |
---|---|---|

`arg` | `number` | `boolean` | `IntExpr` | `IntervalVar` | The argument to check for presence in the solution. |

#### Returns

A boolean expression that is true if the argument is present in the solution.

`Remarks`

The value of the expression remains unknown until a solution is found. The expression can be used in a constraint to restrict possible solutions.

The function is equivalent to IntervalVar.presence and IntExpr.presence.

`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();`

let x = model.intervalVar({ name: "x", optional: true, length: 10, start: [0, 100] });

let y = model.intervalVar({ name: "y", optional: true, length: 10, start: [0, 100] });

model.constraint(model.presenceOf(x).eq(model.presenceOf(y)));

#### Simple constraints over presence

The solver treats binary constraints over presence in a special way: it
uses them to better propagate other constraints over the same pairs of variables.
Let's extend the previous example by a constraint that `x`

must end before
`y`

starts:

`let x = model.intervalVar({ name: "x", optional: true, length: 10, start: [0, 100] });`

let y = model.intervalVar({ name: "y", optional: true, length: 10, start: [0, 100] });

model.constraint(model.presenceOf(x).eq(model.presenceOf(y)));

// x.end <= y.start:

let isBefore = x.end().le(y.start());

model.constraint(isBefore);

In this example the solver sees (propagates) that the minimum start time of
`y`

is 10 and maximum end time of `x`

is 90. Without the constraint over
`presenceOf`

, the solver could not propagate that because in this case one
of the intervals can be *absent* and the other one *present* (and so the
value of `isBefore`

would be *absent* and the constraint would be
satisfied).

In order to achieve good propagation, it is recommended to use binary
constraints over `presenceOf`

when possible. E.g. use multiple binary
constraints instead of a single big constraint.

### pulse

▸ **pulse**(`interval`

, `height`

): `CumulExpr`

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

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

`height` | `number` | `IntExpr` |

#### Returns

`Remarks`

Pulse can be used to model resource requirement during an interval variable. The given amount `height`

of the resource is used during the whole interval (from its start to end).

#### Formal definition

Pulse creates a cumulative function which have the value:

`0`

before`interval.start()`

,`height`

between`interval.start()`

and`interval.end()`

,`0`

after`interval.end()`

If `interval`

is absent then the pulse is `0`

everywhere.

Cumulative functions can be combined together using cumulPlus, cumulMinus, cumulNeg and cumulSum. The minimum and the maximum height of a cumulative function can be constrained using cumulLe and cumulGe.

Pulses with variable heights (i.e. with `height`

given as `IntExpr`

) are not supported yet.

`Example`

Lets consider a set of tasks and a group of 3 workers. Each task requires certain number of workers (`nbWorkersNeeded`

). Our goal is to schedule the tasks so that the length of the schedule (makespan) is minimal.

`// The input data:`

const nbWorkers = 3;

const tasks = [

{ length: 10, nbWorkersNeeded: 3},

{ length: 20, nbWorkersNeeded: 2},

{ length: 15, nbWorkersNeeded: 1},

{ length: 30, nbWorkersNeeded: 2},

{ length: 20, nbWorkersNeeded: 1},

{ length: 25, nbWorkersNeeded: 2},

{ length: 10, nbWorkersNeeded: 1},

];

let model = new CP.Model;

// A set of pulses, one for each task:

let pulses: CP.CumulExpr[] = [];

// End times of the tasks:

let ends: CP.IntExpr[] = [];

for (let i = 0; i < tasks.length; i++) {

// Create a task:

let task = model.intervalVar({ name: "T" + (i+1), length: tasks[i].length} );

// Create a pulse for the task:

pulses.push(model.pulse(task, tasks[i].nbWorkersNeeded));

// Store the end of the task:

ends.push(task.end());

}

// The number of workers used at any time cannot exceed nbWorkers:

model.cumulLe(model.cumulSum(pulses), nbWorkers);

// Minimize the maximum of the ends (makespan):

model.minimize(model.max(ends));

let result = await CP.solve(model, { searchType: "FDS" });

`See`

- IntervalVar.pulse is equivalent function on IntervalVar.
- stepAtStart, stepAtEnd, stepAt for other basic cumulative functions.
- cumulLe and cumulGe for constraints on cumulative functions.

### sequenceVar

▸ **sequenceVar**(`intervals`

, `types?`

): `SequenceVar`

Creates a sequence variable from the provided set of interval variables.

#### Parameters

Name | Type | Description |
---|---|---|

`intervals` | `IntervalVar` [] | Interval variables that will form the sequence in the solution. |

`types?` | `number` [] | Types of the intervals, used in particular for transition times. |

#### Returns

`Remarks`

Sequence variable is used together with noOverlap constraint to model a set of intervals that cannot overlap and so they form a sequence in the solution. Sequence variable allows to further constrain this sequence, for example by specifying sequence-dependent minimum transition times between intervals.

Types can be used to mark intervals that have similar properties, in particular they behave the same from the point of view of transition times.
Interval variable `intervals[0]`

will have type `type[0]`

, `intervals[1]`

will have type `type[1]`

and so on.

If `types`

are not specified then `intervals[0]`

will have type 0, `intervals[1]`

will have type 1 and so on.

Length of the array `types`

must the same as the length of the array `intervals`

.

Types should be integer numbers in the range `0`

to `n-1`

where `n`

is the number of types.

`See`

- SequenceVar.noOverlap for an example of sequenceVar usage with transition times.
- SequenceVar
- Model.noOverlap

### setName

▸ **setName**(`name`

): `void`

Assigns a name to the model. It overwrites any name that was previously set, e.g. in the Model constructor.

Naming the model is optional. The main purpose of the name is to distinguish between different models during benchmarking (see benchmark).

#### Parameters

Name | Type |
---|---|

`name` | `string` |

#### Returns

`void`

### span

▸ **span**(`main`

, `covered`

): `void`

Constraints an interval variable to span (cover) a set of other interval variables.

#### Parameters

Name | Type | Description |
---|---|---|

`main` | `IntervalVar` | The spanning interval variable. |

`covered` | `IntervalVar` [] | The set of interval variables to cover. |

#### Returns

`void`

`Remarks`

Span constraint can be used to model, for example, a composite task that consists of several subtasks.

The constraint makes sure that interval variable `main`

starts with the first interval in `covered`

and ends with the last interval in `covered`

. Absent interval variables in `covered`

are ignored.

#### Formal definition

Span constraint is satisfied in one of the following two cases:

Interval variable

`main`

is absent and all interval variables in`covered`

are absent too.Interval variable

`main`

is present, at least on interval in`covered`

is present and:`main.start()`

is equal to the minimum of starting times of all present intervals in`covered`

.`main.end()`

is equal to the maximum of ending times of all present intervals in`covered`

.

`Example`

Lets consider composite task `T`

that consists of 3 subtasks `T1`

, `T2`

and `T3`

. Subtasks are independent, could be processed in any order and may overlap. However task T is blocking a particular location and no other task can be processed there. The location is blocked as soon as the first task from `T1`

, `T2`

, `T3`

starts and it remains blocked until the last one of them finishes.

`let model = new CP.Model;`

// Subtasks have known lengths:

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

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

let T3 = model.intervalVar({ name: "T3", length: 15 });

// The main task has unknown length though:

let T = model.intervalVar({ name: "T" });

// T spans/covers T1, T2 and T3:

model.span(T, [T1, T2, T3]);

// Tasks requiring the same location cannot overlap.

// Other tasks are not included in the example, therefore '...' below:

model.noOverlap([T, ...]);

`See`

IntervalVar.span is equivalent function on IntervalVar.

### startAtEnd

▸ **startAtEnd**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.startAtEnd is equivalent function on IntervalVar.
- constraint
- start, end
- eq

### startAtStart

▸ **startAtStart**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.startAtStart is equivalent function on IntervalVar.
- constraint
- start, end
- eq

### startBeforeEnd

▸ **startBeforeEnd**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.startBeforeEnd is equivalent function on IntervalVar.
- constraint
- start, end
- le

### startBeforeStart

▸ **startBeforeStart**(`predecessor`

, `successor`

, `delay?`

): `void`

Creates a precedence constraint between two interval variables.

#### Parameters

Name | Type | Default value |
---|---|---|

`predecessor` | `IntervalVar` | `undefined` |

`successor` | `IntervalVar` | `undefined` |

`delay` | `number` | `IntExpr` | `0` |

#### Returns

`void`

`Remarks`

Same as:

`model.constraint(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`

- IntervalVar.startBeforeStart is equivalent function on IntervalVar.
- constraint
- start, end
- le

### startOf

▸ **startOf**(`interval`

): `IntExpr`

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

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

#### Returns

`Remarks`

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

`Example`

In the following example we constraint interval variable `y`

to start after end of `y`

with a delay at least 10. In addition we constrain length of `x`

to be less or equal than length of `y`

.

`let model = new CP.Model;`

let x = model.intervalVar({ name: "x", ... });

let y = model.intervalVar({ name: "y", ... });

model.constraint(model.endOf(x).plus(10).le(model.startOf(y)));

model.constraint(model.lengthOf(x).le(model.lengthOf(y)));

When `x`

or `y`

is *absent* then value of both constraints above is *absent* and therefore they are satisfied.

`See`

- start is equivalent function on IntervalVar.
- Function startOr is a similar function that replaces value
*absent*by a constant.

### startOr

▸ **startOr**(`interval`

, `absentValue`

): `IntExpr`

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

.

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

`absentValue` | `number` |

#### Returns

`Remarks`

This function is equivalent to `startOf(interval).guard(absentValue)`

.

`See`

### stepAt

▸ **stepAt**(`x`

, `height`

): `CumulExpr`

Creates cumulative function (expression) that changes value at `x`

by the given `height`

.

#### Parameters

Name | Type |
---|---|

`x` | `number` |

`height` | `number` | `IntExpr` |

#### Returns

`Remarks`

Function stepAt is functionally the same as stepAtStart and stepAtEnd, but the time of the change is given by parameter `x`

instead of by start/end of an interval variable.

#### Formal definition

stepAt creates a cumulative function which has the value:

- 0 before
`x`

, `height`

after`x`

.

`See`

- stepAtStart, stepAtEnd for an example with
`stepAt`

. - cumulLe and cumulGe for constraints on cumulative functions.

### stepAtEnd

▸ **stepAtEnd**(`interval`

, `height`

): `CumulExpr`

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

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

`height` | `number` | `IntExpr` |

#### Returns

`Remarks`

Cumulative *step* functions could be used to model a resource that is consumed or produced and so its amount is changing over time. Example of such resource is a battery, an account balance, a stock of a product, etc.

A `stepAtEnd`

can be used to change the amount of such resource at the end of a given variable. The amount is changed by the given `height`

.

Cumulative steps could be combined together using cumulPlus, cumulMinus, cumulNeg and cumulSum. The minimum and the maximum height of a cumulative function can be constrained using cumulLe and cumulGe.

#### Formal definition

stepAtEnd creates a cumulative function which has the value:

`0`

before`interval.end()`

,`height`

after`interval.end()`

.

If `interval`

is *absent* then the created cumulative function is `0`

everywhere.

Combining *pulses* (pulse) and *steps* (stepAtStart, stepAtEnd, stepAt) is not supported yet.

`Example`

Lets consider a set of tasks. Each task either costs certain amount of money or makes some money. Money are consumed at the start of a task and produced at the end. We have an initial amount of money `initialMoney`

and we want to schedule the tasks so that we do not run out of money (i.e. the amount of money is always non-negative).

Tasks cannot overlap. Our goal is to find the shortest schedule possible.

`// The input data:`

const initialMoney = 100;

const tasks = [

{ length: 10, money: -150 },

{ length: 20, money: 40 },

{ length: 15, money: 20 },

{ length: 30, money: -10 },

{ length: 20, money: 30 },

{ length: 25, money: -20 },

{ length: 10, money: 10 },

{ length: 20, money: 50 },

];

let model = new CP.Model;

let taskVars: CP.IntervalVar[] = [];

// A set of steps, one for each task:

let steps: CP.CumulExpr[] = [];

for (let i = 0; i < tasks.length; i++) {

let interval = model.intervalVar({ name: "T" + (i+1), length: tasks[i].length} );

taskVars.push(interval);

if (tasks[i].money < 0) {

// Task costs some money:

steps.push(model.stepAtStart(interval, tasks[i].money));

} else {

// Tasks makes some money:

steps.push(model.stepAtEnd(interval, tasks[i].money));

}

}

// The initial money increases the cumul at time 0:

steps.push(model.stepAt(0, initialMoney));

// The money must be non-negative at any time:

model.cumulGe(model.cumulSum(steps), 0);

// Only one task at a time:

model.noOverlap(taskVars);

// Minimize the maximum of the ends (makespan):

model.max(taskVars.map(t => t.end())).minimize();

let result = await CP.solve(model, { searchType: "FDS"});

`See`

- IntervalVar.stepAtEnd is equivalent function on IntervalVar.
- stepAtStart, stepAt, pulse for other basic cumulative functions.
- cumulLe and cumulGe for constraints on cumulative functions.

### stepAtStart

▸ **stepAtStart**(`interval`

, `height`

): `CumulExpr`

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

#### Parameters

Name | Type |
---|---|

`interval` | `IntervalVar` |

`height` | `number` | `IntExpr` |

#### Returns

`Remarks`

Cumulative *step* functions could be used to model a resource that is consumed or produced and so its amount is changing over time. Example of such resource is a battery, an account balance, a stock of a product, etc.

A `stepAtStart`

can be used to change the amount of such resource at the start of a given variable. The amount is changed by the given `height`

.

Cumulative steps could be combined together using cumulPlus, cumulMinus, cumulNeg and cumulSum. The minimum and the maximum height of a cumulative function can be constrained using cumulLe and cumulGe.

#### Formal definition

stepAtStart creates a cumulative function which has the value:

`0`

before`interval.start()`

,`height`

after`interval.start()`

.

If `interval`

is *absent* then the created cumulative function is `0`

everywhere.

Combining *pulses* (pulse) and *steps* (stepAtStart, stepAtEnd, stepAt) is not supported yet.

`Example`

Lets consider a set of tasks. Each task either costs certain amount of money or makes some money. Money are consumed at the start of a task and produced at the end. We have an initial amount of money `initialMoney`

and we want to schedule the tasks so that we do not run out of money (i.e. the amount of money is always non-negative).

Tasks cannot overlap. Our goal is to find the shortest schedule possible.

`// The input data:`

const initialMoney = 100;

const tasks = [

{ length: 10, money: -150 },

{ length: 20, money: 40 },

{ length: 15, money: 20 },

{ length: 30, money: -10 },

{ length: 20, money: 30 },

{ length: 25, money: -20 },

{ length: 10, money: 10 },

{ length: 20, money: 50 },

];

let model = new CP.Model;

let taskVars: CP.IntervalVar[] = [];

// A set of steps, one for each task:

let steps: CP.CumulExpr[] = [];

for (let i = 0; i < tasks.length; i++) {

let interval = model.intervalVar({ name: "T" + (i+1), length: tasks[i].length} );

taskVars.push(interval);

if (tasks[i].money < 0) {

// Task costs some money:

steps.push(model.stepAtStart(interval, tasks[i].money));

} else {

// Tasks makes some money:

steps.push(model.stepAtEnd(interval, tasks[i].money));

}

}

// The initial money increases the cumul at time 0:

steps.push(model.stepAt(0, initialMoney));

// The money must be non-negative at any time:

model.cumulGe(model.cumulSum(steps), 0);

// Only one task at a time:

model.noOverlap(taskVars);

// Minimize the maximum of the ends (makespan):

model.max(taskVars.map(t => t.end())).minimize();

let result = await CP.solve(model, { searchType: "FDS"});

`See`

- IntervalVar.stepAtStart is equivalent function on IntervalVar.
- stepAtEnd, stepAt, pulse for other basic cumulative functions.
- cumulLe and cumulGe for constraints on cumulative functions.

### sum

▸ **sum**(`args`

): `IntExpr`

Creates in integer expression for the sum of the arguments.

#### Parameters

Name | Type |
---|---|

`args` | (`number` | `IntExpr` )[] |

#### Returns

`Remarks`

Absent arguments are ignored (treated as zeros). Therefore the resulting expression is never *absent*.

Note that binary function plus handles absent values differently. For example, when `x`

is *absent* then:

`plus(x, 3)`

is*absent*.`sum([x, 3])`

is 3.

`Example`

Let's consider a set of optional tasks. Due to limited resources and time, only some of them can be executed. Every task has a profit and we want to maximize the total profit of the executed tasks.

`// Lengths and profits of the tasks:`

const lengths = [10, 20, 15, 30, 20, 25, 30, 10, 20, 25];

const profits = [ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];

let model = new CP.Model;

let tasks: CP.IntervalVar[] = [];

// Profits of individual tasks. The value will be zero if the task is not executed.

let taskProfits: CP.IntExpr[] = [];

for (let i = 0; i < lengths.length; i++) {

// All tasks must finish before time 100:

let task = model.intervalVar({ name: "Task" + i, optional: true, length: lengths[i], end: [, 100]});

tasks.push(task);

taskProfits.push(model.times(task.presence(), profits[i]));

}

model.sum(taskProfits).maximize();

// Tasks cannot overlap:

model.noOverlap(tasks);

let result = await CP.solve(model, { searchType: "FDS" });

### times

▸ **times**(`arg1`

, `arg2`

): `IntExpr`

Creates a multiplication of the two integer expressions, i.e. `arg1 * arg2`

.

#### Parameters

Name | Type |
---|---|

`arg1` | `number` | `IntExpr` |

`arg2` | `number` | `IntExpr` |

#### Returns

`Remarks`

If one of the arguments has value *absent* then the resulting expression has also value *absent*.

Same as IntExpr.times.