/// <summary> /// Create a type term from this union. An optional renaming may be applied /// to its elements. /// </summary> internal Term MkTypeTerm(TermIndex index) { Contract.Assert(elements.Count > 0 || intervals.Count > 0); Term t = null; var tunSymb = index.SymbolTable.GetOpSymbol(ReservedOpKind.TypeUnn); var noArgs = new Term[0]; bool wasAdded; //// Step 1. Create an enum of all non-integral constants. foreach (var e in elements) { t = t == null?index.MkApply(e, noArgs, out wasAdded) : index.MkApply(tunSymb, new Term[] { index.MkApply(e, noArgs, out wasAdded), t }, out wasAdded); } //// Step 2. Create an enum of all integer intervals var rngSymb = index.SymbolTable.GetOpSymbol(ReservedOpKind.Range); Term beg, end; foreach (var kv in intervals.CanonicalForm) { beg = index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded); end = index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded); t = t == null?index.MkApply(rngSymb, new Term[] { beg, end }, out wasAdded) : index.MkApply(tunSymb, new Term[] { index.MkApply(rngSymb, new Term[] { beg, end }, out wasAdded), t }, out wasAdded); } return(t); }
private IEnumerable <Node> Expand_Unfold(Node n, Stack <Tuple <Namespace, Symbol> > symbStack, MutableTuple <int> nextDcVarId, SuccessToken success, List <Flag> flags) { var space = symbStack.Peek().Item1; switch (n.NodeKind) { case NodeKind.Cnst: { bool wasAdded; var cnst = (Cnst)n; BaseCnstSymb symb; switch (cnst.CnstKind) { case CnstKind.Numeric: symb = (BaseCnstSymb)index.MkCnst((Rational)cnst.Raw, out wasAdded).Symbol; break; case CnstKind.String: symb = (BaseCnstSymb)index.MkCnst((string)cnst.Raw, out wasAdded).Symbol; break; default: throw new NotImplementedException(); } symbStack.Push(new Tuple <Namespace, Symbol>(space, symb)); return(null); } case NodeKind.Id: { var id = (Id)n; UserSymbol symb; if (index.SymbolTable.HasRenamingPrefix(id)) { if (!Resolve(id.Name, "constant", id, space, x => x.IsNonVarConstant, out symb, flags)) { symbStack.Push(new Tuple <Namespace, Symbol>(null, null)); success.Failed(); return(null); } } else if (id.Fragments.Length == 1 && id.Name == API.ASTQueries.ASTSchema.Instance.DontCareName) { bool wasAdded; var fresh = index.MkVar(string.Format("{0}{1}{2}", SymbolTable.ManglePrefix, "dc", nextDcVarId.Item1), true, out wasAdded); ++nextDcVarId.Item1; symbStack.Push(new Tuple <Namespace, Symbol>(space, fresh.Symbol)); return(null); } else if (!Resolve(id.Fragments[0], "variable or constant", id, space, x => x.Kind == SymbolKind.UserCnstSymb, out symb, flags)) { symbStack.Push(new Tuple <Namespace, Symbol>(null, null)); success.Failed(); return(null); } else if (id.Fragments.Length > 1 && symb.IsNonVarConstant) { var flag = new Flag( SeverityKind.Error, id, Constants.BadSyntax.ToString("constants do not have fields"), Constants.BadSyntax.Code); flags.Add(flag); symbStack.Push(new Tuple <Namespace, Symbol>(null, null)); success.Failed(); return(null); } else if (symb.IsVariable) { var flag = new Flag( SeverityKind.Error, id, Constants.BadSyntax.ToString("Variables cannot appear here."), Constants.BadSyntax.Code); flags.Add(flag); symbStack.Push(new Tuple <Namespace, Symbol>(null, null)); success.Failed(); return(null); } symbStack.Push(new Tuple <Namespace, Symbol>(symb.Namespace, symb)); return(null); } case NodeKind.FuncTerm: { var ft = (FuncTerm)n; if (ft.Function is Id) { UserSymbol symb; var ftid = (Id)ft.Function; if (ValidateUse_UserFunc(ft, space, out symb, flags, true)) { symbStack.Push(new Tuple <Namespace, Symbol>(symb.Namespace, symb)); } else { symbStack.Push(new Tuple <Namespace, Symbol>(null, null)); success.Failed(); return(null); } return(ft.Args); } else { var flag = new Flag( SeverityKind.Error, ft, Constants.BadSyntax.ToString("Only data constructors can appear here."), Constants.BadSyntax.Code); flags.Add(flag); symbStack.Push(new Tuple <Namespace, Symbol>(null, null)); success.Failed(); return(null); } } default: throw new NotImplementedException(); } }
private static Term Parse(string t, int start, TermIndex index, out int end) { Contract.Requires(!string.IsNullOrEmpty(t) && start < t.Length); end = -1; bool wasAdded, result; var tstart = t[start]; while (char.IsWhiteSpace(tstart)) { ++start; tstart = t[start]; } if (tstart == '\"') { end = start; do { end = t.IndexOf('\"', end + 1); Contract.Assert(end >= 0); }while (t[end - 1] == '\\'); if (end == start + 1) { return(index.MkCnst(string.Empty, out wasAdded)); } else { return(index.MkCnst(t.Substring(start + 1, end - start - 1).Replace("\\\"", "\""), out wasAdded)); } } else if (char.IsDigit(tstart) || tstart == '+' || tstart == '-' || tstart == '.') { var end1 = t.IndexOf(',', start); var end2 = t.IndexOf(')', start); end = (end1 >= 0 && end2 >= 0) ? Math.Min(end1, end2) : Math.Max(end1, end2); Rational r; if (end < 0) { result = Rational.TryParseDecimal(t.Substring(start).Trim(), out r); Contract.Assert(result); end = t.Length - 1; } else { --end; result = Rational.TryParseDecimal(t.Substring(start, end - start + 1).Trim(), out r); Contract.Assert(result); } return(index.MkCnst(r, out wasAdded)); } else { Contract.Assert(char.IsLetter(tstart) || tstart == '_'); UserSymbol us, other; var end1 = t.IndexOf(',', start); var end2 = t.IndexOf(')', start); var end3 = t.IndexOf('(', start); end = (end1 >= 0 && end2 >= 0) ? Math.Min(end1, end2) : Math.Max(end1, end2); end = (end >= 0 && end3 >= 0) ? Math.Min(end, end3) : Math.Max(end, end3); if (end < 0) { us = index.SymbolTable.Resolve(t.Substring(start).Trim(), out other); Contract.Assert(us != null && other == null && us.Kind == SymbolKind.UserCnstSymb); end = t.Length - 1; return(index.MkApply(us, TermIndex.EmptyArgs, out wasAdded)); } else if (end == end1 || end == end2) { --end; us = index.SymbolTable.Resolve(t.Substring(start, end - start + 1).Trim(), out other); Contract.Assert(us != null && other == null && us.Kind == SymbolKind.UserCnstSymb); return(index.MkApply(us, TermIndex.EmptyArgs, out wasAdded)); } else { us = index.SymbolTable.Resolve(t.Substring(start, end - start).Trim(), out other); Contract.Assert(us != null && other == null && us.IsDataConstructor); var args = new Term[us.Arity]; for (int i = 0; i < us.Arity; ++i) { ++end; args[i] = Parse(t, end, index, out end); if (i < us.Arity - 1) { end = t.IndexOf(',', end + 1); } else { end = t.IndexOf(')', end + 1); } Contract.Assert(end >= 0); } return(index.MkApply(us, args, out wasAdded)); } } }