Add logic for building dependency graph for statement evaluation

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

View File

@ -11,8 +11,13 @@
"preview": "vite preview"
},
"dependencies": {
"mathjs": "^10.4.3",
"@types/katex": "^0.14.0",
"@types/uuid": "^8.3.4",
"dependency-graph": "^0.11.0",
"install": "^0.13.0",
"katex": "^0.15.3",
"mathjs": "^10.4.3",
"uuid": "^8.3.2",
"vue": "^3.2.25",
"vue-router": "^4.0.14"
},

View File

@ -2,22 +2,32 @@ lockfileVersion: 5.3
specifiers:
'@braks/revue-draggable': ^0.4.2
'@types/katex': ^0.14.0
'@types/uuid': ^8.3.4
'@typescript-eslint/eslint-plugin': ^5.18.0
'@typescript-eslint/parser': ^5.18.0
'@vitejs/plugin-vue': ^2.3.1
'@volar/vue-language-service': ^0.33.9
dependency-graph: ^0.11.0
eslint: ^8.13.0
install: ^0.13.0
katex: ^0.15.3
mathjs: ^10.4.3
typescript: ^4.5.4
uuid: ^8.3.2
vite: ^2.9.0
vue: ^3.2.25
vue-router: ^4.0.14
vue-tsc: ^0.33.9
dependencies:
'@types/katex': 0.14.0
'@types/uuid': 8.3.4
dependency-graph: 0.11.0
install: 0.13.0
katex: 0.15.3
mathjs: 10.4.3
uuid: 8.3.2
vue: 3.2.31
vue-router: 4.0.14_vue@3.2.31
@ -295,6 +305,10 @@ packages:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
/@types/katex/0.14.0:
resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==}
dev: false
/@types/minimatch/3.0.5:
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
dev: true
@ -315,6 +329,10 @@ packages:
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
dev: true
/@types/uuid/8.3.4:
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
dev: false
/@types/vfile-message/2.0.0:
resolution: {integrity: sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==}
deprecated: This is a stub types definition. vfile-message provides its own type definitions, so you do not need this installed.
@ -995,6 +1013,11 @@ packages:
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
dev: true
/commander/8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
dev: false
/complex.js/2.1.0:
resolution: {integrity: sha512-RdcrDz7YynXp/YXGwXIZ4MtmxXXniT5WmLFRX93cuXUX+0geWAqB8l1BoLXF+3BkzviVzHlpw27P9ow7MvlcmA==}
dev: false
@ -1147,6 +1170,11 @@ packages:
slash: 3.0.0
dev: true
/dependency-graph/0.11.0:
resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==}
engines: {node: '>= 0.6.0'}
dev: false
/dir-glob/3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@ -2200,6 +2228,13 @@ packages:
promise: 7.3.1
dev: true
/katex/0.15.3:
resolution: {integrity: sha512-Al6V7RJsmjklT9QItyHWGaQCt+NYTle1bZwB1e9MR/tLoIT1MXaHy9UpfGSB7eaqDgjjqqRxQOaQGrALCrEyBQ==}
hasBin: true
dependencies:
commander: 8.3.0
dev: false
/keyv/3.1.0:
resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
dependencies:
@ -3500,6 +3535,11 @@ packages:
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
dev: true
/uuid/8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
dev: false
/v8-compile-cache/2.3.0:
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
dev: true

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