private Z3Expr MkCoercion(Z3Expr t, AppFreeCanUnn unn, EnumEmbedding te) { var coercions = DefaultMember.Item2; foreach (var s in unn.NonRangeMembers) { Contract.Assert(s.IsNonVarConstant); coercions = t.Eq(Context, te.MkGround(s, null)).Ite( Context, MkGround(s, null), coercions); } return(coercions); }
private Z3Expr MkCoercion(Z3Expr t, AppFreeCanUnn unn, EnumEmbedding te) { return(CreationFun.Apply()); }
/// <summary> /// Factorizes constants into Enum, IntRange, and Singleton embeddings. /// </summary> private void FactorizeConstants(UserSymbol s, int index) { Term type; if (typeToFactors.ContainsKey(Index.GetCanonicalTerm(s, index))) { return; } bool wasAdded; var unn = s.CanonicalForm[index]; ITypeEmbedding factor; //// First, factorize ranges into IntRange and Singleton s.t. each IntRange contains //// 2^n constants for n > 0. BigInteger lower, upper, aligned, width; LinkedList <ITypeEmbedding> intFactors = new LinkedList <ITypeEmbedding>(); foreach (var r in unn.RangeMembers) { lower = r.Key; upper = r.Value; while (lower <= upper) { width = upper - lower + 1; if (width == 1) { type = MkRngType(lower, upper); if (!typeToEmbedding.TryFindValue(type, out factor)) { Register(factor = new SingletonEmbedding(this, type.Args[0].Symbol)); } intFactors.AddLast(factor); break; } else { aligned = lower + BigInteger.Pow(2, (int)width.MostSignificantOne()) - 1; type = MkRngType(lower, aligned); if (!typeToEmbedding.TryFindValue(type, out factor)) { Register(factor = new IntRangeEmbedding(this, lower, aligned)); } lower = aligned + 1; intFactors.AddLast(factor); } } } //// Second, factorize non-integers into Enum and Singleton s.t. each Enum contains 2^n constants for n > 0. //// Need to know the number of constants that will be factorized. uint cnstsToFac = 0; LinkedList <ITypeEmbedding> cnstFactors = new LinkedList <ITypeEmbedding>(); foreach (var m in unn.NonRangeMembers) { if (m.Kind != SymbolKind.BaseCnstSymb && m.Kind != SymbolKind.UserCnstSymb) { continue; } ++cnstsToFac; } if (cnstsToFac != 0) { type = null; uint i = 0; uint amountToFac = ((uint)1) << (int)cnstsToFac.MostSignificantOne(); foreach (var m in unn.NonRangeMembers) { if (m.Kind != SymbolKind.BaseCnstSymb && m.Kind != SymbolKind.UserCnstSymb) { continue; } ++i; type = type == null ? Index.MkApply(m, TermIndex.EmptyArgs, out wasAdded) : Index.MkApply( Index.TypeUnionSymbol, new Term[] { Index.MkApply(m, TermIndex.EmptyArgs, out wasAdded), type }, out wasAdded); if (i < amountToFac) { continue; } else if (amountToFac == 1) { if (!typeToEmbedding.TryFindValue(type, out factor)) { Register(factor = new SingletonEmbedding(this, m)); } cnstFactors.AddLast(factor); break; } else { if (!typeToEmbedding.TryFindValue(type, out factor)) { Register(factor = new EnumEmbedding(this, type, string.Format("{0}_{1}_{2}", s.FullName, index, cnstFactors.Count))); } cnstFactors.AddLast(factor); cnstsToFac -= amountToFac; if (cnstsToFac == 0) { break; } i = 0; type = null; amountToFac = ((uint)1) << (int)cnstsToFac.MostSignificantOne(); } } } typeToFactors.Add( Index.GetCanonicalTerm(s, index), new Tuple <LinkedList <ITypeEmbedding>, LinkedList <ITypeEmbedding> >(intFactors, cnstFactors)); }