/// <summary>
        /// Get the expression for this rule by calling GatherConstraints().
        /// </summary>
        /// <param name="parser">Expression parser.</param>
        /// <returns>Expression which will be cached and used to evaluate this rule.</returns>
        public virtual Expression GetExpression(IExpressionParser parser)
        {
            lock (this.extraConstraints)
            {
                if (this.fullConstraint == null)
                {
                    var allExpressions = new List <Expression>();

                    if (this.Condition != null)
                    {
                        allExpressions.Add(this.Condition.ToExpression());
                    }

                    if (this.extraConstraints.Any())
                    {
                        allExpressions.AddRange(this.extraConstraints);
                    }

                    if (allExpressions.Any())
                    {
                        this.fullConstraint = Expression.AndExpression(allExpressions.ToArray());
                    }
                    else
                    {
                        this.fullConstraint = Expression.ConstantExpression(true);
                    }

                    if (RunOnce)
                    {
                        this.fullConstraint = Expression.AndExpression(
                            this.fullConstraint,
                            new Expression(
                                TriggerTree.LookupFunction("ignore"),
                                new Expression(new ExpressionEvaluator(
                                                   $"runOnce{Id}",
                                                   (expression, os) =>
                        {
                            var state    = os as DialogStateManager;
                            var basePath = $"{AdaptiveDialog.ConditionTracker}.{Id}.";
                            var lastRun  = state.GetValue <uint>(basePath + "lastRun");
                            var paths    = state.GetValue <string[]>(basePath + "paths");
                            var changed  = state.AnyPathChanged(lastRun, paths);
                            return(changed, null);
                        },
                                                   ReturnType.Boolean,
                                                   BuiltInFunctions.ValidateUnary))));
                    }
                }
            }

            return(this.fullConstraint);
        }
Example #2
0
        public List <ExpressionInfo> GenerateOptionals(List <ExpressionInfo> predicates, int numOptionals, int minClause, int maxClause)
        {
            var optionals = new List <ExpressionInfo>();

            for (var i = 0; i < numOptionals; ++i)
            {
                var clauses     = minClause + Rand.Next(maxClause - minClause);
                var expressions = new List <ExpressionInfo>();
                var used        = new List <int>();
                for (var j = 0; j < clauses; ++j)
                {
                    int choice;
                    do
                    {
                        choice = Rand.Next(predicates.Count);
                    }while (used.Contains(choice));

                    var predicate = predicates[choice];
                    if (j == 0)
                    {
                        var optional = Expression.MakeExpression(TriggerTree.LookupFunction(TriggerTree.Optional), predicate.Expression);
                        if (Rand.NextDouble() < 0.25)
                        {
                            optional = Expression.NotExpression(optional);
                        }

                        expressions.Add(new ExpressionInfo(optional, predicate.Bindings));
                    }
                    else
                    {
                        expressions.Add(predicate);
                    }

                    used.Add(choice);
                }

                var conjunction = Binary(ExpressionType.And, expressions, out var bindings);
                optionals.Add(new ExpressionInfo(conjunction, bindings));
            }

            return(optionals);
        }