import { Node, NodeType } from "../model/Argument"; import { CertusContext, FZ } from "../model/Context"; import { EvaluationError } from "../parser/Evaluator"; import { EliminativeMacro } from "./EliminativeMacro"; export class FuseEliminativeMacro extends EliminativeMacro { constructor(name?: string | undefined) { super(name || "fuse_elim"); } public evaluate(ctx: CertusContext): FZ { const root: Node = ctx.getRoot(); const nodes = this.getNodesFromContext(ctx); const P = nodes.filter(n => NodeType.checkSubType(NodeType.PREMISE, n.type)); const D = nodes.filter(n => NodeType.checkSubType(NodeType.DEFEATER, n.type)); if (P.length == 0 && D.length == 0) { return ctx.getDefaultCanonical(root.type); } else { const CS = ctx.getCanonicalSets(); const pScores = P.map(x => this.scoreNode(ctx, x, CS)); const dScores = D.map(x => this.scoreNode(ctx, x, CS)); let result: number = 0; if (NodeType.checkSubType(NodeType.PREMISE, root.type)) { const dSum = dScores.reduce((acc, x) => acc + x, 0); const pSum = pScores.reduce((acc, x) => acc + x, 0); result = (pSum - dSum) / (P.length + D.length) } else if (NodeType.checkSubType(NodeType.DEFEATER, root.type)) { const dSum = dScores.reduce((acc, x) => acc + x, 0); const pSum = pScores.reduce((acc, x) => acc + x, 0); result = (dSum - pSum) / (P.length + D.length); } else { throw new EvaluationError(`Unsupported parent node type ${root.type} when evaluating ${this.name} macro`) } return this.scoreToSet(result, CS); } } public expand(ctx: CertusContext, target?: string): string { const root: Node = ctx.getRoot(); const nodes = this.getNodesFromContext(ctx); const premises = nodes.filter(n => NodeType.checkSubType(NodeType.PREMISE, n.type)).map(x => x.id); const defeaters = nodes.filter(n => NodeType.checkSubType(NodeType.DEFEATER, n.type)).map(x => x.id); if (target) { if (premises.length == 0 && defeaters.length == 0) { return `${target} is ${ctx.getDefaultCanonical(root.type)}` } const expr = this.generateCases(root.type, premises, defeaters, ctx.getCanonicalSets(), ctx.getDefaultCanonical(root.type)); return `${target} is ${expr}` } else { throw new EvaluationError(`${this.name} macro expansion failed without assignment target`); } } }