Добавляя условия в решатель, я хочу проверить с помощью solver.check (), существует ли решение или нет. Поэтому я создал простой пример, чтобы найти решение для t1. Я знаю, что есть решение для t1, а именно t1 = 0. Тем не менее, решатель не имеет статуса «УДОВЛЕТВОРЕННЫЙ».
public static void main(String[] args) {
int h_max = 7;
HashMap<String, String> cfg = new HashMap<String, String>();
cfg.put("model", "true");
Context ctx = new Context(cfg);
FPSort s = ctx.mkFPSort(5, 20);
Solver solver = ctx.mkSolver();
Model model = null;
// Initialize constants
RealExpr half = ctx.mkFPToReal(ctx.mkFP(0.5, s));
RealExpr g = ctx.mkFPToReal(ctx.mkFP(9.81, s));
RealExpr hmax = ctx.mkInt2Real(ctx.mkInt(h_max));
RealExpr v = ctx.mkFPToReal(ctx.mkFP((Math.sqrt(2*h_max*9.81)), s));
// Create query Information
RealExpr q2 = ctx.mkReal(1);
RealExpr q2Min = (RealExpr) ctx.mkSub(q2, half);
RealExpr q2Max = (RealExpr) ctx.mkAdd(q2, half);
// Initialize constraints
RealExpr tmax = ctx.mkFPToReal(ctx.mkFP((Math.sqrt(2*h_max/9.81)), s));
RealExpr t0 = ctx.mkReal(0);
// Initialize sampling interval
RealExpr ts = ctx.mkFPToReal(ctx.mkFP(Math.sqrt(2*h_max/9.81)+0.1, s));
// Variable t1
RealExpr t1 = ctx.mkRealConst("t1");
// 0 <= t1 <= tmax
BoolExpr c1 = ctx.mkGe(t1, t0);
BoolExpr c2 = ctx.mkLe(t1,tmax);
// Elapsed Times
RealExpr tE = (RealExpr) ctx.mkAdd(ts, t1);
// Add conditions to solver
solver.add(c1);
solver.add(c2);
// Calculating tE2 % tmax, since tE2 > tmax
RealExpr quotient = (RealExpr) ctx.mkDiv(tE, tmax);
IntExpr factor = ctx.mkReal2Int(quotient);
RealExpr t2 = (RealExpr) ctx.mkSub(tE, ctx.mkMul(factor, tmax));
// Calculating the observation h2 with t2.
RealExpr h2 = (RealExpr) ctx.mkSub(ctx.mkMul(v,t2), ctx.mkMul(half, t2, t2, g));
// Defining constraint q2Min <= h2 < q2Max
BoolExpr c3 = ctx.mkAnd(ctx.mkGe(h2, q2Min),ctx.mkLt(h2, q2Max));
solver.add(c3);
//System.out.println("solver c1: " + solver.check(c1));
//System.out.println("solver c2: " + solver.check(c2));
//System.out.println("solver c3: " + solver.check(c3));
if (solver.check() == Status.SATISFIABLE) {
model = solver.getModel();
System.out.println("System is Satisfiable");
}
else {
System.out.println("Unsatisfiable");
}
ctx.close();
}
Я обнаружил неожиданное поведение. Если я пытаюсь проверить условия перед тем, как выполнить «solver.check ()», например,
System.out.println("solver c2: " + solver.check(c2));
System.out.println("solver c3: " + solver.check(c3));
, он выдаст:
solver c2: UNKNOWN
solver c3: UNKNOWN
, и внезапно состояние решателя будет «УДОВЛЕТВОРЕНО» , Но если я предварительно проверю только одно условие, оно останется «НЕУДАЧНЫМ».
Кроме этого, если я изменю значение с
t1 = ctx.mkRealConst("t1");
на
t1 = ctx.mkReal(0);
решатель также находит решение, и статус решателя «УДОВЛЕТВОРЕН».
Почему решатель имеет такое поведение и как я могу заставить решатель найти решение? Есть ли альтернативные способы, которые я мог бы попробовать?