More gestalt support
This commit is contained in:
parent
202a6e129b
commit
74acc78aab
173
route.js
173
route.js
|
@ -206,6 +206,12 @@ function Routing(exports) {
|
|||
return s;
|
||||
}
|
||||
|
||||
function setToArray(s) {
|
||||
var r = [];
|
||||
for (var k in s) r.push(s[k]);
|
||||
return r;
|
||||
}
|
||||
|
||||
function setUnion(s1, s2) {
|
||||
var s = {};
|
||||
setUnionInplace(s, s1);
|
||||
|
@ -1013,6 +1019,24 @@ function Routing(exports) {
|
|||
this.advertisements = advs;
|
||||
}
|
||||
|
||||
GestaltLevel.prototype.isEmpty = function () {
|
||||
return is_emptyMatcher(this.subscriptions) && is_emptyMatcher(this.advertisements);
|
||||
};
|
||||
|
||||
function straightGestaltLevelOp(op) {
|
||||
return function (p1, p2) {
|
||||
return new GestaltLevel(op(p1.subscriptions, p2.subscriptions),
|
||||
op(p1.advertisements, p2.advertisements));
|
||||
};
|
||||
};
|
||||
|
||||
function crossedGestaltLevelOp(op) {
|
||||
return function (p1, p2) {
|
||||
return new GestaltLevel(op(p1.subscriptions, p2.advertisements),
|
||||
op(p2.subscriptions, p1.advertisements));
|
||||
};
|
||||
};
|
||||
|
||||
var emptyLevel = new GestaltLevel(emptyMatcher, emptyMatcher);
|
||||
var emptyMetaLevel = [];
|
||||
|
||||
|
@ -1035,7 +1059,7 @@ function Routing(exports) {
|
|||
var matcher = (isFeedback ? levels[i].advertisements : levels[i].subscriptions);
|
||||
setUnionInplace(pids, matchValue(matcher, body));
|
||||
}
|
||||
return pids;
|
||||
return setToArray(pids);
|
||||
};
|
||||
|
||||
Gestalt.prototype.project = function (metaLevel, level, getAdvertisements, spec) {
|
||||
|
@ -1056,7 +1080,7 @@ function Routing(exports) {
|
|||
return new Gestalt(mls);
|
||||
};
|
||||
|
||||
function simpleGestalt(isAdv, pat, level, metaLevel) {
|
||||
function simpleGestalt(isAdv, pat, metaLevel, level) {
|
||||
var matcher = compilePattern(true, pat);
|
||||
var l = new GestaltLevel(isAdv ? emptyMatcher : matcher,
|
||||
isAdv ? matcher : emptyMatcher);
|
||||
|
@ -1080,6 +1104,146 @@ function Routing(exports) {
|
|||
return true;
|
||||
};
|
||||
|
||||
Gestalt.prototype.mapZip = function (other, lengthCombiner, f,
|
||||
levelsTransformer1, levelsTransformer2)
|
||||
{
|
||||
var metaLevels = [];
|
||||
var mls1 = this.metaLevels;
|
||||
var mls2 = other.metaLevels;
|
||||
var nm = lengthCombiner(mls1.length, mls2.length);
|
||||
for (var i = 0; i < nm; i++) {
|
||||
var levels = [];
|
||||
var ls1 = mls1[i] || emptyMetaLevel;
|
||||
var ls2 = mls2[i] || emptyMetaLevel;
|
||||
if (levelsTransformer1) ls1 = levelsTransformer1(ls1);
|
||||
if (levelsTransformer2) ls2 = levelsTransformer2(ls2);
|
||||
var nl = lengthCombiner(ls1.length, ls2.length);
|
||||
for (var j = 0; j < nl; j++) {
|
||||
var p1 = ls1[j] || emptyLevel;
|
||||
var p2 = ls2[j] || emptyLevel;
|
||||
var p = f(p1, p2);
|
||||
if (!p.isEmpty()) {
|
||||
while (levels.length < j) levels.push(emptyLevel);
|
||||
levels.push(p);
|
||||
}
|
||||
}
|
||||
if (levels.length > 0) {
|
||||
while (metaLevels.length < i) metaLevels.push(emptyMetaLevel);
|
||||
metaLevels.push(levels);
|
||||
}
|
||||
}
|
||||
return new Gestalt(metaLevels);
|
||||
};
|
||||
|
||||
Gestalt.prototype.union1 = function (other) {
|
||||
return this.mapZip(other, Math.max, straightGestaltLevelOp(union));
|
||||
};
|
||||
|
||||
Gestalt.prototype.union = function () {
|
||||
var acc = this;
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
acc = acc.union1(arguments[i]);
|
||||
}
|
||||
return acc;
|
||||
};
|
||||
|
||||
// Returns ls, with one level dropped, and with the remaining
|
||||
// matchers "smeared" across lower levels. This could end up being
|
||||
// reasonably expensive - possibly cache it?
|
||||
function smearLevels(levels) {
|
||||
var result = shallowCopyArray(levels);
|
||||
for (var i = result.length - 2; i >= 0; i--) {
|
||||
result[i].subscriptions = union(result[i].subscriptions, result[i+1].subscriptions);
|
||||
result[i].advertisements = union(result[i].advertisements, result[i+1].advertisements);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
Gestalt.prototype.filter = function (perspective) {
|
||||
return this.mapZip(perspective, Math.min, crossedGestaltLevelOp(intersect),
|
||||
null,
|
||||
smearLevels);
|
||||
};
|
||||
|
||||
Gestalt.prototype.match = function (perspective) {
|
||||
var pids = {};
|
||||
var nm = Math.min(this.metaLevels.length, perspective.metaLevels.length);
|
||||
for (var i = 0; i < nm; i++) {
|
||||
var ls1 = mls1[i] || emptyMetaLevel;
|
||||
var ls2 = smearLevels(mls2[i] || emptyMetaLevel);
|
||||
var nl = Math.min(ls1.length, ls2.length);
|
||||
for (var j = 0; j < nl; j++) {
|
||||
var p1 = ls1[j] || emptyLevel;
|
||||
var p2 = ls2[j] || emptyLevel;
|
||||
matchMatcher(p1.subscriptions, p2.advertisements, pids);
|
||||
matchMatcher(p1.advertisements, p2.subscriptions, pids);
|
||||
}
|
||||
}
|
||||
return setToArray(pids);
|
||||
};
|
||||
|
||||
Gestalt.prototype.erasePath = function (path) {
|
||||
return this.mapZip(path, Math.max, straightGestaltLevelOp(erasePath));
|
||||
};
|
||||
|
||||
Gestalt.prototype.transform = function (f) {
|
||||
var metaLevels = [];
|
||||
for (var i = 0; i < this.metaLevels.length; i++) {
|
||||
var ls = this.metaLevels[i];
|
||||
var levels = [];
|
||||
for (var j = 0; j < ls.length; j++) {
|
||||
var p0 = ls[j] || emptyLevel;
|
||||
var p = new GestaltLevel(f(p0.subscriptions), f(p0.advertisements));
|
||||
if (!p.isEmpty()) {
|
||||
while (levels.length < j) levels.push(emptyLevel);
|
||||
levels.push(p);
|
||||
}
|
||||
}
|
||||
if (levels.length > 0) {
|
||||
while (metaLevels.length < i) metaLevels.push(emptyMetaLevel);
|
||||
metaLevels.push(levels);
|
||||
}
|
||||
}
|
||||
return new Gestalt(metaLevels);
|
||||
};
|
||||
|
||||
Gestalt.prototype.stripLabel = function () {
|
||||
return this.transform(function (m) { return relabel(m, function (v) { return true; }); });
|
||||
};
|
||||
|
||||
Gestalt.prototype.label = function (pid) {
|
||||
var pids = newSet(pid);
|
||||
return this.transform(function (m) { return relabel(m, function (v) { return pids; }); });
|
||||
};
|
||||
|
||||
Gestalt.prototype.pretty = function () {
|
||||
var acc = [];
|
||||
if (this.isEmpty()) {
|
||||
acc.push("EMPTY GESTALT\n");
|
||||
} else {
|
||||
for (var i = 0; i < this.metaLevels.length; i++) {
|
||||
var ls = this.metaLevels[i];
|
||||
for (var j = 0; j < ls.length; j++) {
|
||||
var p = ls[j];
|
||||
if (!p.isEmpty()) {
|
||||
acc.push("GESTALT metalevel " + i + " level " + j + ":\n");
|
||||
if (!is_emptyMatcher(p.subscriptions)) {
|
||||
acc.push(" - subs:");
|
||||
acc.push(prettyMatcher(p.subscriptions, 9));
|
||||
acc.push("\n");
|
||||
}
|
||||
if (!is_emptyMatcher(p.advertisements)) {
|
||||
acc.push(" - advs:");
|
||||
acc.push(prettyMatcher(p.advertisements, 9));
|
||||
acc.push("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return acc.join('');
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.__ = __;
|
||||
|
@ -1100,6 +1264,11 @@ function Routing(exports) {
|
|||
exports.project = project;
|
||||
exports.matcherKeys = matcherKeys;
|
||||
exports.prettyMatcher = prettyMatcher;
|
||||
|
||||
exports.GestaltLevel = GestaltLevel;
|
||||
exports.Gestalt = Gestalt;
|
||||
exports.simpleGestalt = simpleGestalt;
|
||||
exports.emptyGestalt = emptyGestalt;
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
|
|
40
tr.js
40
tr.js
|
@ -12,6 +12,12 @@ function dumpM(m) {
|
|||
return m;
|
||||
}
|
||||
|
||||
function dumpG(g) {
|
||||
console.log(g.pretty());
|
||||
console.log();
|
||||
return g;
|
||||
}
|
||||
|
||||
mAny = r.compilePattern(r.newSet('mAny'), r.__);
|
||||
mAAny = r.compilePattern(r.newSet('mAAny'), ['A', r.__]);
|
||||
dumpM(mAny);
|
||||
|
@ -61,3 +67,37 @@ dumpM(R2);
|
|||
dumpM(R12);
|
||||
dumpM(r.erasePath(R12, R1));
|
||||
dumpM(r.erasePath(R12, R2));
|
||||
|
||||
console.log();
|
||||
dumpG(r.simpleGestalt(false, "A", 0, 0));
|
||||
dumpG(r.simpleGestalt(true, "B", 0, 0));
|
||||
dumpG(r.simpleGestalt(false, "A", 0, 0).union(r.simpleGestalt(true, "B", 0, 0)));
|
||||
|
||||
console.log();
|
||||
dumpG(r.simpleGestalt(false, "A", 2, 2));
|
||||
dumpG(r.simpleGestalt(true, "B", 2, 2));
|
||||
dumpG(r.simpleGestalt(false, "A", 2, 2).union(r.simpleGestalt(true, "B", 2, 2)));
|
||||
|
||||
console.log();
|
||||
dump(r.simpleGestalt(false, "A", 0, 0).label(123).matchValue("A", 0, false));
|
||||
dump(r.simpleGestalt(false, "A", 0, 1).label(123).matchValue("A", 0, false));
|
||||
dump(r.simpleGestalt(false, "A", 0, 2).label(123).matchValue("A", 0, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 0).label(123).matchValue("A", 0, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 1).label(123).matchValue("A", 0, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 2).label(123).matchValue("A", 0, false));
|
||||
|
||||
console.log();
|
||||
dump(r.simpleGestalt(false, "A", 0, 0).label(123).matchValue("A", 1, false));
|
||||
dump(r.simpleGestalt(false, "A", 0, 1).label(123).matchValue("A", 1, false));
|
||||
dump(r.simpleGestalt(false, "A", 0, 2).label(123).matchValue("A", 1, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 0).label(123).matchValue("A", 1, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 1).label(123).matchValue("A", 1, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 2).label(123).matchValue("A", 1, false));
|
||||
|
||||
console.log();
|
||||
dump(r.simpleGestalt(false, "A", 0, 0).label(123).matchValue("A", 2, false));
|
||||
dump(r.simpleGestalt(false, "A", 0, 1).label(123).matchValue("A", 2, false));
|
||||
dump(r.simpleGestalt(false, "A", 0, 2).label(123).matchValue("A", 2, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 0).label(123).matchValue("A", 2, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 1).label(123).matchValue("A", 2, false));
|
||||
dump(r.simpleGestalt(false, "A", 2, 2).label(123).matchValue("A", 2, false));
|
||||
|
|
Loading…
Reference in New Issue