# `Tempo.Allen`
[🔗](https://github.com/elixir-tempo/tempo/blob/v2.1.0/lib/tempo/core/allen.ex#L1)

Allen's thirteen relations between two spans, their inverses and their
composition, and the everyday predicates as sets of them.

A span is `[from, to)`. The relation of two spans is read from four
comparisons, start against start, end against end, the first's end against
the second's start and the first's start against the second's end
(`relation/2`); every pair of spans stands in exactly one relation. The
composition table is derived from the classifier when this module compiles,
so the two cannot disagree. The everyday predicates (`before?/2`, `within?/2`,
...) are the sets of relations `Tempo.before?/2` and its companions answer
by for two single spans.

# `predicate`

```elixir
@type predicate() ::
  :before
  | :after
  | :adjacent
  | :within
  | :contains
  | :disjoint
  | :overlaps
  | :equal
```

# `relation`

```elixir
@type relation() ::
  :precedes
  | :meets
  | :overlaps
  | :finished_by
  | :contains
  | :starts
  | :equals
  | :started_by
  | :during
  | :finishes
  | :overlapped_by
  | :met_by
  | :preceded_by
```

# `span`

```elixir
@type span() :: {integer(), integer()}
```

A span as two positions on one frame, `{from, to}`, half-open.

# `compose`

```elixir
@spec compose(relation(), relation()) :: [relation(), ...]
```

The composition of two relations: the relations a first span may stand in
to a third, given its relation to a second and the second's to the third.

### Arguments

* `first` is the `t:relation/0` of the first span to the second.

* `second` is the `t:relation/0` of the second span to the third.

### Returns

* The `t:relation/0` atoms the first span may stand in to the third, in
  Allen's order.

### Examples

    iex> Tempo.Allen.compose(:precedes, :precedes)
    [:precedes]

    iex> Tempo.Allen.compose(:equals, :during)
    [:during]

    iex> Tempo.Allen.compose(:overlaps, :overlaps)
    [:precedes, :meets, :overlaps]

# `contains?`

```elixir
@spec contains?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span contains the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:contains`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.contains?({1, 5}, {2, 3})
    true

# `during?`

```elixir
@spec during?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span during the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:during`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.during?({2, 3}, {1, 5})
    true

# `equals?`

```elixir
@spec equals?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span equals the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:equals`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.equals?({1, 3}, {1, 3})
    true

# `finished_by?`

```elixir
@spec finished_by?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span finished by the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:finished_by`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.finished_by?({1, 5}, {3, 5})
    true

# `finishes?`

```elixir
@spec finishes?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span finishes the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:finishes`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.finishes?({3, 5}, {1, 5})
    true

# `holds?`

```elixir
@spec holds?(predicate() | relation(), span() | Tempo.t(), span() | Tempo.t()) ::
  boolean()
```

Whether a predicate or a relation holds between two spans.

### Arguments

* `name` is a `t:predicate/0` or a `t:relation/0`.

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is one the name stands for, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.holds?(:before, {1, 3}, {3, 5})
    true

    iex> Tempo.Allen.holds?(:precedes, {1, 3}, {3, 5})
    false

# `inverse`

```elixir
@spec inverse(relation()) :: relation()
```

The inverse of a relation: the relation of the second span to the first.

### Arguments

* `relation` is a `t:relation/0`.

### Returns

* The `t:relation/0` the second span stands in to the first.

### Examples

    iex> Tempo.Allen.inverse(:precedes)
    :preceded_by

    iex> Tempo.Allen.inverse(:equals)
    :equals

# `meets?`

```elixir
@spec meets?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span meets the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:meets`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.meets?({1, 3}, {3, 5})
    true

# `met_by?`

```elixir
@spec met_by?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span met by the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:met_by`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.met_by?({3, 5}, {1, 3})
    true

# `overlapped_by?`

```elixir
@spec overlapped_by?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span overlapped by the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:overlapped_by`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.overlapped_by?({3, 6}, {1, 4})
    true

# `overlaps?`

```elixir
@spec overlaps?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span overlaps the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:overlaps`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.overlaps?({1, 4}, {3, 6})
    true

# `preceded_by?`

```elixir
@spec preceded_by?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span preceded by the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:preceded_by`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.preceded_by?({3, 4}, {1, 2})
    true

# `precedes?`

```elixir
@spec precedes?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span precedes the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:precedes`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.precedes?({1, 2}, {3, 4})
    true

# `predicate`

```elixir
@spec predicate(predicate() | relation()) :: [relation(), ...]
```

The relations an everyday predicate stands for.

### Arguments

* `name` is a `t:predicate/0`, or a `t:relation/0`, which stands for
  itself.

### Returns

* The `t:relation/0` atoms the predicate holds for.

### Examples

    iex> Tempo.Allen.predicate(:within)
    [:equals, :starts, :during, :finishes]

    iex> Tempo.Allen.predicate(:meets)
    [:meets]

# `predicates`

```elixir
@spec predicates() :: [predicate(), ...]
```

The everyday predicates: `:before`, `:after`, `:adjacent`, `:within`,
`:contains`, `:disjoint`, `:overlaps` and `:equal`.

### Returns

* A list of the `t:predicate/0` atoms.

### Examples

    iex> :within in Tempo.Allen.predicates()
    true

# `relation`

```elixir
@spec relation(span() | Tempo.t(), span() | Tempo.t()) :: relation()
```

The relation of one span to another, from four comparisons.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0` of two positions on one frame.

### Returns

* One of the thirteen `t:relation/0` atoms. For two expressions it is
  what `Tempo.relation/2` answers, and the error that would return is
  raised; a value that is neither an expression nor a span raises a
  `Tempo.ConversionError`.

### Examples

    iex> Tempo.Allen.relation(~o"2026-01", ~o"2026-02")
    :meets

    iex> Tempo.Allen.relation({1, 3}, {3, 5})
    :meets

    iex> Tempo.Allen.relation({1, 5}, {2, 3})
    :contains

    iex> Tempo.Allen.relation({2, 3}, {1, 5})
    :during

# `relations`

```elixir
@spec relations() :: [relation(), ...]
```

The thirteen relations, in Allen's order.

### Returns

* A list of the thirteen `t:relation/0` atoms.

### Examples

    iex> length(Tempo.Allen.relations())
    13

    iex> hd(Tempo.Allen.relations())
    :precedes

# `started_by?`

```elixir
@spec started_by?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span started by the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:started_by`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.started_by?({1, 5}, {1, 3})
    true

# `starts?`

```elixir
@spec starts?(span() | Tempo.t(), span() | Tempo.t()) :: boolean()
```

Whether the first span starts the
second, under Allen's own name.

### Arguments

* `a` and `b` are each a `t:Tempo.t/0` that names one span, or each a
  `t:span/0`, as for `relation/2`.

### Returns

* `true` when the relation of `a` to `b` is `:starts`, and
  `false` when it is not.

### Examples

    iex> Tempo.Allen.starts?({1, 3}, {1, 5})
    true

---

*Consult [api-reference.md](api-reference.md) for complete listing*
