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);
        }
Пример #3
0
        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);
        }
Пример #5
0
        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();
            }
        }