Beispiel #1
0
        /// <summary>
        /// Creates an element that represents an aggregation of facts.
        /// </summary>
        /// <param name="resultType">Type of the aggregate result.</param>
        /// <param name="name">Aggregate name.</param>
        /// <param name="expressions">Expressions used to construct aggregates from individual facts.</param>
        /// <param name="source">Pattern that matches facts for aggregation.</param>
        /// <param name="customFactoryType">Factory type used construct aggregators for this aggregation.</param>
        /// <returns>Created element.</returns>
        public static AggregateElement Aggregate(Type resultType, string name, IEnumerable <NamedExpressionElement> expressions, PatternElement source, Type customFactoryType)
        {
            if (resultType == null)
            {
                throw new ArgumentNullException(nameof(resultType), "Aggregate result type not provided");
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name), "Aggregate name not provided");
            }
            if (expressions == null)
            {
                throw new ArgumentNullException(nameof(expressions), "Aggregate expressions not provided");
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source), "Aggregate source pattern not provided");
            }

            var expressionCollection = new ExpressionCollection(expressions);
            var element = new AggregateElement(resultType, name, expressionCollection, source, customFactoryType);

            ElementValidator.ValidateAggregate(element);
            return(element);
        }
Beispiel #2
0
        /// <summary>
        /// Creates an element that represents a negative existential quantifier.
        /// </summary>
        /// <param name="source">Source element to apply the negative existential quantifier to.</param>
        /// <returns>Created element.</returns>
        public static NotElement Not(RuleElement source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source), "Source element not provided");
            }

            var element = new NotElement(source);

            ElementValidator.ValidateNot(element);
            return(element);
        }
Beispiel #3
0
        /// <summary>
        /// Creates a left-hand side group element that combines contained elements using an OR operator.
        /// </summary>
        /// <param name="childElements">Child elements contained in the group.</param>
        /// <returns>Created element.</returns>
        /// <see cref="RuleElement"/>
        public static OrElement OrGroup(IEnumerable <RuleElement> childElements)
        {
            if (childElements == null)
            {
                throw new ArgumentNullException(nameof(childElements), "Child elements not provided");
            }

            var element = new OrElement(childElements);

            ElementValidator.ValidateGroup(element);
            return(element);
        }
Beispiel #4
0
        /// <summary>
        /// Creates a dependency group element.
        /// </summary>
        /// <param name="dependencies">Dependency elements in the group.</param>
        /// <returns>Created element.</returns>
        /// <seealso cref="DependencyElement"/>
        public static DependencyGroupElement DependencyGroup(IEnumerable <DependencyElement> dependencies)
        {
            if (dependencies == null)
            {
                throw new ArgumentNullException(nameof(dependencies), "Dependencies not provided");
            }

            var element = new DependencyGroupElement(dependencies);

            ElementValidator.ValidateUniqueDeclarations(element.Dependencies);
            return(element);
        }
Beispiel #5
0
        /// <summary>
        /// Creates an element that represents results of an expression evaluation.
        /// </summary>
        /// <param name="resultType">Type of the expression result.</param>
        /// <param name="expression">Binding expression.</param>
        /// <returns>Created element.</returns>
        public static BindingElement Binding(Type resultType, LambdaExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression), "Binding expression not provided");
            }
            if (resultType == null)
            {
                throw new ArgumentNullException(nameof(resultType), "Binding result type not provided");
            }

            var element = new BindingElement(resultType, expression);

            ElementValidator.ValidateBinding(element);
            return(element);
        }
Beispiel #6
0
        /// <summary>
        /// Creates an element that represents a universal quantifier.
        /// Facts that match the <c>basePattern</c> must also match all other <c>patterns</c>.
        /// </summary>
        /// <param name="basePattern">Base patterns of the universal quantifier that defines the universe of facts to consider.</param>
        /// <param name="patterns">Additional patterns of the universal quantifier that the fact matched by the base pattern must also satisfy.</param>
        /// <returns>Created element.</returns>
        public static ForAllElement ForAll(PatternElement basePattern, IEnumerable <PatternElement> patterns)
        {
            if (basePattern == null)
            {
                throw new ArgumentNullException(nameof(basePattern), "Base pattern not provided");
            }
            if (patterns == null)
            {
                throw new ArgumentNullException(nameof(patterns), "Patterns not provided");
            }

            var element = new ForAllElement(basePattern, patterns);

            ElementValidator.ValidateForAll(element);
            return(element);
        }
