internal T[] ToArray() { List <T> elems = new List <T>(); OverlapWitness ow = this; while (ow != null) { while (ow.replacement != null) { ow = ow.replacement; } elems.Add(ow.first); ow = ow.rest; } return(elems.ToArray()); }
void PreCompute__GetDistinguishingSeq() { var distinguisher = new Dictionary <Tuple <Block, Block>, Sequence <T> >(); __GetDistinguishingSeq = new Dictionary <Tuple <Block, Block>, Sequence <T> >(); HashSet <Sequence <T> > dseqs_set = new HashSet <Sequence <T> >(); List <Sequence <T> > dseqs = new List <Sequence <T> >(); if (initialNonfinalBlock.IsEmpty || initialFinalBlock.IsEmpty) { //degenerate case, there are no distinguishing strings distinguishingSequences = new Sequence <T>[] { }; } else { var overlaps = new Dictionary <Sequence <T>, OverlapWitness>(); int maxDistinguisherLength = 0; dseqs_set.Add(Sequence <T> .Empty); dseqs.Add(Sequence <T> .Empty); for (int i = 0; i < finalBlocks.Length - 1; i++) { var p = finalBlocks[i].Elem(); for (int j = i + 1; j < finalBlocks.Length; j++) { var q = finalBlocks[j].Elem(); var pq = (p < q ? new Tuple <Block, Block>(finalBlocks[i], finalBlocks[j]) : new Tuple <Block, Block>(finalBlocks[j], finalBlocks[i])); var d = GetDistinguishingSequence(p, q); distinguisher[pq] = d; if (dseqs_set.Add(d)) { if (d.Length > maxDistinguisherLength) { maxDistinguisherLength = d.Length; } dseqs.Add(d); overlaps[d] = null; } } } for (int i = 0; i < nonfinalBlocks.Length - 1; i++) { var p = nonfinalBlocks[i].Elem(); for (int j = i + 1; j < nonfinalBlocks.Length; j++) { var q = nonfinalBlocks[j].Elem(); var pq = (p < q ? new Tuple <Block, Block>(nonfinalBlocks[i], nonfinalBlocks[j]) : new Tuple <Block, Block>(nonfinalBlocks[j], nonfinalBlocks[i])); var d = GetDistinguishingSequence(p, q); distinguisher[pq] = d; if (dseqs_set.Add(d)) { if (d.Length > maxDistinguisherLength) { maxDistinguisherLength = d.Length; } dseqs.Add(d); overlaps[d] = null; } } } //create a common distinguishing sequence for overlapping cases List <Sequence <T> >[] distinguishersOrderedByLength = new List <Sequence <T> > [maxDistinguisherLength]; for (int i = 0; i < maxDistinguisherLength; i++) { distinguishersOrderedByLength[i] = new List <Sequence <T> >(); } for (int i = 0; i < dseqs.Count; i++) { if (dseqs[i].Length > 0) { distinguishersOrderedByLength[dseqs[i].Length - 1].Add(dseqs[i]); } } //create initial overlaps overlaps[Sequence <T> .Empty] = null; for (int i = 0; i < maxDistinguisherLength; i++) { var di = distinguishersOrderedByLength[i]; for (int j = 0; j < di.Count; j++) { overlaps[di[j]] = new OverlapWitness(di[j].First, overlaps[di[j].Rest()]); } } //normalize the distinguishing sequences in layers //assuming in each layer that the previous layer has been normalized for (int i = 0; i < maxDistinguisherLength; i++) { //nromalize layer i, i.e., sequences on length i+1 var thislayer = distinguishersOrderedByLength[i]; for (int j = 0; j < thislayer.Count - 1; j++) { var t = thislayer[j]; var t_first = t.First; var t_rest_overlap = overlaps[t.Rest()]; for (int k = j + 1; k < thislayer.Count; k++) { var s = thislayer[k]; var s_First = s.First; var s_rest_overlap = overlaps[s.Rest()]; if (s_rest_overlap == t_rest_overlap || (s_rest_overlap != null && t_rest_overlap != null && s_rest_overlap.Deref == t_rest_overlap.Deref)) { //check if the overlap can be extended to the whole sequence var psi = solver.MkAnd(overlaps[s].GetFirst(), overlaps[t].GetFirst()); if (solver.IsSatisfiable(psi)) { //join the overlaps var ow = new OverlapWitness(psi, s_rest_overlap); overlaps[s].ReplaceWith(ow); overlaps[t].ReplaceWith(ow); } } } } } //recompute distinguishing sequences based on the normalized sequences dseqs_set.Clear(); dseqs.Clear(); dseqs.Add(Sequence <T> .Empty); foreach (var entry in distinguisher) { var normalized_seq = new Sequence <T>(overlaps[entry.Value].ToArray()); if (dseqs_set.Add(normalized_seq)) { dseqs.Add(normalized_seq); } __GetDistinguishingSeq[entry.Key] = normalized_seq; } distinguishingSequences = dseqs.ToArray(); } }
internal void ReplaceWith(OverlapWitness other) { this.replacement = other; }
internal OverlapWitness(T first, OverlapWitness rest) { this.first = first; this.rest = rest; }