/// <summary> /// Get corresponding Z3 formula of a MSF row. /// </summary> /// <param name="rid">The MSF row id</param> private ArithExpr MkGoalRow(int rid) { // Start with the 0 term List <ArithExpr> row = new List <ArithExpr>(); // Now, add all the entries of this row foreach (LinearEntry entry in GetRowEntries(rid)) { // Get the variable and constant in the row ArithExpr e = _solver.GetVariable(entry.Index); if (!entry.Value.IsOne) { e = _solver.Context.MkMul(_solver.GetNumeral(entry.Value, e.Sort), e); } row.Add(e); } switch (row.Count) { case 0: return(_solver.GetNumeral(new Rational())); case 1: return(row[0]); default: return(_solver.Context.MkAdd(row.ToArray())); } }
private BoolExpr MkBool(int rid) { var context = _solver.Context; if (IsConstant(rid)) { Rational lower, upper; GetBounds(rid, out lower, out upper); Debug.Assert(lower == upper); if (lower.IsZero) { return(context.MkFalse()); } return(context.MkTrue()); } if (IsOperation(rid)) { BoolExpr[] children; ArithExpr[] operands; TermModelOperation op = GetOperation(rid); switch (op) { case TermModelOperation.And: Debug.Assert(GetOperandCount(rid) >= 2, "Conjunction requires at least two operands."); children = (GetOperands(rid)).Select(x => MkBool(x)).ToArray(); return(context.MkAnd(children)); case TermModelOperation.Or: Debug.Assert(GetOperandCount(rid) >= 2, "Disjunction requires at least two operands."); children = (GetOperands(rid)).Select(x => MkBool(x)).ToArray(); return(context.MkOr(children)); case TermModelOperation.Not: Debug.Assert(GetOperandCount(rid) == 1, "Negation is unary."); return(context.MkNot(MkBool(GetOperand(rid, 0)))); case TermModelOperation.If: Debug.Assert(GetOperandCount(rid) == 3, "If is ternary."); BoolExpr b = MkBool(GetOperand(rid, 0)); Expr x1 = MkBool(GetOperand(rid, 1)); Expr x2 = MkBool(GetOperand(rid, 2)); return((BoolExpr)context.MkITE(b, x1, x2)); case TermModelOperation.Unequal: Debug.Assert(GetOperandCount(rid) >= 2, "Distinct should have at least two operands."); return(context.MkDistinct((GetOperands(rid)).Select(x => MkTerm(x)).ToArray())); case TermModelOperation.Greater: case TermModelOperation.Less: case TermModelOperation.GreaterEqual: case TermModelOperation.LessEqual: case TermModelOperation.Equal: Debug.Assert(GetOperandCount(rid) >= 2, "Comparison should have at least two operands."); operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray(); return(ReduceComparison(GetOperation(rid), operands)); case TermModelOperation.Identity: Debug.Assert(GetOperandCount(rid) == 1, "Identity takes exactly one operand."); return(MkBool(GetOperand(rid, 0))); default: return(context.MkEq(MkTerm(rid), _solver.GetNumeral(Rational.One))); } } return(context.MkEq(MkTerm(rid), _solver.GetNumeral(Rational.One))); }