diff options
-rw-r--r-- | interval.c | 82 | ||||
-rw-r--r-- | interval.h | 16 | ||||
-rw-r--r-- | mkfile | 7 | ||||
-rw-r--r-- | readme.md | 3 | ||||
-rw-r--r-- | test.c | 41 |
5 files changed, 149 insertions, 0 deletions
diff --git a/interval.c b/interval.c new file mode 100644 index 0000000..df9c14c --- /dev/null +++ b/interval.c @@ -0,0 +1,82 @@ +/* + * for reference: + * - James F. Allen, Maintaining Knowledge about Temporal Intervals, CACM November 1983, Vol. 26, No. 11 + * - https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6188649/ + */ +#include <u.h> +#include <libc.h> +#include "interval.h" + +static int +interval_before(Interval *i, Interval *ii) +{ + return i->t1 < ii->t0; +} + +static int +interval_equals(Interval *i, Interval *ii) +{ + return i->t0 == ii->t0 && + i->t1 == ii->t1; +} + +static int +interval_overlaps(Interval *i, Interval *ii) +{ + return i->t0 < ii->t0 && + i->t1 > ii->t0 && + i->t1 < ii->t1; +} + +static int +interval_meets(Interval *i, Interval *ii) +{ + return i->t1 == ii->t0; +} + +static int +interval_during(Interval *i, Interval *ii) +{ + return (i->t0 > ii->t0 && i->t1 <= ii->t1) || + (i->t0 >= ii->t0 && i->t1 < ii->t1); +} + +static int +interval_intersects(Interval *i, Interval *ii) +{ + return i->equals(i, ii) || + i->overlaps(i, ii) || + ii->overlaps(ii, i) || + i->during(i, ii) || + ii->during(ii, i); +} + +Interval * +mkinterval(uvlong t0, uvlong t1) +{ + Interval *i; + + assert(t0 <= t1); + + i = malloc(sizeof(Interval)); + if(i == nil) + sysfatal("mkinterval: %r"); + + i->t0 = t0; + i->t1 = t1; + i->∆t = t1-t0; + i->before = interval_before; + i->equals = interval_equals; + i->overlaps = interval_overlaps; + i->meets = interval_meets; + i->during = interval_during; + i->intersects = interval_intersects; + + return i; +} + +void +rminterval(Interval *i) +{ + free(i); +} diff --git a/interval.h b/interval.h new file mode 100644 index 0000000..e4a799e --- /dev/null +++ b/interval.h @@ -0,0 +1,16 @@ +typedef struct Interval Interval; +struct Interval +{ + uvlong t0, t1; + uvlong ∆t; /* duration */ + + int (*before)(Interval*, Interval*); + int (*equals)(Interval*, Interval*); + int (*overlaps)(Interval*, Interval*); + int (*meets)(Interval*, Interval*); + int (*during)(Interval*, Interval*); + int (*intersects)(Interval*, Interval*); +}; + +Interval *mkinterval(uvlong, uvlong); +void rminterval(Interval*); @@ -0,0 +1,7 @@ +</$objtype/mkfile + +LIB=libinterval.a$O +OFILES=interval.$O +HFILES=interval.h + +</sys/src/cmd/mklib diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..df2e81b --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# libinterval + +Implementation of the ideas published in James F. Allen, Maintaining Knowledge about Temporal Intervals, CACM November 1983, Vol. 26, No. 11. @@ -0,0 +1,41 @@ +#include <u.h> +#include <libc.h> +#include "interval.h" + +char * +yn(int n) +{ + return n == 0? "no": "yes"; +} + +void +usage(void) +{ + fprint(2, "usage: %s\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Interval *a, *b; + + ARGBEGIN{ + default: usage(); + }ARGEND; + if(argc != 0) + usage(); + + a = mkinterval(20, 30); + b = mkinterval(25, 60); + print("a before b:\t%s\n", yn(a->before(a, b))); + print("a equals b:\t%s\n", yn(a->equals(a, b))); + print("a overlaps b:\t%s\n", yn(a->overlaps(a, b))); + print("a meets b:\t%s\n", yn(a->meets(a, b))); + print("a during b:\t%s\n", yn(a->during(a, b))); + print("a intersects b:\t%s\n", yn(a->intersects(a, b))); + rminterval(a); + rminterval(b); + + exits(nil); +} |