UNPKG

stsys

Version:

String rewriting system (semi-Thue system)

224 lines (206 loc) 6.89 kB
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); }); });