cql-execution
Version:
An execution framework for the Clinical Quality Language (CQL)
334 lines (300 loc) • 11.9 kB
JavaScript
// Generated by CoffeeScript 1.9.3
(function() {
var DateTime, Interval, ThreeValuedLogic, Uncertainty, cmp, maxValueForInstance, minValueForInstance, predecessor, ref, successor;
DateTime = require('./datetime').DateTime;
Uncertainty = require('./uncertainty').Uncertainty;
ThreeValuedLogic = require('./logic').ThreeValuedLogic;
ref = require('../util/math'), successor = ref.successor, predecessor = ref.predecessor, maxValueForInstance = ref.maxValueForInstance, minValueForInstance = ref.minValueForInstance;
cmp = require('../util/comparison');
module.exports.Interval = Interval = (function() {
var areDateTimes, areNumeric, highestNumericUncertainty, lowestNumericUncertainty;
function Interval(low1, high1, lowClosed, highClosed) {
this.low = low1;
this.high = high1;
this.lowClosed = lowClosed != null ? lowClosed : true;
this.highClosed = highClosed != null ? highClosed : true;
}
Interval.prototype.contains = function(item) {
var closed;
if (item instanceof Interval) {
throw new Error("Argument to contains must be a point");
}
closed = this.toClosed();
return ThreeValuedLogic.and(cmp.lessThanOrEquals(closed.low, item), cmp.greaterThanOrEquals(closed.high, item));
};
Interval.prototype.properlyIncludes = function(other) {
if (!(other instanceof Interval)) {
throw new Error("Argument to properlyIncludes must be an interval");
}
return ThreeValuedLogic.and(this.includes(other), ThreeValuedLogic.not(cmp.equals(this, other)));
};
Interval.prototype.includes = function(other) {
var a, b;
if (!(other instanceof Interval)) {
throw new Error("Argument to includes must be an interval");
}
a = this.toClosed();
b = other.toClosed();
return ThreeValuedLogic.and(cmp.lessThanOrEquals(a.low, b.low), cmp.greaterThanOrEquals(a.high, b.high));
};
Interval.prototype.includedIn = function(other) {
if (!(other instanceof Interval)) {
throw new Error("Argument to includedIn must be an interval");
}
return other.includes(this);
};
Interval.prototype.overlaps = function(item) {
var closed, high, itemClosed, low, ref1;
closed = this.toClosed();
ref1 = item instanceof Interval ? (itemClosed = item.toClosed(), [itemClosed.low, itemClosed.high]) : [item, item], low = ref1[0], high = ref1[1];
return ThreeValuedLogic.and(cmp.lessThanOrEquals(closed.low, high), cmp.greaterThanOrEquals(closed.high, low));
};
Interval.prototype.overlapsAfter = function(item) {
var closed, high;
closed = this.toClosed();
high = item instanceof Interval ? item.toClosed().high : item;
return ThreeValuedLogic.and(cmp.lessThanOrEquals(closed.low, high), cmp.greaterThan(closed.high, high));
};
Interval.prototype.overlapsBefore = function(item) {
var closed, low;
closed = this.toClosed();
low = item instanceof Interval ? item.toClosed().low : item;
return ThreeValuedLogic.and(cmp.lessThan(closed.low, low), cmp.greaterThanOrEquals(closed.high, low));
};
areDateTimes = function(x, y) {
return [x, y].every(function(z) {
return z instanceof DateTime;
});
};
areNumeric = function(x, y) {
return [x, y].every(function(z) {
return typeof z === 'number' || (z instanceof Uncertainty && typeof z.low === 'number');
});
};
lowestNumericUncertainty = function(x, y) {
var high, low;
if (!(x instanceof Uncertainty)) {
x = new Uncertainty(x);
}
if (!(y instanceof Uncertainty)) {
y = new Uncertainty(y);
}
low = x.low < y.low ? x.low : y.low;
high = x.high < y.high ? x.high : y.high;
if (low !== high) {
return new Uncertainty(low, high);
} else {
return low;
}
};
highestNumericUncertainty = function(x, y) {
var high, low;
if (!(x instanceof Uncertainty)) {
x = new Uncertainty(x);
}
if (!(y instanceof Uncertainty)) {
y = new Uncertainty(y);
}
low = x.low > y.low ? x.low : y.low;
high = x.high > y.high ? x.high : y.high;
if (low !== high) {
return new Uncertainty(low, high);
} else {
return low;
}
};
Interval.prototype.union = function(other) {
var a, b, h, hc, l, lc, ref1, ref2, ref3;
if (!(other instanceof Interval)) {
throw new Error("Argument to union must be an interval");
}
if (this.overlaps(other) || this.meets(other)) {
ref1 = [this.toClosed(), other.toClosed()], a = ref1[0], b = ref1[1];
ref2 = (function() {
switch (false) {
case !cmp.lessThanOrEquals(a.low, b.low):
return [this.low, this.lowClosed];
case !cmp.greaterThanOrEquals(a.low, b.low):
return [other.low, other.lowClosed];
case !areNumeric(a.low, b.low):
return [lowestNumericUncertainty(a.low, b.low), true];
case !(areDateTimes(a.low, b.low) && a.low.isMorePrecise(b.low)):
return [other.low, other.lowClosed];
default:
return [this.low, this.lowClosed];
}
}).call(this), l = ref2[0], lc = ref2[1];
ref3 = (function() {
switch (false) {
case !cmp.greaterThanOrEquals(a.high, b.high):
return [this.high, this.highClosed];
case !cmp.lessThanOrEquals(a.high, b.high):
return [other.high, other.highClosed];
case !areNumeric(a.low, b.low):
return [highestNumericUncertainty(a.high, b.high), true];
case !(areDateTimes(a.high, b.high) && a.high.isMorePrecise(b.high)):
return [other.high, other.highClosed];
default:
return [this.high, this.highClosed];
}
}).call(this), h = ref3[0], hc = ref3[1];
return new Interval(l, h, lc, hc);
} else {
return null;
}
};
Interval.prototype.intersect = function(other) {
var a, b, h, hc, l, lc, ref1, ref2, ref3;
if (!(other instanceof Interval)) {
throw new Error("Argument to union must be an interval");
}
if (this.overlaps(other)) {
ref1 = [this.toClosed(), other.toClosed()], a = ref1[0], b = ref1[1];
ref2 = (function() {
switch (false) {
case !cmp.greaterThanOrEquals(a.low, b.low):
return [this.low, this.lowClosed];
case !cmp.lessThanOrEquals(a.low, b.low):
return [other.low, other.lowClosed];
case !areNumeric(a.low, b.low):
return [highestNumericUncertainty(a.low, b.low), true];
case !(areDateTimes(a.low, b.low) && b.low.isMorePrecise(a.low)):
return [other.low, other.lowClosed];
default:
return [this.low, this.lowClosed];
}
}).call(this), l = ref2[0], lc = ref2[1];
ref3 = (function() {
switch (false) {
case !cmp.lessThanOrEquals(a.high, b.high):
return [this.high, this.highClosed];
case !cmp.greaterThanOrEquals(a.high, b.high):
return [other.high, other.highClosed];
case !areNumeric(a.low, b.low):
return [lowestNumericUncertainty(a.high, b.high), true];
case !(areDateTimes(a.high, b.high) && b.high.isMorePrecise(a.high)):
return [other.high, other.highClosed];
default:
return [this.high, this.highClosed];
}
}).call(this), h = ref3[0], hc = ref3[1];
return new Interval(l, h, lc, hc);
} else {
return null;
}
};
Interval.prototype.except = function(other) {
var ol, ola, olb;
if (other === null) {
return null;
}
if (!(other instanceof Interval)) {
throw new Error("Argument to except must be an interval");
}
ol = this.overlaps(other);
if (ol === true) {
olb = this.overlapsBefore(other);
ola = this.overlapsAfter(other);
if (olb === true && ola === false) {
return new Interval(this.low, other.low, this.lowClosed, !other.lowClosed);
} else if (ola === true && olb === false) {
return new Interval(other.high, this.high, !other.highClosed, this.highClosed);
} else {
return null;
}
} else if (ol === false) {
return this;
} else {
return null;
}
};
Interval.prototype.equals = function(other) {
var a, b, ref1;
if (other instanceof Interval) {
ref1 = [this.toClosed(), other.toClosed()], a = ref1[0], b = ref1[1];
return ThreeValuedLogic.and(cmp.equals(a.low, b.low), cmp.equals(a.high, b.high));
} else {
return false;
}
};
Interval.prototype.after = function(other) {
var closed, otherClosed;
closed = this.toClosed();
otherClosed = other.toClosed();
return cmp.greaterThan(closed.low, otherClosed.high);
};
Interval.prototype.before = function(other) {
var closed, otherClosed;
closed = this.toClosed();
otherClosed = other.toClosed();
return cmp.lessThan(closed.high, otherClosed.low);
};
Interval.prototype.meets = function(other) {
return ThreeValuedLogic.or(this.meetsBefore(other), this.meetsAfter(other));
};
Interval.prototype.meetsAfter = function(other) {
try {
return cmp.equals(this.toClosed().low, successor(other.toClosed().high));
} catch (_error) {
return false;
}
};
Interval.prototype.meetsBefore = function(other) {
try {
return cmp.equals(this.toClosed().high, predecessor(other.toClosed().low));
} catch (_error) {
return false;
}
};
Interval.prototype.width = function() {
var closed, diff;
if (this.low instanceof DateTime || this.high instanceof DateTime) {
throw new Error("Width of DateTime intervals is not supported");
}
closed = this.toClosed();
if (closed.low instanceof Uncertainty || closed.high instanceof Uncertainty) {
return null;
} else {
diff = Math.abs(closed.high - closed.low);
return Math.round(diff * Math.pow(10, 8)) / Math.pow(10, 8);
}
};
Interval.prototype.toClosed = function() {
var high, low, point, ref1;
point = (ref1 = this.low) != null ? ref1 : this.high;
if (typeof point === 'number' || point instanceof DateTime) {
low = (function() {
switch (false) {
case !(this.lowClosed && (this.low == null)):
return minValueForInstance(point);
case !(!this.lowClosed && (this.low != null)):
return successor(this.low);
default:
return this.low;
}
}).call(this);
high = (function() {
switch (false) {
case !(this.highClosed && (this.high == null)):
return maxValueForInstance(point);
case !(!this.highClosed && (this.high != null)):
return predecessor(this.high);
default:
return this.high;
}
}).call(this);
if (low == null) {
low = new Uncertainty(minValueForInstance(point), high);
}
if (high == null) {
high = new Uncertainty(low, maxValueForInstance(point));
}
return new Interval(low, high, true, true);
} else {
return new Interval(this.low, this.high, true, true);
}
};
return Interval;
})();
}).call(this);
//# sourceMappingURL=interval.js.map