Add logic for building dependency graph for statement evaluation

This commit is contained in:
2022-04-09 02:12:27 -05:00
parent 8f42f771d8
commit 2aa2a5bf05
6 changed files with 106 additions and 3 deletions

View File

@@ -3,7 +3,9 @@
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import HelloWorld from './components/HelloWorld.vue'
import { MathStatement } from './support/parse'
console.log('math statement', MathStatement)
import { MathPage } from './support/page'
(window as any).Stmt = MathStatement
;(window as any).Pg = MathPage
</script>
<template>

View File

@@ -1,5 +1,7 @@
import {MathStatement} from './parse'
import * as math from 'mathjs'
import {DepGraph} from 'dependency-graph'
import { v4 as uuidv4 } from 'uuid'
export class MathPage {
protected statements: Record<string, MathStatement> = {}
@@ -13,6 +15,10 @@ export class MathPage {
return this
}
addRaw(statement: string): this {
return this.addStatement(new MathStatement(uuidv4(), statement))
}
symbols(): math.SymbolNode[] {
return Object.values(this.statements)
.map(x => x.symbols())
@@ -30,4 +36,32 @@ export class MathPage {
.map(x => x.uses())
.reduce((carry, current) => current.concat(carry), [])
}
dependencies(): DepGraph<MathStatement> {
const graph = new DepGraph<MathStatement>()
const defined: Record<string, MathStatement> = {}
for ( const statement of Object.values(this.statements) ) {
for ( const symbol of statement.defines() ) {
defined[symbol.name] = statement
}
}
for ( const statement of Object.values(this.statements) ) {
graph.addNode(statement.id, statement)
}
for ( const statement of Object.values(this.statements) ) {
for ( const symbol of statement.uses() ) {
const provider = defined[symbol.name]
if ( !provider ) {
throw new Error('No provider for undefined symbol: ' + symbol.name)
}
graph.addDependency(statement.id, provider.id)
}
}
return graph
}
}

View File

@@ -1,5 +1,6 @@
import * as math from 'mathjs'
import {hasOwnProperty} from '../types'
import katex from 'katex'
import {HTMLString, LaTeXString} from '../types'
/** Base class for walks over MathNode trees. */
export abstract class MathNodeWalk<TReturn> {
@@ -261,6 +262,24 @@ export class MathStatement {
return math.parse(this.raw)
}
toLaTeX(): LaTeXString {
return this.parse().toTex() as LaTeXString
}
toHTMLString(): HTMLString {
return katex.renderToString(this.toLaTeX(), {
output: 'mathml',
}) as HTMLString
}
toDOM(): HTMLSpanElement {
const node = document.createElement('span')
katex.render(this.toLaTeX(), node, {
output: 'mathml',
})
return node
}
symbols(): math.SymbolNode[] {
return (new SymbolWalk()).walk(this.parse())
}

View File

@@ -80,3 +80,6 @@ export type Integer = TypeTag<'@app.Integer'> & number
export function isInteger(num: number): num is Integer {
return !isNaN(num) && parseInt(String(num), 10) === num
}
export type LaTeXString = TypeTag<'@app.LaTeXString'> & string
export type HTMLString = TypeTag<'@app.HTMLString'> & string