/// <summary> /// If t is a variable name then returns t as a f-o variable and sets psi=null. /// Else returns a fresh f-o variable x and outputs psi(x) s.t. psi(x) iff x=t. /// </summary> Variable ConvertTerm1(MonaExpr t, MapStack<string, MonaParam> locals, out MSOFormula<BDD> psi) { switch (t.symbol.Kind) { case Tokens.NAME: { MonaParam p; if (locals.TryGetValue(t.symbol.text, out p)) { if (p.kind == MonaParamKind.var1) { psi = null; return new Variable(t.symbol.text, true); } else throw new NotImplementedException(t.ToString()); } else { MonaDecl d; if (globals.TryGetValue(t.symbol.text, out d)) { if (d.kind == MonaDeclKind.constant) { int n = ((MonaConstDecl)d).def.ToInt(globals); Variable x = MkNewVar1(); var pred = new MSOeqN<BDD>(x, n); psi = pred; return x; } else if (d.kind == MonaDeclKind.var1) { psi = null; return new Variable(t.symbol.text, true); } else throw new NotImplementedException(t.ToString()); } else throw new NotImplementedException(t.ToString()); } } case Tokens.PLUS: { Variable y = MkNewVar1(); if (t[0].symbol.Kind == Tokens.NAME) { int n = t[1].ToInt(globals); Variable x = new Variable(t[0].symbol.text, true); psi = new MSOSuccN<BDD>(x, y, n); // y = x + n } else { int n = t.ToInt(globals); psi = new MSOeqN<BDD>(y, n); // y = n } return y; } case Tokens.MIN: { MSOFormula<BDD> X_psi; Variable X = ConvertTerm2(t[0], locals, out X_psi); Variable x = MkNewVar1(); MSOFormula<BDD> min = new MSOMin<BDD>(x, X); if (X_psi != null) min = new MSOExists<BDD>(X, new MSOAnd<BDD>(X_psi, min)); psi = min; return x; } case Tokens.MAX: { MSOFormula<BDD> X_psi; Variable X = ConvertTerm2(t[0], locals, out X_psi); Variable x = MkNewVar1(); MSOFormula<BDD> max = new MSOMax<BDD>(x, X); if (X_psi != null) max = new MSOExists<BDD>(X, new MSOAnd<BDD>(X_psi, max)); psi = max; return x; } case Tokens.NUMBER: { Variable x = MkNewVar1(); int num = t.symbol.ToInt(); psi = new MSOeqN<BDD>(x,num); return x; } default: throw new NotImplementedException(t.ToString()); } }
/// <summary> /// If t is a variable name then returns t as a s-o variable and sets psi=null. /// Else returns a fresh s-o variable X and outputs psi(X) s.t. psi(X) iff X=t. /// </summary> private Variable ConvertTerm2(MonaExpr t, MapStack<string, MonaParam> locals, out MSOFormula<BDD> psi) { switch (t.symbol.Kind) { case Tokens.NAME: { psi = null; return new Variable(t.symbol.text, false); } case Tokens.INTER: return ConvertInter(t[0], t[1], locals, out psi); case Tokens.UNION: return ConvertUnion(t[0], t[1], locals, out psi); case Tokens.SETMINUS: return ConvertSetminus(t[0], t[1], locals, out psi); case Tokens.EMPTY: return ConvertEmptyset(out psi); case Tokens.LBRACE: return ConvertSet(t, locals, out psi); default: throw new NotImplementedException(t.ToString()); } }
private MSOFormula<BDD> ConvertFormula(MonaExpr expr, MapStack<string,MonaParam> locals) { switch (expr.symbol.Kind) { case Tokens.TRUE: return new MSOTrue<BDD>(); case Tokens.FALSE: return new MSOFalse<BDD>(); case Tokens.NOT: return new MSONot<BDD>(ConvertFormula(expr[0], locals)); case Tokens.AND: return new MSOAnd<BDD>(ConvertFormula(expr[0], locals), ConvertFormula(expr[1], locals)); case Tokens.OR: return new MSOOr<BDD>(ConvertFormula(expr[0], locals), ConvertFormula(expr[1], locals)); case Tokens.IMPLIES: return new MSOImplies<BDD>(ConvertFormula(expr[0], locals), ConvertFormula(expr[1], locals)); case Tokens.EQUIV: return new MSOEquiv<BDD>(ConvertFormula(expr[0], locals), ConvertFormula(expr[1], locals)); case Tokens.EQ: return ConvertEq(expr[0], expr[1], locals); case Tokens.NE: return new MSONot<BDD>(ConvertEq(expr[0], expr[1], locals)); case Tokens.LT: return ConvertLt(expr[0], expr[1], locals); case Tokens.GT: return ConvertLt(expr[1], expr[0], locals); case Tokens.LE: return ConvertLe(expr[0], expr[1], locals); case Tokens.GE: return ConvertLe(expr[1], expr[0], locals); case Tokens.SUBSET: return ConvertSubset(expr[1], expr[0], locals); case Tokens.IN: return ConvertIn(expr[0], expr[1], locals); case Tokens.NOTIN: return new MSONot<BDD>(ConvertIn(expr[0], expr[1], locals)); case Tokens.EMPTY: return ConvertIsEmpty(expr[0], locals); case Tokens.EX1: case Tokens.EX2: { MonaQFormula phi = (MonaQFormula)expr; if ((phi.universes != null && phi.universes.Count > 1) || phi.vars.Exists(vw => vw.where != null)) throw new NotImplementedException(expr.ToString()); MSOFormula<BDD> psi = ConvertFormula(phi.formula, locals.Push(phi.varmap)); foreach (var vw in phi.vars) psi = new MSOExists<BDD>(new Variable(vw.name, phi.varmap[vw.name].type == MonaExprType.INT), psi); return psi; } case Tokens.ALL1: case Tokens.ALL2: { MonaQFormula phi = (MonaQFormula)expr; if ((phi.universes != null && phi.universes.Count > 1) || phi.vars.Exists(vw => vw.where != null)) throw new NotImplementedException(expr.ToString()); MSOFormula<BDD> psi = ConvertFormula(phi.formula, locals.Push(phi.varmap)); foreach (var vw in phi.vars) psi = new MSOForall<BDD>(new Variable(vw.name, phi.varmap[vw.name].type == MonaExprType.INT), psi); return psi; } case Tokens.NAME: { var name = expr as MonaName; if (name != null) { //must be a nullary predicate application (var0 is not supported) var tmpPredApp = new MonaPredApp(name.symbol, Cons<MonaExpr>.Empty); return ConvertPredApp(tmpPredApp, locals); } var predApp = expr as MonaPredApp; if (predApp != null) { return ConvertPredApp(predApp, locals); } throw new NotImplementedException(expr.ToString()); } default: throw new NotImplementedException(expr.ToString()); } }