UNPKG

simple-boolean-table

Version:

A simple Boolean Table Generator with basics operations

125 lines (98 loc) 4.13 kB
import type { IBooleanTable, BinaryType, hashTableRecord } from "./types"; import Tokenizer from "../lexer/index"; import Parser from "../parser"; import Proposition from "../proposition"; import type { TreeNode } from "../parser/types"; import Evaluate from "../evaluate"; import chalk from "chalk"; import { numberToBinary, WORD_WITHOUT_PARENTHENSES } from "../utils"; class BooleanTable implements IBooleanTable { private tokenizer = new Tokenizer(); private evaluateAST = new Evaluate(); private input: string; private table: hashTableRecord<string> = {}; private step: boolean | undefined; constructor(input: string, step?: boolean) { this.input = input; this.step = step; } generateTable() { const tokens = this.tokenizer.tokenizeInput(this.input); const parser = new Parser(tokens); const ast = parser.parseToAST(); const proposition = new Proposition(ast); const propositionsList = proposition.listPropositions(); if (propositionsList.length === 0) { console.log("Provide a valid propositional expression !!!"); return; } this.fillTable(ast, propositionsList); this.printTable(this.table, propositionsList); } fillTable(ast: TreeNode, propositions: string[]) { const propositionsLength = propositions.length; const rows = Math.pow(2, propositionsLength); this.table[this.input] = []; for (let i = 0; i < propositionsLength; i++) { if (this.table[propositions[i]] !== undefined) continue; this.table[propositions[i]] = []; } //all input combinaisons for (let i = 0; i < rows; i++) { let binary = numberToBinary(i, propositionsLength); for (let j = 0; j < propositionsLength; j++) { if (propositions[j] === undefined) { this.table[propositions[j]] = []; } else { this.table[propositions[j]].push(binary[j] === "0" ? "0" : "1"); } } //all subexpressions and expressions const result = this.evaluateAST.evaluateExpression(ast, this.table, i); this.table[this.input].push(result); const evaluations = this.evaluateAST.getEvaluations(); this.fillSubexpressions(evaluations); } } fillSubexpressions(evaluations: Map<TreeNode, BinaryType>) { evaluations.forEach((value, key, callback) => { const subexpression = this.evaluateAST.treeToExpression(key); //verify if input if (subexpression.match(WORD_WITHOUT_PARENTHENSES)?.join("") === this.input.match(WORD_WITHOUT_PARENTHENSES)?.join("")) { return; } if (!this.table[subexpression]) { this.table[subexpression] = []; } if (typeof subexpression !== undefined) { this.table[subexpression].push(value); } }) } printTable(table: hashTableRecord<string>, propositions: string[]): void { console.log() console.log(`Table boolean for : ${chalk.green(`"${this.input}"`)}`); console.log() const allExpressions = [...propositions, ...(this.step ? Object.keys(table).filter((exp) => !propositions.includes(exp) && exp !== this.input) : []), this.input ]; let columnWidths = allExpressions.map((exp) => { return exp.length; }); let header = allExpressions.map((exp, idx) => { return exp.padEnd(columnWidths[idx]); }) .join(" | "); console.log(header); console.log("-".repeat(header.length)); for (let i = 0; i < table[propositions[0]].length; i++) { let row = allExpressions.map((exp, idx) => { return String(table[exp][i]).padEnd(columnWidths[idx]); }).join(" | "); console.log(row); } } } export default BooleanTable;