stsys
Version:
String rewriting system (semi-Thue system)
104 lines (93 loc) • 2.27 kB
JavaScript
class StrPair
{
constructor(left, right, parent1, parent2)
{
const regex = /^[a-zA-Z]*$/;
this.left = left || '';
this.right = right || '';
if (!regex.test(this.left) || !regex.test(this.right))
throw new Error('invalid string pair (illegal characters): ' + left + ' = ' + right);
this.ordered = false;
this.parent1 = parent1 || null;
this.parent2 = parent2 || null;
this.next = null;
}
toString(withParents)
{
const sb = [this.left, this.ordered ? '->' : '=', this.right];
if (withParents)
{
sb.push('from');
if (this.parent1)
sb.push('#' + this.parent1.id, 'and', '#' + this.parent2.id);
else
sb.push('axiom');
}
return sb.join(' ');
}
copy()
{
return new StrPair(this.left, this.right);
}
isTrivial()
{
return this.left === this.right;
}
isObsolete()
{
return this.parent1 && !this.parent1.ordered || this.parent2 && !this.parent2.ordered;
}
getWeight()
{
return this.left.length + this.right.length;
}
reduce(reducer, rule)
{
let reduced = false;
let s = reducer.reduce(this.left, rule);
if (typeof s === 'string')
{
this.left = s;
this.ordered = false;
reduced = true;
}
s = reducer.reduce(this.right, rule);
if (typeof s === 'string')
{
this.right = s;
reduced = true;
}
return reduced;
}
order(comparer)
{
let cmp = comparer.compare(this.left, this.right);
if (cmp < 0)
{
let s = this.left;
this.left = this.right;
this.right = s;
}
else if (cmp === 0)
throw new Error('invalid state: cannot order ' + this.left + ' and ' + this.right);
this.ordered = true;
}
overlapIntoAt(other, i)
{
return new StrPair(
this.left.substring(0, i) + other.right,
this.right + other.left.substring(this.left.length - i),
this, other);
}
}
module.exports.createStrPair = function(l, r, p1, p2)
{
return new StrPair(l, r, p1, p2);
};
module.exports.parseStrPair = function(s)
{
const i = s.indexOf('=');
if (i < 0)
throw new Error('invalid string pair (missing equality): ' + s);
return new StrPair(s.substring(0, i).trim(), s.substring(i + 1).trim());
};