private void checkForNegativeHyperArc(option location, ruleNode fromLNode, node fromHostNode, ruleHyperarc newLHyperArc) { var otherConnectedNodes = (from n in newLHyperArc.nodes where ((n != fromLNode) && (location.findLMappedNode(n) != null)) select(location.findLMappedNode(n))); var oCNNum = otherConnectedNodes.Count(); var hostHyperArcs = (from ha in fromHostNode.arcs where (ha is hyperarc && !location.hyperarcs.Contains(ha) && (oCNNum == otherConnectedNodes.Intersect(((hyperarc)ha).nodes).Count())) select ha).Cast <hyperarc>(); /* at this stage hostHyperArcs are hyperarcs connected to fromHostNode, the same way that * newLHyperArc is connected to fromLNode. However, this is not enough! What about nodes also * connected to newLHyperArc that have already been recognized. We need to remove any instances * from hostHyperArcs which don't connect to mappings of these already recognized nodes. */ foreach (var hostHyperArc in hostHyperArcs) { checkForNegativeHyperArc(location.copy(), newLHyperArc, hostHyperArc); if ((bool)AllNegativeElementsFound) { return; /* another sub-branch found a match to the negative elements. * There's no point in finding more than one, so this statement * aborts the search down this branch. */ } } }
private void checkForNegativeHyperArc(option location, ruleHyperarc LHyperArc, hyperarc hostHyperArc) { if (!hyperArcMatches(LHyperArc, hostHyperArc)) { return; } location.hyperarcs[L.hyperarcs.IndexOf(LHyperArc)] = hostHyperArc; var newLNode = (ruleNode)LHyperArc.nodes.FirstOrDefault(n => (location.findLMappedNode(n) == null)); if (newLNode == null) { findNegativeStartElement(location); } else { foreach (var n in hostHyperArc.nodes.Where(n => !location.nodes.Contains(n))) { checkForNegativeNode(location.copy(), newLNode, n); if ((bool)AllNegativeElementsFound) { return; /* another sub-branch found a match to the negative elements. * There's no point in finding more than one, so this statement * aborts the search down this branch. */ } } } }
/// <summary> /// Returns a copy of this instance. /// </summary> /// <returns>the copy of the arc.</returns> public override hyperarc copy() { var copyOfNode = new ruleHyperarc(); copy(copyOfNode); return(copyOfNode); }
private void checkHyperArcAvoidNegatives(option location, ruleHyperarc LHyperArc, hyperarc hostHyperArc) { if (!hyperArcMatches(LHyperArc, hostHyperArc) && !hyperArcMatchRelaxed(LHyperArc, hostHyperArc, location)) { return; } location.hyperarcs[L.hyperarcs.IndexOf(LHyperArc)] = hostHyperArc; var newLNode = (ruleNode)LHyperArc.nodes.FirstOrDefault(n => ((ruleNode)n).MustExist && (location.findLMappedNode(n) == null)); if (newLNode == null) { FindPositiveStartElementAvoidNegatives(location); } else { foreach (var n in hostHyperArc.nodes.Where(n => !location.nodes.Contains(n))) { checkNodeAvoidNegatives(location.copy(), newLNode, n); } } }
private void checkHyperArcAvoidNegatives(option location, ruleNode fromLNode, node fromHostNode, ruleHyperarc newLHyperArc) { var otherConnectedNodes = (from n in newLHyperArc.nodes where ((n != fromLNode) && ((ruleNode)n).MustExist && (location.findLMappedNode(n) != null)) select(location.findLMappedNode(n))); var oCNNum = otherConnectedNodes.Count(); var hostHyperArcs = (from ha in fromHostNode.arcs where (ha is hyperarc && !location.hyperarcs.Contains(ha) && (oCNNum == otherConnectedNodes.Intersect(((hyperarc)ha).nodes).Count())) select ha).Cast <hyperarc>(); /* at this stage hostHyperArcs are hyperarcs connected to fromHostNode, the same way that * newLHyperArc is connected to fromLNode. However, this is not enough! What about nodes also * connected to newLHyperArc that have already been recognized. We need to remove any instances * from hostHyperArcs which don't connect to mappings of these already recognized nodes. */ foreach (var hostHyperArc in hostHyperArcs) { checkHyperArcAvoidNegatives(location.copy(), newLHyperArc, hostHyperArc); } }
/// <summary> /// Overrides the object method to check all details of the graphs to see /// if they are identical. It is potentially time-consuming as it makes /// rules and assigns the graphs as the L of the rule, and then performs /// the "recognize" function on the other graph. /// </summary> /// <param name="obj">The other graph to compare to this one.</param> /// <param name="contentsOfGraphAreEqual">if set to <c>true</c> then check that contents of graph are equal even though they occupy different memory.</param> /// <returns> /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// </returns> public bool Equals(object obj, bool contentsOfGraphAreEqual) { if (Equals(obj)) { return(true); } if (!contentsOfGraphAreEqual) { return(false); } if (!(obj is designGraph)) { return(false); } var g = (designGraph)obj; if (!grammarRule.LabelsMatch(globalLabels, g.globalLabels, null, true)) { return(false); } if (nodes.Count != g.nodes.Count) { return(false); } if (arcs.Count != g.arcs.Count) { return(false); } if (hyperarcs.Count != g.hyperarcs.Count) { return(false); } if (!DegreeSequence.SequenceEqual(g.DegreeSequence)) { return(false); } var thisSecondaryDegree = new List <List <int> >(); var gSecondaryDegree = new List <List <int> >(); for (int i = 0; i < nodes.Count; i++) { var thisDegreelist = new List <int>(); var gDegreelist = new List <int>(); var thisNode = nodes[i]; var gNode = g.nodes[i]; foreach (var a in thisNode.arcs) { if (a is arc) { thisDegreelist.Add(((arc)a).otherNode(thisNode).degree); } } thisDegreelist.Sort(); thisSecondaryDegree.Add(thisDegreelist); foreach (var a in gNode.arcs) { if (a is arc) { gDegreelist.Add(((arc)a).otherNode(gNode).degree); } } gDegreelist.Sort(); gSecondaryDegree.Add(gDegreelist); } foreach (var degreeList in thisSecondaryDegree) { var i = gSecondaryDegree.FindIndex(v => v.SequenceEqual(degreeList)); if (i == -1) { return(false); } else { gSecondaryDegree.RemoveAt(i); } } if (gSecondaryDegree.Any()) { return(false); } var maxDegree = DegreeSequence[0]; var dummyRule = new grammarRule { spanning = true, containsAllGlobalLabels = true, induced = true, L = new designGraph() }; #region put g's nodes, arcs and hyperarcs into the LHS of the rule foreach (var n in g.nodes) { var rn = new ruleNode(n) { containsAllLocalLabels = true, strictDegreeMatch = true }; if (n.degree == maxDegree) { dummyRule.L.nodes.Insert(0, rn); } else { dummyRule.L.nodes.Add(rn); } } foreach (var a in g.arcs) { var ra = new ruleArc(a) { containsAllLocalLabels = true, directionIsEqual = true }; dummyRule.L.arcs.Add(ra); } foreach (var ha in g.hyperarcs) { var rha = new ruleHyperarc(ha) { containsAllLocalLabels = true, strictNodeCountMatch = true }; dummyRule.L.hyperarcs.Add(rha); } dummyRule.L.RepairGraphConnections(); #endregion if (dummyRule.recognize(this).Count < 1) { return(false); } #region put this's nodes, arcs and hyperarcs into the LHS of the rule dummyRule.L = new designGraph(); foreach (var n in this.nodes) { var rn = new ruleNode(n) { containsAllLocalLabels = true, strictDegreeMatch = true }; if (n.degree == maxDegree) { dummyRule.L.nodes.Insert(0, rn); } else { dummyRule.L.nodes.Add(rn); } } foreach (var a in this.arcs) { var ra = new ruleArc(a) { containsAllLocalLabels = true, directionIsEqual = true }; dummyRule.L.arcs.Add(ra); } foreach (var ha in this.hyperarcs) { var rha = new ruleHyperarc(ha) { containsAllLocalLabels = true, strictNodeCountMatch = true }; dummyRule.L.hyperarcs.Add(rha); } dummyRule.L.RepairGraphConnections(); #endregion if (dummyRule.recognize(g).Count < 1) { return(false); } return(true); }