public override bool Visit(LetExp node) { violatingExpression = node; bool valueDefAccept = node.Variable.Value.Accept(this); VariableClassMappings.CreateSubCollectionIfNeeded(node.Variable); isSuitable = false; return(false); }
public override bool Visit(IteratorExp node) { // forAll apod. bool sourceAccept = node.Source.Accept(this); OclExpression source = node.Source; while (source is IteratorExp) { if (collectionIteratorsPreservingType.Contains(((IteratorExp)source).IteratorName)) { source = ((IteratorExp)source).Source; } else { break; } } if (source is PropertyCallExp) { // find path to source PIMPath sourcePath = PIMPathBuilder.BuildPIMPath((PropertyCallExp)source); List <PSMPath> navigations = FindNavigationsForPIMNavigation(sourcePath); foreach (VariableDeclaration vd in node.Iterator) { VariableClassMappings.CreateSubCollectionIfNeeded(vd); foreach (PSMPath psmNavigation in navigations) { VariableClassMappings[vd].Add(psmNavigation.LastClass); } } } else if (source is IteratorExp) { foreach (VariableDeclaration vd in node.Iterator) { if (vd.PropertyType.Tag != null) { VariableClassMappings.CreateSubCollectionIfNeeded(vd); VariableClassMappings[vd].AddRange(GetInterpretations((PIMClass)vd.PropertyType.Tag)); } } } loopStacks.Push(node); bool bodyAccept = node.Body.Accept(this); loopStacks.Pop(); return(sourceAccept && bodyAccept); }
public OclExpression TranslateConstraint(ClassifierConstraintBlock classifierConstraintBlock, OclExpression pimInvariant, Dictionary <VariableDeclaration, List <PSMClass> > initialVariableMappings, Dictionary <PIMPath, List <PSMPath> > initialPathMappings, Dictionary <VariableDeclaration, VariableDeclaration> variableTranslations, out Classifier psmContextSuggestion) { #region fill prepared translations foreach (KeyValuePair <VariableDeclaration, List <PSMClass> > kvp in initialVariableMappings) { VariableClassMappings.CreateSubCollectionIfNeeded(kvp.Key); VariableClassMappings[kvp.Key].AddRange(kvp.Value); } foreach (KeyValuePair <PIMPath, List <PSMPath> > kvp in initialPathMappings) { PathMappings.CreateSubCollectionIfNeeded(kvp.Key); PathMappings[kvp.Key].AddRange(kvp.Value); } foreach (KeyValuePair <VariableDeclaration, VariableDeclaration> kvp in variableTranslations) { VariableTranslations[kvp.Key] = kvp.Value; } #endregion psmBridge = new PSMBridge(TargetPSMSchema); #region prepare self variable PSMClass psmClass = VariableClassMappings[classifierConstraintBlock.Self].First(); Classifier variableType = psmBridge.Find(psmClass); VariableDeclaration vd = new VariableDeclaration(classifierConstraintBlock.Self.Name, variableType, null); this.SelfVariableDeclaration = vd; #endregion OclExpression translateConstraint = pimInvariant.Accept(this); psmContextSuggestion = psmBridge.Find(VariableClassMappings[classifierConstraintBlock.Self].First()); if (isSuitable) { return(translateConstraint); } else { return(null); } }
public bool CheckConstraintSuitability(ClassifierConstraintBlock classifierConstraintBlock, OclExpression oclExpression) { Clear(); psmBridge = new PSMBridge(TargetPSMSchema); PIMClass contextClass = (PIMClass)classifierConstraintBlock.Context.Tag; VariableClassMappings.CreateSubCollectionIfNeeded(classifierConstraintBlock.Self); VariableClassMappings[classifierConstraintBlock.Self].AddRange(GetInterpretations(contextClass)); oclExpression.Accept(this); IEnumerable <VariableDeclaration> f = from m in VariableClassMappings where m.Value.Count == 0 select m.Key; if (f.Count() > 0) { isSuitable = false; } return(isSuitable); }
private bool FindNavigationsForPIMNavigationRecursive(PIMPath pimPath, int stepIndex, PSMAssociationMember currentMember, PSMPath builtPath, bool canGoToParent, ref List <PSMPath> result, PSMAssociation associationUsedAlready) { if (stepIndex == pimPath.Steps.Count) { result.Add(builtPath); return(true); } PIMPathStep currentStep = pimPath.Steps[stepIndex]; if (currentStep is PIMPathAssociationStep) { Debug.Assert(currentMember != null); PIMPathAssociationStep nextStep = (PIMPathAssociationStep)currentStep; List <PSMAssociationMember> candidates = currentMember.ChildPSMAssociations.Where(a => allowNonTree || !a.IsNonTreeAssociation).Select(a => a.Child).ToList(); /* * we forbid non-tree associations for now, * it certainly makes thinks easier and I am not sure * whether it is really a restriction */ List <PSMAssociation> candidatesAssociations = currentMember.ChildPSMAssociations.Where(a => allowNonTree || !a.IsNonTreeAssociation).ToList(); PSMAssociationMember parent = currentMember.ParentAssociation != null ? currentMember.ParentAssociation.Parent : null; if (parent != null && canGoToParent && !(parent is PSMSchemaClass)) { bool candidateParent = true; if (currentMember.ParentAssociation.Interpretation != null) { PIMAssociation interpretedAssociation = (PIMAssociation)currentMember.ParentAssociation.Interpretation; PIMAssociationEnd interpretedEnd = currentMember.ParentAssociation.InterpretedAssociationEnd; PIMAssociationEnd oppositeEnd = interpretedAssociation.PIMAssociationEnds.Single(e => e != interpretedEnd); // upwards navigation on ends with upper cardinality > 1 breaks semantics of the expression if (oppositeEnd.Upper > 1) { candidateParent = false; } } if (candidateParent) { candidates.Add(parent); candidatesAssociations.Add(currentMember.ParentAssociation); } } bool found = false; for (int index = 0; index < candidates.Count; index++) { PSMAssociationMember candidate = candidates[index]; PSMAssociation candidateAssociation = candidatesAssociations[index]; bool parentStep = candidate == parent && !candidateAssociation.IsNonTreeAssociation; // forbid traversing the same association several times if (associationUsedAlready == candidateAssociation) { continue; } int nextStepIndex = stepIndex; bool interpretedClassSatisfies = candidateAssociation.Interpretation != null && candidate.DownCastSatisfies <PSMClass>(c => c.Interpretation == nextStep.Class); if (candidate.Interpretation == null || interpretedClassSatisfies) { PSMPath nextBuiltPath = (PSMPath)builtPath.Clone(); nextBuiltPath.Steps.Add(new PSMPathAssociationStep(nextBuiltPath) { Association = candidateAssociation, To = candidate, From = currentMember, IsUp = candidateAssociation.Parent == candidate }); if (interpretedClassSatisfies) { nextStepIndex++; } found |= FindNavigationsForPIMNavigationRecursive(pimPath, nextStepIndex, candidate, nextBuiltPath, canGoToParent && !parentStep, ref result, parentStep ? candidateAssociation : null); } } return(found); } else if (currentStep is PIMPathVariableStep) { Debug.Assert(currentMember == null); PIMPathVariableStep pathVariableStep = (PIMPathVariableStep)currentStep; IEnumerable <PSMClass> candidates = TargetPSMSchema.PSMClasses.Where(c => c.Interpretation == pimPath.StartingClass); if (!VariableClassMappings.ContainsKey(pathVariableStep.Variable)) { return(false); } candidates = candidates.Intersect(VariableClassMappings[pathVariableStep.Variable]); bool found = false; List <PSMClass> eliminatedCandidates = new List <PSMClass>(); eliminatedCandidates.AddRange(VariableClassMappings[pathVariableStep.Variable].Except(candidates)); foreach (PSMClass candidate in candidates) { PSMBridgeClass startType = psmBridge.Find(candidate); builtPath = new PSMPath(); VariableDeclaration vd; if (!variableTranslations.ContainsKey(pathVariableStep.Variable)) { vd = new VariableDeclaration(pathVariableStep.Variable.Name, startType, null); variableTranslations[pathVariableStep.Variable] = vd; } else { vd = variableTranslations[pathVariableStep.Variable]; } builtPath.Steps.Add(new PSMPathVariableStep(builtPath) { VariableExp = new VariableExp(vd) }); bool candidateUsable = FindNavigationsForPIMNavigationRecursive(pimPath, stepIndex + 1, candidate, builtPath, true, ref result, null); if (!candidateUsable) { eliminatedCandidates.Add(candidate); } found |= candidateUsable; } VariableClassMappings[pathVariableStep.Variable].RemoveAll(eliminatedCandidates.Contains); if (PathMappings.ContainsKey(pimPath)) { PathMappings[pimPath].RemoveAll(p => eliminatedCandidates.Contains(p.StartingClass)); } return(found); } else if (currentStep is PIMPathAttributeStep) { PIMPathAttributeStep pathAttributeStep = (PIMPathAttributeStep)currentStep; Debug.Assert(currentMember is PSMClass); bool found = false; foreach (PSMAttribute psmAttribute in ((PSMClass)currentMember).PSMAttributes) { if (psmAttribute.Interpretation == pathAttributeStep.Attribute) { PSMPath nextBuiltPath = (PSMPath)builtPath.Clone(); nextBuiltPath.Steps.Add(new PSMPathAttributeStep(nextBuiltPath) { Attribute = psmAttribute }); result.Add(nextBuiltPath); found |= true; } } return(found); } else { throw new NotImplementedException(); } }