tactic with_options(options const & o, tactic const & t) { return tactic([=](environment const & env, io_state const & ios, proof_state const & s) -> proof_state_seq { options c = ios.get_options(); io_state new_ios(ios, join(c, o)); return t(env, new_ios, s); }); }
tactic change_goal_tactic(elaborate_fn const & elab, expr const & e) { return tactic([=](environment const & env, io_state const & ios, proof_state const & s) { proof_state new_s = s; goals const & gs = new_s.get_goals(); if (!gs) { throw_no_goal_if_enabled(s); return proof_state_seq(); } expr t = head(gs).get_type(); bool report_unassigned = true; if (auto new_e = elaborate_with_respect_to(env, ios, elab, new_s, e, none_expr(), report_unassigned)) { goals const & gs = new_s.get_goals(); goal const & g = head(gs); substitution subst = new_s.get_subst(); auto tc = mk_type_checker(env); constraint_seq cs; if (tc->is_def_eq(t, *new_e, justification(), cs)) { if (cs) { unifier_config cfg(ios.get_options()); buffer<constraint> cs_buf; cs.linearize(cs_buf); to_buffer(new_s.get_postponed(), cs_buf); unify_result_seq rseq = unify(env, cs_buf.size(), cs_buf.data(), subst, cfg); return map2<proof_state>(rseq, [=](pair<substitution, constraints> const & p) -> proof_state { substitution const & subst = p.first; constraints const & postponed = p.second; substitution new_subst = subst; expr final_e = new_subst.instantiate_all(*new_e); expr M = g.mk_meta(mk_fresh_name(), final_e); goal new_g(M, final_e); assign(new_subst, g, M); return proof_state(new_s, cons(new_g, tail(gs)), new_subst, postponed); }); } expr M = g.mk_meta(mk_fresh_name(), *new_e); goal new_g(M, *new_e); assign(subst, g, M); return proof_state_seq(proof_state(new_s, cons(new_g, tail(gs)), subst)); } else { throw_tactic_exception_if_enabled(new_s, [=](formatter const & fmt) { format r = format("invalid 'change' tactic, the given type"); r += pp_indent_expr(fmt, *new_e); r += compose(line(), format("does not match the goal type")); r += pp_indent_expr(fmt, t); return r; }); return proof_state_seq(); } } return proof_state_seq(); }); }
tactic apply_tactic_core(elaborate_fn const & elab, expr const & e, add_meta_kind add_meta, subgoals_action_kind k) { return tactic([=](environment const & env, io_state const & ios, proof_state const & s) { goals const & gs = s.get_goals(); if (empty(gs)) { throw_no_goal_if_enabled(s); return proof_state_seq(); } goal const & g = head(gs); name_generator ngen = s.get_ngen(); expr new_e; substitution new_subst; constraints cs_; auto ecs = elab(g, ngen.mk_child(), e, none_expr(), s.get_subst(), false); std::tie(new_e, new_subst, cs_) = ecs; buffer<constraint> cs; to_buffer(cs_, cs); to_buffer(s.get_postponed(), cs); proof_state new_s(s, new_subst, ngen, constraints()); return apply_tactic_core(env, ios, new_s, new_e, cs, add_meta, k); }); }
void Sem::ContainSim::run( void ) { // Status names const char *StatusName[] = { "Unreported", "Reported", "Attacked", "Contained", "Overrun", "Exhausted", "Sim Overflow", "Size Limit Exceeded", "Time Limit Exceeded" }; const char *TacticName[] = { "Head", "Rear" }; double at, elapsed, factor; // Log levels : 0=none, 1=major events, 2=stepwise int logLevel = 0; // Repeat simulation until [m_minSteps::m_maxSteps] steps achieved, // or if retry==TRUE, until sufficient resources are able to contain fire double area, dx, dy, suma, sumb, sumDT; double totalArea; // double maxArea = 500.0; bool rerun = true; bool MAXSTEPS_EXCEEDED=false; m_pass = 0; while ( rerun ) { m_left->containLog( ( logLevel >= 1 ), "\nPass %d Begins:\n", m_pass ); // Simulate until forces overrun, fire contained, or maxSteps reached int iLeft = 0; // First index of left half values m_u[iLeft] = m_left->m_u; m_h[iLeft] = m_left->m_h; m_x[iLeft] = m_left->m_x; m_y[iLeft] = m_left->m_y; //int iRight = m_maxSteps; // First index of right half values elapsed = m_left->m_attackTime; m_left->containLog( ( logLevel == 2 ), "%d: u=%12.10f, h=%12.10f, t=%f\n", iLeft, m_left->m_u, m_left->m_h, elapsed ); // This is the main simulation loop! m_finalSweep = m_finalLine = m_finalPerim = 0.0; totalArea=0.0; suma = sumb = sumDT = 0.0; while ( m_left->m_status != Sem::Contain::Overrun && m_left->m_status != Sem::Contain::Contained && m_left->m_step < m_maxSteps && totalArea < m_maxFireSize && m_left->m_currentTime < m_maxFireTime // MAF && m_left->m_currentTime < m_left->m_exhausted) // MAF { // Store angle and head position in the proper array element m_left->step(); // Store the new angle, head position, and coordinate values iLeft++; m_u[iLeft] = m_left->m_u; m_h[iLeft] = m_left->m_h; m_x[iLeft] = m_left->m_x; m_y[iLeft] = m_left->m_y; elapsed = m_left->m_currentTime;//m_time; // MAF // m_left->containLog( (logLevel == 2 ), // "%d: u=%12.10f, h=%12.10f, t=%12.10f\n", // iLeft, m_u[iLeft], m_h[iLeft], elapsed ); // Update the extent m_xMin = ( m_x[iLeft] < m_xMin ) ? m_x[iLeft] : m_xMin; m_xMax = ( m_x[iLeft] > m_xMax ) ? m_x[iLeft] : m_xMax; m_yMax = ( m_y[iLeft] > m_yMax ) ? m_y[iLeft] : m_yMax; // Line constructed and area swept during this simulation step dy = fabs( m_y[iLeft-1] - m_y[iLeft] ); dx = fabs( m_x[iLeft-1] - m_x[iLeft] ); m_p[iLeft-1] = sqrt( ( dy * dy ) + ( dx * dx ) ); // Accumulate line constructed for BOTH flanks (ch) m_finalLine += 2.0 * m_p[iLeft-1]; // Accumulate area of containment (apply trapazoidal rule) suma += ( m_y[iLeft-1] * m_x[iLeft] ); sumb += ( m_x[iLeft-1] * m_y[iLeft] ); area = ( suma > sumb ) ? ( 0.5 * ( suma - sumb ) ) : ( 0.5 * ( sumb - suma ) ); // Calculate the area using the trapizoidal rule sumDT = 0; for ( int i = 1; i <= iLeft; i++ ) sumDT = (m_x[i] - m_x[i-1]) * (m_y[i] + m_y[i-1]) + sumDT; if ( sumDT < 0 ) sumDT = -1.0 * sumDT; area = sumDT * .5; // Add in the area for the uncontained portion of the fire DT 1/2013 double UCarea = UncontainedArea( m_h[iLeft], fireLwRatioAtReport(), m_x[iLeft], m_y[iLeft], tactic() ); area = area + UCarea; // Accumulate area for BOTH flanks (ac) m_a[iLeft-1] = 0.2 * area; totalArea = m_a[iLeft-1]; m_left->containLog( (logLevel == 2 ), "%d: u=%12.10f, h=%12.10f, x=%12.10f, y=%12.10f, t=%12.10f, UCA=%12.10f, CA=%12.1f, TA=%12.10f, TP=%12.10f\n", iLeft, m_u[iLeft], m_h[iLeft], m_x[iLeft], m_y[iLeft], elapsed, UCarea*0.2, (area-UCarea)*0.2, totalArea, m_finalLine ); } // BEHAVEPLUS FIX: Adjust the last x-coordinate for contained head attacks if ( m_left->m_status == Sem::Contain::Contained && m_left->m_tactic == Sem::Contain::HeadAttack ) { m_x[m_left->m_step] -= 2. * m_left->m_attackDist; } suma += ( m_y[m_left->m_step] * m_x[0] ); sumb += ( m_x[m_left->m_step] * m_y[0] ); m_finalSweep = ( suma > sumb ) ? ( 0.5 * ( suma - sumb ) ) : ( 0.5 * ( sumb - suma ) ); m_finalSweep *= 0.20; // Calculate the area using the trapizoidal rule sumDT = 0; for ( int i = 1; i <= m_left->m_step; i++ ) sumDT = (m_x[i] - m_x[i-1]) * (m_y[i] + m_y[i-1]) + sumDT; if ( sumDT < 0 ) sumDT = -1.0 * sumDT; area = sumDT * .5; // Add in the area for the uncontained portion of the fire DT 1/2013 double UCarea = UncontainedArea( m_h[m_left->m_step], fireLwRatioAtReport(), m_x[m_left->m_step], m_y[m_left->m_step], tactic() ); area = area + UCarea; // Accumulate area for BOTH flanks (ac) m_finalSweep = 0.2 * area; // Cases 1-3: forces are overrun by fire... if ( m_left->m_status == Sem::Contain::Overrun ) { // Case 1: No retry allowed, simulation is complete if ( ! m_retry ) { rerun = false; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 1: Overrun\n" " - resources overrun at %3.1f minutes (%d steps)\n" " - re-run is FALSE\n" " - FIRE ESCAPES at %3.1f minutes\n", m_pass, elapsed, m_left->m_step, elapsed ); } // Case 2: Try initial attack after more forces have arrived else if ( ( at = m_force->nextArrival( m_left->m_attackTime, m_left->m_exhausted, LeftFlank ) ) > 0.01 ) { m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 2: Retry\n" " - resources overrun at %3.1f minutes (%d steps)\n" " - Pass %d will wait for IA until %3.1f minutes\n" " - when line building rate will be %3.2f ch/h\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step, m_pass+1, at, m_force->productionRate( at, LeftFlank ) ); m_pass++; m_left->m_attackTime = at; m_left->reset(); rerun = true; } // Case 3: All resources exhausted else { // No more forces available, so we're done rerun = false; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 3: Exhausted\n" " - resources exhausted at %3.1f minutes (%d steps)\n" " - FIRE ESCAPES at %3.1f minutes\n", m_pass, elapsed, m_left->m_step, elapsed ); m_left->m_status = Sem::Contain::Exhausted; } } // New Case 3: to set rerun to false when the outrun fires are // removed DT 7/8/10 else if (m_left->m_currentTime >= m_left->m_exhausted) { // No more forces available, so we're done rerun = false; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 3: Exhausted\n" " - resources exhausted at %3.1f minutes (%d steps)\n" " - FIRE ESCAPES at %3.1f minutes\n", m_pass, elapsed, m_left->m_step, elapsed ); m_left->m_status = Sem::Contain::Exhausted; } // Case 4: maximum number of steps was exceeded // (should never happen as long as m_distStep is calculated from // m_exhausted, m_reportRate, ... ) else if ( iLeft >= m_maxSteps ) { // Make the distance step size bigger and rerun the simulation // MAF 9/29/2010, remove factor calc, just reverse previous factor and redo //factor = (double) m_maxSteps / (double) m_minSteps; factor = 2.0; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 4: Less Precision\n" " - fire uncontained at %f minutes\n" " - %d steps exceeds maximum of %d steps\n" " - increasing Eta from %f to %f chains for next Pass %d\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step, m_maxSteps, m_left->m_distStep, (m_left->m_distStep*factor), m_pass+1 ); m_left->m_distStep *= factor; m_pass++; if(MAXSTEPS_EXCEEDED==false) { m_left->reset(); rerun = true; } else rerun=false; MAXSTEPS_EXCEEDED=true; } // Cases 5-6: fire is contained... else if ( m_left->m_status == Sem::Contain::Contained ) { // Case 5: there were insufficient simulation steps... if ( iLeft < m_minSteps && MAXSTEPS_EXCEEDED==false) // MAF 9/29/2010 added MAXSTEPS_EXCEEDED check { // Make the distance step size smaller and rerun the simulation // Need to make sure that with the new smaller step we will not // exceed the MAX steps - otherwise we end up looping // Diane 08/10 decrease the step size at a slower rate factor = 0.5 ; // (double) ( m_left->m_step + 1 ) / ((double) m_minSteps*1.25); m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 5: More Precision\n" " - fire contained at %3.1f minutes\n" " - %d steps is less than minimum of %d steps\n" " - decreasing Eta from %f to %f chains for Pass %d\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step, m_minSteps, m_left->m_distStep, (m_left->m_distStep * factor), m_pass+1 ); m_left->m_distStep *= factor; m_pass++; // Diane 08/10 decrease the step size at a slower rate //if(m_pass<10) //{ m_left->reset(); rerun = true; //} //else // rerun=false; } // Case 6: fire contained within the simulation step range else { m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 6: Contained\n" " - FIRE CONTAINED at %3.1f minutes (%d steps)\n", m_pass, elapsed, m_left->m_step ); rerun = false; } } //Add check for maximum Area else if(totalArea >= m_maxFireSize){ at = m_force->nextArrival( m_left->m_attackTime, m_left->m_exhausted, LeftFlank ); /*////////////////////////////////////////////////////////////////////////// Removed DT 6/2010 Stop when fire exceeds maximum size if (at > .01){ rerun = true; m_left->m_attackTime = at; m_left->containLog( ( logLevel >= 1 ), "Pass %d Result max area exceeded: Retry\n" " - Maximum Area of %d exceeded at %3.1f minutes (%d steps)\n" " - Pass %d will wait for IA until %3.1f minutes\n" " - when line building rate will be %3.2f ch/h\n" " - RE-RUN\n", m_pass,m_maxFireSize, elapsed, m_left->m_step, m_pass+1, at, m_force->productionRate( at, LeftFlank ) ); m_pass++; m_left->reset(); }else{ */ // cout << m_pass << " " << totalArea << " " <<m_maxFireSize << " " << "\n"; m_left->containLog( ( logLevel >= 1 ), "Pass %d total fire size of %3.2f acres exceeds max fire size of %d acres at time %3.1f minutes\n", m_pass, totalArea, m_maxFireSize, elapsed); rerun = false; //Production rate is not longer increasing m_left->m_status = Sem::Contain::SizeLimitExceeded; // } } // time limit exceeded //------------------------------------------------------------------ // MAF 6/2010 //------------------------------------------------------------------ else if(((m_left->m_currentTime) > (m_maxFireTime-1))) { m_left->m_currentTime=m_maxFireTime; m_left->m_status = Sem::Contain::TimeLimitExceeded; rerun=false; } // Case 7: anything else (should never get here!)... else { m_left->containLog( ( logLevel >= 1 ), "Pass %d Result 7:\n" " - unknown condition at %3.1f minutes (%d steps)\n" " - RE-RUN\n", m_pass, elapsed, m_left->m_step ); rerun = true; } } // Special case for contained head tactic with non-zero offset if ( m_left->m_status == Sem::Contain::Contained && m_left->m_tactic == Sem::Contain::HeadAttack && m_left->m_attackDist > 0.01 ) { } //special case for time limit //if the time is greater than the max time, then the fire escapes //all resources that arrive prior to the max time are considered used //always subtract 1 minute from the fire time, we don't get a correct state //otherwise because the simulation forces all resources to end work before the //fire time limit is reached //if ((m_left->m_time) > (m_maxFireTime-1)) { // m_left->m_time=m_maxFireTime; // m_left->m_status = Sem::Contain::TimeLimitExceeded; //} //------------------------------------------------------------------ // MAF 6/2010 //------------------------------------------------------------------ if ((m_left->m_currentTime) > (m_maxFireTime-1)) { m_left->m_currentTime=m_maxFireTime; m_left->m_status = Sem::Contain::TimeLimitExceeded; } // Simulation complete: display results finalStats(); m_left->containLog( ( logLevel > 0 ), "\n Pass %d Step Size : %f ch\n", m_pass, m_left->m_distStep ); m_left->containLog( ( logLevel > 0 ), " Tactic : %8s\n", TacticName[m_left->m_tactic] ); m_left->containLog( ( logLevel > 0 ), " Simulation Steps : %8d\n", m_left->m_step+1 ); m_left->containLog( ( logLevel > 0 ), " Simulation Time : %8.2f min\n", m_finalTime ); m_left->containLog( ( logLevel > 0 ), " Simulation Result : %s\n", StatusName[m_left->m_status] ); m_left->containLog( ( logLevel > 0 ), " Containment Line : %8.4f ch\n", m_finalLine ); m_left->containLog( ( logLevel > 0 ), " Containment Size : %8.4f ac\n", m_finalSize ); m_left->containLog( ( logLevel > 0 ), " Resources Used : %8d\n", m_used ); m_left->containLog( ( logLevel > 0 ), " Resource Cost : %8.0f\n\n", m_finalCost ); return; }
tactic apply_tactic_core(expr const & e, constraint_seq const & cs) { return tactic([=](environment const & env, io_state const & ios, proof_state const & s) { return apply_tactic_core(env, ios, s, e, cs); }); }