Skip to content

Commit

Permalink
Finish turing machine
Browse files Browse the repository at this point in the history
  • Loading branch information
irdkwmnsb committed May 9, 2024
1 parent 6128d80 commit 88fcc90
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 10 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"license": "GPL-3.0+",
"devDependencies": {
"@types/cytoscape": "^3.21.0",
"@types/lodash": "^4.14.202",
"@types/node": "^20.10.6",
"@types/react": "^18.2.46",
Expand All @@ -37,6 +38,7 @@
"@fontsource-variable/raleway": "^5.0.19",
"@monaco-editor/react": "^4.6.0",
"classnames": "^2.5.1",
"cytoscape": "^3.29.2",
"immer": "^10.0.3",
"lodash": "^4.17.21",
"monaco-editor": "^0.46.0",
Expand Down
15 changes: 15 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/core/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class RuntimeStore<

updateSnapshot = () => {
this._dataSnapshot = {
curState: this.curState,
curState: _.cloneDeep(this.curState),
curEvent: this.error === undefined ? this.curEvent : {name: "error", error: this.error, state: null},
currentStep: this.curStep,
events: this.events,
Expand Down
4 changes: 2 additions & 2 deletions src/visualizers/turing-machine/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export const manifest: TuringMachineManifest = {
nameEn: "Turing machine",
authorEn: "Alzhanov Maksim",
authorRu: "Альжанов Максим",
descriptionRu: "Машина Тьюринга с одной бесконечной лентой и бесконечным количеством состояний",
descriptionRu: "Машина Тьюринга с одной бесконечной лентой и бесконечным числом состояний",
descriptionEn: "Turing machine with a single infinite tape and infinite number of states"
}


export const { bind, here, store } = initAlgo<TuringMachineState, TuringMachineEvent, TuringMachineArguments, TuringMachineManifest>(manifest)
export const { bind, here, update, store } = initAlgo<TuringMachineState, TuringMachineEvent, TuringMachineArguments, TuringMachineManifest>(manifest)

8 changes: 8 additions & 0 deletions src/visualizers/turing-machine/render.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.graphCanvas {
width: 500px;
height: 500px;
border: 2px #f0f0f0 solid;
box-sizing: border-box;

border-radius: 16px;
}
124 changes: 121 additions & 3 deletions src/visualizers/turing-machine/render.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,140 @@
import _ from "lodash"
import { RenderProps } from "../../core/manifest"
import { SafeRenderProps } from "../../core/manifest"
import { TuringMachineEvent, TuringMachineState } from "./turing-machine"
import { TapeRender } from "./tape-render"
import styles from "./render.module.scss"
import cytoscape from "cytoscape"
import { useEffect, useRef } from "react"

export const TuringMachineRender = ({ curState, curEvent }: RenderProps<TuringMachineState, TuringMachineEvent>) => {

export const TuringMachineRender = ({ curState, curEvent }: SafeRenderProps<TuringMachineState, TuringMachineEvent>) => {
const program = curState.program
const cy = useRef<cytoscape.Core | null>(null)
const graphRef = useRef<HTMLDivElement>(null)
if (curEvent.name === "error") {
return <div>
Error while running: {curEvent.error + ""}
</div>
}
useEffect(() => {
cy.current = cytoscape({
container: graphRef.current,
elements: [],
style: [
{
selector: "edge",
style: {
"curve-style": "bezier",
"target-arrow-shape": "triangle",
"label": "data(fullstring)",
}
},
{
selector: "node",
style: {
"content": "data(id)",
"text-valign": "center",
"text-halign": "center"
}
},
{
selector: ".active",
style: {
"border-width": 3,
"border-color": "black",
"border-style": "solid",
}
},
{
selector: "edge.selected",
style: {
"line-color": "black",
"target-arrow-color": "black"
}
},
{
selector: ".start",
style: {
"background-color": "yellow"
}
},
{
selector: ".accept",
style: {
"background-color": "green"
}
},
{
selector: ".reject",
style: {
"background-color": "red"
}
}
]
})
return () => { cy.current?.destroy() }
}, [])
useEffect(() => {
const newActive = cy.current?.$("#" + curState.machineState.state)
newActive?.addClass("active")
return () => {
const oldActive = cy.current?.$(".active")
oldActive?.removeClass("active")
}
}, [curState])
useEffect(() => {
console.log(curEvent)
if (curEvent.name === "fetch" && curEvent.args[0] !== null) {
const edge = cy.current?.$("#" + curEvent.args[0].lineNumber)
console.log("edge", edge)
edge?.addClass("selected")
}
return () => {
cy.current?.$("edge.selected").removeClass("selected")
}
}, [curEvent])
useEffect(() => {
const {start, accept, reject, rules} = program
const states = new Set([...rules.flatMap((rule) => [rule.curState, rule.newState]), start, accept, reject])
cy.current?.add([...states].map((state) => ({
data: {
id: state
}
})))
cy.current?.$("#" + start).addClass("start")
cy.current?.$("#" + accept).addClass("accept")
cy.current?.$("#" + reject).addClass("reject")
for (const rule of rules) {
cy.current?.add({
data: {
id: rule.lineNumber + "",
source: rule.curState,
target: rule.newState,
fullstring: rule.fullString
}
})
}
const layout = cy.current?.layout({
name: "cose",
idealEdgeLength: () => 4
})
layout?.run()
return () => {
console.log("removing")
cy.current?.remove("")
console.log(cy.current?.elements())
}
}, [JSON.stringify(program)])
return <div>
{curState.machineState.description}
<br/>
<TapeRender tape={curState.tape} headPosition={curState.machineState.curPosition}/>
<br/>
Selected rule:
{
curEvent.name == "fetch" &&
(curEvent.args[0] === null ? "Not found." : curEvent.args[0].fullString)
}
<div className={styles.graphCanvas} ref={graphRef}></div>
</div>
}
}
3 changes: 1 addition & 2 deletions src/visualizers/turing-machine/start.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export const TuringMachineStart = ({ doStart }: StartProps<TuringMachineArgument
}
}, [])
return <div className={styles.startContainer}>
{centerCell}
<div className={styles.tapeContainer}>
{els}
</div>
Expand All @@ -95,7 +94,7 @@ s _ -> ac _ ^
s 0 -> n _ >
n 0 -> s _ >
n _ -> rj _ >"/>
<button onClick={onStart}>Start</button>
<button onClick={onStart(false)}>Start</button>
<button onClick={onStart(true)}>Full run</button>
</div>
}
6 changes: 4 additions & 2 deletions src/visualizers/turing-machine/turing-machine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bind, here } from "."
import { bind, here, update } from "."
import { Tape } from "./tape"

type TapeMove = ">" | "^" | "<"
Expand Down Expand Up @@ -112,6 +112,7 @@ export const turingMachine = async (program: Readonly<string>, startTape: Readon
}
bind("machineState", state)
bind("tape", tapeCopy)
update("program", parsed)
for (;;) {
if (state.curStep > maxSteps) {
state.status = "halted"
Expand Down Expand Up @@ -157,7 +158,8 @@ export const turingMachine = async (program: Readonly<string>, startTape: Readon

export type TuringMachineState = {
tape: Tape,
machineState: InnerState
machineState: InnerState,
program: Program
}

export type TuringMachineEvent = {
Expand Down

0 comments on commit 88fcc90

Please sign in to comment.