propositional
Version:
Propositional logic symbolic computation library
135 lines (134 loc) • 5.31 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Formula = void 0;
/**
* Representation of a propositional logic formula.
*/
class Formula {
/**
* Abstract Syntax Tree (AST) expression representing the formula.
*/
ast;
/**
* @param source The expression to construct the formula,
* either as a string or already parsed AST expression.
*
* @throws Will throw an error on a malformed string input.
*/
constructor(source) {
if (typeof source == 'string') {
source = (0, parse_1.parse)((0, tokenise_1.tokenise)(source));
}
this.ast = source;
}
;
/**
* Converts the formula to a string.
*
* @param pretty Whether or not to use traditional, non-ascii symbols in the string for operators
* @returns String representation of the formula
*/
toString(pretty = true) {
return (0, toString_1.toString)(this.ast, pretty);
}
/**
* Converts the formula to Conjunctive Normal Form.
*
* @returns The formula in CNF
*/
cnf() {
return (0, cnfExpression_1.toCNF)(this.ast);
}
/**
* Simplify a formula according to some equivalences involving constants (false, true) and
* syntactically equivalent expressions.
*
* @returns The formula transformed with simplifications
*/
simplify() {
return new Formula((0, simplify_1.simplify)(this.ast));
}
/**
* Substitute a variable in the formula with either another variable or a constant
* (false, true).
* @param v1 Variable to substitute
* @param v2 Value to substitute the variable with
* @returns The formula with the substitution applied
*/
substitute(v1, v2) {
let l1 = (0, generate_1.variable)(v1);
let l2 = typeof v2 == 'string' ? (0, generate_1.variable)(v2) : v2 ? generate_1.TRUE : generate_1.FALSE;
return new Formula((0, substitute_1.substituteVariable)(this.ast, l1, l2));
}
/**
* Check whether the formula is an atom, ie an instance of either a single variable
* or a constant.
*/
isAtom() {
return this.ast instanceof AST.Literal;
}
/**
* Evaluate whether an expression is true or false with a given combination of variable values.
*
* @param values An object mapping variables in the formula to boolean values
* (eg. `{ a: false, b: true }`)
* @returns The result of the formula evaluation, true or false
* @throws Will throw an error if not enough variables have been assigned to simplify a formula completely.
*/
evaluate(values) {
let ast = this.ast;
for (let v in values) {
ast = (0, substitute_1.substituteVariable)(ast, (0, generate_1.variable)(v), !!values[v] ? generate_1.TRUE : generate_1.FALSE);
}
ast = (0, simplify_1.simplify)(ast);
if (!(ast instanceof AST.Literal) || ast.value.type != token_1.TokenType.CONSTANT) {
throw new Error('Unable to evaluate, not enough variables were assigned a value');
}
return ast.value.lexeme == '1';
}
/**
* Generate a truth table string for the formula, evaluating it for every possible combination of variables.
* Includes sub-formulas in the output, unless otherwise specified.
*
* @param options Truth table formatting options.
* @returns A string containing the truth table for the formula.
*/
truthTable(options) {
return (0, generateTruthTable_1.generateTruthTable)(this.ast, options);
}
}
exports.Formula = Formula;
// Imports are below the class definition to resolve problems related to circular imports in the compiled output
const AST = __importStar(require("./syntax/ast"));
const parse_1 = require("./syntax/parse");
const token_1 = require("./syntax/token");
const tokenise_1 = require("./syntax/tokenise");
const generate_1 = require("./syntax/generate");
const toString_1 = require("./transform/toString");
const simplify_1 = require("./transform/simplify");
const substitute_1 = require("./transform/substitute");
const cnfExpression_1 = require("./cnf/cnfExpression");
const generateTruthTable_1 = require("./truthtable/generateTruthTable");
;