public CausalSetNode copyShallow() { Ensure.ensureHard(content == null); CausalSetNode result = new CausalSetNode(); result.next = ListHelpers.copy(next); result.nodeIndexInParentSystemBlock = nodeIndexInParentSystemBlock; result.globalIndex = globalIndex; return(result); }
public void getRandomFollowerSetInternalRecursive(uint entryIdx, ISet <uint> followerSet, float terminationPropability) { bool terminate = randomBool(terminationPropability); if (terminate) { return; } followerSet.Add(entryIdx); CausalSetNode selectedNode = this.nodes[(int)entryIdx]; foreach (CausalIndirectionIndex iFollowerIndirectionIdx in selectedNode.next) { uint followerIndex = this.translateIndirectIndexToIndex(iFollowerIndirectionIdx); this.getRandomFollowerSetInternalRecursive(followerIndex, followerSet, terminationPropability); } }
// creates a new block with the content as the fused nodes and fuses the nodes in the "entryBlock" and returns the created "CausalSystemBlock" which contains all fused nodes on the next level // entryblock doesn't get modified static public CausalSetSystemBlock fuse(CausalSetSystemBlock entryBlock, out CausalSetSystemBlock modifiedEntryBlock, IList <uint> indices) { CausalSetSystemBlock modifiedEntryBlock_localVar = entryBlock.copyDeep(); CausalSetSystemBlock higherLevelBlock = new CausalSetSystemBlock(); // fill higherLevelBlock with as many nodes as required foreach (uint iterationIndex in indices) { CausalSetNode createdNode = new CausalSetNode(); createdNode.nodeIndexInParentSystemBlock = iterationIndex; higherLevelBlock.nodes.Add(createdNode); higherLevelBlock.indirectionArray.Add(higherLevelBlock.getNewIndirectionNumber()); } // translates the index in entryBlock to the index in higherLevelBlock Dictionary <uint, uint> indexToElementInHigherLevelBlock = new Dictionary <uint, uint>(); for (uint i = 0; i < indices.Count; i++) { uint redirectedIndex = indices[(int)i]; indexToElementInHigherLevelBlock[redirectedIndex] = i; } // rewire from entryBlock the subnetwork to HigherLevelBlock foreach (Tuple <uint, CausalSetNode> iterationIndexAndNodePair in indices.Select(index => new Tuple <uint, CausalSetNode>(index, modifiedEntryBlock_localVar.getNodeByIndex(index)))) { uint higherLevelBlock_index = indexToElementInHigherLevelBlock[iterationIndexAndNodePair.Item1]; var nextValidIndicesFromIterationNode = iterationIndexAndNodePair.Item2.next .Select(nextIndirection => modifiedEntryBlock_localVar.translateIndirectIndexToIndex(nextIndirection)) .Where(index => indexToElementInHigherLevelBlock.ContainsKey(index)); // if the node points to an node which is not in nextLevelBlock then we ignore it foreach (uint iterationNextValidIndexFromIterationNode in nextValidIndicesFromIterationNode) { uint higherLevelBlock_nextIndex = indexToElementInHigherLevelBlock[iterationNextValidIndexFromIterationNode]; // make sure that the indirection is an identity // only this way we don't have to do an inverse lookup to get the CausalIndirectionIndex Ensure.ensureHard(higherLevelBlock.translateIndirectIndexToIndex(new CausalIndirectionIndex(higherLevelBlock_nextIndex)) == higherLevelBlock_nextIndex); higherLevelBlock.nodes[(int)higherLevelBlock_index].next.Add(new CausalIndirectionIndex(higherLevelBlock_nextIndex)); } } // transfer global index // global indices of fused nodes get reset to null by fuse so we ignore them for (uint i = 0; i < indices.Count; i++) { uint entryBlockIndex = indices[(int)i]; uint higherLevelBlock_index = indexToElementInHigherLevelBlock[entryBlockIndex]; higherLevelBlock.nodes[(int)higherLevelBlock_index].globalIndex = modifiedEntryBlock_localVar.nodes[(int)entryBlockIndex].globalIndex; } // now do the fuse uint fuseAsIndirectionNumber = modifiedEntryBlock_localVar.getNewIndirectionNumber(); modifiedEntryBlock_localVar.fuse(indices, fuseAsIndirectionNumber); // add fused node modifiedEntryBlock_localVar.nodes.Add(new CausalSetNode(higherLevelBlock)); // remove fused nodes and rewire indirectionArray accordingly indices.ToList().Sort(); var reversedSortedIndices = indices.Reverse(); foreach (uint iterationNodeIndex in reversedSortedIndices) { // redirect all indices pointing at the element behind the removed one to one before it modifiedEntryBlock_localVar.indirectionArray = modifiedEntryBlock_localVar.indirectionArray.Select(v => v > iterationNodeIndex ? v - 1 : v).ToList(); modifiedEntryBlock_localVar.nodes.RemoveAt((int)iterationNodeIndex); } modifiedEntryBlock = modifiedEntryBlock_localVar; return(higherLevelBlock); }