All files / src/pages/VisProgPage/visualProgrammingUI/nodes BeliefGlobals.ts

0% Statements 0/26
0% Branches 0/18
0% Functions 0/9
0% Lines 0/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63                                                                                                                             
import {getOutgoers, type Node} from '@xyflow/react';
import {type HandleRule, type RuleResult, ruleResult} from "../HandleRuleLogic.ts";
import useFlowStore from "../VisProgStores.tsx";
import {BasicBeliefReduce} from "./BasicBeliefNode.tsx";
import {type InferredBeliefNodeData, InferredBeliefReduce} from "./InferredBeliefNode.tsx";
 
export function BeliefGlobalReduce(beliefNode: Node, nodes: Node[]) {
  switch (beliefNode.type) {
    case 'basic_belief':
      return BasicBeliefReduce(beliefNode, nodes);
    case 'inferred_belief':
      return InferredBeliefReduce(beliefNode, nodes);
  }
}
 
export const noMatchingLeftRightBelief : HandleRule = (connection, _)=> {
  const { nodes } = useFlowStore.getState();
  const thisNode = nodes.find(node => node.id === connection.target && node.type === 'inferred_belief');
  if (!thisNode) return ruleResult.satisfied;
 
  const iBelief = (thisNode.data as InferredBeliefNodeData).inferredBelief;
  return (iBelief.left === connection.source || iBelief.right === connection.source)
    ? ruleResult.notSatisfied("Connecting one belief to both input handles of an inferred belief node is not allowed")
    : ruleResult.satisfied;
}
/**
 * makes it impossible to connect Inferred belief nodes
 * if the connection would create a cyclical connection between inferred beliefs
 */
export const noBeliefCycles: HandleRule = (connection, _): RuleResult => {
  const {nodes, edges} = useFlowStore.getState();
  const defaultErrorMessage = "Cyclical connection exists between inferred beliefs";
 
  /**
   * recursively checks for cyclical connections between InferredBelief nodes
   *
   * to check for a cycle provide the source of an attempted connection as the targetNode for the cycle check,
   * the currentNodeId should be initialised with the id of the targetNode of the attempted connection.
   *
   * @param {string} targetNodeId - the id of the node we are looking for as the endpoint of a cyclical connection
   * @param {string} currentNodeId - the id of the node we are checking for outgoing connections to the provided target node
   * @returns {RuleResult}
   */
  function checkForCycle(targetNodeId: string, currentNodeId: string): RuleResult {
    const outgoingBeliefs = getOutgoers({id: currentNodeId}, 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(defaultErrorMessage);
 
    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(defaultErrorMessage)
    : checkForCycle(connection.source, connection.target);
};