stsys
Version:
String rewriting system (semi-Thue system)
224 lines (206 loc) • 6.89 kB
JavaScript
const assert = require('assert');
const rulemgr = require('../lib/rulemgr');
const goalmgr = require('../lib/goalmgr');
const comparer = require('../lib/cmp');
const strpair = require('../lib/strpair');
const createProver = require('../lib/prover').createProver;
const createStrPair = strpair.createStrPair;
const parseStrPair = strpair.parseStrPair;
describe('String pairs', function(){
it('creation fails', function(){
try
{
createStrPair('ab0');
}
catch (error)
{
assert.equal(error.message, 'invalid string pair (illegal characters): ab0 = undefined');
return;
}
assert.fail('expected exception not thrown');
});
it('creation succeeds', function(){
let sp = createStrPair('ab', 'b');
assert.equal(sp.left, 'ab');
assert.equal(sp.right, 'b');
assert.equal(typeof sp.ordered, 'boolean');
assert.ok(!sp.ordered);
assert.ok(sp.hasOwnProperty('parent1'));
assert.ok(sp.hasOwnProperty('parent2'));
sp = createStrPair('aaa');
assert.equal(sp.left, 'aaa');
assert.equal(sp.right, '');
});
it('parsing fails (missing equality)', function(){
try
{
parseStrPair('ab ba');
}
catch (error)
{
assert.equal(error.message, 'invalid string pair (missing equality): ab ba');
return;
}
assert.fail('expected exception not thrown');
});
it('parsing fails (invalid characters)', function(){
try
{
parseStrPair('ab = b$a');
}
catch (error)
{
assert.equal(error.message, 'invalid string pair (illegal characters): ab = b$a');
return;
}
assert.fail('expected exception not thrown');
});
it('parsing succeeds', function(){
let eq = parseStrPair(' ab= ba ');
assert.equal('ab = ba', eq.toString());
eq = parseStrPair(' =bb');
assert.equal(' = bb', eq.toString());
eq = parseStrPair(' =');
assert.equal(' = ', eq.toString());
});
it('to string', function(){
const sp = createStrPair('aba', 'bb');
assert.equal(sp.toString(), 'aba = bb');
sp.ordered = true;
assert.equal(sp.toString(), 'aba -> bb');
});
it('get weight', function(){
let sp = createStrPair('aba', 'bb');
assert.equal(sp.getWeight(), 5);
sp = createStrPair('b', 'aa');
assert.equal(sp.getWeight(), 3);
});
it('check trivial', function(){
let sp = createStrPair('ba', 'bb');
assert.ok(!sp.isTrivial());
sp = createStrPair('bb', 'bb');
assert.ok(sp.isTrivial());
});
});
describe('Rule Manager', function(){
it('creation', function(){
const rm = rulemgr.createRuleManager();
assert.ok(rm);
assert.equal(typeof rm.indexRoot, 'object');
assert.ok(rm.indexRoot);
assert.ok(rulemgr.createRuleManager() !== rm);
});
it('add and remove rules', function(){
const rm = rulemgr.createRuleManager();
assert.equal(rm.getRulesCount(), 0);
let rule = createStrPair('bba', 'ab');
rule.ordered = true;
rm.addRule(rule);
assert.equal(rm.getRulesCount(), 1);
assert.ok(rm.findOverlap('abb', 1)[0] === rule);
rule = createStrPair('aba', 'ba');
rule.ordered = true;
rm.addRule(rule);
assert.equal(rm.getRulesCount(), 2);
assert.ok(!rm.findOverlap('abab', 0));
assert.ok(rm.findOverlap('abab', 2)[0] === rule);
rm.removeRule(rule);
assert.equal(rm.getRulesCount(), 1);
assert.ok(!rm.findOverlap('abab', 2));
});
it('reduction', function(){
const rm = rulemgr.createRuleManager();
const sp = createStrPair('abbba', 'abab');
const rule = createStrPair('a', 'ba');
const cmp = comparer.createComparer('lpo', ['a', 'b']);
assert.ok(!sp.reduce(rm));
assert.equal(sp.left, 'abbba');
assert.equal(sp.right, 'abab');
assert.ok(!rule.ordered);
rule.order(cmp);
assert.ok(rule.ordered);
assert.equal(rule.left, 'ba');
assert.equal(rule.right, 'a');
rm.addRule(rule);
assert.ok(sp.reduce(rm));
assert.equal(sp.left, 'aa');
assert.equal(sp.right, 'aab');
assert.ok(!sp.reduce(rm));
});
it('overlap', function(){
const rule = createStrPair('aba', 'ba');
const sp = rule.overlapIntoAt(rule, 2);
assert.ok(sp.parent1 === rule);
assert.ok(sp.parent2 === rule);
assert.equal(sp.left, 'abba');
assert.equal(sp.right, 'baba');
});
});
describe('Goal Manager', function(){
it('successful usage', function(){
const gm = goalmgr.createGoalManager();
assert.ok(gm !== goalmgr.createGoalManager());
assert.ok(!gm.allGoalsProved());
assert.equal(gm.getGoalsCount(), 0);
assert.deepEqual(gm.getGoals(), []);
gm.addGoals();
assert.equal(gm.getGoalsCount(), 0);
gm.addGoals('aa = aa');
assert.equal(gm.getGoalsCount(), 1);
assert.ok(gm.allGoalsProved());
assert.deepEqual(gm.getGoals(), [{id:1, goal:'aa = aa', proved:true, provedBy:'aa = aa'}]);
gm.addGoals('bb = aa');
assert.equal(gm.getGoalsCount(), 2);
assert.ok(!gm.allGoalsProved());
assert.deepEqual(gm.getGoals(), [
{id:1, goal:'aa = aa', proved:true, provedBy:'aa = aa'},
{id:2, goal:'bb = aa', proved:false}
]);
gm.addGoals(['ab = ba', 'aab =']);
assert.equal(gm.getGoalsCount(), 4);
assert.ok(!gm.allGoalsProved());
assert.equal(gm.unprovedGoalsCount, 3);
assert.equal(gm.getGoals().length, 4);
gm.clearGoals();
assert.equal(gm.getGoalsCount(), 0);
assert.ok(!gm.allGoalsProved());
assert.equal(gm.unprovedGoalsCount, 0);
assert.equal(gm.getGoals().length, 0);
});
it('erroneous usage', function(){
const gm = goalmgr.createGoalManager();
try
{
gm.addGoals(42);
}
catch (error)
{
assert.equal(error.message, 'invalid specification of goals (illegal type: number)');
return;
}
assert.fail('expected exception not thrown');
});
});
describe('Features', function(){
it('normalization', function(){
const prover = createProver(['ab = ba', 'aba = ba']);
const s = 'abaaaa';
assert.equal(prover.normalize(''), '');
assert.equal(prover.normalize(s), s);
prover.run({ordering:'lex', preorder:['a', 'b']});
assert.equal(prover.normalize(s), 'ba');
});
it('testing equality', function(){
const prover = createProver(['ab = ba', 'aba = ba']);
assert.equal(prover.testEquality('aaaab', 'aaba'), undefined);
assert.equal(prover.testEquality('ab=ba'), undefined);
assert.equal(prover.testEquality('aa', 'aa'), true);
assert.equal(prover.testEquality('ab=ab'), true);
assert.equal(prover.testEquality(' = '), true);
prover.run({ordering:'lex', preorder:['a', 'b']});
assert.equal(prover.testEquality('aaaab', 'aaba'), true);
assert.equal(prover.testEquality('aabaab = baaba'), true);
assert.equal(prover.testEquality('aabaab', 'aaba'), false);
assert.equal(prover.testEquality('aab = bba'), false);
});
});