/// <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 { 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); } default: throw new NotImplementedException(t.ToString()); } }
/// <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()); } }