Add logic for building dependency graph for statement evaluation
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user