Feel.Analysis.MomentTests (feel v0.1.0)

Copy Markdown View Source

What a comparison of a time or a date and time says of the values, as sets of their images (D-109).

The run compares two of them (Feel.Runtime.Temporal.compare/3) by their clocks when either has no zone, and by their instants when both have one, at the second. A set has the three lines of Feel.Type.Moment (the clock of the values with no zone, and the instant and the clock of those with a zone), and ? < y is, for the pairs of classes that ? and y can be of:

? isy is? < y is true for
no zoneno zonea clock before that of y
no zonea zonea clock before the clock of y
a zoneno zonea zoned clock before the clock of y (its instant follows, within the largest offset)
a zonea zonean instant before that of y (its zoned clock follows, within the largest offset)

So the sets are exact for the class that y is, whichever ? is. The set of the values for which a comparison can be true and the set for which it can be false are not each other's complement: a value 10 hours either side of y can be either, when y may or may not have a zone. Feel.Analysis.TestSets reads both, as it does for a number, for the narrowing of a name (Feel.Analysis.Narrowing) and for the allowed values of a variable.

Two sets are compared in the same way by decide/3, which says whether a comparison is true for every pair, false for every pair, or for some.

iex> alias Feel.Type.{Moment, NumberSet}
iex> {:ok, date_time} = Feel.Value.DateTime.parse("2021-01-01T00:00:00")
iex> {:ok, images} = Moment.images(date_time)
iex> other = Enum.reduce(Enum.map(images, &NumberSet.point/1), &NumberSet.union/2)
iex> {before, _} = Feel.Analysis.MomentTests.compared(:date_and_time, :lt, other, false, true)
iex> Moment.format_member(:date_and_time, before)
"in [-999999999-01-01T00:00:00..2021-01-01T00:00:00) any zone"

Summary

Functions

Returns {where? operator othercan be true, where it can be false} for a kind of moments, given the images that other can be (numbers), whether it can be null, and whether it is one member of its type (a single value, if the set says one).

Whether left operator right is true for every pair of images of the two sets (:always), false for every pair (:never), or for some (:unknown). The images are compared as the run compares the values: the clocks of two with no zone, the clock of one with no zone and the clock of one with a zone, and the instants of two with one.

Functions

compared(kind, operator, numbers, null?, one?)

Returns {where? operator othercan be true, where it can be false} for a kind of moments, given the images that other can be (numbers), whether it can be null, and whether it is one member of its type (a single value, if the set says one).

Both are supersets of the images for which the comparison is true and false, in the form of the kind (Feel.Type.Moment.normalize/2).

decide(operator, left, right)

@spec decide(atom(), Feel.Type.NumberSet.t(), Feel.Type.NumberSet.t()) ::
  :always | :never | :unknown

Whether left operator right is true for every pair of images of the two sets (:always), false for every pair (:never), or for some (:unknown). The images are compared as the run compares the values: the clocks of two with no zone, the clock of one with no zone and the clock of one with a zone, and the instants of two with one.

iex> alias Feel.Type.NumberSet
iex> a = NumberSet.interval(Decimal.new(0), Decimal.new(10))
iex> b = NumberSet.interval(Decimal.new(100), Decimal.new(110))
iex> Feel.Analysis.MomentTests.decide(:lt, a, b)
:always
iex> Feel.Analysis.MomentTests.decide(:gt, a, b)
:never