예제 #1
0
        private static Zen <T2> Simplify(Zen <T1> expr, string fieldName, bool unroll)
        {
            // get(with(o, name, f), name) == f
            // get(with(o, name', f), name) == get(o, name)
            if (expr is ZenWithFieldExpr <T1, T2> e1)
            {
                return((e1.FieldName == fieldName) ?
                       e1.FieldValue :
                       Create(e1.Expr, fieldName)); // recurse
            }

            // get(if e1 then e2 else e3, name) = if e1 then get(e2, name) else get(e3, name)
            if (unroll && expr is ZenIfExpr <T1> e2)
            {
                var trueBranch  = Create(e2.TrueExpr, fieldName);
                var falseBranch = Create(e2.FalseExpr, fieldName);
                return(ZenIfExpr <T2> .Create(e2.GuardExpr, trueBranch.Unroll(), falseBranch.Unroll()));
            }

            // get(createobject(p1, ..., pn), namei) == pi
            if (expr is ZenCreateObjectExpr <T1> coe)
            {
                return((Zen <T2>)coe.Fields[fieldName]);
            }

            return(new ZenGetFieldExpr <T1, T2>(expr, fieldName));
        }
예제 #2
0
 private static Zen <FiniteString> At(Zen <IList <ushort> > s, Zen <ushort> i, int current)
 {
     return(s.Case(
                empty: FiniteString.Empty(),
                cons: (hd, tl) =>
                If(i == (ushort)current, FiniteString.Singleton(hd), At(tl, i, current + 1))));
 }
예제 #3
0
        /// <summary>
        /// Gets the first index of a substring in a
        /// string starting at an offset.
        /// </summary>
        /// <param name="s">The string.</param>
        /// <param name="sub">The substring.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>An index.</returns>
        public static Zen <Option <ushort> > IndexOf(this Zen <FiniteString> s, Zen <FiniteString> sub, Zen <ushort> offset)
        {
            var trimmed = s.GetCharacters().Drop(offset);
            var idx     = IndexOf(trimmed, sub.GetCharacters(), 0);

            return(If(idx.HasValue(), Some(idx.Value() + offset), idx));
        }
예제 #4
0
        /// <summary>
        /// Create a new ZenStringLengthExpr.
        /// </summary>
        /// <param name="expr">The string expr.</param>
        /// <returns>The new Zen expr.</returns>
        public static Zen <BigInteger> Create(Zen <string> expr)
        {
            CommonUtilities.ValidateNotNull(expr);

            hashConsTable.GetOrAdd(expr.Id, () => Simplify(expr), out var value);
            return(value);
        }
예제 #5
0
        private static Zen <TResult> Simplify(Zen <IList <T> > e, Zen <TResult> emptyCase, Func <Zen <T>, Zen <IList <T> >, Zen <TResult> > consCase)
        {
            if (e is ZenListEmptyExpr <T> l1)
            {
                return(emptyCase);
            }

            if (e is ZenListAddFrontExpr <T> l2)
            {
                return(consCase(l2.Element, l2.Expr));
            }

            if (Settings.SimplifyRecursive)
            {
                if (e is ZenIfExpr <IList <T> > l3)
                {
                    var tbranch = ZenListCaseExpr <T, TResult> .Create(l3.TrueExpr, emptyCase, consCase);

                    var fbranch = ZenListCaseExpr <T, TResult> .Create(l3.FalseExpr, emptyCase, consCase);

                    return(ZenIfExpr <TResult> .Create(l3.GuardExpr, tbranch, fbranch));
                }
            }

            return(new ZenListCaseExpr <T, TResult>(e, emptyCase, consCase));
        }
예제 #6
0
        /// <summary>
        /// Create a new ZenBitwiseNot expr.
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public static Zen <T> Create(Zen <T> expr)
        {
            CommonUtilities.ValidateNotNull(expr);
            CommonUtilities.ValidateIsIntegerType(typeof(T));

            hashConsTable.GetOrAdd(expr.Id, () => Simplify(expr), out var value);
            return(value);
        }
예제 #7
0
 private static Zen <bool> StartsWith(Zen <IList <ushort> > s, Zen <IList <ushort> > pre)
 {
     return(pre.Case(
                empty: true,
                cons: (hd1, tl1) => s.Case(
                    empty: false,
                    cons: (hd2, tl2) => AndIf(hd1 == hd2, StartsWith(tl2, tl1)))));
 }
