diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/InferredBeliefNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/InferredBeliefNode.tsx index 70062f2..05a772a 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/InferredBeliefNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/InferredBeliefNode.tsx @@ -2,11 +2,12 @@ import { type NodeProps, Position, type Node, - getConnectedEdges + getConnectedEdges, getOutgoers } from '@xyflow/react'; import {useState} from "react"; import { Toolbar } from '../components/NodeComponents.tsx'; import styles from '../../VisProg.module.css'; +import {type HandleRule, type RuleResult, ruleResult} from "../HandleRuleLogic.ts"; import {BeliefReduce} from "./BeliefReduce.ts"; import switchStyles from './InferredBeliefNode.module.css'; import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx"; @@ -100,6 +101,30 @@ export function InferredBeliefDisconnectionSource(_thisNode: Node, _targetNodeId // no additional connection logic exists yet } +/** + * This rule makes it impossible to connect Inferred belief nodes + * if the connection would create a looping connection between inferred beliefs + */ +const noBeliefCycles : HandleRule = (connection, _): RuleResult => { + const { nodes, edges } = useFlowStore.getState(); + function checkForCycle(targetNodeId: string, current: string) : RuleResult { + const outgoingBeliefs = getOutgoers({id: current}, nodes, edges).filter(node => node.type === 'inferred_belief'); + if (outgoingBeliefs.length === 0) return ruleResult.satisfied; + if (outgoingBeliefs.some(node => node.id === targetNodeId)) return ruleResult + .notSatisfied("Cyclical connection exists between inferred beliefs"); + + const next = outgoingBeliefs.map(node => checkForCycle(targetNodeId, node.id)).find(result => !result.isSatisfied); + return next + ? next + : ruleResult.satisfied; + } + + return connection.source === connection.target + ? ruleResult.notSatisfied("Cyclical connection exists between inferred beliefs") + : checkForCycle(connection.source, connection.target); +} + + /** * Defines how a BasicBelief node should be rendered * @param props - Node properties provided by React Flow, including `id` and `data`. @@ -144,14 +169,17 @@ export default function InferredBeliefNode(props: NodeProps) {/* outgoing connections */} {/* incoming connections */}