By adding conditions to the solver, I want to check with "solver.check()", whether there exists a solution or not. Therefore, I created a simple example to find a solution for t1. I know that there is a solution for t1, namely t1 = 0. Nevertheless, the solver has not the status "SATISFIABLE".
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();
}
I discovered some unexpected behaviour. If I try to check conditions before I do "solver.check()", for example
System.out.println("solver c2: " + solver.check(c2));
System.out.println("solver c3: " + solver.check(c3));
it outputs:
solver c2: UNKNOWN
solver c3: UNKNOWN
and suddenly, the solver's status is "SATISFIABLE". But if I only check one condition beforehand, the status is still "UNSATISFIABLE".
Other than that, if I change from
t1 = ctx.mkRealConst("t1");
to
t1 = ctx.mkReal(0);
the solver also finds a solution and the solver status is "SATISFIABLE".
Why does the solver have this behaviour and how could I possibly make the solver find a solution? Are there any alternative ways that I could try?