private bool IsCompletedTermConsistentWithNextTerm(NonTerminalObject completedTerm, NonTerminalObject nextTerm, out NonTerminalStack intersection) { intersection = null; if (nextTerm == null) { return(false); } //the above case happens where the rule to be continued is already completed at the start column (next term = null). //this can only happen in a single case: that rule was an epsilon rule. if (completedTerm.NonTerminal != nextTerm.NonTerminal) { return(false); } if (nextTerm.Stack == null && completedTerm.Stack == null) { return(true); } var intersectAlgo = new StackGraphIntersect(); intersection = intersectAlgo.Execute(nextTerm.Stack, completedTerm.Stack); return(intersection != null); }
public NonTerminalStack GetPrefixListStackObjectOfGivenTop(string top) { if (top != Top && Top != Grammar.Epsilon) { throw new Exception( string.Format("popping {0} from stack graph headed by {1}, should be headed by EPSILON", top, Top)); } var newPrefixList = PrefixList; if (Top == Grammar.Epsilon) { if (PrefixList != null) { newPrefixList = PrefixList.Where(x => x.Top == top).ToList(); } } if (PrefixList == null) { return(null); } if (newPrefixList.Count == 1) { return(newPrefixList.First()); } var newStack = new NonTerminalStack(Grammar.Epsilon); newStack.PrefixList = newPrefixList; return(newStack); }
public override NonTerminalStack Execute(NonTerminalStack arg1, NonTerminalStack arg2) { var stackToIntersect = arg1; var otherStackToIntersect = arg2; if (arg1 == null || arg2 == null) { return(null); } if (arg1.Top != arg2.Top) { if (arg1.Top != Grammar.Epsilon) { stackToIntersect = new NonTerminalStack(Grammar.Epsilon, arg1); //stackToMerge.Weight = arg1.Weight; } if (arg2.Top != Grammar.Epsilon) { otherStackToIntersect = new NonTerminalStack(Grammar.Epsilon, arg2); //otherStackToMerge.Weight = arg2.Weight; } } InputNonTerminalStack v1 = new InputNonTerminalStack(stackToIntersect, 1); InputNonTerminalStack v2 = new InputNonTerminalStack(otherStackToIntersect, 2); return(InnerExecute(v1, v2)); }
protected void RecordSonDataOfInputGraphs(NonTerminalStack outputStack, int inputGraphNumber) { if (inputGraphNumber == 0) { SonsOfInputVertices[outputStack] = new SonDataFromInputGraphs(false, false); } else if (inputGraphNumber == 1) { if (!SonsOfInputVertices.ContainsKey(outputStack)) { SonsOfInputVertices[outputStack] = new SonDataFromInputGraphs(true, false); } SonsOfInputVertices[outputStack].VertexFromGraph1HasSon = true; } else if (inputGraphNumber == 2) { if (!SonsOfInputVertices.ContainsKey(outputStack)) { SonsOfInputVertices[outputStack] = new SonDataFromInputGraphs(false, true); } SonsOfInputVertices[outputStack].VertexFromGraph2HasSon = true; } else if (inputGraphNumber == 3) { SonsOfInputVertices[outputStack] = new SonDataFromInputGraphs(true, true); } }
//shallow copy. public NonTerminalStack(NonTerminalStack otherStack) { if (otherStack == null) return; Top = otherStack.Top; //Weight = otherStack.Weight; if (otherStack.PrefixList != null) PrefixList = otherStack.PrefixList; //shallow copy. //GetID(); }
//deep copy, used in intersect // ReSharper disable once UnusedParameter.Local public NonTerminalStack(NonTerminalStack otherStack, bool deepCopy) { if (otherStack == null) return; Top = otherStack.Top; //Weight = otherStack.Weight; if (otherStack.PrefixList != null) { PrefixList = new List<NonTerminalStack>(otherStack.PrefixList.Count); PrefixList = otherStack.PrefixList.Select(x => new NonTerminalStack(x, deepCopy)).ToList(); } }
//StackEquality here is used to identify the exact same structure - used //only in specific EqualityComparer (NonTerminalObjectStackComparer). //Equals is not implemented - the regular behavior of NonTerminalStack is ByReference. public static bool StackEquality(NonTerminalStack x, NonTerminalStack y) { if (x.Top != y.Top) return false; if (x.PrefixList != null && y.PrefixList != null) { if (x.PrefixList.Count != y.PrefixList.Count) return false; for (var i = 0; i < x.PrefixList.Count; i++) if (!StackEquality(x.PrefixList[i], y.PrefixList[i])) return false; return true; } return x.PrefixList == null && y.PrefixList == null; }
public void MapVertices(InputNonTerminalStack vertex1, NonTerminalStack target) { if (Mappings.ContainsKey(vertex1) && Mappings[vertex1].Contains(target)) { return; } if (!Mappings.ContainsKey(vertex1)) { Mappings[vertex1] = new List <NonTerminalStack>(); } Mappings[vertex1].Add(target); }
//shallow copy. public NonTerminalStack(NonTerminalStack otherStack) { if (otherStack == null) { return; } Top = otherStack.Top; //Weight = otherStack.Weight; if (otherStack.PrefixList != null) { PrefixList = otherStack.PrefixList; //shallow copy. } //GetID(); }
protected override NonTerminalStack AddSubtree(InputNonTerminalStack inputStack, int inputGraphNumber) { if (Mappings.ContainsKey(inputStack)) { if (inputGraphNumber == 1 && SonsOfInputVertices.ContainsKey(Mappings[inputStack].Last()) && !SonsOfInputVertices[Mappings[inputStack].Last()].VertexFromGraph2HasSon) { return(Mappings[inputStack].Last()); } if (inputGraphNumber == 2 && SonsOfInputVertices.ContainsKey(Mappings[inputStack].Last()) && !SonsOfInputVertices[Mappings[inputStack].Last()].VertexFromGraph1HasSon) { return(Mappings[inputStack].Last()); } } var newStack = new NonTerminalStack(inputStack.Stack.Top); if (inputStack.Stack.PrefixList != null) { foreach (var vertex in inputStack.Stack.PrefixList) { var vv = new InputNonTerminalStack(vertex, inputGraphNumber); var subtree = AddSubtree(vv, inputGraphNumber); if (newStack.PrefixList == null) { newStack.PrefixList = new List <NonTerminalStack>(); } newStack.PrefixList.Add(subtree); } RecordSonDataOfInputGraphs(newStack, inputGraphNumber); } else { RecordSonDataOfInputGraphs(newStack, 0); } MapVertices(inputStack, newStack); return(newStack); }
// uncomment for debugging purposes (commented to maximize efficiency) //public static int IDCounter; //public int ID { get; set; } //public int Weight { get; set; } //private void GetID() //{ // ID = IDCounter; // IDCounter += 1; //} public NonTerminalStack(string term, NonTerminalStack prefixStack) { Top = term; if (prefixStack != null) { PrefixList = new List <NonTerminalStack>(); if (prefixStack.Top == Grammar.Epsilon) { PrefixList = prefixStack.PrefixList; } else { PrefixList.Add(prefixStack); } } //GetID(); }
// uncomment for debugging purposes (commented to maximize efficiency) //public static int IDCounter; //public int ID { get; set; } //public int Weight { get; set; } //private void GetID() //{ // ID = IDCounter; // IDCounter += 1; //} public NonTerminalStack(string term, NonTerminalStack prefixStack) { Top = term; if (prefixStack != null) { PrefixList = new List<NonTerminalStack>(); if (prefixStack.Top == Grammar.Epsilon) { PrefixList = prefixStack.PrefixList; } else { PrefixList.Add(prefixStack); } } //GetID(); }
public bool Equals(NonTerminalObject x, NonTerminalObject y) { var b = x.NonTerminal == y.NonTerminal; if (!b) { return(false); } if (x.Stack == null && y.Stack == null) { return(true); } if (x.Stack != null && y.Stack != null) { return(NonTerminalStack.StackEquality(x.Stack, y.Stack)); } return(false); //one of the stack is null and the other is not. }
public bool CheckForFinalLeaves(InputNonTerminalStack v1, InputNonTerminalStack v2, NonTerminalStack outputStack) { //both null prefix lists and identical tops = return stack1 / stack2. (the leaf). if (v1.Stack.PrefixList == null && v2.Stack.PrefixList == null) { //if we already visited the output stack, if it has sons we cannot use it, we need to create new node. if (SonsOfInputVertices.ContainsKey(outputStack)) { if (SonsOfInputVertices[outputStack].VertexFromGraph1HasSon || SonsOfInputVertices[outputStack].VertexFromGraph2HasSon) { outputStack = new NonTerminalStack(v1.Stack.Top); } } MapVertices(v1, outputStack); MapVertices(v2, outputStack); RecordSonDataOfInputGraphs(outputStack, 0); return(true); } return(false); }
protected override bool CheckForInternalLeaves(InputNonTerminalStack stack1, InputNonTerminalStack stack2, NonTerminalStack outputStack, out NonTerminalStack res) { var retVal = false; res = null; if (stack1.Stack.IsInternalLeaf || stack2.Stack.IsInternalLeaf) { outputStack.IsInternalLeaf = true; } if (stack1.Stack.PrefixList == null && stack2.Stack.PrefixList != null) { RecordSonDataOfInputGraphs(outputStack, 2); if (stack1.Stack.IsInternalLeaf) { throw new Exception("3: internal leaf, but prefix list is null; contradiction"); } res = AddSubtree(stack2, 2); res.IsInternalLeaf = true; retVal = true; } if (stack2.Stack.PrefixList == null && stack1.Stack.PrefixList != null) { RecordSonDataOfInputGraphs(outputStack, 1); if (stack2.Stack.IsInternalLeaf) { throw new Exception("4: internal leaf, but prefix list is null; contradiction"); } res = AddSubtree(stack1, 1); res.IsInternalLeaf = true; retVal = true; } return(retVal); }
protected override bool CheckForInternalLeaves(InputNonTerminalStack stack1, InputNonTerminalStack stack2, NonTerminalStack outputStack, out NonTerminalStack res) { var retVal = false; res = null; if (stack1.Stack.IsInternalLeaf && stack2.Stack.IsInternalLeaf) { outputStack.IsInternalLeaf = true; } //one stack is leaf, the other is not => empty intersection. if (stack1.Stack.PrefixList == null && stack2.Stack.PrefixList != null) { RecordSonDataOfInputGraphs(outputStack, 2); if (stack1.Stack.IsInternalLeaf) { throw new Exception("1: internal leaf, but prefix list is null; contradiction"); } res = stack2.Stack.IsInternalLeaf ? outputStack : null; retVal = true; } else if (stack2.Stack.PrefixList == null && stack1.Stack.PrefixList != null) { RecordSonDataOfInputGraphs(outputStack, 1); if (stack2.Stack.IsInternalLeaf) { throw new Exception("2:internal leaf, but prefix list is null; contradiction"); } res = stack1.Stack.IsInternalLeaf ? outputStack : null; retVal = true; } return(retVal); }
protected override void TraverseRemainingList(bool moveNext, List <NonTerminalStack> .Enumerator iterator, NonTerminalStack outputStack, int inputGraphNumber) { var bRecorded = false; //map subtrees left after simulatenous traversal of the two lists ends (with the shorter list). while (moveNext) { var current = iterator.Current; InputNonTerminalStack vcurrent = new InputNonTerminalStack(current, inputGraphNumber); var son = AddSubtree(vcurrent, inputGraphNumber); if (outputStack.PrefixList == null) { outputStack.PrefixList = new List <NonTerminalStack>(); } outputStack.PrefixList.Add(son); if (!bRecorded) { RecordSonDataOfInputGraphs(outputStack, inputGraphNumber); bRecorded = true; } moveNext = iterator.MoveNext(); } }
private NonTerminalStack GetOrCreateOutputStack(InputNonTerminalStack v1, InputNonTerminalStack v2) { NonTerminalStack outputStack = null; if (Mappings.ContainsKey(v1)) { outputStack = Mappings[v1].Last(); } if (Mappings.ContainsKey(v2)) { if (outputStack != null) { throw new Exception("both vertices were already visited"); } outputStack = Mappings[v2].Last(); } if (outputStack == null) { outputStack = new NonTerminalStack(v1.Stack.Top); } return(outputStack); }
//StackEquality here is used to identify the exact same structure - used //only in specific EqualityComparer (NonTerminalObjectStackComparer). //Equals is not implemented - the regular behavior of NonTerminalStack is ByReference. public static bool StackEquality(NonTerminalStack x, NonTerminalStack y) { if (x.Top != y.Top) { return(false); } if (x.PrefixList != null && y.PrefixList != null) { if (x.PrefixList.Count != y.PrefixList.Count) { return(false); } for (var i = 0; i < x.PrefixList.Count; i++) { if (!StackEquality(x.PrefixList[i], y.PrefixList[i])) { return(false); } } return(true); } return(x.PrefixList == null && y.PrefixList == null); }
public static NonTerminalStack Intersect(NonTerminalStack stack1, NonTerminalStack stack2, HashSet<NonTerminalStack> visited1, HashSet<NonTerminalStack> visited2, Dictionary<NonTerminalStack, HashSet<NonTerminalStack>> mappings) { if (stack1 == null || stack2 == null) return null; visited1.Add(stack1); visited2.Add(stack2); if (!stack1.Top.Equals(stack2.Top)) return null; //both null prefix lists and identical tops = return stack1 / stack2. (the leaf). if (stack1.PrefixList == null && stack2.PrefixList == null) { return new NonTerminalStack(stack1.Top); } //one stack is leaf, the other is not => empty intersection. if (stack1.PrefixList == null || stack2.PrefixList == null) return null; //SEFI - update the function to allow arbitrary nodes to be leaves. //i.e. if TOP is leaf and the other top is leaf and one of the prefix lists is null, allow returning the leaf top as intersection. var intersectedStack = new NonTerminalStack(stack1.Top); var iterator1 = stack1.PrefixList.GetEnumerator(); var iterator2 = stack2.PrefixList.GetEnumerator(); var moveNext1 = iterator1.MoveNext(); var moveNext2 = iterator2.MoveNext(); //if MoveNext() passes the end of the list, it returns false while (moveNext1 && moveNext2) { var current1 = iterator1.Current; var current2 = iterator2.Current; //if at least one of the sons was not visited, we neet to compare the sons. if (!visited1.Contains(current1) || !visited2.Contains(current2)) { var compare = string.CompareOrdinal(current1.Top, current2.Top); if (compare > 0) moveNext2 = iterator2.MoveNext(); else if (compare < 0) moveNext1 = iterator1.MoveNext(); else //equal - call recursively. { var subtreesIntersection = Intersect(current1, current2, visited1, visited2, mappings); if (subtreesIntersection != null) { if (intersectedStack.PrefixList == null) intersectedStack.PrefixList = new List<NonTerminalStack>(); intersectedStack.PrefixList.Add(subtreesIntersection); MapVertices(current1, current2, subtreesIntersection, mappings); } moveNext1 = iterator1.MoveNext(); moveNext2 = iterator2.MoveNext(); } } else //both sons were visited - we check if they are in the same equivalence set. { var visitedSequence = mappings[current1].Intersect(mappings[current2]); if (visitedSequence.Any()) { if (intersectedStack.PrefixList == null) intersectedStack.PrefixList = new List<NonTerminalStack>(); intersectedStack.PrefixList.Add(visitedSequence.First()); } moveNext1 = iterator1.MoveNext(); moveNext2 = iterator2.MoveNext(); } } //if there is no common son to both stacks, there is no intersection down the subtrees. //reminder: if one of the prefixList of the compared stacks is null, we return earlier in this function. if (intersectedStack.PrefixList == null) return null; return intersectedStack; }
protected abstract void TraverseRemainingList(bool moveNext, List <NonTerminalStack> .Enumerator iterator, NonTerminalStack outputStack, int inputGraphNumber);
protected abstract bool CheckForInternalLeaves(InputNonTerminalStack stack1, InputNonTerminalStack stack2, NonTerminalStack outputStack, out NonTerminalStack res);
public abstract NonTerminalStack Execute(NonTerminalStack stack1, NonTerminalStack stack2);
public static void MapVertices(NonTerminalStack vertex1, NonTerminalStack vertex2, NonTerminalStack target, Dictionary<NonTerminalStack, HashSet<NonTerminalStack>> mappings) { if (mappings.ContainsKey(vertex1) && mappings.ContainsKey(vertex2)) { throw new Exception("should not occur! visited vertices are compared elsewhere."); } if (!mappings.ContainsKey(vertex1)) mappings[vertex1] = new HashSet<NonTerminalStack>(); mappings[vertex1].Add(target); if (!mappings.ContainsKey(vertex2)) mappings[vertex2] = new HashSet<NonTerminalStack>(); mappings[vertex2].Add(target); }
public static List<NonTerminalStack> EnforceStrictOrdering(NonTerminalStack[] l) { var mergedSortedList = new List<NonTerminalStack>(); for (var i = 0; i < l.Length - 1; i++) { var currentStackObject = l[i]; var nextStackObject = l[i + 1]; if (currentStackObject.Top == nextStackObject.Top) { var mergedSon = Merge(currentStackObject, nextStackObject); mergedSortedList.Add(mergedSon); i++; //skip l[i+1] (nextStackObject) - it has been merged into mergedSon. //also: assuming that both source lists are strictly ordered (each symbol appears only once), //so the seqeunce of some identical symbols is at most of length 2. } else mergedSortedList.Add(l[i]); if (i == l.Length - 2) { //if we arrive at the one before last element without it being merged with the last element, //add the last element (the loop above is from 0 to length-1). mergedSortedList.Add(l[i + 1]); } } return mergedSortedList; }
public static NonTerminalStack Merge(NonTerminalStack arg1, NonTerminalStack arg2) { var stackToMerge = arg1; var otherStackToMerge = arg2; if (otherStackToMerge == null) return stackToMerge; if (stackToMerge == null) return otherStackToMerge; if (arg1.Top != arg2.Top) { if (arg1.Top != Grammar.Epsilon) { stackToMerge = new NonTerminalStack(Grammar.Epsilon, arg1); //stackToMerge.Weight = arg1.Weight; } if (arg2.Top != Grammar.Epsilon) { otherStackToMerge = new NonTerminalStack(Grammar.Epsilon, arg2); //otherStackToMerge.Weight = arg2.Weight; } } var mergedStack = new NonTerminalStack(stackToMerge.Top); //mergedStack.Weight = stackToMerge.Weight + otherStackToMerge.Weight; if (stackToMerge.PrefixList == null && otherStackToMerge.PrefixList == null) return mergedStack; IEnumerable<NonTerminalStack> combinedList; if (stackToMerge.PrefixList == null && otherStackToMerge.PrefixList != null) combinedList = otherStackToMerge.PrefixList; else if (stackToMerge.PrefixList != null && otherStackToMerge.PrefixList == null) combinedList = stackToMerge.PrefixList; else combinedList = stackToMerge.PrefixList.Concat(otherStackToMerge.PrefixList); var sortedList = combinedList.OrderBy(x => x.Top).ToArray(); var forcedList = EnforceStrictOrdering(sortedList); //create a new merged stack without altering the original stacks. mergedStack.PrefixList = forcedList; return mergedStack; }
public InputNonTerminalStack(NonTerminalStack s, int number) { Stack = s; GraqphNumber = number; }
private bool IsCompletedTermConsistentWithNextTerm(NonTerminalObject completedTerm, NonTerminalObject nextTerm, out NonTerminalStack intersection) { intersection = null; if (nextTerm == null) return false; //the above case happens where the rule to be continued is already completed at the start column (next term = null). //this can only happen in a single case: that rule was an epsilon rule. if (completedTerm.NonTerminal != nextTerm.NonTerminal) return false; if (nextTerm.Stack == null && completedTerm.Stack == null) return true; NonTerminalStack arg1 = null; //deep copy the stacks in order not to alter the graphs of past stacks. if (nextTerm.Stack != null) arg1 = new NonTerminalStack(nextTerm.Stack, true); NonTerminalStack arg2 = null; if (completedTerm.Stack != null) arg2 = new NonTerminalStack(completedTerm.Stack, true); intersection = NonTerminalStack.Intersect(arg1, arg2, new HashSet<NonTerminalStack>(), new HashSet<NonTerminalStack>(), new Dictionary<NonTerminalStack, HashSet<NonTerminalStack>>()); return intersection != null; }
public NonTerminalStack GetPrefixListStackObjectOfGivenTop(string top) { if (top != Top && Top != Grammar.Epsilon) throw new Exception( string.Format("popping {0} from stack graph headed by {1}, should be headed by EPSILON", top, Top)); var newPrefixList = PrefixList; if (Top == Grammar.Epsilon) { if (PrefixList != null) newPrefixList = PrefixList.Where(x => x.Top == top).ToList(); } if (PrefixList == null) return null; if (newPrefixList.Count == 1) return newPrefixList.First(); var newStack = new NonTerminalStack(Grammar.Epsilon); newStack.PrefixList = newPrefixList; return newStack; }