From f8acdda03c48c651e6e3b3146fb2129a0a64f285 Mon Sep 17 00:00:00 2001 From: JGerla Date: Tue, 13 Jan 2026 08:52:50 +0100 Subject: [PATCH] feat: added rule to prevent cyclical connections between inferred belief nodes ref: N25B-433 --- .../nodes/InferredBeliefNode.tsx | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) 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 */}