import { NodeType } from "../model/Argument"; import { FZ } from "../model/Context"; import { EvaluationError } from "../parser/Evaluator"; import { Macro } from "./Macro"; export abstract class DeductiveMacro extends Macro { protected generateCases(parent: NodeType, premises: string[], defeaters: string[], sets: FZ[], defaultFz: FZ) { const cases: string[] = []; const setNums = this.setsToNumbers(sets); const combs = this.combinations(setNums, premises.length + defeaters.length); for (const C of combs) { // List of combinations is interpreted as: // - Indices 0..k-1 are premise-typed nodes // - Indices k .. N-1 are defeater-typed nodes const k = premises.length; const combPremises = C.slice(0, k); const combDefeaters = C.slice(k) const caseScore = this.scoreCase(parent, combPremises, combDefeaters); const outcome = this.scoreToSet(caseScore, sets); const caseFzSets = combPremises.concat(combDefeaters).map(n => this.scoreToSet(n, sets)); const theCase = this.buildCase(premises.concat(defeaters), caseFzSets, outcome, "and", "<="); cases.push(theCase); } cases.push(`otherwise ${defaultFz.name}`); return `cases\n\t${cases.join(",\n\t")}`; } protected scoreCase(parent: NodeType, P: number[], D: number[]): number { if (P.length + D.length < 1) { throw new EvaluationError(`Cannot expand deductive macro without children`); } if (NodeType.checkSubType(NodeType.PREMISE, parent)) { const dFiltered = D.map(x => Math.max(0, x)); const pSum = P.reduce((S,x) => S+x, 0); const dSum = dFiltered.reduce((S,x) => S+x, 0); if (P.length > 0) { return this.roundScore((pSum - dSum)/(P.length)); } else { return this.roundScore(-1 * dSum); } } else if (NodeType.checkSubType(NodeType.DEFEATER, parent)) { const pFiltered = P.map(x => Math.max(0, x)); const pSum = pFiltered.reduce((S,x) => S+x, 0); const dSum = D.reduce((S,x) => S+x, 0); return this.roundScore((dSum - pSum)/(P.length + D.length)); } } }