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