[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/results/reason/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Reason

Why the planner placed a task where it did. It's read from [`Mutation.reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>), which the planner fills only when the call ran with `reasons = true` in [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md#reasons>) or [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/preview-options.md#reasons>). The planner creates the values; caller code only reads them.

## Declaration

```java
package org.dhtmlx.plen;

public abstract class Reason extends ValueRecord {
  public static class Asap extends Reason {
    public Id linkId;
    public Id sourceId;
    public Asap(Id linkId, Id sourceId)
  }

  public static class Alap extends Reason {
    public Id linkId;
    public Id targetId;
    public Alap(Id linkId, Id targetId)
  }

  public static class SummaryTranslation extends Reason {
    public Id summaryId;
    public SummaryTranslation(Id summaryId)
  }

  public static class Constraint extends Reason {}

  public static class Preferred extends Reason {}

  public Reason copy()
}
```

The five nested classes are the variants. Match a value with `instanceof` patterns, or with a `switch` over type patterns that ends in a `default` case. Variants compare by field values through `equals` and `hashCode`. `copy()` returns a shallow copy of the same variant.

## Variants

| Variant | Description |
|---|---|
| `Asap(linkId, sourceId)` | A predecessor pushed the task later. `linkId` is the driving link, `sourceId` the driving predecessor. |
| `Alap(linkId, targetId)` | A successor pulled the task earlier, in backward planning. `linkId` is the driving link, `targetId` the driving successor. |
| `SummaryTranslation(summaryId)` | The task moved together with its summary. `summaryId` is the summary that moved. |
| `Constraint` | The task's own constraint placed it. |
| `Preferred` | The task stayed at, or returned to, its own input date. |

[Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/java/scheduling/links-constraints-summaries.md>) covers how links, constraints and summaries decide a task's dates.

## Example

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class ReasonExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 1, 5, 8, 0);

    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("design")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("build")).withStartDate(monday).withDuration(3.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1"))
                .withSource(Id.str("design"))
                .withTarget(Id.str("build"))));

    ScheduleResult result = Engine.schedule(data, new SolveOptions().withReasons(true));

    for (Mutation update : result.updates) {
      String why;
      if (update.reason instanceof Reason.Asap r) {
        why = "pushed by " + r.sourceId + " through link " + r.linkId;
      } else if (update.reason instanceof Reason.Alap r) {
        why = "pulled by " + r.targetId + " through link " + r.linkId;
      } else if (update.reason instanceof Reason.SummaryTranslation r) {
        why = "moved with summary " + r.summaryId;
      } else if (update.reason instanceof Reason.Constraint) {
        why = "placed by its constraint";
      } else if (update.reason instanceof Reason.Preferred) {
        why = "kept at its own date";
      } else {
        why = "no reason recorded";
      }
      System.out.println(update.id + ": " + why);
      // build: pushed by design through link l1
    }
  }
}
```

## Related

- [`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) - the result entry that carries `reason`
- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md#reasons>) - turning reasons on
- [Reading results](<https://docs.dhtmlx.com/planning-engine/java/scheduling/reading-results.md#reasons>) - reading reasons from a result
- [Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/java/scheduling/links-constraints-summaries.md>) - the rules that place a task
