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; }
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()); } }