// predicate.js BAYES STAR (c) coppola.ai class FirstOrderArgument { constructor(type, domain) { this.type = type; this.domain = domain; } IsVariable() { return this.type == 'variable' } static FromTuple(tuple) { switch (tuple.type) { case "constant": return ConstantArgument.FromTuple(tuple) case "variable": return VariableArgument.FromTuple(tuple) default: throw new Error("not found!") } } } class ConstantArgument extends FirstOrderArgument { constructor(domain, entity_id) { super("constant", domain); this.entity_id = entity_id; } SearchString() { const cstring = `${this.entity_id}` return cstring } ConvertToQuantified() { return new VariableArgument(this.domain) } static FromTuple(tuple) { return new ConstantArgument(tuple.domain, tuple.entity_id) } } const BOUND_VARIABLE = '?' class VariableArgument extends FirstOrderArgument { constructor(domain) { super("variable", domain); } SearchString() { return `${BOUND_VARIABLE}${this.domain}` } static FromTuple(tuple) { return new VariableArgument(tuple.domain) } } class FilledRole { constructor(role_name, argument) { this.role_name = role_name this.argument = argument } SearchString() { const roleString = `${this.role_name}=${this.argument.SearchString()}` return roleString } ConvertToQuantified() { return new FilledRole(this.role_name, this.argument.ConvertToQuantified()) } DoSubstitution(value) { return new FilledRole(this.role_name, value) } static FromTuple(tuple) { const role_name = tuple.role_name const argument = FirstOrderArgument.FromTuple(tuple.argument) return new FilledRole(role_name, argument) } } class Proposition { constructor(roles) { roles.sort((a, b) => { if (a.role_name < b.role_name) { return -1; } if (a.role_name > b.role_name) { return 1; } return 0; }); this.roles = roles } RoleNames() { var result = [] for (const role of this.roles) { result.push(role.role_name) } return result } SearchString() { var result = '[' var started = false for (const column of this.roles) { if (started) { result += ', ' } result += column.SearchString() started = true } result += ']' return result } IsFact() { this.roles.forEach((column) => { if (column.argument.type == 'variable') { return false } else { // console.log('not quantified', {column}) } }) return true } ToString() { return JSON.stringify(this.roles) } static FromString(record) { const parsedObj = JSON.parse(record); var roles = [] for (const rolePart of parsedObj) { const newRole = FilledRole.FromTuple(rolePart) roles.push(newRole) } return new Proposition(roles) } } function ToStringObjectCanonical(obj) { const sortedObj = {}; Object.keys(obj).sort().forEach(function(key) { sortedObj[key] = obj[key]; }); return JSON.stringify(sortedObj); } class Implication { constructor(premise, conclusion, roleMap) { this.premise = premise this.conclusion = conclusion this.roleMap = roleMap } SearchString() { return this.conclusion.SearchString() } UniqueKey() { return `${this.premise.SearchString()}->${this.conclusion.SearchString()}${this.MappingString()}` } FeatureString() { return `${this.premise.SearchString()}${this.MappingString()}` } MappingString() { return this.roleMap.ToString() } static FromRecord(record) { const {premiseRecord, conclusionRecord, mappingRecord} = record; const premise = Proposition.FromString(premiseRecord) const conclusion = Proposition.FromString(conclusionRecord) const roleMap = RoleMap.FromRecord(mappingRecord) return new Implication(premise, conclusion, roleMap) } } class Entity { constructor(domain, name) { this.domain = domain this.name = name } } class RoleMap { constructor(roleMap) { this.roleMap = roleMap } Get(role_name) { const rval = this.roleMap[role_name] return rval } ToString() { return ToStringObjectCanonical(this.roleMap) } static FromRecord(record) { const roleMap = JSON.parse(record) return new RoleMap(roleMap) } } class BackLink { constructor(implication, proposition) { this.implication = implication this.proposition = proposition } } module.exports = { ConstantArgument, VariableArgument, Proposition, Implication, FilledRole, Entity, RoleMap, BackLink }