public AlphabetDef(FastToken name, IEnumerable<KeyValuePair<FastToken, FastToken>> attrs, IEnumerable<KeyValuePair<FastToken, FastToken>> constructors) : base(DefKind.Alphabet) { this.sort = new FastSort(name, FastSortKind.Tree); this.symbols = new List<FuncSymbol>(); this.name = name; AddAttributes(attrs); AddConstructors(constructors); }
internal override void CheckFunctionExpr(Dictionary<string, FastSort> vars, HashSet<string> attrNames, HashSet<string> patternTrees, FastPgm pgm) { if (!vars.ContainsKey(token.text)) throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}'", token.text)); if (_sort == null) _sort = vars[token.text]; else if (!_sort.name.text.Equals(vars[token.text].name)) throw new FastParseException(token.Location, string.Format("unexpected sort '{1}' of '{0}' expecting '{2}'", token.text, _sort.name, vars[token.text].name)); }
internal override void CalcSort(Func<FastToken, FastSort> context, FastPgm program) { if (program.defsMap.ContainsKey(this._token.text)) _sort = program.GetConstantSort(this._token); else _sort = context(this._token); }
public Variable(FastToken token) { this._token = token; _sort = null; }
protected DefDef(DefDefKind ddkind, FastSort domain) : base(DefKind.Def) { this.ddkind = ddkind; this.domain = domain; }
internal override void CheckTransformation(HashSet<string> subs, AlphabetDef domAlph, AlphabetDef rangeAlph, FastPgm pgm) { foreach (var expr in args) expr.CheckTransformation(subs, domAlph, rangeAlph, pgm); var constsAndFuns = new Dictionary<string, FastSort>(); foreach (var def in pgm.defs) { if (def.kind == DefKind.Function) constsAndFuns.Add(((FunctionDef)def).name.text, ((FunctionDef)def).sort); if (def.kind == DefKind.Const) constsAndFuns.Add(((ConstDef)def).name.text, ((ConstDef)def).sort); } bool ok = CheckStandardOps(constsAndFuns); if (!ok) { string f = func.name.text; if (this is RecordExp) // --- record constrctor --- { if (rangeAlph.attrSort.fields.Count != args.Count) throw new FastParseException(func.name.Location, string.Format("unxecpected nr of attribute fields {0}, expecting {1}", args.Count, rangeAlph.attrSort.fields.Count)); for (int i = 0; i < args.Count; i++) { if (args[i].sort.name.text != rangeAlph.attrSort.fields[i].Value.name.text) throw new FastParseException(args[i].sort.name.Location, string.Format("invalid argument sort '{0}' of field '{1}', expecting sort '{2}'", args[i].sort.name.text, rangeAlph.attrSort.fields[i].Key.text, rangeAlph.attrSort.fields[i].Value.name.text)); } _sort = rangeAlph.attrSort; } else if (rangeAlph.symbols.Exists(_f => func.name.text == _f.name.text)) // --- tree constructor --- { if (!rangeAlph.IsValidSymbol(func.name, func.arity)) { throw new FastParseException(func.name.Location, string.Format("wrong number of arguments of constructor '{0}'", func.name)); } for (int i = 1; i < args.Count; i++) { if (args[i].sort.name.text != rangeAlph.id.text) throw new FastParseException(func.name.Location, string.Format("unexected argument of function '{0}'", func.name)); } _sort = rangeAlph.sort; } else { var def = pgm.FindDef(func.name); if (def.kind == DefKind.Trans) { if (args.Count != 1) throw new FastParseException(func.name.Location, string.Format("transduction '{0}' is unary", func.name)); var tdef = def as TransDef; if (tdef.domain.name.text != args[0].sort.name.text) throw new FastParseException(args[0].sort.name.Location, string.Format("transduction '{0}' has unexpected argument of sort '{1}', expecting sort '{2}'", func.name, args[0].sort.name.text, tdef.domain.name.text)); _sort = tdef.range; isTranDef = true; if (args[0].kind == FExpKind.App) throw new FastParseException(func.name.Location, string.Format("Transduction '{0}' cannot be nested inside another Transduction", func.name)); } else { throw new FastParseException(func.name.Location, string.Format("ID '{0}' is not a Transduction", func.name)); } } } }
public FunctionDef(FastToken name, List<KeyValuePair<FastToken, FastSort>> vars, FastSort outputSort, FExp expr) : base(DefKind.Function) { this.name = name; this.outputSort = outputSort; this.expr = expr; inputVariables = vars; var domain = new List<FastSort>(); foreach (var kv in vars) { if (varSortMap.ContainsKey(kv.Key.text)) throw new FastParseException(kv.Key.Location, string.Format("Duplicate parameter ID '{0}'", kv.Key.text)); FastSort s = kv.Value; varSortMap[kv.Key.text] = s; domain.Add(s); } this.sort = new FunctionSort(this.name, domain, this.outputSort); }
internal override void CheckSort(FastSort s) { if (!sort.Equals(s)) throw new FastParseException(token.Location, string.Format("wrong sort '{0}', expecting '{1}'", sort, s)); }
public AppExp(FastToken func, IEnumerable<FExp> args) { this.args = new List<FExp>(args); this.func = new FuncSymbol(func, this.args.Count); this._sort = null; this.isTranDef = false; this.isLangDef = false; }
internal abstract void CheckSort(FastSort s);
internal override void CalcSort(Func<FastToken, FastSort> context, FastPgm program) { string[] split = token.text.Split('.'); Def d; if (!program.defsMap.TryGetValue(split[0], out d)) throw new FastParseException(token.Location, string.Format("Undefined Enum '{0}'", split[0])); EnumDef ed = d as EnumDef; if (ed == null) throw new FastParseException(token.Location, string.Format("ID '{0}' is not an Enum", split[0])); if (!ed.elems.Contains(split[1])) throw new FastParseException(token.Location, string.Format("Enum '{0}' does not contain member '{1}'", split[0], split[1])); _sort = ed.sort; }
public EnumValue(FastToken token) : base(GetEnumValue(token), token) { this._sort = new FastSort(new FastToken(GetEnumName(token)), FastSortKind.Tree); }
public EnumDef(FastToken name) : base(DefKind.Enum) { this.name = name; this.sort = new FastSort(name, FastSortKind.Tree); }
internal override void CheckSubtreeGuard(Dictionary<string, FastSort> subs, AlphabetDef alph, FastPgm pgm) { if (!subs.ContainsKey(token.text)) throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}', expecting a subtree parameter", token.text)); else _sort = subs[token.text]; }
public FunctionSort(FastToken name, List<FastSort> domain, FastSort range) : base(name, FastSortKind.Function) { this.domain = domain; this.range = range; }
internal override void CheckTransformation(HashSet<string> subs, AlphabetDef domAlph, AlphabetDef rangeAlph, FastPgm pgm) { if (subs.Contains(this.token.text)) { _sort = domAlph.sort; } else { //Check if the current variable is a constant FastSort s; foreach (var def in pgm.defs) { if (def.kind == DefKind.Const && ((ConstDef)def).id.text == this.token.text) { s = ((ConstDef)def).sort; if (s == null || (_sort != null && s.name.text != _sort.name.text)) throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}'", token.text)); _sort = s; return; } } //Oterwise look for attr symbol if (Array.Exists(rangeAlph.symbols.ToArray(), x => x.name.text == this.token.text)) throw new FastParseException(this.token.Location, string.Format("the constructor '{0}' is not applied to a tuple", this.token.text)); if (domAlph == null) throw new FastParseException(this.token.Location, string.Format("the variable '{0}' is not defined", this.token.text)); s = domAlph.attrSort.getSort(this.token); if (s == null || (_sort != null && s.name.text != _sort.name.text)) throw new FastParseException(token.Location, string.Format("unexpected identifier '{0}'", token.text)); _sort = s; } }
internal override void CalcSort(Func<FastToken, FastSort> context, FastPgm program) { foreach (var arg in this.args) arg.CalcSort(context, program); if (func.alph != null) //func is a costructor { if (args.Count != func.arity) throw new FastParseException(func.name.Location, string.Format("Invalid use of constructor '{0}' of alphabet '{1}', wrong nr of arguments", func.name.text, func.alph.sort)); if (!args[0].sort.Equals(func.alph.attrSort)) throw new FastParseException(func.name.Location, string.Format("Invalid use of constructor '{0}' of alphabet '{1}', wrong attribute sort", func.name.text, func.alph.sort)); for (int i = 1; i < args.Count; i++) if (!args[i].sort.Equals(func.alph.sort)) throw new FastParseException(func.name.Location, string.Format("Invalid use of constructor '{0}' of alphabet '{1}', subtree nr {2} has unexpected sort '{3}'", func.name.text, func.alph.sort, i, args[i].sort)); _sort = func.alph.sort; return; } switch (func.name.Kind) { case (Tokens.EQ): case (Tokens.NE): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, "Both arguments must have the same sort"); _sort = FastSort.Bool; break; } case (Tokens.LE): case (Tokens.GE): case (Tokens.LT): case (Tokens.GT): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, "Both arguments must have the same sort"); if (!(args[0].sort.kind == FastSortKind.Char || args[0].sort.kind == FastSortKind.Int || args[0].sort.kind == FastSortKind.Real)) throw new FastParseException(func.name.Location, "Arguments have wrong sort, expecting numeric sort"); _sort = FastSort.Bool; break; } case (Tokens.AND): case (Tokens.OR): case (Tokens.IMPLIES): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, "Both arguments must have the same sort"); if (!(args[0].sort.kind == FastSortKind.Bool)) throw new FastParseException(func.name.Location, "Arguments must be Boolean"); _sort = FastSort.Bool; break; } case (Tokens.PLUS): case (Tokens.MINUS): case (Tokens.TIMES): case (Tokens.DIV): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, "Both arguments must have the same sort"); if (!(args[0].sort.kind == FastSortKind.Char || args[0].sort.kind == FastSortKind.Int || args[0].sort.kind == FastSortKind.Real)) throw new FastParseException(func.name.Location, "Wrong argument sorts"); _sort = args[0].sort; break; } case (Tokens.MOD): case (Tokens.SHL): case (Tokens.SHR): case (Tokens.BVAND): case (Tokens.BAR): case (Tokens.BVXOR): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, "Both arguments must have the same sort"); if (!(args[0].sort.kind == FastSortKind.Char || args[0].sort.kind == FastSortKind.Int)) throw new FastParseException(func.name.Location, "Wrong argument sorts"); _sort = args[0].sort; break; } case (Tokens.NOT): { if (this.args.Count != 1) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 1 argument"); if (!(args[0].sort.kind == FastSortKind.Bool)) throw new FastParseException(func.name.Location, string.Format("Wrong argument sort, expecting '{0}'",FastSort.Bool.name.text)); _sort = args[0].sort; break; } case (Tokens.BVNOT): { if (this.args.Count != 1) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 1 argument"); if (!(args[0].sort.kind == FastSortKind.Char || args[0].sort.kind == FastSortKind.Int)) throw new FastParseException(func.name.Location, "Wrong argument sort, expecting 'char' or 'int'"); _sort = args[0].sort; break; } case (Tokens.COMPLEMENT): { if (this.args.Count != 1) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 1 argument"); if (!(args[0].sort.kind == FastSortKind.Tree)) throw new FastParseException(func.name.Location, "Wrong argument sort, expecting a tree sort"); _sort = args[0].sort; break; } case (Tokens.INTERSECT): case (Tokens.UNION): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!(args[0].sort.kind == FastSortKind.Tree && args[1].sort.kind == FastSortKind.Tree)) throw new FastParseException(func.name.Location, "Wrong argument sort, expecting a tree sort"); if (!(args[0].sort.name.Equals(args[1].sort.name))) throw new FastParseException(func.name.Location, "Both arguments must have the same tree sort"); _sort = args[0].sort; break; } case (Tokens.EQ_LANG): { if (this.args.Count != 2) throw new FastParseException(func.name.Location, "Wrong nr of arguments, expecting 2 arguments"); if (!(args[0].sort.kind == FastSortKind.Tree && args[1].sort.kind == FastSortKind.Tree)) throw new FastParseException(func.name.Location, "Wrong argument sort, expecting a tree sort"); if (!(args[0].sort.name.Equals(args[1].sort.name))) throw new FastParseException(func.name.Location, "Both arguments must have the same tree sort"); _sort = FastSort.Bool; break; } case (Tokens.ITE): { if (this.args.Count != 3) throw new FastParseException(func.name.Location, "Wrong nr of arguments of If-Then-Else expression, expecting 3 arguments"); if (!(args[0].sort.kind == FastSortKind.Bool)) throw new FastParseException(func.name.Location, string.Format("If-Then-Else condition has wrong sort '{0}' expecting '{1}'", args[0].sort.name.text, FastSort.Bool.name.text)); if (!(args[1].sort.name.text.Equals(args[2].sort.name.text))) throw new FastParseException(func.name.Location, string.Format("If-Then-Else true and false cases have different sorts '{0}' and '{1}' but must have the same sort", args[1].sort.name.text, args[2].sort.name.text)); _sort = args[1].sort; break; } case (Tokens.ID): { var fdef = program.FindDef(func.name); var tdef = fdef as TransDef; if (tdef != null) { if (1 != args.Count) throw new FastParseException(func.name.Location, string.Format("Transduction '{0}' arity is 1 not {2}", func.name.text, 1, args.Count)); if (!args[0].sort.Equals(tdef.domain)) throw new FastParseException(func.name.Location, string.Format("Transduction '{0}' has domain '{0}' not '{1}'", func.name.text, tdef.domain, args[0].sort)); _sort = tdef.range; isTranDef = true; } else { var ldef = fdef as LangDef; if (ldef != null) { if (1 != args.Count) throw new FastParseException(func.name.Location, string.Format("Acceptor '{0}' arity is 1 not {2}", func.name.text, 1, args.Count)); if (!args[0].sort.Equals(ldef.domain)) throw new FastParseException(func.name.Location, string.Format("Acceptor '{0}' has domain '{0}' not '{1}'", func.name.text, ldef.domain, args[0].sort)); _sort = FastSort.Bool; isLangDef = true; } else { FunctionDef d = fdef as FunctionDef; if (d == null) throw new FastParseException(func.name.Location, string.Format("Unexpected ID '{0}' ", func.name.text)); if (d.inputVariables.Count != args.Count) throw new FastParseException(func.name.Location, string.Format("Function '{0}' arity is {1} not {2}", func.name.text, d.inputVariables.Count, args.Count)); for (int i = 0; i < args.Count; i++) { var expectedSort = d.inputVariables[i].Value; var actualSort = args[i].sort; if (expectedSort.kind != actualSort.kind || !expectedSort.name.text.Equals(actualSort.name.text)) throw new FastParseException(func.name.Location, string.Format("Function '{0}' parameter (#{4}) '{3}' has sort '{1}' not '{2}'", func.name.text, d.inputVariables[i].Key.text, expectedSort.name.text, actualSort.name.text, i + 1)); } _sort = d.outputSort; } } break; } case (Tokens.LBRACKET): //Record constructor { List<KeyValuePair<FastToken, FastSort>> sorts = new List<KeyValuePair<FastToken, FastSort>>(); for (int i = 0; i < args.Count; i++) sorts.Add(new KeyValuePair<FastToken, FastSort>(new FastToken("_" + (1+i).ToString()), args[i].sort)); _sort = new RecordSort(sorts); break; } default: throw new FastParseException(func.name.Location, string.Format("Unexpected function '{0}'", func.name.text)); } }
internal override void CheckSubtreeGuard(Dictionary<string, FastSort> subs, AlphabetDef alph, FastPgm pgm) { Predicate<FExp> IsNotBool = (x => { return x.sort == null || x.sort.kind != FastSortKind.Bool; }); foreach (var expr in args) expr.CheckSubtreeGuard(subs, alph, pgm); if (func.name.text != "and" && func.name.text != "or" && !pgm.defs.Exists(d => d.id.text == func.name.text && d.kind == DefKind.Lang && ((LangDef)d).domain.name.text == alph.sort.name.text)) throw new FastParseException(func.name.Location, string.Format("illeagal identifier '{0}'", func.name.text)); if ((func.name.text == "and" || func.name.text == "or") && args.Exists(IsNotBool)) throw new FastParseException(func.name.Location, string.Format("arguments of '{0}' must be Boolean", func.name.text)); if (pgm.defs.Exists(d => d.id.text == func.name.text && d.kind == DefKind.Lang && ((LangDef)d).domain.name.text == alph.sort.name.text)) isLangDef = true; _sort = FastSort.Bool; }
protected LangOrTransDef(DefKind kind, FastSort domain) : base(kind) { this.domain = domain; }
private bool CheckStandardOps(Dictionary<string, FastSort> varsConstsSorts) { Predicate<FExp> IsNotBool = (x => { return x.sort == null || x.sort.kind != FastSortKind.Bool; }); if (func.IsBuiltinBooleanConnective) { if (args.Exists(IsNotBool)) throw new FastParseException(func.name.Location, string.Format("all arguments of '{0}' must be Boolean", func.name)); if (func.IsBuiltinUnary && args.Count != 1) throw new FastParseException(func.name.Location, string.Format("'{0}' is unary, not arity {1}", func.name, args.Count)); if (!func.IsBuiltinAssociative && !func.IsBuiltinUnary && args.Count != 2) throw new FastParseException(func.name.Location, string.Format("'{0}' is binary, not arity {1}", func.name, args.Count)); _sort = FastSort.Bool; } else if (func.IsBuiltinITE) { if (args.Count != 3) throw new FastParseException(func.name.Location, string.Format("'{0}' takes 3 arguments, wrong nr of arguments {1}", func.name, args.Count)); if (args[0].sort.kind != FastSortKind.Bool) throw new FastParseException(func.name.Location, string.Format("first argument of '{0}' must be Boolean not '{1}'", func.name, args[0].sort.name)); if (args[1].sort.name.text != args[2].sort.name.text) throw new FastParseException(func.name.Location, string.Format("arguments 2 and 3 of '{0}' must have the same type, not {1},{2}", func.name, args[1].sort.name.text, args[2].sort.name.text)); _sort = args[1].sort; } else if (func.IsBuiltinEq || func.IsBuiltinArithmeticRelation) { if (args.Count != 2) throw new FastParseException(func.name.Location, string.Format("'{0}' is binary, wrong nr of arguments {1}", func.name, args.Count)); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, string.Format("both arguments of '{0}' must have the same type, not {1},{2}", func.name, args[0].sort.name.text, args[1].sort.name.text)); _sort = FastSort.Bool; } else if (func.IsBuiltinArithmeticFunction) { if (args.Count != 2) throw new FastParseException(func.name.Location, string.Format("'{0}' is binary, wrong nr of arguments {1}", func.name, args.Count)); if (!args[0].sort.name.text.Equals(args[1].sort.name.text)) throw new FastParseException(func.name.Location, string.Format("both arguments of '{0}' must have the same sort, not {1},{2}", func.name, args[0].sort.name.text, args[1].sort.name.text)); if (!args[0].sort.name.text.Equals(FastSort.Real.name.text) && !args[0].sort.name.text.Equals(FastSort.Int.name.text) && !args[0].sort.name.text.Equals(FastSort.Char.name.text)) throw new FastParseException(func.name.Location, string.Format("arguments of '{0}' must be either 'int' or 'real' or 'char', not '{1}',", func.name, args[0].sort.name.text)); _sort = args[0].sort; } else if (func.IsBuiltinIntegerFunction) { if (args.Count != 2) throw new FastParseException(func.name.Location, string.Format("'{0}' is binary, wrong nr of arguments {1}", func.name, args.Count)); if (!args[0].sort.name.text.Equals("int")) throw new FastParseException(func.name.Location, string.Format("both arguments of '{0}' must have the same sort, not int,{2}", func.name, args[0].sort.name.text, args[1].sort.name.text)); _sort = args[0].sort; } else if (func.IsBuiltinStringFunction) { if (args.Count != 2) throw new FastParseException(func.name.Location, string.Format("'{0}' is binary, wrong nr of arguments {1}", func.name, args.Count)); if (!args[0].sort.name.text.Equals("string") || !args[1].sort.name.text.Equals("string")) throw new FastParseException(func.name.Location, string.Format("both arguments of '{0}' must have the same sort, not string,{2}", func.name, args[0].sort.name.text, args[1].sort.name.text)); _sort = args[0].sort; } else if (varsConstsSorts.ContainsKey(func.name.text)) { FunctionSort fsort = (FunctionSort)varsConstsSorts[func.name.text]; if (args.Count != fsort.domain.Count) throw new FastParseException(func.name.Location, string.Format("'{0}' expects '{1}' arguments, but it is applied to {2}", func.name, fsort.domain.Count, args.Count)); int i = 0; foreach (var v in args) { if (!v.sort.name.text.Equals(fsort.domain[i].name.text)) throw new FastParseException(func.name.Location, string.Format("argument '{0}' of '{1}' must have sort '{2}', not '{3}'", i, func.name, fsort.domain[i], v.sort)); i++; } _sort = fsort.range; } else { return false; } return true; }
public TransDefDef(FastToken name, FastToken alphabet1, FastToken alphabet2, BuiltinTransExp expr) : base(DefDefKind.Trans, new FastSort(alphabet1, FastSortKind.Tree)) { this.func = new FuncSymbol(name, 1); range = new FastSort(alphabet2, FastSortKind.Tree); this.expr = expr; }
private Sort getSort(FastSort fs, FastTransducerInstance fti) { switch (fs.kind) { case (FastSortKind.Real): return z3p.RealSort; case (FastSortKind.Bool): return z3p.BoolSort; case (FastSortKind.Int): return z3p.IntSort; case (FastSortKind.Char): return z3p.CharSort; case (FastSortKind.String): return z3p.MkListSort(z3p.CharSort); case (FastSortKind.Tree): { foreach (var enumSort in fti.enums) { if (enumSort.name == fs.name.text) { return enumSort.sort; } } break; } } return null; }
public ConstDef(FastToken name, FastToken sort, FExp expr) : base(DefKind.Const) { this.name = name; this.sort = FastSort.GetSort(sort); this.expr = expr; }