npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@toryt/allen

v0.8.2

Published

Reason and validate the relations between intervals, and points and intervals, in JavaScript and TypeScript.

Downloads

14

Readme

Allen

Validate and reason about relations between intervals, and between points and intervals, in JavaScript and TypeScript.

When working with intervals, we often want to express constraints (invariants) that limit acceptable combinations. Expressing this correctly proves difficult in practice. Falling back to working with isolated start and end points, and reasoning about their relations, in practice proves to be even much more difficult and error-prone. This problem was tackled in 1983 by James Allen:

Good synopses of this theory are

This library does not help with inference.

ppwcode dotnet-util-allen offers a C# version of the functionality of this library.

How to use

Example

JavaScript

const { AllenRelation, PointIntervalRelation } = require('@toryt/allen')

function allenRelationExample () {
  const iiCondition1 = AllenRelation.fromString('psSd')
  const iiCondition2 = AllenRelation.fromString('sde')
  const iiCondition = iiCondition1.compose(iiCondition2)

  const i1 = { start: '2022-11-04', end: '2023-04-12' }
  const i2 = { start: '2021-08-22' }

  const iiActual = AllenRelation.relation(i1, i2)
  if (!iiActual.implies(iiCondition)) {
    throw new Error(`i1 and i2 do no uphold ${iiCondition.toString()}`)
  }

  return iiActual
}

function pointIntervalExample () {
  const piCondition1 = PointIntervalRelation.or(PointIntervalRelation.BEFORE, PointIntervalRelation.TERMINATES)
  const iiCondition2 = AllenRelation.fromString('sde')
  const piCondition = piCondition1.compose(iiCondition2)

  const p = '2021-08-15'
  const i = { start: '2021-08-22' }

  const piActual = PointIntervalRelation.relation(p, i)
  if (!piActual.implies(piCondition)) {
    throw new Error(`p and i2 do not uphold ${piCondition.toString()}`)
  }

  return piActual
}

TypeScript

import { AllenRelation, Interval, PointIntervalRelation } from '@toryt/allen'

function allenRelationExample (): AllenRelation {
  const iiCondition1: AllenRelation = AllenRelation.fromString<AllenRelation>('psSd')
  const iiCondition2: AllenRelation = AllenRelation.fromString<AllenRelation>('sde')
  const iiCondition: AllenRelation = iiCondition1.compose(iiCondition2)

  const i1: Interval<string> = { start: '2022-11-04', end: '2023-04-12' }
  const i2: Interval<string> = { start: '2021-08-22' }

  const iiActual: AllenRelation = AllenRelation.relation(i1, i2)
  if (!iiActual.implies(iiCondition)) {
    throw new Error(`i1 and i2 do no uphold ${iiCondition.toString()}`)
  }

  return iiActual
}

function pointIntervalExample (): PointIntervalRelation {
  const piCondition1: PointIntervalRelation = PointIntervalRelation.or(
    PointIntervalRelation.BEFORE,
    PointIntervalRelation.TERMINATES
  )
  const iiCondition2: AllenRelation = AllenRelation.fromString<AllenRelation>('sde')
  const piCondition: PointIntervalRelation = piCondition1.compose(iiCondition2)

  const p: string = '2021-08-15'
  const i: Interval<string> = { start: '2021-08-22' }

  const piActual: PointIntervalRelation = PointIntervalRelation.relation(p, i)
  if (!piActual.implies(piCondition)) {
    throw new Error(`p and i2 do not uphold ${piCondition.toString()}`)
  }

  return piActual
}

Algebra

We find that there are 5 basic relations possible between a definite point and a definite interval:

  • t is BEFORE I (b)

    before

  • t COMMENCES I (c)

    begins

  • t IN I (i)

    in

  • t TERMINATESI(t`)

    ends

  • t is AFTER I (a)

    after

and that there are 13 basic relations possible between definite intervals:

| Basic relation | (.) | Illustration | | -------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------- | | i1 precedes i2 | (p) | precedes | | i1 meets i2 | (m) | meets | | i1 overlaps i2 | (o) | overlaps | | i1 is finished by i2 | (F) | is finished by | | i1 contains i2 | (D) | contains | | i1 starts i2 | (s) | starts | | i1 equals i2 | (e) | equals | | i1 is started by i2 | (S) | is started by | | i1 during i2 | (d) | during | | i1 finishes i2 | (f) | finishes | | i1 is overlapped by i2 | (O) | is overlapped by | | i1 is met by i2 | (M) | is met by | | i1 is preceded by i2 | (P) | is preceded by |

These 5, respectively 13, basic relations are an orthogonal basis for all possible general relation-conditions between a point and an interval (PointIntervalRelation), respectively between two intervals (AllenRelation).

(bt) says that a point can be before an interval, or terminate it. (sde) says that an interval i1 may start an interval i2, may be during i2, or be equal to it. Each general relation expresses a certain amount of uncertainty, where a basic relation expresses certainty, and the FULL relation ( (bcita), respectively (pmoFDseSdfOMP)) expresses complete uncertainty.

These 32 (25), respectively 8192 (213), general relations form an algebra, with the operations

  • complement
  • converse (only for AllenRelation)
  • min
  • or
  • and
  • compose

A relation to be used as a condition to the problem at hand is build using these operations.

A relation implies another relation, or not. E.g., if we have determined that a relation between i1 and i2 is (oO), and we need it to be (pmoOMP), this is ok because (oO) implies (pmoOMP). If the relation is (oeO) however, it is not ok, because (pmoOMP) does not allow the intervals to be equal.

Things get even more interesting when we need to reason about indefinite intervals, where the start or end is unknown 🤷.

There are some pitfalls.

Details

All functions and methods are protected with explicit asserts, that throw when a precondition is violated. Although written in TypeScript, types are verified dynamically too, so that type safety is ensured dynamically when the library is used with plain JavaScript too.

Where to find

Repo, CI, issues, pull requests This project is maintained in Bitbucket (repo, CI, issues, pull requests, …).

npm

@toryt/allen

Style

JavaScript Style Guide

This code uses the application to TypeScript of the Standard coding style. Tests require complete code coverage.

License

Released under the Apache License, Version 2.0.

Notes

This code was based on a Java implementation last updated in December 2008.