예제 #1
0
        private IRule <TModel> LoadLogic(string equationId)
        {
            StepTracer <LintTrace>    trace = new StepTracer <LintTrace>();
            StepTraceNode <LintTrace> root  = trace.TraceFirst(new LintTrace(LintStatusOptions.Loading, "Loading Logic", equationId));


            //Lint.... make sure we have everything we need first.
            Func <LogicDefine.Rule, StepTraceNode <LintTrace>, bool, IRule <TModel> > LoadRule = null;

            LoadRule = (rule, parentStep, inner) =>
            {
                StepTraceNode <LintTrace> step     = trace.TraceNext(parentStep, new LintTrace(LintStatusOptions.Inspecting, "Inspecting Rule", rule.Id));
                IRule <TModel>            toReturn = null;
                //if id is an equation, we are creating an expression

                //since we've formalized convention, we can just check that
                if (ConventionHelper.MatchesConvention(NamePrefixOptions.Equation, rule.Id, this.Configuration.Convention))
                {
                    LogicDefine.Equation eq = this.WorkflowManager.GetEquation(rule.Id);

                    IRule <TModel> first  = LoadRule(eq.First, step, true);
                    IRule <TModel> second = LoadRule(eq.Second, step, true);
                    toReturn = new Expression <TModel>(rule, eq.Condition, first, second, this, inner);
                }
                else
                {
                    LogicDefine.Evaluator ev = this.WorkflowManager.GetEvaluator(rule.Id);
                    toReturn = new Rule <TModel>(rule, this, inner);
                }



                return(toReturn);
            };



            LogicDefine.Rule eqRule = equationId;
            IRule <TModel>   loaded = LoadRule(eqRule, root, false);

            return(loaded);
        }
예제 #2
0
        public List <LogicTest> LogicLint()
        {
            int        id    = 1;
            Func <int> newId = () =>
            {
                return(id += 1);
            };

            List <bool> tf = new List <bool>()
            {
                true, false
            };

            Func <Equation, List <Rule> > getAllRulesForEquation = null;

            getAllRulesForEquation = (eq) =>
            {
                List <Rule> rules = new List <Rule>();
                //left hand side of equation

                if (ConventionHelper.MatchesConvention(NamePrefixOptions.Equation, eq.First.Id, this.configuration.Convention))
                {
                    Equation    traverse = this.WorkflowManager.GetEquation(eq.First.Id);
                    List <Rule> parsed   = getAllRulesForEquation(traverse);

                    rules = rules.Union(parsed, new RuleEqualityComparer()).ToList();
                }
                else
                {
                    if (!rules.Contains(eq.First, new RuleEqualityComparer()))
                    {
                        rules.Add((Rule)eq.First.Clone());
                    }
                }

                if (ConventionHelper.MatchesConvention(NamePrefixOptions.Equation, eq.Second.Id, this.configuration.Convention))
                {
                    Equation    traverse = this.WorkflowManager.GetEquation(eq.Second.Id);
                    List <Rule> parsed   = getAllRulesForEquation(traverse);

                    rules = rules.Union(parsed, new RuleEqualityComparer()).ToList();
                }
                else
                {
                    if (!rules.Contains(eq.Second, new RuleEqualityComparer()))
                    {
                        rules.Add((Rule)eq.Second.Clone());
                    }
                }

                string trueId = ConventionHelper.TrueEvaluator(this.configuration.Convention);
                return((from r in rules where r.Id != trueId select r).ToList());
            };

            Func <Stack <List <Case> >, List <Case> > mergeCases = null;

            mergeCases = (llc) =>
            {
                List <Case> merged = llc.Pop();
                if (llc.Count > 0)
                {
                    List <Case> toMerge  = mergeCases(llc);
                    List <Case> newMerge = new List <Case>();
                    merged.ForEach(m =>
                    {
                        toMerge.ForEach(g =>
                        {
                            List <Rule> newCaseRules = new List <Rule>(from r in m.Rules select(Rule) r.Clone());
                            newCaseRules.AddRange(from r in g.Rules select(Rule) r.Clone());
                            Case newCase = new Case(newCaseRules);
                            newMerge.Add(newCase);
                        });
                    });

                    merged = newMerge;
                }

                return(merged);
            };



            if (this.logicTests == default)
            {
                this.logicTests = new List <LogicTest>();
                //get the root
                foreach (string rootEquationId in this.roots)
                {
                    Stack <List <Case> > preMerge  = new Stack <List <Case> >();
                    Equation             root      = this.WorkflowManager.GetEquation(rootEquationId);
                    List <Rule>          evalRules = getAllRulesForEquation(root);
                    foreach (Rule evalRule in evalRules)
                    {
                        List <Case> evalRuleCases = new List <Case>();
                        if (evalRule.Context == null)
                        {
                            evalRuleCases.AddRange(from c in tf
                                                   select new Case(new List <Rule>()
                            {
                                new Rule()
                                {
                                    Context       = evalRule.Context,
                                    Id            = evalRule.Id,
                                    TrueCondition = c
                                }
                            }));
                        }
                        else
                        {
                            Stack <List <Case> > contextCases = new Stack <List <Case> >();

                            evalRule.Context.Keys.ForEach(k =>
                            {
                                List <Case> cases = new List <Case>();
                                cases.AddRange(from c in tf
                                               select new Case(new List <Rule>()
                                {
                                    new Rule()
                                    {
                                        Context = new Context(new List <string>()
                                        {
                                            k
                                        }, evalRule.Context.Name),
                                        Id            = evalRule.Id,
                                        TrueCondition = c
                                    }
                                }));
                                contextCases.Push(cases);
                                evalRuleCases = mergeCases(contextCases);
                                contextCases.Push(evalRuleCases);
                            });
                            var contextDef = this.WorkflowManager.GetContextDefinition(evalRule.Context.Name);
                            if (contextDef.Validate == ValidateOptions.OneOf)
                            {
                                evalRuleCases.RemoveAll(c => c.Rules.Count(r => r.TrueCondition) != 1 && c.Rules.Any(r => r.TrueCondition));
                            }
                            if (contextDef.Exclusive)
                            {
                                evalRuleCases.RemoveAll(c => c.Rules.Count(r => !r.TrueCondition) == c.Rules.Count() && c.Rules.Count == contextDef.Items.Count);
                            }
                        }

                        preMerge.Push(evalRuleCases);
                    }
                    List <Case> finalCases = mergeCases(preMerge);
                    LogicTest   eqTest     = new LogicTest(rootEquationId, true)
                    {
                        TestCases = finalCases
                    };
                    this.logicTests.Add(eqTest);
                }
            }

            return(this.logicTests);
        }
