ode_solver::ODE_result ode_solver::simple_ODE_backward(IVector & X_0, IVector const & X_t, interval const & T, IVector const & inv, vector<IFunction> & funcs) { // X_0 = X_0 \cup (X_t - + (d/dt Inv) * T) for (int i = 0; i < X_0.dimension(); i++) { interval & x_0 = X_0[i]; interval const & x_t = X_t[i]; IFunction & dxdt = funcs[i]; for (Enode * par : m_pars) { double lb = get_lb(par); double ub = get_ub(par); string name = par->getCar()->getName(); dxdt.setParameter(name, interval(lb, ub)); } try { interval const new_x_0 = x_t - dxdt(inv) * T; if (!intersection(new_x_0, x_0, x_0)) { DREAL_LOG_INFO << "Simple_ODE: no intersection for X_0"; return ODE_result::UNSAT; } } catch (exception& e) { DREAL_LOG_INFO << "Exception in Simple_ODE: " << e.what(); } } // update IVector_to_varlist(X_0, m_0_vars); return ODE_result::SAT; }
void ode_solver::IVector_to_varlist(IVector const & v, vector<Enode*> & vars) { for (auto i = 0; i < v.dimension(); i++) { double lb = get_lb(vars[i]); double ub = get_ub(vars[i]); if (lb < v[i].leftBound()) set_lb(vars[i], v[i].leftBound()); if (ub > v[i].rightBound()) set_ub(vars[i], v[i].rightBound()); } }
void printSample(const double &t, const IVector &x) { cout.setf(ios::scientific); cout.setf(ios::showpos); cout.precision(10); cout << t << " "; for(int i=0; i<x.dimension(); ++i) cout << x[i].leftBound() << " " << x[i].rightBound() << " "; cout << endl; }
// Take an intersection of v and inv. // If there is no intersection, return false. bool ode_solver::check_invariant(IVector & v, IVector const & inv) { if (!intersection(v, inv, v)) { DREAL_LOG_INFO << "invariant violated!"; for (auto i = 0; i < v.dimension(); i++) { if (v[i].leftBound() < inv[i].leftBound() || v[i].rightBound() > inv[i].rightBound()) { DREAL_LOG_INFO << "inv[" << i << "] = " << inv[i]; DREAL_LOG_INFO << " v[" << i << "] = " << v[i]; } } return false; } return true; }