Skip to content

Commit

Permalink
[half-edge] PortEntry -- connection through HalfEdge
Browse files Browse the repository at this point in the history
- `connectPorts`
- `connectHalfEdges`
- `connectPortWithHalfEdge`
- remove active edge during `interact`
  • Loading branch information
xieyuheng committed Sep 17, 2023
1 parent 52add32 commit 21c2489
Show file tree
Hide file tree
Showing 38 changed files with 337 additions and 132 deletions.
6 changes: 4 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# half-edge

[half-edge] `PortEntry` -- `connection` through `HalfEdge`
[half-edge] rename `net.activeEdges` to `net.activePortPairs`

[half-edge] `Edge` has two `HalfEdge`s

[half-edge] `HalfEdge` should be a kind of `Value`
[half-edge] `HalfEdge` should be a kind of `Value` -- `Port` should quit being a `Value`

[half-edge] avoid using `closeAllFreePorts`

[half-edge] `@edge` as a builtin to create two `HalfEdge`s

[half-edge] refactor

# docs

[docs] add mimor to inet docs
Expand Down
4 changes: 2 additions & 2 deletions src/lang/builtins/connect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ComposeOptions } from "../compose/compose"
import { connect } from "../connect/connect"
import { connectPorts } from "../connect/connectPorts"
import { Env } from "../env"
import { unifyTypes } from "../unify/unifyTypes"
import { formatValue } from "../value/formatValue"
Expand Down Expand Up @@ -46,7 +46,7 @@ export function compose(env: Env, options: ComposeOptions): void {
)
}

connect(env.net, first, second)
connectPorts(env.net, first, second)
if (options.checking) {
unifyTypes(env, options.checking.substitution, first.t, second.t)
}
Expand Down
4 changes: 2 additions & 2 deletions src/lang/cap/capInputPort.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { connect } from "../connect/connect"
import { connectPorts } from "../connect/connectPorts"
import { Mod } from "../mod"
import { Net } from "../net"
import { addNode } from "../net/addNode"
Expand All @@ -23,6 +23,6 @@ export function capInputPort(mod: Mod, net: Net, port: Port): Port {
}

const capPort = findOutputPorts(net, node)[0]
connect(net, port, capPort)
connectPorts(net, port, capPort)
return capPort
}
4 changes: 2 additions & 2 deletions src/lang/cap/capOutputPort.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { connect } from "../connect/connect"
import { connectPorts } from "../connect/connectPorts"
import { Mod } from "../mod"
import { Net } from "../net"
import { addNode } from "../net/addNode"
Expand All @@ -23,6 +23,6 @@ export function capOutputPort(mod: Mod, net: Net, port: Port): Port {
}

