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()); } }
private MSOFormula <BDD> ConvertPredApp(MonaPredApp predApp, MapStack <string, MonaParam> locals) { var predDef = predMap[predApp.symbol.text]; var predDecl = (MonaPredDecl)globals[predApp.symbol.text]; int k = predDecl.parameters.Count; if (k != predApp.NrOfSubexprs) { throw new ArgumentException("invalid call of " + predDecl.name); } if (k == 0) { return(predDef); } var newVars = new Variable[k]; Dictionary <string, Variable> substitution = new Dictionary <string, Variable>(); var argPreds = new MSOFormula <BDD> [k]; var argVars = new Variable[k]; for (int i = 0; i < k; i++) { if (predDecl.parameters[i].kind != MonaParamKind.var1 && predDecl.parameters[i].kind != MonaParamKind.var2) { throw new NotImplementedException("parameter kind " + predDecl.parameters[i].kind.ToString()); } MSOFormula <BDD> argPreds_i; Variable argVars_i; if (predDecl.parameters[i].kind == MonaParamKind.var1) { argVars_i = ConvertTerm1(predApp[i], locals, out argPreds_i); if (argPreds_i == null) { var tmp1 = MkNewVar1(); argPreds_i = new MSOEq <BDD>(tmp1, argVars_i); argVars_i = tmp1; } } else { argVars_i = ConvertTerm2(predApp[i], locals, out argPreds_i); if (argPreds_i == null) { var tmp2 = MkNewVar2(); argPreds_i = new MSOEq <BDD>(tmp2, argVars_i); argVars_i = tmp2; } } argPreds[i] = argPreds_i; argVars[i] = argVars_i; substitution[predDecl.parameters[i].Token.text] = argVars_i; } MSOFormula <BDD> psi = predDef.SubstituteVariables(substitution); for (int i = k - 1; i >= 0; i--) { psi = new MSOExists <BDD>(argVars[i], argPreds[i] & psi); } return(psi); }