예제 #8
0
 /// <summary>
 /// Find all inputs that solve the constraint.
 /// </summary>
 /// <param name="input">Default input that captures structural constraints.</param>
 /// <param name="listSize">The maximum number of elements to consider in an input list.</param>
 /// <param name="checkSmallerLists">Whether to check smaller list sizes as well.</param>
 /// <param name="backend">The backend.</param>
 /// <returns>An input if one exists satisfying the constraints.</returns>
 public IEnumerable <T> FindAll(
     Zen <T> input          = null,
     int listSize           = 5,
     bool checkSmallerLists = true,
     Backend backend        = Backend.Z3)
 {
     return(this.FindAll((i, o) => o, input, listSize, checkSmallerLists, backend));
 }
예제 #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZenListCaseExpr{TList, TResult}"/> class.
 /// </summary>
 /// <param name="listExpr">The list.</param>
 /// <param name="empty">The empty case.</param>
 /// <param name="cons">The cons case.</param>
 private ZenListCaseExpr(
     Zen <IList <T> > listExpr,
     Zen <TResult> empty,
     Func <Zen <T>, Zen <IList <T> >, Zen <TResult> > cons)
 {
     this.ListExpr  = listExpr;
     this.EmptyCase = empty;
     this.ConsCase  = cons;
 }
예제 #10
0
        /// <summary>
        /// Get a constant string value.
        /// </summary>
        /// <typeparam name="T">The type.</typeparam>
        /// <param name="value">The Zen string value.</param>
        /// <returns>A string.</returns>
        public static string GetConstantString <T>(Zen <T> value)
        {
            if (value is ZenConstantStringExpr xs)
            {
                return(xs.UnescapedValue);
            }

            return(null);
        }
예제 #11
0
        public static Zen <ushort> Simplify(Zen <string> e1)
        {
            var x = ReflectionUtilities.GetConstantString(e1);

            if (x != null)
            {
                return(x.Length);
            }
            return(new ZenStringLengthExpr(e1));
        }
예제 #12
0
        public static Zen <TResult> Create(
            Zen <IList <T> > listExpr,
            Zen <TResult> empty,
            Func <Zen <T>, Zen <IList <T> >, Zen <TResult> > cons)
        {
            CommonUtilities.ValidateNotNull(listExpr);
            CommonUtilities.ValidateNotNull(empty);
            CommonUtilities.ValidateNotNull(cons);

            return(Simplify(listExpr, empty, cons));
        }
예제 #13
0
        private static Zen <bool> Simplify(Zen <bool> e)
        {
            if (e is ZenConstantBoolExpr x)
            {
                return(x.Value ? ZenConstantBoolExpr.False : ZenConstantBoolExpr.True);
            }

            if (e is ZenNotExpr y)
            {
                return(y.Expr);
            }

            return(new ZenNotExpr(e));
        }
예제 #14
0
        public static Zen <bool> Create(Zen <bool> expr)
        {
            CommonUtilities.ValidateNotNull(expr);

            if (hashConsTable.TryGetValue(expr, out var value))
            {
                return(value);
            }

            var ret = Simplify(expr);

            hashConsTable[expr] = ret;
            return(ret);
        }
예제 #15
0
        private static Zen <bool> Simplify(Zen <bool> e)
        {
            if (e is ZenConstantExpr <bool> x)
            {
                return(x.Value ? ZenConstantExpr <bool> .Create(false) : ZenConstantExpr <bool> .Create(true));
            }

            if (e is ZenNotExpr y)
            {
                return(y.Expr);
            }

            return(new ZenNotExpr(e));
        }
예제 #16
0
        public static Zen <T> Create(Zen <T> expr)
        {
            CommonUtilities.ValidateNotNull(expr);
            CommonUtilities.ValidateIsIntegerType(typeof(T));

            if (hashConsTable.TryGetValue(expr, out var value))
            {
                return(value);
            }

            var ret = Simplify(expr);

            hashConsTable[expr] = ret;
            return(ret);
        }
