feat: added rule to prevent cyclical connections between inferred belief nodes
ref: N25B-433
This commit is contained in:
@@ -2,11 +2,12 @@ import {
|
|||||||
type NodeProps,
|
type NodeProps,
|
||||||
Position,
|
Position,
|
||||||
type Node,
|
type Node,
|
||||||
getConnectedEdges
|
getConnectedEdges, getOutgoers
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import { Toolbar } from '../components/NodeComponents.tsx';
|
import { Toolbar } from '../components/NodeComponents.tsx';
|
||||||
import styles from '../../VisProg.module.css';
|
import styles from '../../VisProg.module.css';
|
||||||
|
import {type HandleRule, type RuleResult, ruleResult} from "../HandleRuleLogic.ts";
|
||||||
import {BeliefReduce} from "./BeliefReduce.ts";
|
import {BeliefReduce} from "./BeliefReduce.ts";
|
||||||
import switchStyles from './InferredBeliefNode.module.css';
|
import switchStyles from './InferredBeliefNode.module.css';
|
||||||
import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
||||||
@@ -100,6 +101,30 @@ export function InferredBeliefDisconnectionSource(_thisNode: Node, _targetNodeId
|
|||||||
// no additional connection logic exists yet
|
// 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
|
* Defines how a BasicBelief node should be rendered
|
||||||
* @param props - Node properties provided by React Flow, including `id` and `data`.
|
* @param props - Node properties provided by React Flow, including `id` and `data`.
|
||||||
@@ -144,14 +169,17 @@ export default function InferredBeliefNode(props: NodeProps<InferredBeliefNode>)
|
|||||||
{/* outgoing connections */}
|
{/* outgoing connections */}
|
||||||
<MultiConnectionHandle type="source" position={Position.Right} id="source" rules={[
|
<MultiConnectionHandle type="source" position={Position.Right} id="source" rules={[
|
||||||
allowOnlyConnectionsFromType(["norm", "trigger"]),
|
allowOnlyConnectionsFromType(["norm", "trigger"]),
|
||||||
|
noBeliefCycles
|
||||||
]}/>
|
]}/>
|
||||||
|
|
||||||
{/* incoming connections */}
|
{/* incoming connections */}
|
||||||
<SingleConnectionHandle type="target" position={Position.Left} style={{top: '30%'}} id="beliefLeft" rules={[
|
<SingleConnectionHandle type="target" position={Position.Left} style={{top: '30%'}} id="beliefLeft" rules={[
|
||||||
allowOnlyConnectionsFromType(["basic_belief", "inferred_belief"]),
|
allowOnlyConnectionsFromType(["basic_belief", "inferred_belief"]),
|
||||||
|
noBeliefCycles
|
||||||
]}/>
|
]}/>
|
||||||
<SingleConnectionHandle type="target" position={Position.Left} style={{top: '70%'}} id="beliefRight" rules={[
|
<SingleConnectionHandle type="target" position={Position.Left} style={{top: '70%'}} id="beliefRight" rules={[
|
||||||
allowOnlyConnectionsFromType(["basic_belief", "inferred_belief"]),
|
allowOnlyConnectionsFromType(["basic_belief", "inferred_belief"]),
|
||||||
|
noBeliefCycles
|
||||||
]}/>
|
]}/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user