UNPKG

propositional

Version:

Propositional logic symbolic computation library

135 lines (134 loc) 5.31 kB
"use strict"; 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");