Deduplicate entries in domain inversion's simplify

issue11248
review397301002
This commit is contained in:
Nicolas Évrard committed 2022-03-30 19:20:31 +02:00
1 parent 50567a1cd7
commit 030772688b
2 files changed
+125 -23

No files matched your search

+69 -12
View File
@@ -2571,22 +2571,79 @@
return models;
}
},
_bool_operator: function(domain) {
var bool_op = 'AND';
if ((domain.length > 0) &&
((domain[0] == 'AND') || (domain[0] == 'OR'))) {
bool_op = domain[0];
}
return bool_op;
},
simplify_nested: function(domain) {
if (!domain.length) {
return [];
} else if (this.is_leaf(domain)) {
return [domain];
} else if ((domain == 'AND') || (domain == 'OR')) {
return [domain];
} else if ((domain instanceof Array) && (domain.length == 1)) {
return this.simplify_nested(domain[0]);
} else {
var simplified = [];
var domain_op = this._bool_operator(domain);
for (var branch of domain) {
var simplified_branch = this.simplify_nested(branch);
if ((this._bool_operator(branch) == domain_op) ||
(simplified_branch.length == 1)) {
simplified.push(...simplified_branch);
} else {
simplified.push(simplified_branch);
}
}
return simplified;
}
},
simplify_duplicate: function(domain) {
var dedup_branches = [];
var bool_op = null;
if (~['AND', 'OR'].indexOf(domain[0])) {
bool_op = domain[0];
domain = domain.slice(1);
}
for (var branch of domain) {
var simplified_branch = this.simplify(branch);
if (simplified_branch.length == 0) {
if (bool_op === 'OR') {
return [];
} else {
continue;
}
}
var found_branch = false;
for (var duped_branch of dedup_branches) {
if (Sao.common.compare(
simplified_branch, duped_branch)) {
found_branch = true;
break;
}
}
if (!found_branch) {
dedup_branches.push(simplified_branch);
}
}
if (bool_op && (dedup_branches.length > 1)) {
dedup_branches.unshift(bool_op);
}
return dedup_branches;
},
simplify: function(domain) {
if (this.is_leaf(domain)) {
return domain;
} else if (~['OR', 'AND'].indexOf(domain)) {
return domain;
} else if ((domain instanceof Array) && (domain.length == 1) &&
(~['OR', 'AND'].indexOf(domain[0]))) {
return [domain];
} else if (!domain.length) {
return [];
} else if ((domain instanceof Array) && (domain.length == 1) &&
(!this.is_leaf(domain[0]))) {
return this.simplify(domain[0]);
} else if ((domain instanceof Array) && (domain.length == 2) &&
~['AND', 'OR'].indexOf(domain[0])) {
return [this.simplify(domain[1])];
} else {
return domain.map(this.simplify.bind(this));
return this.simplify_nested(this.simplify_duplicate(domain));
}
},
merge: function(domain, domoperator) {
+56 -11
View File
@@ -2574,7 +2574,7 @@
JSON.stringify(context) + ')');
context = {y: 4, z: 'b'};
QUnit.ok(compare(domain_inversion(domain, 'x', context),
['OR', [['x', '=', 3]], [['x', '=', 2]]]),
['OR', ['x', '=', 3], ['x', '=', 2]]),
'domain_inversion(' + JSON.stringify(domain) + ', \'x\', ' +
JSON.stringify(context) + ')');
});
@@ -2600,15 +2600,25 @@
var compare = Sao.common.compare;
[
[[['x', '=', 3]], [['x', '=', 3]]],
[[[['x', '=', 3]]], [['x', '=', 3]]],
[['OR', ['x', '=', 3]], [['x', '=', 3]]],
[['OR', [['x', '=', 3]], [['y', '=', 5]]],
['OR', [['x', '=', 3]], [['y', '=', 5]]]],
[['OR', ['x', '=', 3], ['AND', ['y', '=', 5]]],
['OR', ['x', '=', 3], [['y', '=', 5]]]],
[['AND'], []],
[['OR'], []]
[[['x', '=', 3]], [['x', '=', 3]]],
[[[['x', '=', 3]]], [['x', '=', 3]]],
[
[[['x', '=', 3], ['y', '=', 4]]],
[['x', '=', 3], ['y', '=', 4]]],
[['OR', ['x', '=', 3]], [['x', '=', 3]]],
[
['OR', [['x', '=', 3]], [['y', '=', 5]]],
['OR', ['x', '=', 3], ['y', '=', 5]]],
[
['OR', ['x', '=', 3], ['AND', ['y', '=', 5]]],
['OR', ['x', '=', 3], ['y', '=', 5]]],
[[['x', '=', 3], ['OR']], [['x', '=', 3]]],
[['OR', ['x', '=', 3], []], []],
[['OR', ['x', '=', 3], ['OR']], []],
[[['x', '=', 3], []], [['x', '=', 3]]],
[[['x', '=', 3], ['AND']], [['x', '=', 3]]],
[['AND'], []],
[['OR'], []]
].forEach(function(test) {
var domain = test[0];
var result = test[1];
@@ -2617,6 +2627,41 @@
});
});
QUnit.test('DomainInversion simplify deduplicate', function() {
var domain_inversion = new Sao.common.DomainInversion();
var simplify = domain_inversion.simplify.bind(domain_inversion);
var compare = Sao.common.compare;
var clause = ['x', '=', 3];
var another = ['y', '=', 4];
var third = ['z', '=', 5];
[
[[], []],
[['OR', []], []],
[['AND', []], []],
[[clause], [clause]],
[['OR', clause], [clause]],
[[clause, clause], [clause]],
[['OR', clause, clause], [clause]],
[[clause, [clause, clause]], [clause]],
[[clause, another], [clause, another]],
[['OR', clause, another], ['OR', clause, another]],
[[clause, clause, another], [clause, another]],
[[clause, [clause, clause], another], [clause, another]],
[[clause, clause, another, another], [clause, another]],
[[clause, another, clause, another], [clause, another]],
[
['AND', ['OR', clause, another], third],
['AND', ['OR', clause, another], third]],
].forEach(function(test) {
var domain = test[0];
var result = test[1];
QUnit.ok(compare(simplify(domain), result),
'simplify(' + JSON.stringify(domain) + ')');
});
});
QUnit.test('DomainInversion merge', function() {
var domain_inversion = new Sao.common.DomainInversion();
var merge = domain_inversion.merge.bind(domain_inversion);
@@ -2669,7 +2714,7 @@
QUnit.ok(compare(concat([[], []]), []),
'compare(' + JSON.stringify([[], []]) + ')');
QUnit.ok(compare(concat([domain1, domain2], 'OR'),
['OR', [['a', '=', 1]], [['b', '=', 2]]]),
['OR', ['a', '=', 1], ['b', '=', 2]]),
'compare(' + JSON.stringify([domain1, domain2]) + ', \'OR\')');
});