Example #1
0
        // this function fills the rest of the graph with random nodes
        private void fillNodesRecursively(NodeObject currentNode, List<int> currentPosition, int currentDepth, int maxDepth, List<PossibleNode> allPossibleNodes, ValidGraphPath[] validPaths) {

            // check if the maximal depth is reached
            if (currentDepth >= maxDepth) {
                return;
            }

            // fill all missing nodes of the current object with new random nodes
            for (int idx = 0; idx < currentNode.dimension; idx++) {

                // copy position list and add path index to the position 
                List<int> tempCurrentPosition = new List<int>(currentPosition);
                tempCurrentPosition.Add(idx);

                if (currentNode.nodeObjects[idx] == null) {

                    // get random possible node from list of all possible nodes
                    int randElement = this.prng.Next(allPossibleNodes.Count);
                    PossibleNode possibleNode = allPossibleNodes.ElementAt(randElement);
                    NamespaceTypeDefinition classToUse = possibleNode.givenClass;
                    MethodDefinition nodeConstructor = possibleNode.nodeConstructor;

                    // generate path element from chosen interface
                    PathElement pathElement = new PathElement();

                    // create new node object
                    currentNode.nodeObjects[idx] = new NodeObject(this.graphDimension, this.graphValidPathCount, classToUse, nodeConstructor, pathElement, tempCurrentPosition);


                    // search through every valid path if the new created filler node has the same attributes as the valid path node
                    // => add it to the list of possible nodes that can be used for an exchange between valid node and filler node
                    for (int validPathId = 0; validPathId < validPaths.Count(); validPathId++) {
                        for (int depth = 0; depth < validPaths[validPathId].pathElements.Count(); depth++) {

                            // check if the used class of the current filler node is in the list of possible classes of the valid path node
                            if (validPaths[validPathId].pathElements.ElementAt(depth).linkGraphObject.possibleClasses.Contains(classToUse)) {

                                // add current filler node to the list of possible exchange nodes
                                if (!validPaths[validPathId].pathElements.ElementAt(depth).linkGraphObject.possibleExchangeObjects.Contains(currentNode.nodeObjects[idx])) {
                                    validPaths[validPathId].pathElements.ElementAt(depth).linkGraphObject.possibleExchangeObjects.Add(currentNode.nodeObjects[idx]);
                                }
                            }
                        }
                    }

                }

                this.fillNodesRecursively(currentNode.nodeObjects[idx], tempCurrentPosition, currentDepth + 1, maxDepth, allPossibleNodes, validPaths);

            }
        }
