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;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setToArray(s) {
|
||||||
|
var r = [];
|
||||||
|
for (var k in s) r.push(s[k]);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
function setUnion(s1, s2) {
|
function setUnion(s1, s2) {
|
||||||
var s = {};
|
var s = {};
|
||||||
setUnionInplace(s, s1);
|
setUnionInplace(s, s1);
|
||||||
|
@ -1013,6 +1019,24 @@ function Routing(exports) {
|
||||||
this.advertisements = advs;
|
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 emptyLevel = new GestaltLevel(emptyMatcher, emptyMatcher);
|
||||||
var emptyMetaLevel = [];
|
var emptyMetaLevel = [];
|
||||||
|
|
||||||
|
@ -1035,7 +1059,7 @@ function Routing(exports) {
|
||||||
var matcher = (isFeedback ? levels[i].advertisements : levels[i].subscriptions);
|
var matcher = (isFeedback ? levels[i].advertisements : levels[i].subscriptions);
|
||||||
setUnionInplace(pids, matchValue(matcher, body));
|
setUnionInplace(pids, matchValue(matcher, body));
|
||||||
}
|
}
|
||||||
return pids;
|
return setToArray(pids);
|
||||||
};
|
};
|
||||||
|
|
||||||
Gestalt.prototype.project = function (metaLevel, level, getAdvertisements, spec) {
|
Gestalt.prototype.project = function (metaLevel, level, getAdvertisements, spec) {
|
||||||
|
@ -1056,7 +1080,7 @@ function Routing(exports) {
|
||||||
return new Gestalt(mls);
|
return new Gestalt(mls);
|
||||||
};
|
};
|
||||||
|
|
||||||
function simpleGestalt(isAdv, pat, level, metaLevel) {
|
function simpleGestalt(isAdv, pat, metaLevel, level) {
|
||||||
var matcher = compilePattern(true, pat);
|
var matcher = compilePattern(true, pat);
|
||||||
var l = new GestaltLevel(isAdv ? emptyMatcher : matcher,
|
var l = new GestaltLevel(isAdv ? emptyMatcher : matcher,
|
||||||
isAdv ? matcher : emptyMatcher);
|
isAdv ? matcher : emptyMatcher);
|
||||||
|
@ -1080,6 +1104,146 @@ function Routing(exports) {
|
||||||
return true;
|
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.__ = __;
|
exports.__ = __;
|
||||||
|
@ -1100,6 +1264,11 @@ function Routing(exports) {
|
||||||
exports.project = project;
|
exports.project = project;
|
||||||
exports.matcherKeys = matcherKeys;
|
exports.matcherKeys = matcherKeys;
|
||||||
exports.prettyMatcher = prettyMatcher;
|
exports.prettyMatcher = prettyMatcher;
|
||||||
|
|
||||||
|
exports.GestaltLevel = GestaltLevel;
|
||||||
|
exports.Gestalt = Gestalt;
|
||||||
|
exports.simpleGestalt = simpleGestalt;
|
||||||
|
exports.emptyGestalt = emptyGestalt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
|
40
tr.js
40
tr.js
|
@ -12,6 +12,12 @@ function dumpM(m) {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dumpG(g) {
|
||||||
|
console.log(g.pretty());
|
||||||
|
console.log();
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
mAny = r.compilePattern(r.newSet('mAny'), r.__);
|
mAny = r.compilePattern(r.newSet('mAny'), r.__);
|
||||||
mAAny = r.compilePattern(r.newSet('mAAny'), ['A', r.__]);
|
mAAny = r.compilePattern(r.newSet('mAAny'), ['A', r.__]);
|
||||||
dumpM(mAny);
|
dumpM(mAny);
|
||||||
|
@ -61,3 +67,37 @@ dumpM(R2);
|
||||||
dumpM(R12);
|
dumpM(R12);
|
||||||
dumpM(r.erasePath(R12, R1));
|
dumpM(r.erasePath(R12, R1));
|
||||||
dumpM(r.erasePath(R12, R2));
|
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