示例#1
0
/*****************************************************************************************
 *  Advance the state of this FMU from the current communication point to that point plus
 *  the specified step size.
 *  @param c The FMU.
 *  @param currentCommunicationPoint The time at the start of the step interval.
 *  @param communicationStepSize The width of the step interval.
 *  @param noSetFMUStatePriorToCurrentPoint True to assert that the master will not subsequently
 *   restore the state of this FMU or call fmiDoStep with a communication point less than the
 *   current one. An FMU may use this to determine that it is safe to take actions that have side
 *   effects, such as printing outputs. This FMU ignores this argument.
 *  @return fmi2Discard if the FMU rejects the step size, otherwise fmi2OK.
 */
fmi2Status fmiDoStep(fmi2Component c, fmi2Real currentCommunicationPoint,
                fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint) {
        ModelInstance* component = (ModelInstance *) c;

        // If current time is greater than period * (value + 1), then it is
        // time for another increment.
        double endOfStepTime = currentCommunicationPoint + communicationStepSize;
        double targetTime = TICK_PERIOD * (component->currentCount + 1);
        if (endOfStepTime >= targetTime - EPSILON) {
                // It is time for an increment.
                // Is it too late for the increment?
                if (endOfStepTime > targetTime + EPSILON) {
                        // Indicate that the last successful time is
                        // at the target time.
                        component->lastSuccessfulTime = targetTime;
                        fflush(stdout);
                        return fmi2Discard;
                }
                // We are at the target time. Are we
                // ready for the increment yet? Have to have already
                // completed one firing at this time.
                if (component->atBreakpoint) {
                        // Not the first firing. Go ahead an increment.
                        component->currentCount++;

                        input_function(component->controller,component->input,component->dInput);

                        transition_function(component->controller);

                        output_function(component->controller,component->output);
                        // Reset the indicator that the increment is needed.
                        component->atBreakpoint = fmi2False;
                } else {
                        // This will complete the first firing at the target time.
                        // We don't want to increment yet, but we set an indicator
                        // that we have had a firing at this time.
                        fflush(stdout);
                        component->atBreakpoint = fmi2True;
                }
        }
        component->lastSuccessfulTime = endOfStepTime;
        fflush(stdout);
        return fmi2OK;
}
示例#2
0
    void aig_exporter::operator()(std::ostream& out) {
        expr_ref_vector transition_function(m), output_preds(m);
        var_ref_vector input_vars(m);

        rule_counter& vc = m_rm.get_counter();
        expr_ref_vector exprs(m);
        substitution subst(m);

        for (rule_set::decl2rules::iterator I = m_rules.begin_grouped_rules(),
            E = m_rules.end_grouped_rules(); I != E; ++I) {
            for (rule_vector::iterator II = I->get_value()->begin(),
                EE = I->get_value()->end(); II != EE; ++II) {
                rule *r = *II;
                unsigned numqs = r->get_positive_tail_size();
                if (numqs > 1) {
                    std::cerr << "non-linear clauses not supported\n";
                    exit(-1);
                }

                if (numqs != r->get_uninterpreted_tail_size()) {
                    std::cerr << "negation of queries not supported\n";
                    exit(-1);
                }

                exprs.reset();
                assert_pred_id(numqs ? r->get_tail(0)->get_decl() : 0, m_ruleid_var_set, exprs);
                assert_pred_id(r->get_head()->get_decl(), m_ruleid_varp_set, exprs);

                subst.reset();
                subst.reserve(1, vc.get_max_rule_var(*r)+1);
                if (numqs)
                    collect_var_substs(subst, r->get_tail(0), m_latch_vars, exprs);
                collect_var_substs(subst, r->get_head(), m_latch_varsp, exprs);

                for (unsigned i = numqs; i < r->get_tail_size(); ++i) {
                    expr_ref e(m);
                    subst.apply(r->get_tail(i), e);
                    exprs.push_back(e);
                }

                transition_function.push_back(m.mk_and(exprs.size(), exprs.c_ptr()));
            }
        }

        // collect table facts
        if (m_facts) {
            for (fact_vector::const_iterator I = m_facts->begin(), E = m_facts->end(); I != E; ++I) {
                exprs.reset();
                assert_pred_id(0, m_ruleid_var_set, exprs);
                assert_pred_id(I->first, m_ruleid_varp_set, exprs);

                for (unsigned i = 0; i < I->second.size(); ++i) {
                    exprs.push_back(m.mk_eq(get_latch_var(i, m_latch_varsp), I->second[i]));
                }

                transition_function.push_back(m.mk_and(exprs.size(), exprs.c_ptr()));
            }
        }

        expr *tr = m.mk_or(transition_function.size(), transition_function.c_ptr());
        aig_ref aig = m_aigm.mk_aig(tr);
        expr_ref aig_expr(m);
        m_aigm.to_formula(aig, aig_expr);

#if 0
        std::cout << mk_pp(tr, m) << "\n\n";
        std::cout << mk_pp(aig_expr, m) << "\n\n";
#endif

        // make rule_id vars latches
        for (unsigned i = 0; i < m_ruleid_var_set.size(); ++i) {
            m_latch_vars.push_back(m_ruleid_var_set.get(i));
            m_latch_varsp.push_back(m_ruleid_varp_set.get(i));
        }

        // create vars for latches
        for (unsigned i = 0; i < m_latch_vars.size(); ++i) {
            mk_var(m_latch_vars.get(i));
            mk_input_var(m_latch_varsp.get(i));
        }

        unsigned tr_id = expr_to_aig(aig_expr);

        // create latch next state variables: (ite tr varp var)
        unsigned_vector latch_varp_ids;
        for (unsigned i = 0; i < m_latch_vars.size(); ++i) {
            unsigned in_val = mk_and(tr_id, get_var(m_latch_varsp.get(i)));
            unsigned latch_val = mk_and(neg(tr_id), get_var(m_latch_vars.get(i)));
            latch_varp_ids.push_back(mk_or(in_val, latch_val));
        }
        m_latch_varsp.reset();

        // create output variable (true iff an output predicate is derivable)
        unsigned output_id = 0;
        {
            expr_ref_vector output(m);
            const func_decl_set& preds = m_rules.get_output_predicates();

            for (func_decl_set::iterator I = preds.begin(), E = preds.end(); I != E; ++I) {
                exprs.reset();
                assert_pred_id(*I, m_ruleid_var_set, exprs);
                output.push_back(m.mk_and(exprs.size(), exprs.c_ptr()));
            }

            expr *out = m.mk_or(output.size(), output.c_ptr());
            aig = m_aigm.mk_aig(out);
            m_aigm.to_formula(aig, aig_expr);
            output_id = expr_to_aig(aig_expr);

#if 0
            std::cout << "output formula\n";
            std::cout << mk_pp(out, m) << "\n\n";
            std::cout << mk_pp(aig_expr, m) << "\n\n";
#endif
        }

        // 1) print header
        // aag var_index inputs latches outputs andgates
        out << "aag " << (m_next_aig_expr_id-1)/2 << ' ' << m_input_vars.size()
            << ' ' << m_latch_vars.size() << " 1 " << m_num_and_gates << '\n';

        // 2) print inputs
        for (unsigned i = 0; i < m_input_vars.size(); ++i) {
            out << m_input_vars[i] << '\n';
        }
        
        // 3) print latches
        for (unsigned i = 0; i < m_latch_vars.size(); ++i) {
            out << get_var(m_latch_vars.get(i)) << ' ' << latch_varp_ids[i] << '\n';
        }

        // 4) print outputs  (just one for now)
        out << output_id << '\n';

        // 5) print formula
        out << m_buffer.str();
    }