예제 #17
0
        public static Zen <TTo> CreateMulti(Zen <TFrom> expr, ImmutableList <Func <object, object> > converters, bool unroll = false)
        {
            CommonUtilities.ValidateNotNull(expr);
            var key = (expr, ConvertersHashCode(converters), unroll);

            if (hashConsTable.TryGetValue(key, out var value))
            {
                return(value);
            }

            var ret = Simplify(expr, converters, unroll);

            hashConsTable[key] = ret;
            return(ret);
        }
예제 #18
0
        private static Zen <T> Simplify(Zen <T> e)
        {
            var x = ReflectionUtilities.GetConstantIntegerValue(e);

            if (x.HasValue)
            {
                return(ReflectionUtilities.CreateConstantValue <T>(~x.Value));
            }

            if (e is ZenBitwiseNotExpr <T> y)
            {
                return(y.Expr);
            }

            return(new ZenBitwiseNotExpr <T>(e));
        }
예제 #19
0
        private static Zen <TTo> Simplify(Zen <TFrom> e, ImmutableList <Func <object, object> > converters, bool unroll)
        {
            // adapt(t1, t2, adapt(t2, t1, e)) == e
            if (e is ZenAdapterExpr <TFrom, TTo> inner1)
            {
                return(inner1.Expr);
            }

            if (unroll && e is ZenIfExpr <TFrom> inner2)
            {
                var trueBranch  = CreateMulti(inner2.TrueExpr, converters);
                var falseBranch = CreateMulti(inner2.FalseExpr, converters);
                return(ZenIfExpr <TTo> .Create(inner2.GuardExpr, trueBranch.Unroll(), falseBranch.Unroll()));
            }

            return(new ZenAdapterExpr <TTo, TFrom>(e, converters));
        }
예제 #20
0
        public static Zen <T2> Create(Zen <T1> expr, string fieldName, bool unroll = false)
        {
            CommonUtilities.ValidateNotNull(expr);
            CommonUtilities.ValidateNotNull(fieldName);
            ReflectionUtilities.ValidateFieldOrProperty(typeof(T1), typeof(T2), fieldName);

            var key = (expr, fieldName, unroll);

            if (hashConsTable.TryGetValue(key, out var value))
            {
                return(value);
            }

            var ret = Simplify(expr, fieldName, unroll);

            hashConsTable[key] = ret;
            return(ret);
        }
예제 #21
0
        private static Zen <TTo> Simplify(Zen <TFrom> e, ImmutableList <Func <object, object> > converters)
        {
            // adapt(t1, t2, adapt(t2, t1, e)) == e
            if (e is ZenAdapterExpr <TFrom, TTo> inner1)
            {
                return(inner1.Expr);
            }

            // adapt(t1, t2, adapt(t2, t3, e)) == adapt(t1, t3, e)

            /* var type = e.GetType();
             * if (type.GetGenericTypeDefinition() == typeof(ZenAdapterExpr<,>))
             * {
             *  if (type.GetGenericArguments()[0] == typeof(T2))
             *  {
             *      var type1 = typeof(T1);
             *      var type3 = type.GetGenericArguments()[1];
             *      var astType = typeof(ZenAdapterExpr<,>).MakeGenericType(type1, type3);
             *      var paramType1 = typeof(Zen<>).MakeGenericType(type3);
             *      var paramType2 = typeof(ImmutableList<>).MakeGenericType(typeof(Func<object, object>));
             *      var method = astType.GetMethod("CreateMulti");
             *      var param1 = type.GetProperty("Expr").GetValue(e);
             *      var converters = (ImmutableList<Func<object, object>>)type.GetProperty("Converters").GetValue(e);
             *      var param2 = converters.AddRange(expression.Converters);
             *      return (Zen<T1>)method.Invoke(null, new object[] { param1, param2 });
             *  }
             * } */
            if (Settings.SimplifyRecursive)
            {
                if (e is ZenIfExpr <TFrom> inner2)
                {
                    var trueBranch = ZenAdapterExpr <TTo, TFrom> .CreateMulti(inner2.TrueExpr, converters);

                    var falseBranch = ZenAdapterExpr <TTo, TFrom> .CreateMulti(inner2.FalseExpr, converters);

                    return(ZenIfExpr <TTo> .Create(inner2.GuardExpr, trueBranch, falseBranch));
                }
            }

            return(new ZenAdapterExpr <TTo, TFrom>(e, converters));
        }
