/* 1-dimension diffusion equation solver with constant boundaries. * Accuracy is first-order in time and second order in space. * To verify with CIVL, type: * civl verify diffusion.cvl */ $input int n; // number of discrete spatial points $assume(n >= 1); $input double dx; // distance between two consecutive points $assume(0 0); $input double u_init[n]; // initial temperatures // assume u:R^2->R has 4 continuous derivatives in [-1,1]x[0,100]: $abstract $differentiable(4, [-1,1][0,100]) $real u($real x, $real t); $input int step; // some arbitrary time step $assume(step >= 0); double v[n]; // values at this time step double v_new[n]; // values at next time step /* Updates the array v. The new values of v are computed from the old * values of v, and the constants dt, dx, and k. */ void update() { // compute the new values in v_new: /*@ loop invariant 1<=i && i<=n-1; @ loop invariant $forall (int j:1..i-1) @ v_new[j] == v[j] + dt*k*(v[j+1] - 2*v[j] + v[j-1])/(dx*dx); @ loop assigns i, v_new[1..n-2]; @*/ for (int i=1; i