Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03.1k
1import {makeSpan} from "../buildCommon";2import defineFunction from "../defineFunction";3import {makeLeftRightDelim, makeSizedDelim, sizeToMaxHeight} from "../delimiter";4import {MathNode} from "../mathMLTree";5import ParseError from "../ParseError";6import {assertNodeType, checkSymbolNodeType} from "../parseNode";7import {makeEm} from "../units";8 9import * as html from "../buildHTML";10import * as mml from "../buildMathML";11 12import type Options from "../Options";13import type {AnyParseNode, ParseNode, SymbolParseNode} from "../parseNode";14import type {FunctionContext} from "../defineFunction";15import type {HtmlDomNode} from "../domTree";16 17// Extra data needed for the delimiter handler down below18const delimiterSizes: Record<string, {19 mclass: "mopen" | "mclose" | "mrel" | "mord";20 size: 1 | 2 | 3 | 4;21}> = {22 "\\bigl" : {mclass: "mopen", size: 1},23 "\\Bigl" : {mclass: "mopen", size: 2},24 "\\biggl": {mclass: "mopen", size: 3},25 "\\Biggl": {mclass: "mopen", size: 4},26 "\\bigr" : {mclass: "mclose", size: 1},27 "\\Bigr" : {mclass: "mclose", size: 2},28 "\\biggr": {mclass: "mclose", size: 3},29 "\\Biggr": {mclass: "mclose", size: 4},30 "\\bigm" : {mclass: "mrel", size: 1},31 "\\Bigm" : {mclass: "mrel", size: 2},32 "\\biggm": {mclass: "mrel", size: 3},33 "\\Biggm": {mclass: "mrel", size: 4},34 "\\big" : {mclass: "mord", size: 1},35 "\\Big" : {mclass: "mord", size: 2},36 "\\bigg" : {mclass: "mord", size: 3},37 "\\Bigg" : {mclass: "mord", size: 4},38};39 40const delimiters = new Set([41 "(", "\\lparen", ")", "\\rparen",42 "[", "\\lbrack", "]", "\\rbrack",43 "\\{", "\\lbrace", "\\}", "\\rbrace",44 "\\lfloor", "\\rfloor", "\u230a", "\u230b",45 "\\lceil", "\\rceil", "\u2308", "\u2309",46 "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt",47 "\\lvert", "\\rvert", "\\lVert", "\\rVert",48 "\\lgroup", "\\rgroup", "\u27ee", "\u27ef",49 "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1",50 "/", "\\backslash",51 "|", "\\vert", "\\|", "\\Vert",52 "\\uparrow", "\\Uparrow",53 "\\downarrow", "\\Downarrow",54 "\\updownarrow", "\\Updownarrow",55 ".",56]);57 58type IsMiddle = {delim: string, options: Options};59 60/**61 * An HtmlDomNode that carries an `isMiddle` property, used by the62 * \middle command to communicate delimiter info to the \left/\right builder.63 */64type MiddleDelimNode = HtmlDomNode & {isMiddle: IsMiddle};65 66function isMiddleDelimNode(node: HtmlDomNode): node is MiddleDelimNode {67 return 'isMiddle' in node;68}69 70// Delimiter functions71function checkDelimiter(72 delim: AnyParseNode,73 context: FunctionContext,74): SymbolParseNode {75 const symDelim = checkSymbolNodeType(delim);76 if (symDelim && delimiters.has(symDelim.text)) {77 return symDelim;78 } else if (symDelim) {79 throw new ParseError(80 `Invalid delimiter '${symDelim.text}' after '${context.funcName}'`,81 delim);82 } else {83 throw new ParseError(`Invalid delimiter type '${delim.type}'`, delim);84 }85}86 87defineFunction({88 type: "delimsizing",89 names: [90 "\\bigl", "\\Bigl", "\\biggl", "\\Biggl",91 "\\bigr", "\\Bigr", "\\biggr", "\\Biggr",92 "\\bigm", "\\Bigm", "\\biggm", "\\Biggm",93 "\\big", "\\Big", "\\bigg", "\\Bigg",94 ],95 props: {96 numArgs: 1,97 argTypes: ["primitive"],98 },99 handler: (context, args) => {100 const delim = checkDelimiter(args[0], context);101 102 return {103 type: "delimsizing",104 mode: context.parser.mode,105 size: delimiterSizes[context.funcName].size,106 mclass: delimiterSizes[context.funcName].mclass,107 delim: delim.text,108 };109 },110 htmlBuilder: (group, options) => {111 if (group.delim === ".") {112 // Empty delimiters still count as elements, even though they don't113 // show anything.114 return makeSpan([group.mclass]);115 }116 117 return makeSizedDelim(118 group.delim, group.size, options, group.mode, [group.mclass]);119 },120 mathmlBuilder: (group) => {121 const children = [];122 123 if (group.delim !== ".") {124 children.push(mml.makeText(group.delim, group.mode));125 }126 127 const node = new MathNode("mo", children);128 129 if (group.mclass === "mopen" ||130 group.mclass === "mclose") {131 // Only some of the delimsizing functions act as fences, and they132 // return "mopen" or "mclose" mclass.133 node.setAttribute("fence", "true");134 } else {135 // Explicitly disable fencing if it's not a fence, to override the136 // defaults.137 node.setAttribute("fence", "false");138 }139 140 node.setAttribute("stretchy", "true");141 const size = makeEm(sizeToMaxHeight[group.size]);142 node.setAttribute("minsize", size);143 node.setAttribute("maxsize", size);144 145 return node;146 },147});148 149 150function assertParsed(group: ParseNode<"leftright">) {151 if (!group.body) {152 throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");153 }154}155 156 157defineFunction({158 type: "leftright-right",159 names: ["\\right"],160 props: {161 numArgs: 1,162 primitive: true,163 },164 handler: (context, args) => {165 // \left case below triggers parsing of \right in166 // `const right = parser.parseFunction();`167 // uses this return value.168 const color = context.parser.gullet.macros.get("\\current@color");169 if (color && typeof color !== "string") {170 throw new ParseError(171 "\\current@color set to non-string in \\right");172 }173 return {174 type: "leftright-right",175 mode: context.parser.mode,176 delim: checkDelimiter(args[0], context).text,177 color: color as string | null | undefined, // undefined if not set via \color178 };179 },180});181 182 183defineFunction({184 type: "leftright",185 names: ["\\left"],186 props: {187 numArgs: 1,188 primitive: true,189 },190 handler: (context, args) => {191 const delim = checkDelimiter(args[0], context);192 193 const parser = context.parser;194 // Parse out the implicit body195 ++parser.leftrightDepth;196 // parseExpression stops before '\\right'197 const body = parser.parseExpression(false);198 --parser.leftrightDepth;199 // Check the next token200 parser.expect("\\right", false);201 const right = assertNodeType(parser.parseFunction(), "leftright-right");202 return {203 type: "leftright",204 mode: parser.mode,205 body,206 left: delim.text,207 right: right.delim,208 rightColor: right.color,209 };210 },211 htmlBuilder: (group, options) => {212 assertParsed(group);213 // Build the inner expression214 const inner = html.buildExpression(group.body, options, true,215 ["mopen", "mclose"]);216 217 let innerHeight = 0;218 let innerDepth = 0;219 let hadMiddle = false;220 221 // Calculate its height and depth222 for (let i = 0; i < inner.length; i++) {223 const node = inner[i];224 if (isMiddleDelimNode(node)) {225 hadMiddle = true;226 } else {227 innerHeight = Math.max(inner[i].height, innerHeight);228 innerDepth = Math.max(inner[i].depth, innerDepth);229 }230 }231 232 // The size of delimiters is the same, regardless of what style we are233 // in. Thus, to correctly calculate the size of delimiter we need around234 // a group, we scale down the inner size based on the size.235 innerHeight *= options.sizeMultiplier;236 innerDepth *= options.sizeMultiplier;237 238 let leftDelim;239 if (group.left === ".") {240 // Empty delimiters in \left and \right make null delimiter spaces.241 leftDelim = html.makeNullDelimiter(options, ["mopen"]);242 } else {243 // Otherwise, use leftRightDelim to generate the correct sized244 // delimiter.245 leftDelim = makeLeftRightDelim(246 group.left, innerHeight, innerDepth, options,247 group.mode, ["mopen"]);248 }249 // Add it to the beginning of the expression250 inner.unshift(leftDelim);251 252 // Handle middle delimiters253 if (hadMiddle) {254 for (let i = 1; i < inner.length; i++) {255 const middleDelim = inner[i];256 if (isMiddleDelimNode(middleDelim)) {257 const isMiddle = middleDelim.isMiddle;258 // Apply the options that were active when \middle was called259 inner[i] = makeLeftRightDelim(260 isMiddle.delim, innerHeight, innerDepth,261 isMiddle.options, group.mode, []);262 }263 }264 }265 266 let rightDelim;267 // Same for the right delimiter, but using color specified by \color268 if (group.right === ".") {269 rightDelim = html.makeNullDelimiter(options, ["mclose"]);270 } else {271 const colorOptions = group.rightColor ?272 options.withColor(group.rightColor) : options;273 rightDelim = makeLeftRightDelim(274 group.right, innerHeight, innerDepth, colorOptions,275 group.mode, ["mclose"]);276 }277 // Add it to the end of the expression.278 inner.push(rightDelim);279 280 return makeSpan(["minner"], inner, options);281 },282 mathmlBuilder: (group, options) => {283 assertParsed(group);284 const inner = mml.buildExpression(group.body, options);285 286 if (group.left !== ".") {287 const leftNode = new MathNode(288 "mo", [mml.makeText(group.left, group.mode)]);289 290 leftNode.setAttribute("fence", "true");291 292 inner.unshift(leftNode);293 }294 295 if (group.right !== ".") {296 const rightNode = new MathNode(297 "mo", [mml.makeText(group.right, group.mode)]);298 299 rightNode.setAttribute("fence", "true");300 301 if (group.rightColor) {302 rightNode.setAttribute("mathcolor", group.rightColor);303 }304 305 inner.push(rightNode);306 }307 308 return mml.makeRow(inner);309 },310});311 312defineFunction({313 type: "middle",314 names: ["\\middle"],315 props: {316 numArgs: 1,317 primitive: true,318 },319 handler: (context, args) => {320 const delim = checkDelimiter(args[0], context);321 if (!context.parser.leftrightDepth) {322 throw new ParseError("\\middle without preceding \\left", delim);323 }324 325 return {326 type: "middle",327 mode: context.parser.mode,328 delim: delim.text,329 };330 },331 htmlBuilder: (group, options) => {332 let middleDelim;333 if (group.delim === ".") {334 middleDelim = html.makeNullDelimiter(options, []);335 } else {336 middleDelim = makeSizedDelim(337 group.delim, 1, options,338 group.mode, []);339 340 // Patch an ad-hoc property onto the node so the \left/\right341 // builder can reconstruct appropriately sized middle delimiters.342 // isMiddle is not part of HtmlDomNode; the read side uses343 // isMiddleDelimNode() to check before accessing.344 (middleDelim as unknown as MiddleDelimNode).isMiddle = {345 delim: group.delim, options,346 };347 }348 return middleDelim;349 },350 mathmlBuilder: (group, options) => {351 // A Firefox \middle will stretch a character vertically only if it352 // is in the fence part of the operator dictionary at:353 // https://www.w3.org/TR/MathML3/appendixc.html.354 // So we need to avoid U+2223 and use plain "|" instead.355 const textNode = (group.delim === "\\vert" || group.delim === "|")356 ? mml.makeText("|", "text")357 : mml.makeText(group.delim, group.mode);358 const middleNode = new MathNode("mo", [textNode]);359 middleNode.setAttribute("fence", "true");360 // MathML gives 5/18em spacing to each <mo> element.361 // \middle should get delimiter spacing instead.362 middleNode.setAttribute("lspace", "0.05em");363 middleNode.setAttribute("rspace", "0.05em");364 return middleNode;365 },366});367 