예제 #22
0
        private static Zen <TResult> Simplify(Zen <IList <T> > e, Zen <TResult> emptyCase, Func <Zen <T>, Zen <IList <T> >, Zen <TResult> > consCase, bool unroll)
        {
            if (e is ZenListEmptyExpr <T> l1)
            {
                return(emptyCase);
            }

            if (e is ZenListAddFrontExpr <T> l2)
            {
                return(consCase(l2.Element, l2.Expr));
            }

            if (unroll && e is ZenIfExpr <IList <T> > l3)
            {
                var tbranch = Create(l3.TrueExpr, emptyCase, consCase);
                var fbranch = Create(l3.FalseExpr, emptyCase, consCase);
                return(ZenIfExpr <TResult> .Create(l3.GuardExpr, tbranch.Unroll(), fbranch.Unroll()));
            }

            return(new ZenListCaseExpr <T, TResult>(e, emptyCase, consCase));
        }
예제 #23
0
        /// <summary>
        /// Get an integer value as a long.
        /// </summary>
        /// <typeparam name="T">The integer gype.</typeparam>
        /// <param name="value">The Zen integer value.</param>
        /// <returns>A long.</returns>
        public static long?GetConstantIntegerValue <T>(Zen <T> value)
        {
            if (value is ZenConstantByteExpr xb)
            {
                return(xb.Value);
            }

            if (value is ZenConstantShortExpr xs)
            {
                return(xs.Value);
            }

            if (value is ZenConstantUshortExpr xus)
            {
                return(xus.Value);
            }

            if (value is ZenConstantIntExpr xi)
            {
                return(xi.Value);
            }

            if (value is ZenConstantUintExpr xui)
            {
                return(xui.Value);
            }

            if (value is ZenConstantLongExpr xl)
            {
                return(xl.Value);
            }

            if (value is ZenConstantUlongExpr xul)
            {
                return((long?)xul.Value);
            }

            return(null);
        }
예제 #24
0
 /// <summary>
 /// Replaces all occurrences of a given character with another.
 /// </summary>
 /// <param name="s">The string.</param>
 /// <param name="src">The source value.</param>
 /// <param name="dst">The destination value.</param>
 /// <returns>A new string.</returns>
 public static Zen <FiniteString> ReplaceAll(this Zen <FiniteString> s, Zen <ushort> src, Zen <ushort> dst)
 {
     return(FiniteString.Create(s.GetCharacters().Select(c => If(c == src, dst, c))));
 }
예제 #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZenStringLengthExpr"/> class.
 /// </summary>
 /// <param name="expr">The string expression.</param>
 private ZenStringLengthExpr(Zen <string> expr)
 {
     this.Expr = expr;
 }
예제 #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZenBitwiseNotExpr{T}"/> class.
 /// </summary>
 /// <param name="expr">The expression.</param>
 private ZenBitwiseNotExpr(Zen <T> expr)
 {
     this.Expr = expr;
 }
예제 #27
0
 /// <summary>
 /// Removes all occurrences of a given character.
 /// </summary>
 /// <param name="s">The string.</param>
 /// <param name="value">The value to remove.</param>
 /// <returns>A new string.</returns>
 public static Zen <FiniteString> RemoveAll(this Zen <FiniteString> s, Zen <ushort> value)
 {
     return(Transform(s, l => l.Where(c => c != value)));
 }
예제 #28
0
 /// <summary>
 /// Transform a string by modifying its characters.
 /// </summary>
 /// <param name="s">The string.</param>
 /// <param name="f">The transformation function.</param>
 /// <returns>A new string.</returns>
 public static Zen <FiniteString> Transform(this Zen <FiniteString> s, Func <Zen <IList <ushort> >, Zen <IList <ushort> > > f)
 {
     return(FiniteString.Create(f(s.GetCharacters())));
 }
예제 #29
0
 /// <summary>
 /// Creates an empty string.
 /// </summary>
 /// <returns>The empty string.</returns>
 public static Zen <FiniteString> Singleton(Zen <ushort> b)
 {
     return(Create(Language.Singleton(b)));
 }
예제 #30
0
 /// <summary>
 /// Creates an FiniteString.
 /// </summary>
 /// <returns>The empty string.</returns>
 public static Zen <FiniteString> Create(Zen <IList <ushort> > values)
 {
     return(Create <FiniteString>(("Characters", values)));
 }