pcfg-generator
Version:
A module to convert JSON-formated treebank data into a Stochastic Context-Free Grammar
123 lines (100 loc) • 2.94 kB
JavaScript
var strip_duplicate_indicator = function(property_name) {
var stripped_property_name = property_name.replace(/_\d+$/, '');
return stripped_property_name;
};
var add_rule = function(pcfg, rule) {
var rhs_matched = false;
for (var i=0; i<pcfg.length; i++) {
if (rule.lhs === pcfg[i].lhs) {
for (var j=0; j<pcfg[i].rhs.length; j++) {
rhs_matched = true;
for (var k=0; k<rule.rhs.length; k++) {
if (rule.rhs[k] !== pcfg[i].rhs[j].values[k]) {
rhs_matched = false;
}
}
if (rhs_matched) {
pcfg[i].rhs[j].count++;
return pcfg;
}
}
pcfg[i].rhs.push({count: 1, values: rule.rhs});
return pcfg;
}
}
pcfg.push({lhs: rule.lhs, rhs: [{count: 1, values: rule.rhs}]});
return pcfg;
};
var generate_probabilities = function(pcfg, index) {
var i, j, start = index || 0, past_end = index ? index+1 : pcfg.length;
for (i=start; i<past_end; i++) {
var count = 0;
for (j=0; j<pcfg[i].rhs.length; j++) {
count += pcfg[i].rhs[j].count;
}
for (j=0; j<pcfg[i].rhs.length; j++) {
pcfg[i].rhs[j].probability = pcfg[i].rhs[j].count / count;
}
}
return pcfg;
};
var generate_helper = function(input, pcfg, parent) {
var rule = null, property = null;
if (parent !== null) {
rule = {lhs: parent, rhs: []};
if (typeof input === 'string') {
rule.rhs.push('\''+input+'\'');
}
else {
for (property in input) {
rule.rhs.push(strip_duplicate_indicator(property));
}
}
pcfg = add_rule(pcfg, rule);
}
if (typeof input === 'object') {
for (property in input) {
pcfg = generate_helper(input[property], pcfg, strip_duplicate_indicator(property));
}
}
return pcfg;
};
exports.generate = function(input) {
var pcfg = [];
pcfg = generate_probabilities(generate_helper(input, pcfg, null));
return pcfg;
};
exports.add_to_pcfg = function(pcfg, lhs, rhs, count) {
count = count || 1;
for (var i=0; i<pcfg.length; i++) {
if (pcfg[i].lhs === lhs) {
pcfg[i].rhs.push({count: count, values: rhs});
return generate_probabilities(pcfg, i);
}
}
throw "LHS not found!";
};
exports.toCNF = function(pcfg) {
var cnf = [];
for (var i=0; i<pcfg.length; i++) {
var lhs = pcfg[i].lhs;
for (var j=0; j<pcfg[i].rhs.length; j++) {
var rhs = pcfg[i].rhs[j].values.join(' ');
var prob = pcfg[i].rhs[j].probability;
cnf.push(lhs + ' -> ' + rhs + ' [' + prob + ']');
}
}
return cnf.join('\n');
};
exports.finalize = function(pcfg) {
var finalized_pcfg = [];
for (var i=0; i<pcfg.length; i++) {
var lhs = pcfg[i].lhs;
for (var j=0; j<pcfg[i].rhs.length; j++) {
var rhs = pcfg[i].rhs[j].values;
var prob = pcfg[i].rhs[j].probability;
finalized_pcfg.push({lhs: lhs, rhs: rhs, prob: prob});
}
}
return finalized_pcfg;
};