/// <summary> /// Constructs a canonical union where the canonical form is s. /// </summary> internal AppFreeCanUnn(SymbolTable table, Symbol s) { Contract.Requires(s != null); this.table = table; this.typeExpr = null; if (s.Kind != SymbolKind.BaseCnstSymb) { elements.Add(s); return; } var bc = (BaseCnstSymb)s; if (bc.CnstKind == CnstKind.Numeric && ((Rational)bc.Raw).IsInteger) { intervals.Add(((Rational)bc.Raw).Numerator, ((Rational)bc.Raw).Numerator); } else { elements.Add(s); } }
private void Add(Term t) { if (t.Symbol == unnSymb) { return; } bool wasAdded; Set <Term> bin; switch (t.Symbol.Kind) { case SymbolKind.ConSymb: case SymbolKind.MapSymb: { if (!binMap.TryFindValue(t.Symbol, out bin)) { bin = new Set <Term>(Term.Compare); binMap.Add(t.Symbol, bin); } Term max = null; if (t.Symbol.Kind == SymbolKind.ConSymb) { max = index.MkApply(((ConSymb)t.Symbol).SortSymbol, TermIndex.EmptyArgs, out wasAdded); } else { max = index.MkApply(((MapSymb)t.Symbol).SortSymbol, TermIndex.EmptyArgs, out wasAdded); } if (bin.Contains(max)) { return; } else { bin.Add(t); } break; } case SymbolKind.UserSortSymb: { if (!binMap.TryFindValue(((UserSortSymb)t.Symbol).DataSymbol, out bin)) { bin = new Set <Term>(Term.Compare); binMap.Add(((UserSortSymb)t.Symbol).DataSymbol, bin); bin.Add(t); } else if (!bin.Contains(t)) { bin.Clear(); bin.Add(t); } break; } case SymbolKind.UserCnstSymb: { Contract.Assert(t.Symbol.IsNonVarConstant); if (!binMap.TryFindValue(trueSymb, out bin)) { bin = new Set <Term>(Term.Compare); binMap.Add(trueSymb, bin); } bin.Add(t); break; } case SymbolKind.BaseSortSymb: { var baseSort = ((BaseSortSymb)t.Symbol); var binName = baseSort.SortKind == BaseSortKind.String ? stringSymb : realSymb; if (!binMap.TryFindValue(binName, out bin)) { bin = new Set <Term>(Term.Compare); binMap.Add(binName, bin); } switch (baseSort.SortKind) { case BaseSortKind.String: if (!bin.Contains(t)) { bin.Clear(); bin.Add(t); } break; case BaseSortKind.Real: if (!bin.Contains(t)) { bin.Clear(); bin.Add(t); intervals = null; } break; case BaseSortKind.Integer: if (!bin.Contains(t) && !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded))) { bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)); bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded)); bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded)); bin.Add(t); intervals = null; } break; case BaseSortKind.Natural: if (!bin.Contains(t) && !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)) && !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded))) { bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded)); bin.Add(t); if (intervals != null && intervals.Count > 0) { BigInteger min, max; intervals.GetExtrema(out min, out max); intervals.Remove(BigInteger.Zero, BigInteger.Max(BigInteger.Zero, max)); } } break; case BaseSortKind.PosInteger: if (!bin.Contains(t) && !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)) && !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)) && !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded))) { bin.Add(t); if (intervals != null && intervals.Count > 0) { BigInteger min, max; intervals.GetExtrema(out min, out max); intervals.Remove(BigInteger.One, BigInteger.Max(BigInteger.One, max)); } } break; case BaseSortKind.NegInteger: if (!bin.Contains(t) && !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)) && !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded))) { bin.Add(t); if (intervals != null && intervals.Count > 0) { BigInteger min, max; intervals.GetExtrema(out min, out max); intervals.Remove(BigInteger.Min(min, BigInteger.MinusOne), BigInteger.MinusOne); } } break; default: throw new NotImplementedException(); } break; } case SymbolKind.BaseCnstSymb: { var baseCnst = (BaseCnstSymb)t.Symbol; var binName = baseCnst.CnstKind == CnstKind.String ? stringSymb : realSymb; if (!binMap.TryFindValue(binName, out bin)) { bin = new Set <Term>(Term.Compare); binMap.Add(binName, bin); } switch (baseCnst.CnstKind) { case CnstKind.String: if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.String), TermIndex.EmptyArgs, out wasAdded))) { bin.Add(t); } break; case CnstKind.Numeric: { var rat = (Rational)baseCnst.Raw; if (bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded))) { } else if (!rat.IsInteger) { bin.Add(t); } else if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded))) { } else if (rat.Sign < 0) { if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded))) { intervals = intervals == null ? new IntIntervals() : intervals; intervals.Add(rat.Numerator, rat.Numerator); } } else if (rat.Sign == 0) { if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded))) { intervals = intervals == null ? new IntIntervals() : intervals; intervals.Add(rat.Numerator, rat.Numerator); } } else { if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)) && !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded))) { intervals = intervals == null ? new IntIntervals() : intervals; intervals.Add(rat.Numerator, rat.Numerator); } } break; } default: throw new NotImplementedException(); } break; } case SymbolKind.BaseOpSymb: { Contract.Assert(t.Symbol == rngSymb); if (!binMap.TryFindValue(realSymb, out bin)) { bin = new Set <Term>(Term.Compare); binMap.Add(realSymb, bin); } if (!bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)) && !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded))) { var end1 = ((Rational)((BaseCnstSymb)t.Args[0].Symbol).Raw).Numerator; var end2 = ((Rational)((BaseCnstSymb)t.Args[1].Symbol).Raw).Numerator; intervals = intervals == null ? new IntIntervals() : intervals; intervals.Add(end1, end2); BigInteger min, max; intervals.GetExtrema(out min, out max); if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded))) { intervals.Remove(BigInteger.Zero, BigInteger.Max(BigInteger.Zero, max)); } else if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded))) { intervals.Remove(BigInteger.One, BigInteger.Max(BigInteger.One, max)); } if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded))) { intervals.Remove(BigInteger.Min(BigInteger.MinusOne, min), BigInteger.MinusOne); } } break; } default: throw new InvalidOperationException(); } }