/// <summary> /// Evaluates whether trace is complaint with the the constraint. /// </summary> /// <param name="events">A trace for evaluation</param> /// <param name="template">constraint for evaluation</param> /// <param name="preprocessing"> /// Some expressions need preprocessing for strict evaluation. /// This involves mainly expressions containing precedence. True to preprocess, False otherwise. /// </param> /// <returns></returns> public bool EvaluateConstraint(List <Event> events, ITemplate template, bool preprocessing = true) { var expr = template switch { AlternateResponse ar => ar.GetFinishingExpression(), AlternateSuccession asu => asu.GetFinishingExpression(), _ => template.GetExpression() }; if (expr is null) { return(false); } if (preprocessing) { events = UtilMethods.PreprocessTraceForEvaluation(template, events); } return(EvaluateExpression(events, expr)); } }
/// <summary> /// Builds an ActivationBinaryTree from a trace and a constraint. /// Idea behind this algorithm is taken from /// https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6337271 /// </summary> /// <param name="trace">Trace</param> /// <param name="constraint">Constraint</param> /// <returns></returns> public ActivationBinaryTree BuildTree(List <Event> trace, BiTemplate constraint) { trace = UtilMethods.PreprocessTraceForEvaluation(constraint, trace); ActivationBinaryTree tree = new(constraint); var id = 1; foreach (var e in trace) { e.ActivityInTraceId = id; id++; foreach (var leaf in tree.Leaves.ToList()) { if (leaf.IsDead) { continue; } if (constraint.IsActivation(e)) { //left ActivationNode left = new(leaf.Subtrace.ToList()); tree.AddNodeLeft(leaf, left); //right ActivationNode right = new(leaf.Subtrace.ToList()); right.Subtrace.Add(e); tree.AddNodeRight(leaf, right); } else { leaf.Subtrace.Add(e); } } } AssignLeavesStatus(tree.Leaves, constraint); return(tree); }