/// <summary> /// Instantiates a new PatternEdge object /// </summary> /// <param name="fixedDirection">Whether this pattern edge should be matched with a fixed direction or not.</param> /// <param name="typeID">The type ID of the pattern edge.</param> /// <param name="type">The GrGen type of the pattern edge.</param> /// <param name="typeName">The name of the type interface of the pattern element.</param> /// <param name="name">The name of the pattern edge.</param> /// <param name="unprefixedName">Pure name of the pattern element as specified in the .grg without any prefixes</param> /// <param name="allowedTypes">An array of allowed types for this pattern element. /// If it is null, all subtypes of the type specified by typeID (including itself) /// are allowed for this pattern element.</param> /// <param name="isAllowedType">An array containing a bool for each edge type (order defined by the TypeIDs) /// which is true iff the corresponding type is allowed for this pattern element. /// It should be null if allowedTypes is null or empty or has only one element.</param> /// <param name="cost"> default cost/priority from frontend, user priority if given</param> /// <param name="parameterIndex">Specifies to which rule parameter this pattern element corresponds</param> /// <param name="maybeNull">Tells whether this pattern edge may be null (is a parameter if true).</param> /// <param name="storage">If not null this edge is to be bound by iterating the given storage.</param> /// <param name="storageIndex">If not null this edge is to be determined by a storage lookup, /// with the accessor given here applied as index into the storage given in the storage parameter.</param> /// <param name="indexAccess">If not null this pattern element is to be determined by an index lookup, with details specified by the concrete index access type contained in this field.</param> /// <param name="nameLookup">If not null this pattern element is to be determined by a name map lookup.</param> /// <param name="uniqueLookup">If not null this pattern element is to be determined by a unique index lookup.</param> /// <param name="elementBeforeCasting">If not null this pattern node is to be bound by casting the given elementBeforeCasting to the pattern node type or causing matching to fail.</param> /// <param name="defToBeYieldedTo">Iff true the element is only defined in its PointOfDefinition pattern, /// it gets matched in another, nested or called pattern which yields it to the containing pattern.</param> /// <param name="initialization">The initialization expression for the edge if some was defined, /// only possible for defToBeYieldedTo edges, otherwise null.</param> public PatternEdge(bool fixedDirection, int typeID, EdgeType type, String typeName, String name, String unprefixedName, GrGenType[] allowedTypes, bool[] isAllowedType, float cost, int parameterIndex, bool maybeNull, StorageAccess storage, StorageAccessIndex storageIndex, IndexAccess indexAccess, NameLookup nameLookup, UniqueLookup uniqueLookup, PatternElement elementBeforeCasting, bool defToBeYieldedTo, Expression initialization) : base(typeID, typeName, name, unprefixedName, allowedTypes, isAllowedType, cost, parameterIndex, maybeNull, storage, storageIndex, indexAccess, nameLookup, uniqueLookup, elementBeforeCasting, defToBeYieldedTo, initialization) { this.fixedDirection = fixedDirection; this.type = type; }
//////////////////////////////////////////////////////////////////////////// /// <summary> /// Instantiates a new PatternElement object. /// </summary> /// <param name="typeID">The type ID of the pattern element.</param> /// <param name="typeName">The name of the type interface of the pattern element.</param> /// <param name="name">The name of the pattern element.</param> /// <param name="unprefixedName">Pure name of the pattern element as specified in the .grg without any prefixes</param> /// <param name="allowedTypes">An array of allowed types for this pattern element. /// If it is null, all subtypes of the type specified by typeID (including itself) /// are allowed for this pattern element.</param> /// <param name="isAllowedType">An array containing a bool for each node/edge type (order defined by the TypeIDs) /// which is true iff the corresponding type is allowed for this pattern element. /// It should be null if allowedTypes is null or empty or has only one element.</param> /// <param name="cost">Default cost/priority from frontend, user priority if given.</param> /// <param name="parameterIndex">Specifies to which rule parameter this pattern element corresponds.</param> /// <param name="maybeNull">Tells whether this pattern element may be null (is a parameter if true).</param> /// <param name="storage">If not null this pattern element is to be bound by iterating the given storage.</param> /// <param name="storageIndex">If not null this pattern element is to be determined by a storage lookup, /// with the accessor given here applied as index into the storage given in the storage parameter.</param> /// <param name="indexAccess">If not null this pattern element is to be determined by an index lookup, with details specified by the concrete index access type contained in this field.</param> /// <param name="nameLookup">If not null this pattern element is to be determined by a name map lookup.</param> /// <param name="uniqueLookup">If not null this pattern element is to be determined by a unique index lookup.</param> /// <param name="elementBeforeCasting">If not null this pattern node is to be bound by casting the given elementBeforeCasting to the pattern node type or causing matching to fail.</param> /// <param name="defToBeYieldedTo">Iff true the element is only defined in its PointOfDefinition pattern, /// it gets matched in another, nested or called pattern which yields it to the containing pattern.</param> /// <param name="initialization">The initialization expression for the element if some was defined, /// only possible for defToBeYieldedTo elements, otherwise null.</param> public PatternElement(int typeID, String typeName, String name, String unprefixedName, GrGenType[] allowedTypes, bool[] isAllowedType, float cost, int parameterIndex, bool maybeNull, StorageAccess storage, StorageAccessIndex storageIndex, IndexAccess indexAccess, NameLookup nameLookup, UniqueLookup uniqueLookup, PatternElement elementBeforeCasting, bool defToBeYieldedTo, Expression initialization) { this.TypeID = typeID; this.typeName = typeName; this.name = name; this.unprefixedName = unprefixedName; this.AllowedTypes = allowedTypes; this.IsAllowedType = isAllowedType; this.Cost = cost; this.ParameterIndex = parameterIndex; this.MaybeNull = maybeNull; this.Storage = storage; this.StorageIndex = storageIndex; this.IndexAccess = indexAccess; this.NameLookup = nameLookup; this.UniqueLookup = uniqueLookup; this.ElementBeforeCasting = elementBeforeCasting; this.defToBeYieldedTo = defToBeYieldedTo; this.initialization = initialization; // TODO: the last parameters are (mostly) mutually exclusive, // introduce some abstract details class with specialized classed for the different cases, // only one instance needed instead of the large amount of mostly null valued variables now // better now with the introduction of helper classes for StorageAccess and StorageAccessIndex, but could be improved further }
/// <summary> /// Instantiates a new PatternElement object as a copy from an original element, used for independent inlining. /// </summary> /// <param name="original">The original pattern element to be copy constructed.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern element (to avoid name collisions).</param> public PatternElement(PatternElement original, String nameSuffix) { TypeID = original.TypeID; typeName = original.typeName; name = original.name + nameSuffix; unprefixedName = original.unprefixedName + nameSuffix; pointOfDefinition = original.pointOfDefinition; defToBeYieldedTo = original.defToBeYieldedTo; initialization = original.initialization != null ? original.initialization.Copy(nameSuffix) : null; annotations = original.annotations; AllowedTypes = original.AllowedTypes; IsAllowedType = original.IsAllowedType; Cost = original.Cost; ParameterIndex = original.ParameterIndex; MaybeNull = original.MaybeNull; Storage = original.Storage != null ? new StorageAccess(original.Storage) : null; StorageIndex = original.StorageIndex != null ? new StorageAccessIndex(original.StorageIndex) : null; IndexAccess = original.IndexAccess != null ? original.IndexAccess.Copy(nameSuffix) : null; NameLookup = original.NameLookup != null ? original.NameLookup.Copy(nameSuffix) : null; UniqueLookup = original.UniqueLookup != null ? original.UniqueLookup.Copy(nameSuffix) : null; ElementBeforeCasting = original.ElementBeforeCasting; AssignmentSource = original.AssignmentSource; OriginalIndependentElement = original; }
/// <summary> /// Search program operations implementing the /// PickByUnique or PickByUniqueDependent search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildPickByUnique( SearchProgramOperation insertionPoint, int currentOperationIndex, SearchPlanNode target, UniqueLookup uniqueLookup, IsomorphyInformation isomorphy) { bool isNode = target.NodeType == PlanNodeType.Node; string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek()); SourceBuilder expression = new SourceBuilder(); uniqueLookup.Expr.Emit(expression); // get candidate from unique index, only creates variable to hold it, get is fused with check for index membership GetCandidateByDrawing elementByUnique = new GetCandidateByDrawing( GetCandidateByDrawingType.MapByUnique, target.PatternElement.Name, expression.ToString(), isNode); insertionPoint = insertionPoint.Append(elementByUnique); // check existence of candidate in unique map CheckCandidateMapByUnique checkElementInUniqueMap = new CheckCandidateMapByUnique( target.PatternElement.Name, isNode); insertionPoint = insertionPoint.Append(checkElementInUniqueMap); // check type of candidate insertionPoint = decideOnAndInsertCheckType(insertionPoint, target); // check connectedness of candidate SearchProgramOperation continuationPointAfterConnectednessCheck; if(isNode) { insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap( insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck); } else { insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap( insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck); } if(continuationPointAfterConnectednessCheck == insertionPoint) continuationPointAfterConnectednessCheck = null; // check candidate for isomorphy if(isomorphy.CheckIsMatchedBit) { CheckCandidateForIsomorphy checkIsomorphy = new CheckCandidateForIsomorphy( target.PatternElement.Name, isomorphy.PatternElementsToCheckAgainstAsListOfStrings(), negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(checkIsomorphy); } // check candidate for global isomorphy if(programType == SearchProgramType.Subpattern || programType == SearchProgramType.AlternativeCase || programType == SearchProgramType.Iterated) { if(!isomorphy.TotallyHomomorph) { CheckCandidateForIsomorphyGlobal checkIsomorphy = new CheckCandidateForIsomorphyGlobal( target.PatternElement.Name, isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(), isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel); insertionPoint = insertionPoint.Append(checkIsomorphy); } } // check candidate for pattern path isomorphy if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath) { CheckCandidateForIsomorphyPatternPath checkIsomorphy = new CheckCandidateForIsomorphyPatternPath( target.PatternElement.Name, isNode, patternGraphWithNestingPatterns.Peek().isPatternpathLocked, getCurrentLastMatchAtPreviousNestingLevel()); insertionPoint = insertionPoint.Append(checkIsomorphy); } // accept candidate (write isomorphy information) if(isomorphy.SetIsMatchedBit) { AcceptCandidate acceptCandidate = new AcceptCandidate( target.PatternElement.Name, negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(acceptCandidate); } // mark element as visited target.Visited = true; //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- // unmark element for possibly following run target.Visited = false; // abandon candidate (restore isomorphy information) if(isomorphy.SetIsMatchedBit) { // only if isomorphy information was previously written AbandonCandidate abandonCandidate = new AbandonCandidate( target.PatternElement.Name, negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(abandonCandidate); } if(continuationPointAfterConnectednessCheck != null) insertionPoint = continuationPointAfterConnectednessCheck; return insertionPoint; }