///// <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)));
            }
        }
        public SymbolicRegexNode <S> UnrollRE(SymbolicRegexNode <S> re)
        {
            // Create a regular expression without loops by unrolling
            // each loop a random number of times as dictated by the
            // maxUnroll parameter
            SymbolicRegexNode <S> newRoot = null;

            switch (re.Kind)
            {
            case SymbolicRegexKind.Concat:
                newRoot = builder.MkConcat(UnrollRE(re.Left),
                                           UnrollRE(re.Right));
                break;

            case SymbolicRegexKind.IfThenElse:
                newRoot = builder.MkIfThenElse(re.IteCond,
                                               UnrollRE(re.Left), UnrollRE(re.Right));
                break;

            case SymbolicRegexKind.Or:
                var alts = Array.ConvertAll(re.alts.ToArray(builder), UnrollRE);
                newRoot = builder.MkOr(alts);
                break;

            case SymbolicRegexKind.And:
                var conj = Array.ConvertAll(re.alts.ToArray(builder), UnrollRE);
                newRoot = builder.MkAnd(conj);
                break;

            case SymbolicRegexKind.Loop:
                newRoot = UnrollRE(UnrollLoop(re));
                break;

            default:     //anchors or singleton or epsilon
                newRoot = re;
                break;
            }
            return(newRoot);
        }
Example #3
0
        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.Epsilon:
                return(builderT.epsilon);

            case SymbolicRegexKind.Singleton:
                return(builderT.MkSingleton(predicateTransformer(sr.set)));

            case SymbolicRegexKind.Loop:
                return(builderT.MkLoop(Transform(sr.left, builderT, predicateTransformer), 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:
                return(builderT.MkConcat(Transform(sr.left, builderT, predicateTransformer),
                                         Transform(sr.right, builderT, predicateTransformer)));

            default:     //ITE
                return
                    (builderT.MkIfThenElse(Transform(sr.IteCond, builderT, predicateTransformer),
                                           Transform(sr.left, builderT, predicateTransformer),
                                           Transform(sr.right, builderT, predicateTransformer)));
            }
        }