const capPort = findInputPorts(net, node)[0]
connect(net, port, capPort)
connectPorts(net, port, capPort)
return capPort
}
4 changes: 2 additions & 2 deletions src/lang/check/checkPortSigns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function checkPortSigns(net: Net, first: Port, second: Port): void {
if (first.sign === 1 && second.sign === 1) {
throw new Error(
[
`[checkSigns] I expect the two ports to have opposite signs,`,
`[checkPortSigns] I expect the two ports to have opposite signs,`,
` but they all have positive sign.`,
``,
` first port: ${formatPort(net, first)}`,
Expand All @@ -18,7 +18,7 @@ export function checkPortSigns(net: Net, first: Port, second: Port): void {
if (first.sign === -1 && second.sign === -1) {
throw new Error(
[
`[checkSigns] I expect the two ports to have opposite signs,`,
`[checkPortSigns] I expect the two ports to have opposite signs,`,
` but they all have negative sign.`,
``,
` first port: ${formatPort(net, first)}`,
Expand Down
4 changes: 2 additions & 2 deletions src/lang/compose/compose.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Checking } from "../checking"
import { connect } from "../connect/connect"
import { connectPorts } from "../connect/connectPorts"
import { Env } from "../env"
import { appendReport } from "../errors/appendReport"
import { Mod } from "../mod"
Expand Down Expand Up @@ -142,7 +142,7 @@ export function compose(
)
}

connect(env.net, value, currentPort)
connectPorts(env.net, value, currentPort)
if (options.checking) {
unifyTypes(env, options.checking.substitution, value.t, currentPort.t)
}
Expand Down
5 changes: 3 additions & 2 deletions src/lang/compose/composeNode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { connect } from "../connect/connect"
import { connectPorts } from "../connect/connectPorts"
import { Env } from "../env"
import { refreshNode } from "../freshen/refreshNode"
import { findInputPorts } from "../net/findInputPorts"
Expand Down Expand Up @@ -39,7 +39,8 @@ export function composeNode(
)
}

connect(env.net, value, port)
connectPorts(env.net, value, port)

if (options.checking) {
unifyTypes(env, options.checking.substitution, value.t, port.t)
}
Expand Down
25 changes: 21 additions & 4 deletions src/lang/compose/findCurrentPortOrFail.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Net } from "../net"
import { findHalfEdgeEntry } from "../net/findHalfEdgeEntry"
import { findInputPorts } from "../net/findInputPorts"
import { findOutputPorts } from "../net/findOutputPorts"
import { findPortEntry } from "../net/findPortEntry"
Expand Down Expand Up @@ -66,15 +67,31 @@ function findPortInNode(
): Port | undefined {
for (const port of findInputPorts(net, node)) {
if (port.name === portName) {
const portEntry = findPortEntry(net, port)
return portEntry?.connection?.port
return findCorrespondingPort(net, port)
}
}

for (const port of findOutputPorts(net, node)) {
if (port.name === portName) {
const portEntry = findPortEntry(net, port)
return portEntry?.connection?.port
return findCorrespondingPort(net, port)
}
}
}

function findCorrespondingPort(net: Net, port: Port): Port | undefined {
const portEntry = findPortEntry(net, port)

if (portEntry === undefined) return
if (portEntry.connection === undefined) return

const halfEdge = portEntry.connection.halfEdge
const halfEdgeEntry = findHalfEdgeEntry(net, halfEdge)

if (halfEdgeEntry === undefined) return

const ohterHalfEdgeEntry = findHalfEdgeEntry(net, halfEdgeEntry.otherHalfEdge)

if (ohterHalfEdgeEntry === undefined) return

return ohterHalfEdgeEntry.port
}
31 changes: 31 additions & 0 deletions src/lang/connect/connectHalfEdges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { HalfEdge } from "../half-edge"
import { Net } from "../net"
import { deleteHalfEdgeEntry } from "../net/deleteHalfEdgeEntry"
import { findHalfEdgeEntryOrFail } from "../net/findHalfEdgeEntryOrFail"

export function connectHalfEdges(
net: Net,
firstHalfEdge: HalfEdge,
secondHalfEdge: HalfEdge,
): void {
const firstHalfEdgeEntry = findHalfEdgeEntryOrFail(net, firstHalfEdge)
const secondHalfEdgeEntry = findHalfEdgeEntryOrFail(net, secondHalfEdge)

const firstOtherHalfEdge = firstHalfEdgeEntry.otherHalfEdge
const secondOtherHalfEdge = secondHalfEdgeEntry.otherHalfEdge

const firstOtherHalfEdgeEntry = findHalfEdgeEntryOrFail(
net,
firstOtherHalfEdge,
)
const secondOtherHalfEdgeEntry = findHalfEdgeEntryOrFail(
net,
secondOtherHalfEdge,
)

firstOtherHalfEdgeEntry.otherHalfEdge = secondOtherHalfEdge
secondOtherHalfEdgeEntry.otherHalfEdge = firstOtherHalfEdge

deleteHalfEdgeEntry(net, firstHalfEdge)
deleteHalfEdgeEntry(net, secondHalfEdge)
}
42 changes: 42 additions & 0 deletions src/lang/connect/connectPortWithHalfEdge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { edgeEqual } from "../edge"
import { HalfEdge } from "../half-edge"
import { Net } from "../net"
import { findHalfEdgeEntryOrFail } from "../net/findHalfEdgeEntryOrFail"
import { findPortRecordOrFail } from "../net/findPortRecordOrFail"
import { Port } from "../port"

export function connectPortWithHalfEdge(
net: Net,
port: Port,
halfEdge: HalfEdge,
): void {
const portRecord = findPortRecordOrFail(net, port.node)
portRecord[port.name].connection = { halfEdge }

const halfEdgeEntry = findHalfEdgeEntryOrFail(net, halfEdge)
if (halfEdgeEntry.port !== undefined) {
throw new Error(
`[connectPortWithHalfEdge] halfEdgeEntry is already connected`,
)
}

halfEdgeEntry.port = port

const otherHalfEdgeEntry = findHalfEdgeEntryOrFail(
net,
halfEdgeEntry.otherHalfEdge,
)

if (otherHalfEdgeEntry.port !== undefined) {
if (port.isPrincipal && otherHalfEdgeEntry.port.isPrincipal) {
const edge = {
first: port,
second: otherHalfEdgeEntry.port,
}

if (!net.activeEdges.find((activeEdge) => edgeEqual(activeEdge, edge))) {
net.activeEdges.push(edge)
}
}
}
}
26 changes: 6 additions & 20 deletions src/lang/connect/connect.ts → src/lang/connect/connectPorts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { checkPortSigns } from "../check/checkPortSigns"
import { Net } from "../net"
import { addEdge } from "../net/addEdge"
import { findPortEntry } from "../net/findPortEntry"
import { findPortRecordOrFail } from "../net/findPortRecordOrFail"
import { Port } from "../port"
import { formatPort } from "../port/formatPort"
import { connectPortWithHalfEdge } from "./connectPortWithHalfEdge"

export function connect(net: Net, first: Port, second: Port): void {
export function connectPorts(net: Net, first: Port, second: Port): void {
const firstPortEntry = findPortEntry(net, first)

if (firstPortEntry?.connection !== undefined) {
Expand All @@ -14,10 +15,6 @@ export function connect(net: Net, first: Port, second: Port): void {
`[connect] The first port is already connected.`,
``,
` first port: ${formatPort(net, first)}`,
` first connected port: ${formatPort(
net,
firstPortEntry.connection.port,
)}`,
` second port: ${formatPort(net, second)}`,
].join("\n"),
)
Expand All @@ -32,25 +29,14 @@ export function connect(net: Net, first: Port, second: Port): void {
``,
` first port: ${formatPort(net, first)}`,
` second port: ${formatPort(net, second)}`,
` second connected port: ${formatPort(
net,
secondPortEntry.connection.port,
)}`,
].join("\n"),
)
}

checkPortSigns(net, first, second)

const edge = { first, second }
const halfEdges = addEdge(net)

const firstPortRecord = findPortRecordOrFail(net, first.node)
firstPortRecord[first.name].connection = { port: second }

const secondPortRecord = findPortRecordOrFail(net, second.node)
secondPortRecord[second.name].connection = { port: first }

if (first.isPrincipal && second.isPrincipal) {
net.activeEdges.push(edge)
}
connectPortWithHalfEdge(net, first, halfEdges.first)
connectPortWithHalfEdge(net, second, halfEdges.second)
}
6 changes: 3 additions & 3 deletions src/lang/half-edge/createHalfEdgeId.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Mod } from "../mod"
import { globalHalfEdgeInfo } from "./globalHalfEdgeInfo"

export function createHalfEdgeId(mod: Mod): string {
const n = mod.halfEdgeCounter++
export function createHalfEdgeId(): string {
const n = globalHalfEdgeInfo.counter++
return n.toString()
}
3 changes: 3 additions & 0 deletions src/lang/half-edge/globalHalfEdgeInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const globalHalfEdgeInfo = {
counter: 0,
}
14 changes: 14 additions & 0 deletions src/lang/interact/interact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { compose } from "../compose/compose"
import { Edge } from "../edge"
import { Env } from "../env"
import { findRuleByPorts } from "../mod/findRuleByPorts"
import { deleteHalfEdgeEntry } from "../net/deleteHalfEdgeEntry"
import { deleteNodeEntry } from "../net/deleteNodeEntry"
import { findPortEntryOrFail } from "../net/findPortEntryOrFail"

export type InteractOptions = {
checking?: Checking
Expand All @@ -15,6 +17,7 @@ export function interact(
options: InteractOptions,
): void {
const rule = findRuleByPorts(env.mod, activeEdge.first, activeEdge.second)

if (rule === undefined) return

for (const word of rule.words) {
Expand All @@ -27,6 +30,17 @@ export function interact(
})
}

const firstPortEntry = findPortEntryOrFail(env.net, activeEdge.first)
const secondPortEntry = findPortEntryOrFail(env.net, activeEdge.second)

if (firstPortEntry.connection !== undefined) {
deleteHalfEdgeEntry(env.net, firstPortEntry.connection.halfEdge)
}

if (secondPortEntry.connection !== undefined) {
deleteHalfEdgeEntry(env.net, secondPortEntry.connection.halfEdge)
}

deleteNodeEntry(env.net, activeEdge.first.node)
deleteNodeEntry(env.net, activeEdge.second.node)
}
2 changes: 0 additions & 2 deletions src/lang/mod/Mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,4 @@ export type Mod = {
builtins: Map<string, Definition>
ruleEntries: Map<string, RuleEntry>
requiredMods: Map<string, Mod>
nodeCounters: Map<string, number>
halfEdgeCounter: number
}
2 changes: 0 additions & 2 deletions src/lang/mod/createMod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export function createMod(options: {
builtins: new Map(),
ruleEntries: new Map(),
requiredMods: new Map(),
nodeCounters: new Map(),
halfEdgeCounter: 0,
} as Mod

mod.env = createEnv(mod)
Expand Down
7 changes: 4 additions & 3 deletions src/lang/mod/findRuleByNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export function findRuleByNodes(
const firstKey = nodeKeyWithoutId(firstNode)
const secondKey = nodeKeyWithoutId(secondNode)

const key = `${firstKey} ${secondKey}`

return mod.ruleEntries.get(key)
return (
mod.ruleEntries.get(`${firstKey} ${secondKey}`) ||
mod.ruleEntries.get(`${secondKey} ${firstKey}`)
)
}
5 changes: 2 additions & 3 deletions src/lang/net/Net.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type Net = {
export type HalfEdgeEntry = {
id: string
port?: Port
otherHalf?: HalfEdge
otherHalfEdge: HalfEdge
}

export type NodeEntry = {
Expand Down Expand Up @@ -56,6 +56,5 @@ export type PortEntry = {
// interfere with each other.

export type Connection = {
// halfEdge: HalfEdge
port: Port
halfEdge: HalfEdge
}
Loading

0 comments on commit 21c2489

Please sign in to comment.