/// <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); }
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); }