Add logic for building dependency graph for statement evaluation
This commit is contained in:
parent
8f42f771d8
commit
2aa2a5bf05
@ -11,8 +11,13 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mathjs": "^10.4.3",
|
"@types/katex": "^0.14.0",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
|
"dependency-graph": "^0.11.0",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
|
"katex": "^0.15.3",
|
||||||
|
"mathjs": "^10.4.3",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
"vue": "^3.2.25",
|
"vue": "^3.2.25",
|
||||||
"vue-router": "^4.0.14"
|
"vue-router": "^4.0.14"
|
||||||
},
|
},
|
||||||
|
@ -2,22 +2,32 @@ lockfileVersion: 5.3
|
|||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@braks/revue-draggable': ^0.4.2
|
'@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/eslint-plugin': ^5.18.0
|
||||||
'@typescript-eslint/parser': ^5.18.0
|
'@typescript-eslint/parser': ^5.18.0
|
||||||
'@vitejs/plugin-vue': ^2.3.1
|
'@vitejs/plugin-vue': ^2.3.1
|
||||||
'@volar/vue-language-service': ^0.33.9
|
'@volar/vue-language-service': ^0.33.9
|
||||||
|
dependency-graph: ^0.11.0
|
||||||
eslint: ^8.13.0
|
eslint: ^8.13.0
|
||||||
install: ^0.13.0
|
install: ^0.13.0
|
||||||
|
katex: ^0.15.3
|
||||||
mathjs: ^10.4.3
|
mathjs: ^10.4.3
|
||||||
typescript: ^4.5.4
|
typescript: ^4.5.4
|
||||||
|
uuid: ^8.3.2
|
||||||
vite: ^2.9.0
|
vite: ^2.9.0
|
||||||
vue: ^3.2.25
|
vue: ^3.2.25
|
||||||
vue-router: ^4.0.14
|
vue-router: ^4.0.14
|
||||||
vue-tsc: ^0.33.9
|
vue-tsc: ^0.33.9
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@types/katex': 0.14.0
|
||||||
|
'@types/uuid': 8.3.4
|
||||||
|
dependency-graph: 0.11.0
|
||||||
install: 0.13.0
|
install: 0.13.0
|
||||||
|
katex: 0.15.3
|
||||||
mathjs: 10.4.3
|
mathjs: 10.4.3
|
||||||
|
uuid: 8.3.2
|
||||||
vue: 3.2.31
|
vue: 3.2.31
|
||||||
vue-router: 4.0.14_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==}
|
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/katex/0.14.0:
|
||||||
|
resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/minimatch/3.0.5:
|
/@types/minimatch/3.0.5:
|
||||||
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
|
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -315,6 +329,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/uuid/8.3.4:
|
||||||
|
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/vfile-message/2.0.0:
|
/@types/vfile-message/2.0.0:
|
||||||
resolution: {integrity: sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==}
|
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.
|
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==}
|
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/commander/8.3.0:
|
||||||
|
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
|
||||||
|
engines: {node: '>= 12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/complex.js/2.1.0:
|
/complex.js/2.1.0:
|
||||||
resolution: {integrity: sha512-RdcrDz7YynXp/YXGwXIZ4MtmxXXniT5WmLFRX93cuXUX+0geWAqB8l1BoLXF+3BkzviVzHlpw27P9ow7MvlcmA==}
|
resolution: {integrity: sha512-RdcrDz7YynXp/YXGwXIZ4MtmxXXniT5WmLFRX93cuXUX+0geWAqB8l1BoLXF+3BkzviVzHlpw27P9ow7MvlcmA==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -1147,6 +1170,11 @@ packages:
|
|||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
dev: true
|
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:
|
/dir-glob/3.0.1:
|
||||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -2200,6 +2228,13 @@ packages:
|
|||||||
promise: 7.3.1
|
promise: 7.3.1
|
||||||
dev: true
|
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:
|
/keyv/3.1.0:
|
||||||
resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
|
resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -3500,6 +3535,11 @@ packages:
|
|||||||
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
|
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/uuid/8.3.2:
|
||||||
|
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/v8-compile-cache/2.3.0:
|
/v8-compile-cache/2.3.0:
|
||||||
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
|
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
|
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
|
||||||
import HelloWorld from './components/HelloWorld.vue'
|
import HelloWorld from './components/HelloWorld.vue'
|
||||||
import { MathStatement } from './support/parse'
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import {MathStatement} from './parse'
|
import {MathStatement} from './parse'
|
||||||
import * as math from 'mathjs'
|
import * as math from 'mathjs'
|
||||||
|
import {DepGraph} from 'dependency-graph'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
export class MathPage {
|
export class MathPage {
|
||||||
protected statements: Record<string, MathStatement> = {}
|
protected statements: Record<string, MathStatement> = {}
|
||||||
@ -13,6 +15,10 @@ export class MathPage {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addRaw(statement: string): this {
|
||||||
|
return this.addStatement(new MathStatement(uuidv4(), statement))
|
||||||
|
}
|
||||||
|
|
||||||
symbols(): math.SymbolNode[] {
|
symbols(): math.SymbolNode[] {
|
||||||
return Object.values(this.statements)
|
return Object.values(this.statements)
|
||||||
.map(x => x.symbols())
|
.map(x => x.symbols())
|
||||||
@ -30,4 +36,32 @@ export class MathPage {
|
|||||||
.map(x => x.uses())
|
.map(x => x.uses())
|
||||||
.reduce((carry, current) => current.concat(carry), [])
|
.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 * as math from 'mathjs'
|
||||||
import {hasOwnProperty} from '../types'
|
import katex from 'katex'
|
||||||
|
import {HTMLString, LaTeXString} from '../types'
|
||||||
|
|
||||||
/** Base class for walks over MathNode trees. */
|
/** Base class for walks over MathNode trees. */
|
||||||
export abstract class MathNodeWalk<TReturn> {
|
export abstract class MathNodeWalk<TReturn> {
|
||||||
@ -261,6 +262,24 @@ export class MathStatement {
|
|||||||
return math.parse(this.raw)
|
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[] {
|
symbols(): math.SymbolNode[] {
|
||||||
return (new SymbolWalk()).walk(this.parse())
|
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 {
|
export function isInteger(num: number): num is Integer {
|
||||||
return !isNaN(num) && parseInt(String(num), 10) === num
|
return !isNaN(num) && parseInt(String(num), 10) === num
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LaTeXString = TypeTag<'@app.LaTeXString'> & string
|
||||||
|
export type HTMLString = TypeTag<'@app.HTMLString'> & string
|
||||||
|
Loading…
Reference in New Issue
Block a user