private Z3Expr MkCoercion(Z3Expr t, AppFreeCanUnn unn, UnionEmbedding te) { Z3Expr unbox; //// If the union contains string, then it cannot contain other strings. var test = te.MkTestAndUnbox(Index.SymbolTable.GetSortSymbol(BaseSortKind.String), t, out unbox); if (test != null) { return(test.Ite(Context, unbox, DefaultMember.Item2)); } ITypeEmbedding tep; Z3Expr coercions = DefaultMember.Item2; foreach (var s in unn.NonRangeMembers) { if (s.Kind != SymbolKind.BaseCnstSymb) { continue; } test = te.MkTestAndUnbox(s, t, out unbox); Contract.Assert(test != null); tep = Owner.GetEmbedding(unbox.Sort); switch (tep.Kind) { case TypeEmbeddingKind.Enum: coercions = test.And(Context, unbox.Eq(Context, tep.MkGround(s, null))).Ite( Context, MkGround(s, null), coercions); break; case TypeEmbeddingKind.Singleton: coercions = test.Ite( Context, MkGround(s, null), coercions); break; default: throw new NotImplementedException(); } } return(coercions); }
private Z3Expr MkCoercion(Z3Expr t, AppFreeCanUnn unn, UnionEmbedding te) { Z3BoolExpr test; Z3Expr unboxed; ITypeEmbedding ubxTE; var coercions = DefaultMember.Item2; foreach (var s in unn.NonRangeMembers) { test = te.MkTestAndUnbox(s, t, out unboxed); Contract.Assert(test != null); ubxTE = Owner.GetEmbedding(unboxed.FuncDecl.Range); test = test.And(Context, ubxTE.MkGround(s, null).Eq(Context, unboxed)); coercions = test.Ite(Context, MkGround(s, null), coercions); } return(coercions); }
private Z3Expr MkCoercion(Z3Expr t, AppFreeCanUnn unn, UnionEmbedding te) { Z3Expr unbox; //// If the union contains real, then it cannot contain other integral numerics. var test = te.MkTestAndUnbox(Index.SymbolTable.GetSortSymbol(BaseSortKind.Real), t, out unbox); if (test != null) { return(test.Ite( Context, MkCoercion(unbox, unn, (RealEmbedding)Owner.GetEmbedding(BaseSortKind.Real)), DefaultMember.Item2)); } //// If the union contains int, then it cannot contain other integral numerics. test = te.MkTestAndUnbox(Index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), t, out unbox); if (test != null) { return(test.Ite( Context, MkCoercion(unbox, unn, (IntegerEmbedding)Owner.GetEmbedding(BaseSortKind.Integer)), DefaultMember.Item2)); } //// Otherwise unn may contain subsorts of Integer or integer ranges. //// First handle the base subsorts var coercions = DefaultMember.Item2; test = te.MkTestAndUnbox(Index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), t, out unbox); if (test != null) { coercions = test.Ite( Context, MkCoercion(unbox, unn, (NaturalEmbedding)Owner.GetEmbedding(BaseSortKind.Natural)), coercions); } test = te.MkTestAndUnbox(Index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), t, out unbox); if (test != null) { coercions = test.Ite( Context, MkCoercion(unbox, unn, (PosIntegerEmbedding)Owner.GetEmbedding(BaseSortKind.PosInteger)), coercions); } test = te.MkTestAndUnbox(Index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), t, out unbox); if (test != null) { coercions = test.Ite( Context, MkCoercion(unbox, unn, (NegIntegerEmbedding)Owner.GetEmbedding(BaseSortKind.NegInteger)), coercions); } //// Additionally, there may be integer ranges. Z3BoolExpr[] tests; Z3Expr[] unboxeds; ITypeEmbedding tep; foreach (var kv in unn.RangeMembers) { tests = te.MkTestAndUnbox(kv.Key, kv.Value, t, out unboxeds); for (int i = 0; i < tests.Length; ++i) { test = tests[i]; unbox = unboxeds[i]; tep = Owner.GetEmbedding(unbox.Sort); switch (tep.Kind) { case TypeEmbeddingKind.IntRange: coercions = test.Ite( Context, MkCoercion(unbox, unn, (IntRangeEmbedding)tep), coercions); break; case TypeEmbeddingKind.Singleton: coercions = test.Ite( Context, MkCoercion(unbox, unn, (SingletonEmbedding)tep), coercions); break; default: throw new NotImplementedException(); } } } return(coercions); }