/// <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 ArithExpr MkTerm(int rid) { var context = _solver.Context; if (IsConstant(rid)) { Rational lower, upper; GetBounds(rid, out lower, out upper); Debug.Assert(lower == upper); return(_solver.GetNumeral(lower)); } else if (IsOperation(rid)) { ArithExpr[] operands; TermModelOperation op = GetOperation(rid); switch (op) { case TermModelOperation.And: case TermModelOperation.Or: case TermModelOperation.Not: case TermModelOperation.Unequal: case TermModelOperation.Greater: case TermModelOperation.Less: case TermModelOperation.GreaterEqual: case TermModelOperation.LessEqual: case TermModelOperation.Equal: return(MkBoolToArith(MkBool(rid))); case TermModelOperation.If: Debug.Assert(GetOperandCount(rid) == 3, "If is ternary."); BoolExpr b = MkBool(GetOperand(rid, 0)); Expr x1 = MkTerm(GetOperand(rid, 1)); Expr x2 = MkTerm(GetOperand(rid, 2)); return((ArithExpr)context.MkITE(b, x1, x2)); case TermModelOperation.Plus: Debug.Assert(GetOperandCount(rid) >= 2, "Plus takes at least two operands."); operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray(); return(context.MkAdd(operands)); case TermModelOperation.Minus: Debug.Assert(GetOperandCount(rid) == 1, "Minus takes exactly one operand."); return(context.MkUnaryMinus(MkTerm(GetOperand(rid, 0)))); case TermModelOperation.Times: Debug.Assert(GetOperandCount(rid) >= 2, "Times requires at least two operands."); operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray(); return(context.MkMul(operands)); case TermModelOperation.Identity: Debug.Assert(GetOperandCount(rid) == 1, "Identity takes exactly one operand."); return(MkTerm(GetOperand(rid, 0))); case TermModelOperation.Abs: Debug.Assert(GetOperandCount(rid) == 1, "Abs takes exactly one operand."); ArithExpr e = MkTerm(GetOperand(rid, 0)); ArithExpr minusE = context.MkUnaryMinus(e); ArithExpr zero = _solver.GetNumeral(Rational.Zero); return((ArithExpr)context.MkITE(context.MkGe(e, zero), e, minusE)); default: Console.Error.WriteLine("{0} operation isn't supported.", op); throw new NotSupportedException(); } } else { return(_solver.GetVariable(rid)); } }