Example #1
0
 /// <summary>
 /// Checks if a <typeparamref name="TFact"/> fact can be retrieved from a container.
 /// </summary>
 /// <inheritdoc/>
 public override bool Condition <TFactWork, TFactRule, TWantAction, TFactContainer>(TFactWork factWork, IFactRulesContext <TFactRule, TWantAction, TFactContainer> context)
 {
     return(context.SingleEntity.CanExtractFact(GetFactType <TFact>(), factWork, context));
 }
Example #2
0
 /// <summary>
 /// Checks if a <typeparamref name="TFact"/> fact can be retrieved from a container.
 /// </summary>
 /// <inheritdoc/>
 public override bool Condition <TFactWork, TFactRule, TWantAction, TFactContainer>(TFactWork factWork, IFactRulesContext <TFactRule, TWantAction, TFactContainer> context)
 {
     return(!ConditionHelper.CanDeriveFact(
                this,
                GetFactType <TFact>(),
                factWork,
                context));
 }
 /// <inheritdoc/>
 public abstract bool Condition <TFactWork, TFactRule, TWantAction, TFactContainer>(TFactWork factWork, IFactRulesContext <TFactRule, TWantAction, TFactContainer> context)
     where TFactWork : IFactWork
     where TFactRule : IFactRule
     where TWantAction : IWantAction
     where TFactContainer : IFactContainer;
        /// <summary>
        /// Determines you can no longer consider the <paramref name="factType"/> necessary.
        /// </summary>
        /// <typeparam name="TFactRule">FactRole type.</typeparam>
        /// <typeparam name="TWantAction">WantAction type.</typeparam>
        /// <typeparam name="TFactContainer">FactContainer type.</typeparam>
        /// <param name="factType">Fact type info.</param>
        /// <param name="node"></param>
        /// <param name="context"></param>
        /// <param name="copatibleAllFinishedNodes"></param>
        /// <returns>True - may not be considered necessary</returns>
        private bool CanRemoveFromNeedFactTypes <TFactRule, TWantAction, TFactContainer>(IFactType factType, NodeByFactRule <TFactRule> node, IFactRulesContext <TFactRule, TWantAction, TFactContainer> context, Dictionary <NodeByFactRuleInfo <TFactRule>, NodeByFactRule <TFactRule> > copatibleAllFinishedNodes)
            where TFactRule : IFactRule
            where TWantAction : IWantAction
            where TFactContainer : IFactContainer
        {
            // Exclude condition special facts
            if (factType.IsFactType <IBuildConditionFact>())
            {
                var nodeInfo = node.Info;

                if (nodeInfo.BuildSuccessConditions.Exists(fact => context.Cache.GetFactType(fact).EqualsFactType(factType)))
                {
                    return(true);
                }
                else if (nodeInfo.BuildFailedConditions.Exists(fact => context.Cache.GetFactType(fact).EqualsFactType(factType)))
                {
                    return(false);
                }

                var condition = Factory.CreateObject(
                    type => type.CreateBuildConditionFact <IBuildConditionFact>(),
                    factType
                    );

                if (condition.Condition(nodeInfo.Rule, context, _ => nodeInfo.CompatibleRules))
                {
                    nodeInfo.BuildSuccessConditions.Add(condition);
                    return(true);
                }
                else
                {
                    nodeInfo.BuildFailedConditions.Add(condition);
                    return(false);
                }
            }
            else if (factType.IsFactType <IRuntimeConditionFact>())
            {
                var nodeInfo = node.Info;

                if (nodeInfo.RuntimeConditions.Exists(fact => context.Cache.GetFactType(fact).EqualsFactType(factType)))
                {
                    return(true);
                }

                var condition = Factory.CreateObject(
                    type => type.CreateRuntimeConditionFact <IRuntimeConditionFact>(),
                    factType
                    );

                condition.SetGetRelatedRulesFunc <TFactRule, TWantAction, TFactContainer>(GetRelatedRules, node.Info.Rule, context.FactRules);

                nodeInfo.RuntimeConditions.Add(condition);

                return(true);
            }
            else
            {
                // Exclude facts for which a solution has already been found.
                List <KeyValuePair <NodeByFactRuleInfo <TFactRule>, NodeByFactRule <TFactRule> > > finishedNodesForCurrentFact = copatibleAllFinishedNodes
                                                                                                                                 .Where(finishedNode => finishedNode.Key.Rule.OutputFactType.EqualsFactType(factType))
                                                                                                                                 .ToList();

                if (finishedNodesForCurrentFact.Count != 0)
                {
                    node.Childs.Insert(0, finishedNodesForCurrentFact[0].Value);
                    return(true);
                }
            }

            return(false);
        }
        internal static bool CanDeriveFact <TFactWork, TFactRule, TWantAction, TFactContainer>(IRuntimeConditionFact conditionFact, IFactType searchFactType, TFactWork factWork, IFactRulesContext <TFactRule, TWantAction, TFactContainer> context)
            where TFactWork : IFactWork
            where TFactRule : IFactRule
            where TWantAction : IWantAction
            where TFactContainer : IFactContainer
        {
            if (context.SingleEntity.CanExtractFact(searchFactType, factWork, context))
            {
                return(true);
            }

            var rulesWithoutConditionFact = context.FactRules
                                            .FindAll(rule => rule.InputFactTypes
                                                     .All(factType => !factType.EqualsFactType(context.Cache.GetFactType(conditionFact))));

            var request = new BuildTreeForFactInfoRequest <TFactRule, TWantAction, TFactContainer>
            {
                WantFactType = searchFactType,
                Context      = new FactRulesContext <TFactRule, TWantAction, TFactContainer>
                {
                    Cache        = context.Cache,
                    Container    = context.Container,
                    FactRules    = rulesWithoutConditionFact,
                    SingleEntity = context.SingleEntity,
                    TreeBuilding = context.TreeBuilding,
                    WantAction   = context.WantAction,
                    Engine       = context.Engine,
                },
            };

            try
            {
                return(context.TreeBuilding.TryBuildTreeForFactInfo(request, out var _, out var _));
            }
            catch (InvalidDeriveOperationException ex)
            {
                if (ex.Details != null && ex.Details.Count == 1)
                {
                    DeriveErrorDetail detail = ex.Details.First();

                    if (detail.Code == ErrorCode.RuleNotFound || detail.Code == ErrorCode.EmptyRuleCollection)
                    {
                        return(false);
                    }
                }

                throw;
            }
        }