///// <summary> ///// node is assumed to be in left-assoc form if it is a concatenation ///// </summary> //Sequence<CounterOperation> GetNullabilityCondition_of_left_assoc(SymbolicRegexNode<S> node) //{ // switch (node.kind) // { // case SymbolicRegexKind.StartAnchor: // case SymbolicRegexKind.EndAnchor: // case SymbolicRegexKind.Epsilon: // { // return Sequence<CounterOperation>.Empty; // } // case SymbolicRegexKind.Singleton: // { // return null; // } // case SymbolicRegexKind.Or: // { // if (node.isNullable) // return Sequence<CounterOperation>.Empty; // else // return null; // } // case SymbolicRegexKind.Loop: // { // if (node.isNullable) // return Sequence<CounterOperation>.Empty; // else if (IsCountingLoop(node)) // return new Sequence<CounterOperation>(new CounterOperation(node, CounterOp.EXIT)); // else // return null; // } // case SymbolicRegexKind.Concat: // { // var reset1 = GetNullabilityCondition_of_left_assoc(node.left); // if (reset1 == null) // return null; // else // { // //we know that right is not a concat // var reset2 = GetNullabilityCondition_of_left_assoc(node.right); // if (reset2 == null) // return null; // else // { // //TBD: this optimization needs to be verified // //if reset2 is nonempty it can only be a singleton // if (reset1.IsEmpty || reset2.IsEmpty || // reset1.TrueForAll(x => reset2[0].Counter.ContainsSubCounter(x.Counter))) // return reset1.Append(reset2); // else if (reset2[0].Counter.LowerBound == 0) // { // return reset1; // } // else // { // return null; // } // } // } // } // default: // { // throw new NotSupportedException("GetNullabilityCondition not supported for " + node.kind); // } // } //} internal SymbolicRegexNode <T> Transform <T>(SymbolicRegexNode <S> sr, SymbolicRegexBuilder <T> builderT, Func <S, T> predicateTransformer) { switch (sr.kind) { case SymbolicRegexKind.StartAnchor: return(builderT.startAnchor); case SymbolicRegexKind.EndAnchor: return(builderT.endAnchor); case SymbolicRegexKind.WatchDog: return(builderT.MkWatchDog(sr.lower)); case SymbolicRegexKind.Epsilon: return(builderT.epsilon); case SymbolicRegexKind.Singleton: return(builderT.MkSingleton(predicateTransformer(sr.set))); //case SymbolicRegexKind.Sequence: // return builderT.MkSequence(new Sequence<T>(Array.ConvertAll<S,T>(sr.sequence.ToArray(), x => predicateTransformer(x)))); case SymbolicRegexKind.Loop: return(builderT.MkLoop(Transform(sr.left, builderT, predicateTransformer), sr.isLazyLoop, sr.lower, sr.upper)); case SymbolicRegexKind.Or: return(builderT.MkOr(sr.alts.Transform(builderT, predicateTransformer))); case SymbolicRegexKind.And: return(builderT.MkAnd(sr.alts.Transform(builderT, predicateTransformer))); case SymbolicRegexKind.Concat: { var sr_elems = sr.ToArray(); var sr_elems_trasformed = Array.ConvertAll(sr_elems, x => Transform(x, builderT, predicateTransformer)); return(builderT.MkConcat(sr_elems_trasformed, false)); } default: //ITE return (builderT.MkIfThenElse(Transform(sr.IteCond, builderT, predicateTransformer), Transform(sr.left, builderT, predicateTransformer), Transform(sr.right, builderT, predicateTransformer))); } }