Reputation: 33
I would like to somebody help me. There is a very good JS library math.js. It implements boolean logical operators NOT, OR, AND, XOR. I need the others ones: NOR, NAND, XNOR.
I know that NOR is NOT OR, but; there is a problem I need this operators to be able to use them as a string input to evaluate, for example:
(A OR B) XNOR C
B NAND (NOT (A OR B AND C))
The math.js has a parser and can deliminate (?) the string to the structure with nodes and evaluate it. But, it knows NOT, OR, AND, XOR only.
Is my request clear? Anybody help me?
Thanks!
Upvotes: 1
Views: 4585
Reputation: 5525
Math.js has a regular parser to do so. That means you can simply (for some large values of "simple") add to it what you need.
(Assuming you clone'd Math.js from Github)
One round to add nor
, the others are similar.
In /lib/expression/parse.js add what you need in the object NAMED_DELIMITERS
(and don't be like me and forget the commas ;-) ).
var NAMED_DELIMITERS = {
'mod': true,
'to': true,
'in': true,
'and': true,
'xor': true,
'or': true,
'nor': true,
'not': true
};
Add it to the operators listed in /lib/expression/operators.js, too. e.g.:
{ //logical nor
'OperatorNode:nor': {
associativity: 'left',
associativeWith: []
}
},
Write the working code (just build them from the existing functions) and put the files in the directory /lib/function/logical/.
'use strict';
function factory (type, config, load, typed) {
var latex = require('../../utils/latex');
var matrix = load(require('../../type/matrix/function/matrix'));
var algorithm03 = load(require('../../type/matrix/utils/algorithm03'));
var algorithm05 = load(require('../../type/matrix/utils/algorithm05'));
var algorithm12 = load(require('../../type/matrix/utils/algorithm12'));
var algorithm13 = load(require('../../type/matrix/utils/algorithm13'));
var algorithm14 = load(require('../../type/matrix/utils/algorithm14'));
var nor = typed('nor', {
'number, number': function (x, y) {
return !(!!(x || y));
},
'Complex, Complex': function (x, y) {
return !((x.re !== 0 || x.im !== 0) || (y.re !== 0 || y.im !== 0));
},
'BigNumber, BigNumber': function (x, y) {
return !((!x.isZero() && !x.isNaN()) || (!y.isZero() && !y.isNaN()));
},
'Unit, Unit': function (x, y) {
return !((x.value !== 0 && x.value !== null) || (y.value !== 0 && y.value !== null));
},
'Matrix, Matrix': function (x, y) {
// result
var c;
// process matrix storage
switch (x.storage()) {
case 'sparse':
switch (y.storage()) {
case 'sparse':
// sparse + sparse
c = algorithm05(x, y, nor);
break;
default:
// sparse + dense
c = algorithm03(y, x, nor, true);
break;
}
break;
default:
switch (y.storage()) {
case 'sparse':
// dense + sparse
c = algorithm03(x, y, nor, false);
break;
default:
// dense + dense
c = algorithm13(x, y, nor);
break;
}
break;
}
return c;
},
'Array, Array': function (x, y) {
// use matrix implementation
return nor(matrix(x), matrix(y)).valueOf();
},
'Array, Matrix': function (x, y) {
// use matrix implementation
return nor(matrix(x), y);
},
'Matrix, Array': function (x, y) {
// use matrix implementation
return nor(x, matrix(y));
},
'Matrix, any': function (x, y) {
// result
var c;
// check storage format
switch (x.storage()) {
case 'sparse':
c = algorithm12(x, y, nor, false);
break;
default:
c = algorithm14(x, y, nor, false);
break;
}
return c;
},
'any, Matrix': function (x, y) {
// result
var c;
// check storage format
switch (y.storage()) {
case 'sparse':
c = algorithm12(y, x, nor, true);
break;
default:
c = algorithm14(y, x, nor, true);
break;
}
return c;
},
'Array, any': function (x, y) {
// use matrix implementation
return algorithm14(matrix(x), y, nor, false).valueOf();
},
'any, Array': function (x, y) {
// use matrix implementation
return algorithm14(matrix(y), x, nor, true).valueOf();
}
});
nor.toTex = '\\left(${args[0]}' + latex.operators['nor'] + '${args[1]}\\right)';
return nor;
}
exports.name = 'nor';
exports.factory = factory;
Add those files to index.js residing in the same directory.
module.exports = [
require('./and'),
require('./not'),
require('./or'),
require('./nor'),
require('./xor')
];
Add the correct symbol to the Latex dictionary in /lib/utils/latex.js
exports.operators = {
// ...
'nor': '\\curlywedge'
};
Math.js is quite legible, it should be no problem to add what you need and if not…well…that's what Stackoverflow is for, isn't it? ;-)
Update the documentation. In the file ./lib/expression/docs/function/logical/nor.js put
module.exports = {
'name': 'nor',
'category': 'Logical',
'syntax': [
'x or y',
'or(x, y)'
],
'description': 'Logical nor. Test if neither value is defined with a nonzero/nonempty value.',
'examples': [
'true nor false',
'false nor false',
'0 nor 4'
],
'seealso': [
'not', 'and', 'xor', 'or'
]
};
and update the doc-index in the file ./lib/expression/docs/index.js with
docs['nor'] = require('./function/logical/or');
Update the tests. Copy the file test/function/logical/or.test.js to the file test/function/logical/nor.test.js and replace every or
with nor
and reverse all of the booleans. With the following exceptions:
it('should nor two booleans', function () {
assert.strictEqual(nor(false, false), true);
assert.strictEqual(nor(false, true), false);
assert.strictEqual(nor(true, false), false);
assert.strictEqual(nor(true, true), false);
});
it('should nor mixed numbers and booleans', function () {
assert.strictEqual(nor(2, false), false);
assert.strictEqual(nor(2, true), false);
assert.strictEqual(nor(0, false), true);
assert.strictEqual(nor(0, true), false);
assert.strictEqual(nor(false, 2), false);
assert.strictEqual(nor(true, 2), false);
assert.strictEqual(nor(true, 0), false);
});
Build math.js by running:
npm install
npm run build
The building process might last a little while (two and a half minutes for minify
).
Run the tests.
npm test
The test in test/function/logical/nor.test.js at line 202 fails and I do not know if it is in the nor
implementation (unlikely but possible) or in the implementation of the sparse matrix optimizations.
If it works: offer your changes to math.js but the chance is quite small that they get accepted (syntactic sugar is sometimes, albeit not always, frowned upon), so don't get too disappointed.
Upvotes: 3