Пример #1
0
        /*
         * 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.
        }
Пример #2
0
        /*
         * Copy all the units bound by the precondition into the OutputPool adding a KC_EvaluatablePrologExpression and evaluate the expression.
         */
        protected override void Execute(object[] boundVars)
        {
            // Get the units and the prolog KB from the precondition bindings.
            var  units    = (IEnumerable <Unit>)boundVars[FilteredUnits];
            Unit prologKB = (Unit)boundVars[PrologKB];

            // Copy each of the units to the output pool, adding a KC_EvaluatablePrologExpression and evaluating it.
            foreach (var unit in units)
            {
                Unit unitCopy = CopyUnitToOutputPool(unit);

                // fixme: ignoring the name. When the Unit component infrastructure is updated to handle multiple named components, change the call here.
                KC_PrologExpression expToEvaluate = unitCopy.GetComponent <KC_PrologExpression>();

                // Remove the KC_PrologExpression
                unitCopy.RemoveComponent(expToEvaluate);

                // Create a KC_EvaluatablePrologExpression based on expToEvaluate.
                KC_EvaluatablePrologExpression evaluatablePrologExp = new KC_EvaluatablePrologExpression(expToEvaluate);

                // Add the KC_EvaluatablePrologExpression to the Unit
                unitCopy.AddComponent(evaluatablePrologExp);

                /*
                 * Evaluate the prolog expression.
                 * The original unit now being linked (via CopyUnitToOutputPool) to a unit with a matching and evaled KC_EvaluatablePrologExpression
                 * is what will keep this unit from repeatedly matching in the precondition. The precondition is testing !HasLinkToEvaluatedExpression
                 * as a filter condition.
                 */
                evaluatablePrologExp.Evaluate(prologKB.GetComponent <KC_PrologKB>());
            }
        }