The bridge between Tempo's two constraint networks.
Tempo.Network reasons metrically: dated periods, bounds like
"at least twenty years after", solved completely and in polynomial time
by shortest paths. Its relation vocabulary is convex, so it cannot
represent "before or after".
Tempo.Interval.RelationNetwork reasons qualitatively: relation
sets over undated periods, propagated by Allen's path consistency. It
represents disjunction, and is correspondingly incomplete.
Neither subsumes the other, and each can tighten the other:
Metric → qualitative. A solved metric network already excludes relations its bounds make impossible.
from_network/1reads those out as relation sets, giving the qualitative network a much tighter starting point than "all thirteen".Qualitative → metric. A relation set that has narrowed to a single relation is a convex constraint the metric network accepts.
apply_to_network/2feeds those back, where they may tighten dates that the metric constraints alone left loose.
refine/1 runs the round trip.
Example
Two periods whose order the dates leave open, plus the qualitative fact that they cannot overlap:
iex> alias Tempo.Network
iex> alias Tempo.Network.Qualitative
iex> network =
...> Network.new()
...> |> Network.add_period("dig", from: {:not_before, ~o"2020"}, to: {:not_after, ~o"2030"})
...> |> Network.add_period("survey", from: {:not_before, ~o"2020"}, to: {:not_after, ~o"2030"})
iex> qualitative = Qualitative.from_network(network)
iex> is_struct(qualitative, Tempo.Interval.RelationNetwork)
true
Summary
Functions
Add every determined qualitative relation to a metric network.
Read a metric network out as a qualitative one.
Run the round trip: read the metric network qualitatively, propagate, and feed back what propagation determined.
Functions
@spec apply_to_network(Tempo.Interval.RelationNetwork.t(), Tempo.Network.t()) :: Tempo.Network.t()
Add every determined qualitative relation to a metric network.
A relation set narrowed to exactly one relation is knowledge the metric network can use; a set with two or more still-possible relations is a disjunction it cannot represent, and is skipped.
Arguments
qualitativeis aTempo.Interval.RelationNetwork.t/0.networkis theTempo.Network.t/0to add constraints to.
Returns
- The updated
Tempo.Network.t/0.
Examples
iex> network =
...> Tempo.Network.new()
...> |> Tempo.Network.add_period(:a, from: ~o"2000", to: ~o"2005")
...> |> Tempo.Network.add_period(:b, from: ~o"2010", to: ~o"2015")
...> |> Tempo.Network.add_period(:c, [])
...> |> Tempo.Network.add_relation(:before, :b, :c)
iex> {:ok, propagated} =
...> network
...> |> Tempo.Network.Qualitative.from_network()
...> |> Tempo.Interval.RelationNetwork.propagate()
iex> refined = Tempo.Network.Qualitative.apply_to_network(propagated, network)
iex> Tempo.Network.Solver.relation(refined, :a, :c)
:precedes
@spec from_network(Tempo.Network.t()) :: Tempo.Interval.RelationNetwork.t() | {:error, :inconsistent | Exception.t()}
Read a metric network out as a qualitative one.
Every pair of periods is seeded with the relations the solved metric network still permits, so propagation starts from what the dates already prove rather than from the full thirteen.
Arguments
networkis aTempo.Network.t/0.
Returns
A
Tempo.Interval.RelationNetwork.t/0over the same period ids.{:error, :inconsistent}when the metric network has no solution, so there are no relations to read.{:error, reason}for an error the network's builders recorded.
Examples
iex> network =
...> Tempo.Network.new()
...> |> Tempo.Network.add_period(:a, from: ~o"2000", to: ~o"2005")
...> |> Tempo.Network.add_period(:b, from: ~o"2010", to: ~o"2015")
...> |> Tempo.Network.add_period(:c, [])
...> |> Tempo.Network.add_relation(:before, :b, :c)
iex> qualitative = Tempo.Network.Qualitative.from_network(network)
iex> Tempo.Interval.RelationNetwork.between(qualitative, :a, :b)
[:precedes]
@spec refine(Tempo.Network.t()) :: {:ok, Tempo.Network.t()} | {:error, :inconsistent | {:inconsistent, {term(), term()}} | Exception.t()}
Run the round trip: read the metric network qualitatively, propagate, and feed back what propagation determined.
This is where the two formalisms pay for each other. The metric bounds prune relations Allen's algebra alone would leave open; propagation then determines relations the bounds alone did not, and those become metric constraints that can tighten dates.
Arguments
networkis aTempo.Network.t/0.
Returns
{:ok, network}— the metric network with every qualitatively determined relation added.{:error, :inconsistent}when the metric network has no solution.{:error, {:inconsistent, pair}}when qualitative propagation finds a contradiction the metric solver did not.{:error, reason}for an error the network's builders recorded.
Examples
iex> network =
...> Tempo.Network.new()
...> |> Tempo.Network.add_period(:a, from: ~o"2000", to: ~o"2005")
...> |> Tempo.Network.add_period(:b, from: ~o"2010", to: ~o"2015")
...> |> Tempo.Network.add_period(:c, [])
...> |> Tempo.Network.add_relation(:before, :b, :c)
iex> {:ok, refined} = Tempo.Network.Qualitative.refine(network)
iex> Tempo.Network.Solver.relation(refined, :a, :c)
:precedes