예제 #3
0
        public ArticulateActivity ArticulateFlow(bool removeConvention, bool verbose)
        {
            Func <WorkDefine.ActionRef, IArticulateActivity> createAction = (s) =>
            {
                var actionDef           = this.workflow.Actions.FirstOrDefault(g => g.Id == s.Id);
                ArticulateAction action = new ArticulateAction()
                {
                    Id = s.Id, Literal = actionDef.Description
                };


                if (s.Id == "*placeHolder")
                {
                    return(new NothingAction());
                }
                else
                {
                    if (s.Input != null)
                    {
                        ArticulateContext articulateContext = new ArticulateContext()
                        {
                            Literal = "Input",
                            Value   = s.Input
                        };
                        action.Context = articulateContext;
                    }

                    return(action);
                }
            };

            ArticulateActivity toReturn = new ArticulateActivity();

            string activityId = workflow.Id;

            activityId = $"{ConventionHelper.EnsureConvention(NamePrefixOptions.Activity, activityId, this.configuration.Convention)}.Main";

            WorkDefine.Activity toArticulate = this.workflow.Activities.FirstOrDefault(g => g.Id == activityId);
            toReturn.Id = toArticulate.Id;



            Func <LogicDefine.Rule, IArticulateExpression> traverseExpression = null;

            traverseExpression = (x) =>
            {
                IArticulateExpression buildExpression = null;


                if (ConventionHelper.MatchesConvention(NamePrefixOptions.Evaluator, x.Id, this.configuration.Convention))
                {
                    buildExpression = this.ArticulateEvaluator(x);
                }
                else
                {
                    ArticulateExpression toBuild = new ArticulateExpression()
                    {
                        Id = x.Id
                    };
                    LogicDefine.Equation eq = this.workflow.Equations.FirstOrDefault(g => g.Id == x.Id);
                    toBuild.Condition = (eq.Condition == Logic.Operand.And) ? "and": "or";
                    Rule asRule = x.ShortHand;
                    toBuild.TrueCondition = asRule.TrueCondition;
                    toBuild.First         = traverseExpression(eq.First);
                    toBuild.Second        = traverseExpression(eq.Second);
                    buildExpression       = toBuild;
                }


                return(buildExpression);
            };

            Action <ArticulateActivity, WorkDefine.Activity> traverseActivity = null;

            traverseActivity = (a, d) =>
            {
                if (d.Reactions != null && d.Reactions.Count() > 0)
                {
                    a.Reactions = new List <ArticulateReaction>();
                    d.Reactions.ForEach(r =>
                    {
                        //all logic at this point should be equations
                        //if logic = true, then if = "Always".
                        ArticulateReaction toAdd = new ArticulateReaction();
                        if (r.Logic == ConventionHelper.TrueEquation(this.configuration.Convention))
                        {
                            toAdd.If = new TrueExpression();
                        }
                        else
                        {
                            toAdd.If = traverseExpression(r.Logic);
                        }

                        WorkDefine.ActionRef aref = r.Work;
                        if (ConventionHelper.MatchesConvention(NamePrefixOptions.Action, aref.Id, this.configuration.Convention))
                        {
                            toAdd.Then = createAction(aref);
                        }
                        else
                        {
                            WorkDefine.Activity toTraverse = this.workflow.Activities.FirstOrDefault(g => g.Id == aref.Id);
                            ArticulateActivity Then        = new ArticulateActivity()
                            {
                                Id = aref.Id
                            };
                            traverseActivity(Then, toTraverse);
                            toAdd.Then = Then;
                        }
                        a.Reactions.Add(toAdd);
                    });
                }
            };

            traverseActivity(toReturn, toArticulate);


            return(toReturn);
        }