Example #2
0
        // builds a graph
        public void buildGraph(ValidGraphPath[] validPaths) {

            // check if at least one valid path is given
            int countValidPath = validPaths.Count();
            if (countValidPath < 1) {
                throw new ArgumentException("At least 1 valid path have to be given.");
            }
           
            // check if the path has enough elements
            int maxDepth = this.graphDepth;
            if (maxDepth <= 1) {
                throw new ArgumentException("Path has to have at least 2 elements.");
            }

            // set needed attributes
            this.graphValidPathCount = countValidPath;

            // a list of all possible nodes for all graph elements
            List<PossibleNode> allPossibleNodes = new List<PossibleNode>();

            // get a list of possible nodes that implement the first valid interface of the first node of the first valid path 
            ITypeReference tempInterface = validPaths[0].pathElements[0].mandatoryInterfaces.ElementAt(0);
            List<PossibleNode> possibleNodes = new List<PossibleNode>((List<PossibleNode>)this.graphInterfaces[tempInterface]);

            List<PossibleNode> copiedList = new List<PossibleNode>(possibleNodes);
            foreach (PossibleNode possibleNode in copiedList) {

                // check if all needed interfaces (by all valid paths) are contained by the possible node
                // if not => remove if from the list of possible nodes
                bool validNode = true;
                foreach (ITypeReference neededInterface in validPaths[0].pathElements[0].mandatoryInterfaces) {
                    if(!possibleNode.givenClass.Interfaces.Contains(neededInterface)) {
                        validNode = false;
                        break;
                    }
                }
                if(!validNode) {
                    possibleNodes.Remove(possibleNode);
                }

                // check if all forbidden interfaces (by all valid paths) are NOT contained by the possible node
                // if the possible node contains it => remove it from the list of possible nodes
                foreach (ITypeReference forbiddenInterface in validPaths[0].pathElements[0].forbiddenInterfaces) {
                    if(possibleNode.givenClass.Interfaces.Contains(forbiddenInterface)) {
                        validNode = false;
                        break;
                    }
                }
                if(!validNode) {
                    possibleNodes.Remove(possibleNode);
                }

            }

            if (possibleNodes.Count() == 0) {
                throw new ArgumentException("No class was found which satisfies the given requirements.");
            }

            // add all possible nodes for this graph element to the list of all possible nodes
            allPossibleNodes.AddRange(possibleNodes);


            // get first random node of graph            
            int randElement = this.prng.Next(possibleNodes.Count());
            NamespaceTypeDefinition classToUse = possibleNodes.ElementAt(randElement).givenClass;
            MethodDefinition nodeConstructor = possibleNodes.ElementAt(randElement).nodeConstructor;

            // create start node of graph
            List<int> startPosition = new List<int>();
            NodeObject startNode = new NodeObject(this.graphDimension, this.graphValidPathCount, classToUse, nodeConstructor, validPaths[0].pathElements[0], startPosition, 0);
            validPaths[0].pathElements[0].linkGraphObject = startNode;
            for (int validPathId = 1; validPathId < countValidPath; validPathId++) {
                startNode.elementOfValidPath.Add(validPathId);
                startNode.pathElements.Add(validPaths[validPathId].pathElements[0]);
                validPaths[validPathId].pathElements[0].linkGraphObject = startNode;
            }

            // add possible nodes to list of possible classes
            foreach (PossibleNode possibleNode in possibleNodes) {
                startNode.possibleClasses.Add(possibleNode.givenClass);
            }


            // build all valid paths
            for (int validPathId = 0; validPathId < countValidPath; validPathId++) {

                NodeObject currentNode = startNode;
                List<int> positionInGraph = new List<int>();

                // build a random valid path
                for (int idx = 1; idx < maxDepth; idx++) {

                    // get a list of possible nodes that implement the first valid interface of the first node of the first valid path 
                    tempInterface = validPaths[validPathId].pathElements[idx].mandatoryInterfaces.ElementAt(0);
                    possibleNodes = new List<PossibleNode>((List<PossibleNode>)this.graphInterfaces[tempInterface]);

                    // sort out nodes that do not satisfy all valid and invalid interface requirements of the node
                    copiedList = new List<PossibleNode>(possibleNodes);
                    foreach (PossibleNode possibleNode in copiedList) {

                        // check if all needed interfaces (by all valid paths) are contained by the possible node
                        // if not => remove if from the list of possible nodes
                        bool validNode = true;
                        foreach (ITypeReference neededInterface in validPaths[validPathId].pathElements[idx].mandatoryInterfaces) {
                            if (!possibleNode.givenClass.Interfaces.Contains(neededInterface)) {
                                validNode = false;
                                break;
                            }
                        }
                        if (!validNode) {
                            possibleNodes.Remove(possibleNode);
                        }

                        // check if all forbidden interfaces (by all valid paths) are NOT contained by the possible node
                        // if the possible node contains it => remove it from the list of possible nodes
                        foreach (ITypeReference forbiddenInterface in validPaths[validPathId].pathElements[idx].forbiddenInterfaces) {
                            if (possibleNode.givenClass.Interfaces.Contains(forbiddenInterface)) {
                                validNode = false;
                                break;
                            }
                        }
                        if (!validNode) {
                            possibleNodes.Remove(possibleNode);
                        }

                    }
                    if (possibleNodes.Count() == 0) {
                        throw new ArgumentException("No class was found which satisfies the given requirements.");
                    }


                    // add all distinct possible nodes for this graph element to the list of all possible nodes
                    foreach (PossibleNode possibleNode in possibleNodes) {
                        if (!allPossibleNodes.Contains(possibleNode)) {
                            allPossibleNodes.Add(possibleNode);
                        }
                    }


                    int pathIdx = validPaths[validPathId].pathIndices[idx];

                    if (currentNode.nodeObjects[pathIdx] != null) {

                        // check if the used class of the node satisfy both paths
                        NamespaceTypeDefinition usedClass = currentNode.nodeObjects[pathIdx].thisClass;
                        bool validNode = false; 
                        foreach (PossibleNode possibleNode in possibleNodes) {
                            if (usedClass == possibleNode.givenClass) {
                                validNode = true;
                                break;
                            }
                        }
                        if (!validNode) {
                            throw new ArgumentException("Node does not satisfy both valid paths.");
                        }


                        currentNode.nodeObjects[pathIdx].pathElements.Add(validPaths[validPathId].pathElements[idx]);
                        currentNode.nodeObjects[pathIdx].elementOfValidPath.Add(validPathId);
                        positionInGraph.Add(pathIdx);

                        validPaths[validPathId].pathElements[idx].linkGraphObject = currentNode.nodeObjects[pathIdx];

                    }

                    else {

                        // add path index to the position and copy position list
                        positionInGraph.Add(pathIdx);
                        List<int> tempPositionInGraph = new List<int>(positionInGraph);

                        // get random node for graph
                        randElement = this.prng.Next(possibleNodes.Count());
                        classToUse = possibleNodes.ElementAt(randElement).givenClass;
                        nodeConstructor = possibleNodes.ElementAt(randElement).nodeConstructor;

                        currentNode.nodeObjects[pathIdx] = new NodeObject(this.graphDimension, this.graphValidPathCount, classToUse, nodeConstructor, validPaths[validPathId].pathElements[idx], tempPositionInGraph, validPathId);
                        validPaths[validPathId].pathElements[idx].linkGraphObject = currentNode.nodeObjects[pathIdx];

                        // add possible nodes to list of possible classes
                        foreach (PossibleNode possibleNode in possibleNodes) {
                            currentNode.nodeObjects[pathIdx].possibleClasses.Add(possibleNode.givenClass);
                        }

                    }

                    currentNode = currentNode.nodeObjects[pathIdx];

                }

            }

            // fill the rest of the graph
            this.fillNodesRecursively(startNode, startPosition, 1, maxDepth, allPossibleNodes, validPaths);

            this.startingNode = startNode;

        }