Beispiel #7
0
        /// <summary>
        /// Creates a left-hand side group element that combines contained elements using an AND operator.
        /// </summary>
        /// <param name="childElements">Child elements contained in the group.</param>
        /// <returns>Created element.</returns>
        /// <see cref="RuleLeftElement"/>
        public static AndElement AndGroup(IEnumerable <RuleLeftElement> childElements)
        {
            if (childElements == null)
            {
                throw new ArgumentNullException(nameof(childElements), "Child elements not provided");
            }

            var element = new AndElement(childElements);

            if (!element.ChildElements.Any())
            {
                throw new InvalidOperationException("Group element AND requires at least one child element");
            }
            ElementValidator.ValidateUniqueDeclarations(element.ChildElements);
            return(element);
        }
Beispiel #8
0
        /// <summary>
        /// Creates a pattern element that represents a match over results of the source element.
        /// </summary>
        /// <param name="declaration">Declaration that references the pattern.</param>
        /// <param name="expressions">Expressions used by the pattern to match elements.</param>
        /// <param name="source">Source of the elements matched by the pattern. If it's <c>null</c>, the pattern matches facts in rules engine's working memory.</param>
        /// <returns>Created element.</returns>
        public static PatternElement Pattern(Declaration declaration, IEnumerable <NamedExpressionElement> expressions, RuleElement source)
        {
            if (declaration == null)
            {
                throw new ArgumentNullException(nameof(declaration), "Pattern declaration not provided");
            }
            if (expressions == null)
            {
                throw new ArgumentNullException(nameof(expressions), "Pattern expressions not provided");
            }

            var expressionCollection = new ExpressionCollection(expressions);
            var element = new PatternElement(declaration, expressionCollection, source);

            declaration.Target = element;
            ElementValidator.ValidatePattern(element);
            return(element);
        }
Beispiel #9
0
        /// <summary>
        /// Creates a rule definition.
        /// </summary>
        /// <param name="name">Rule's name.</param>
        /// <param name="description">Rule's description.</param>
        /// <param name="priority">Rule's priority.</param>
        /// <param name="repeatability">Rule's repeatability.</param>
        /// <param name="tags">Tags associated with the rule.</param>
        /// <param name="properties">Properties associated with the rule.</param>
        /// <param name="dependencies">Rule's dependency group element.</param>
        /// <param name="leftHandSide">Rule's left-hand side top group element.</param>
        /// <param name="filters">Rule's filter group element.</param>
        /// <param name="rightHandSide">Rule's right-hand side group element.</param>
        /// <returns>Created rule definition.</returns>
        public static IRuleDefinition RuleDefinition(string name, string description, int priority,
                                                     RuleRepeatability repeatability, IEnumerable <string> tags, IEnumerable <RuleProperty> properties,
                                                     DependencyGroupElement dependencies, GroupElement leftHandSide, FilterGroupElement filters, ActionGroupElement rightHandSide)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("Rule name not provided", nameof(name));
            }
            if (tags == null)
            {
                throw new ArgumentNullException(nameof(tags), "Rule tags not provided");
            }
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties), "Rule properties not provided");
            }
            if (dependencies == null)
            {
                throw new ArgumentNullException(nameof(dependencies), "Rule dependencies not provided");
            }
            if (leftHandSide == null)
            {
                throw new ArgumentNullException(nameof(leftHandSide), "Rule left-hand side not provided");
            }
            if (filters == null)
            {
                throw new ArgumentNullException(nameof(filters), "Rule filters not provided");
            }
            if (rightHandSide == null)
            {
                throw new ArgumentNullException(nameof(rightHandSide), "Rule right-hand side not provided");
            }

            var ruleDefinition = new RuleDefinition(name, description, priority, repeatability, tags, properties, dependencies, leftHandSide, filters, rightHandSide);

            ElementValidator.ValidateUniqueDeclarations(ruleDefinition.LeftHandSide, ruleDefinition.DependencyGroup);
            ElementValidator.ValidateRuleDefinition(ruleDefinition);

            return(ruleDefinition);
        }