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();
        });
}
Exemple #3
0
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);
        });
}
Exemple #4
0
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;
}
Exemple #5
0
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);
        });
}