/* * Returns true if the KC_PrologExpression on the unit has already been evaluated, false otherwise. * Given a unit containing a KC_PrologExpression and a blackboard, returns true if there is a * L_SelectedUnitLink to a Unit with a KC_EvaluatablePrologExpression matching the KC_PrologExpression. */ protected static bool HasLinkToEvaluatedExpression(Unit unit, IBlackboard blackboard) { ISet <(IUnit, string, LinkDirection)> links = blackboard.LookupLinks(unit); foreach ((IUnit linkedIUnit, string type, LinkDirection dir) in links) { /* * There should only be up to 1 outgoing L_SelectedUnit link, but since I'm not enforcing this on the blackboard, * for now testing all L_SelectedUnit links until I find a matching KC_EvaluatablePrologExpression */ if (type.Equals(LinkTypes.L_SelectedUnit) && dir == LinkDirection.End) { Unit linkedUnit = linkedIUnit as Unit; // If the linkedUnit contains a matching, evaluated, KC_EvaluatablePrologExpression, return true. if (linkedUnit.HasComponent <KC_EvaluatablePrologExpression>()) { KC_EvaluatablePrologExpression evaledPrologExp = linkedUnit.GetComponent <KC_EvaluatablePrologExpression>(); if (evaledPrologExp.PrologExpName.Equals(unit.GetPrologExpName <KC_PrologExpression>()) && evaledPrologExp.Evaluated) { Debug.Assert(evaledPrologExp.PrologExp.Equals(unit.GetPrologExp())); return(true); } /* fixme * Consider making this recursively search links if the linked Unit has an EvaluatablePrologExpression with a matching name but it has * not been evaluated (though currently there's no KS in the system that does this) OR there's a PrologExpression with a matching name. * The latter is a likely use case. If we downselected in a pool with prolog expressions first, then evaluated those, that would result * in this case. */ } } } return(false); // No linked, matching KC_EvaluatablePrologExpression was found. }
public static Unit FindOriginalUnit(Unit unit, IBlackboard blackboard) { var linkToPreviousUnitsInFilterChain = from link in blackboard.LookupLinks(unit) where link.LinkType.Equals(LinkTypes.L_SelectedUnit) where link.Direction.Equals(LinkDirection.Start) select link; int count = linkToPreviousUnitsInFilterChain.Count(); // There should be 0 (if we've reached the original) or 1 (if we're still crawling back up the filter chain) links. Debug.Assert(count == 0 || count == 1); if (count == 0) { return(unit); // The passed in CU was the parent of a chain. } else { // Recursively search back up the filter chain (IUnit previousUnitInChain, _, _) = linkToPreviousUnitsInFilterChain.ElementAt(0); return(FindOriginalUnit((Unit)previousUnitInChain, blackboard)); } }