Example #1
0
    ~imp() {
#if defined(_WINDOWS) || defined(_CYGWIN)
        DeleteTimerQueueTimer(NULL,
                              m_timer,
                              INVALID_HANDLE_VALUE);
#elif defined(__APPLE__) && defined(__MACH__)
        // Mac OS X

        // If the waiting-thread is not up and waiting yet, 
        // we can make sure that it finishes quickly by 
        // setting the end-time to zero.
        m_end_time.tv_sec = 0;
        m_end_time.tv_nsec = 0;

        // Otherwise it's already up and waiting, and
        // we can send a signal on m_condition_var:
        pthread_mutex_lock(&m_mutex);
        pthread_cond_signal(&m_condition_var);
        pthread_mutex_unlock(&m_mutex);

        if (pthread_join(m_thread_id, NULL) != 0)
            throw default_exception("failed to join thread");
        if (pthread_mutex_destroy(&m_mutex) != 0)
            throw default_exception("failed to destroy pthread mutex");
        if (pthread_cond_destroy(&m_condition_var) != 0)
            throw default_exception("failed to destroy pthread condition variable");
        if (pthread_attr_destroy(&m_attributes) != 0)
            throw default_exception("failed to destroy pthread attributes object");
#elif defined(_LINUX_) || defined(_FREEBSD_)
    // Linux & FreeBSD
        timer_delete(m_timerid);
#else
    // Other Platforms
#endif
    }
Example #2
0
    // Mac OS X
    static void * thread_func(void * arg) {
        scoped_timer::imp * st = static_cast<scoped_timer::imp*>(arg);  

        pthread_mutex_t  mutex;
        clock_serv_t host_clock;
        struct timespec abstime;
        mach_timespec_t now;
        unsigned long long nano = static_cast<unsigned long long>(st->m_interval) * 1000000ull;

        host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock);

        if (pthread_mutex_init(&mutex, NULL) != 0)
            throw default_exception("failed to initialize timer mutex");
        if (pthread_cond_init(&st->m_condition_var, NULL) != 0)
            throw default_exception("failed to initialize timer condition variable");

        abstime.tv_sec  = nano / 1000000000ull;
        abstime.tv_nsec = nano % 1000000000ull;

        pthread_mutex_lock(&mutex);
        clock_get_time(host_clock, &now);
        ADD_MACH_TIMESPEC(&abstime, &now);
        int e = pthread_cond_timedwait(&st->m_condition_var, &mutex, &abstime);
        if (e != 0 && e != ETIMEDOUT)
            throw default_exception("failed to start timed wait");
        st->m_eh->operator()();
        pthread_mutex_unlock(&mutex);

        if (pthread_mutex_destroy(&mutex) != 0)
            throw default_exception("failed to destroy pthread mutex");
        if (pthread_cond_destroy(&st->m_condition_var) != 0)
            throw default_exception("failed to destroy pthread condition variable");
        return st;
    }
Example #3
0
 void throw_unknown_parameter(symbol const & param_name, param_descrs const& d, symbol const & mod_name) {
     if (mod_name == symbol::null) {
         char const * new_name = get_new_param_name(param_name);
         if (new_name) {
             std::stringstream strm;
             strm << "the parameter '" << param_name
                  << "', invoke 'z3 -p' to obtain the new parameter list, and 'z3 -pp:" << new_name
                  << "' for the full description of the parameter";
             throw exception(strm.str());
         }
         else if (is_old_param_name(param_name)) {
             std::stringstream strm;
             strm << "unknown parameter '" << param_name 
                  << "', this is an old parameter name, invoke 'z3 -p' to obtain the new parameter list";
             throw default_exception(strm.str());
         }
         else {
             std::stringstream strm;
             strm << "unknown parameter '" << param_name << "'\n";    
             strm << "Legal parameters are:\n";
             d.display(strm, 2, false, false);
             throw default_exception(strm.str());
         }
     }
     else {
         std::stringstream strm;
         strm << "unknown parameter '" << param_name << "' ";
         strm << "at module '" << mod_name << "'\n";
         strm << "Legal parameters are:\n";
         d.display(strm, 2, false, false);
         throw default_exception(strm.str());
     }
 }
Example #4
0
 void context::pop() {
     if (m_trail.get_num_scopes() == 0) {
         throw default_exception("there are no backtracking points to pop to");
     }
     throw default_exception("pop operation is not supported");
     m_trail.pop_scope(1);
 }
Example #5
0
void context::pop() {
    if (m_trail.get_num_scopes() == 0) {
        throw default_exception("there are no backtracking points to pop to");
    }
    if(m_engine.get()) {
        if(get_engine() != DUALITY_ENGINE)
            throw default_exception("operation is not supported by engine");
    }
    m_trail.pop_scope(1);
}
Example #6
0
 void validate(param_descrs const & p) const {
     svector<params::entry>::const_iterator it  = m_entries.begin();  
     svector<params::entry>::const_iterator end = m_entries.end();
     for (; it != end; ++it) {                                
         param_kind expected = p.get_kind(it->first);
         if (expected == CPK_INVALID)
             throw default_exception("unknown parameter '%s'", it->first.str().c_str());
         if (it->second.m_kind != expected) 
             throw default_exception("parameter kind mismatch '%s'", it->first.str().c_str());
     }
 }
Example #7
0
    imp(unsigned ms, event_handler * eh):
        m_eh(eh) {
#ifdef _WINDOWS
        m_first = true;
        CreateTimerQueueTimer(&m_timer,			
                              NULL,				
                              abort_proc,
                              this,
                              0,				
                              ms,				
                              WT_EXECUTEINTIMERTHREAD);	
#elif defined(__APPLE__) && defined(__MACH__)
        // Mac OS X
        m_interval = ms;
        if (pthread_attr_init(&m_attributes) != 0)
            throw default_exception("failed to initialize timer thread attributes");
        if (pthread_create(&m_thread_id, &m_attributes, &thread_func, this) != 0)
            throw default_exception("failed to start timer thread");
#else
	// Linux version
        if (omp_in_parallel()) {
            // It doesn't work in with more than one thread.
            // SIGEV_SIGNAL: the event is handled by the process not by the thread that installed the handler.
            // SIGEV_THREAD: the event is handled by a new thread (Z3 crashes with this configuration).
            // 
            // It seems the way to go is SIGEV_SIGNAL, but I have to find a way to identify the thread the event is meant to.
            return;
        }
	m_old_timer   = g_timer;
	g_timer       = this;
	m_old_handler = signal(SIG, sig_handler);

	struct sigevent sev;
        memset(&sev, 0, sizeof(sigevent));
	sev.sigev_notify = SIGEV_SIGNAL;
	sev.sigev_signo  = SIG;
	sev.sigev_value.sival_ptr = &m_timerid;
	if (timer_create(CLOCKID, &sev, &m_timerid) == -1)
	    throw default_exception("failed to create timer");

	unsigned long long nano = static_cast<unsigned long long>(ms) * 1000000ull;
	struct itimerspec its;
	its.it_value.tv_sec  = nano / 1000000000ull;
	its.it_value.tv_nsec = nano % 1000000000ull;
	its.it_interval.tv_sec  = 0; // timer experies once
	its.it_interval.tv_nsec = 0;
	if (timer_settime(m_timerid, 0, &its, NULL) == -1)
	    throw default_exception("failed to set timer");
#endif
    }
Example #8
0
void context::check_quantifier_free(rule_ref& r) {
    if (r->has_quantifiers()) {
        std::stringstream stm;
        stm << "cannot process quantifiers in rule ";
        r->display(*this, stm);
        throw default_exception(stm.str());
    }
}
Example #9
0
 unsigned context::scoped_state::add(app* t, bool is_max) {
     app_ref tr(t, m);
     if (!m_bv.is_bv(t) && !m_arith.is_int_real(t)) {
         throw default_exception("Objective must be bit-vector, integer or real");   
     }
     unsigned index = m_objectives.size();
     m_objectives.push_back(objective(is_max, tr, index));
     return index;
 }
Example #10
0
    subpaving::var process_arith_app(app * t, unsigned depth, mpz & n, mpz & d) {
        SASSERT(m_autil.is_arith_expr(t));

        switch (t->get_decl_kind()) {
        case OP_NUM:
            return process_num(t, depth, n, d);
        case OP_ADD: 
            return process_add(t, depth, n, d);
        case OP_MUL: 
            return process_mul(t, depth, n, d);
        case OP_POWER:
            return process_power(t, depth, n, d);
        case OP_TO_REAL: 
            return process(t->get_arg(0), depth+1, n, d);
        case OP_SUB:
        case OP_UMINUS:
            found_non_simplified();
            break;
        case OP_TO_INT:
        case OP_DIV:
        case OP_IDIV:
        case OP_MOD:
        case OP_REM:
        case OP_IRRATIONAL_ALGEBRAIC_NUM:
            throw default_exception("you must apply arithmetic purifier before internalizing expressions into the subpaving module.");
        case OP_SIN: 
        case OP_COS:
        case OP_TAN:
        case OP_ASIN:
        case OP_ACOS:
        case OP_ATAN:
        case OP_SINH:
        case OP_COSH:
        case OP_TANH:
        case OP_ASINH:
        case OP_ACOSH:
        case OP_ATANH:
            // TODO
            throw default_exception("transcendental and hyperbolic functions are not supported yet.");
        default:
            UNREACHABLE();
        }
        return subpaving::null_var;
    }
Example #11
0
 void set(param_descrs const & d, symbol const & param_name, char const * value, symbol const & mod_name) {
     param_kind k = d.get_kind(param_name);
     params_ref & ps = get_params(mod_name);
     if (k == CPK_INVALID) {
         throw_unknown_parameter(param_name, d, mod_name);
     }
     else if (k == CPK_UINT) {
         long val = strtol(value, nullptr, 10);
         ps.set_uint(param_name, static_cast<unsigned>(val));
     }
     else if (k == CPK_DOUBLE) {
         char * aux;
         double val = strtod(value, &aux);
         ps.set_double(param_name, val);
     }
     else if (k == CPK_BOOL) {
         if (strcmp(value, "true") == 0) {
             ps.set_bool(param_name, true);
         }
         else if (strcmp(value, "false") == 0) {
             ps.set_bool(param_name, false);
         }
         else {
             std::stringstream strm;
             strm << "invalid value '" << value << "' for Boolean parameter '" << param_name << "'";                
             if (mod_name == symbol::null) {
                 strm << " at module '" << mod_name << "'";
             }
             throw default_exception(strm.str());
         }
     }
     else if (k == CPK_SYMBOL) {
         ps.set_sym(param_name, symbol(value));
     }
     else if (k == CPK_STRING) {
         // There is no guarantee that (external) callers will not delete value after invoking gparams::set.
         // I see two solutions:
         //    1) Modify params_ref to create a copy of set_str parameters.
         //       This solution is not nice since we create copies and move the params_ref around.
         //       We would have to keep copying the strings.
         //       Moreover, when we use params_ref internally, the value is usually a static value. 
         //       So, we would be paying this price for nothing.
         //    2) "Copy" value by transforming it into a symbol. 
         //       I'm using this solution for now.
         ps.set_str(param_name, symbol(value).bare_str());
     }
     else {
         std::stringstream strm;
         strm << "unsupported parameter type '" << param_name << "'";            
         if (mod_name == symbol::null) {
             strm << " at module '" << mod_name << "'";            
         }
         throw exception(strm.str());
     }
 }
Example #12
0
//
// Update a rule with a new.
// It requires basic subsumption.
//
void context::update_rule(expr* rl, symbol const& name) {
    datalog::rule_manager& rm = get_rule_manager();
    proof* p = 0;
    if (generate_proof_trace()) {
        p = m.mk_asserted(rl);
    }
    unsigned size_before = m_rule_set.get_num_rules();
    rm.mk_rule(rl, p, m_rule_set, name);
    unsigned size_after = m_rule_set.get_num_rules();
    if (size_before + 1 != size_after) {
        std::stringstream strm;
        strm << "Rule " << name << " has a non-trivial body. It cannot be modified";
        throw default_exception(strm.str());
    }
    // The new rule is inserted last:
    rule_ref r(m_rule_set.get_rule(size_before), rm);
    rule_ref_vector const& rls = m_rule_set.get_rules();
    rule* old_rule = 0;
    for (unsigned i = 0; i < size_before; ++i) {
        if (rls[i]->name() == name) {
            if (old_rule) {
                std::stringstream strm;
                strm << "Rule " << name << " occurs twice. It cannot be modified";
                m_rule_set.del_rule(r);
                throw default_exception(strm.str());
            }
            old_rule = rls[i];
        }
    }
    if (old_rule) {
        if (!check_subsumes(*old_rule, *r)) {
            std::stringstream strm;
            strm << "Old rule ";
            old_rule->display(*this, strm);
            strm << "does not subsume new rule ";
            r->display(*this, strm);
            m_rule_set.del_rule(r);
            throw default_exception(strm.str());
        }
        m_rule_set.del_rule(old_rule);
    }
}
Example #13
0
void context_params::set_bool(bool & opt, char const * param, char const * value) {
    if (strcmp(value, "true") == 0) {
        opt = true;
    }
    else if (strcmp(value, "false") == 0) {
        opt = false;
    }
    else {
        throw default_exception("invalid value '%s' for Boolean parameter '%s'", value, param);
    }
}
Example #14
0
void context::check_uninterpreted_free(rule_ref& r) {
    func_decl* f = 0;
    if (r->has_uninterpreted_non_predicates(m, f)) {
        std::stringstream stm;
        stm << "Uninterpreted '"
            << f->get_name()
            << "' in ";
        r->display(*this, stm);
        throw default_exception(stm.str());
    }
}
Example #15
0
 unsigned context::scoped_state::add(expr* f, rational const& w, symbol const& id) {
     if (w.is_neg()) {
         throw default_exception("Negative weight supplied. Weight should be positive");
     }
     if (w.is_zero()) {
         throw default_exception("Zero weight supplied. Weight should be positive");
     }
     if (!m.is_bool(f)) {
         throw default_exception("Soft constraint should be Boolean");
     }
     if (!m_indices.contains(id)) {
         m_objectives.push_back(objective(m, id));
         m_indices.insert(id, m_objectives.size() - 1);
     }
     SASSERT(m_indices.contains(id));        
     unsigned idx = m_indices[id];
     m_objectives[idx].m_terms.push_back(f);
     m_objectives[idx].m_weights.push_back(w);
     m_objectives_term_trail.push_back(idx);
     return idx;
 }
Example #16
0
void context_params::set(char const * param, char const * value) {
    std::string p = param;
    unsigned n = static_cast<unsigned>(p.size());
    for (unsigned i = 0; i < n; i++) {
        if (p[i] >= 'A' && p[i] <= 'Z')
            p[i] = p[i] - 'A' + 'a';
        else if (p[i] == '-')
            p[i] = '_';
    }
    if (p == "timeout") {
        long val = strtol(value, 0, 10);
        m_timeout = static_cast<unsigned>(val);
    }
    else if (p == "type_check" || p == "well_sorted_check") {
        set_bool(m_well_sorted_check, param, value);
    }
    else if (p == "auto_config") {
        set_bool(m_auto_config, param, value);
    }
    else if (p == "proof") {
        set_bool(m_proof, param, value);
    }
    else if (p == "model") {
        set_bool(m_model, param, value);
    }
    else if (p == "model_validate") {
        set_bool(m_model_validate, param, value);
    }
    else if (p == "trace") {
        set_bool(m_trace, param, value);
    }
    else if (p == "trace_file_name") {
        m_trace_file_name = value;
    }
    else if (p == "unsat_core") {
        set_bool(m_unsat_core, param, value);
    }
    else if (p == "debug_ref_count") {
        set_bool(m_debug_ref_count, param, value);
    }
    else if (p == "smtlib2_compliant") {
        set_bool(m_smtlib2_compliant, param, value);
    }
    else {
       param_descrs d;
       collect_param_descrs(d);
       std::stringstream strm;
       strm << "unknown parameter '" << p << "'\n";
       strm << "Legal parameters are:\n";
       d.display(strm, 2, false, false);
       throw default_exception(strm.str());        
    }
}
Example #17
0
bool user_simplifier_plugin::reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result) {
    if (m_reduce_distinct_fptr == 0 || !m_enabled)
        return false;
    expr * _result = 0;
    bool flag = m_reduce_distinct_fptr(m_owner, num_args, args, &_result);
    if (flag) {
        if (_result == 0)
            throw default_exception("invalid reduce_distinct callback: result is null");
        result = _result;
    }
    return flag;
}
Example #18
0
bool user_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) {
    if (m_reduce_eq_fptr == 0 || !m_enabled)
        return false;
    expr * _result = 0;
    bool flag = m_reduce_eq_fptr(m_owner, lhs, rhs, &_result);
    if (flag) {
        if (_result == 0)
            throw default_exception("invalid reduce_eq callback: result is null");
        result = _result;
    }
    return flag;
}
Example #19
0
    ~imp() {
#ifdef _WINDOWS
        DeleteTimerQueueTimer(NULL,
                              m_timer,
                              INVALID_HANDLE_VALUE);
#elif defined(__APPLE__) && defined(__MACH__)
        // Mac OS X
        pthread_cond_signal(&m_condition_var); // this is okay to fail
        if (pthread_join(m_thread_id, NULL) != 0)
            throw default_exception("failed to join thread");
        if (pthread_attr_destroy(&m_attributes) != 0)
            throw default_exception("failed to destroy pthread attributes object");
#else
	// Linux version
        if (omp_in_parallel())
            return; // see comments in the constructor.
	timer_delete(m_timerid);
	if (m_old_handler != SIG_ERR)
	    signal(SIG, m_old_handler);
	g_timer = m_old_timer;
#endif
    }
Example #20
0
 void validate(param_descrs const & p) {
     svector<params::entry>::iterator it  = m_entries.begin();  
     svector<params::entry>::iterator end = m_entries.end();
     symbol suffix, prefix;
     for (; it != end; ++it) {                                
         param_kind expected = p.get_kind_in_module(it->first);
         if (expected == CPK_INVALID) {
             std::stringstream strm;
             strm << "unknown parameter '" << it->first.str() << "'\n";    
             strm << "Legal parameters are:\n";
             p.display(strm, 2, false, false);
             throw default_exception(strm.str());
         }
         if (it->second.m_kind != expected && 
             !(it->second.m_kind == CPK_UINT && expected == CPK_NUMERAL)) {
             std::stringstream strm;
             strm << "Parameter " << it->first.str() << " was given argument of type ";
             strm << it->second.m_kind << ", expected " << expected;                
             throw default_exception(strm.str());
         }
     }
 }
Example #21
0
    // Mac OS X
    static void * thread_func(void * arg) {
        scoped_timer::imp * st = static_cast<scoped_timer::imp*>(arg);  

        pthread_mutex_lock(&st->m_mutex);

        int e = pthread_cond_timedwait(&st->m_condition_var, &st->m_mutex, &st->m_end_time);
        if (e != 0 && e != ETIMEDOUT)
            throw default_exception("failed to start timed wait");
        st->m_eh->operator()();

        pthread_mutex_unlock(&st->m_mutex);

        return st;
    }
Example #22
0
    imp(unsigned ms, event_handler * eh):
        m_eh(eh) {
#if defined(_WINDOWS) || defined(_CYGWIN)
        m_first = true;
        CreateTimerQueueTimer(&m_timer,
                              NULL,
                              abort_proc,
                              this,
                              0,
                              ms,
                              WT_EXECUTEINTIMERTHREAD);
#elif defined(__APPLE__) && defined(__MACH__)
        // Mac OS X
        m_interval = ms?ms:0xFFFFFFFF;
        if (pthread_attr_init(&m_attributes) != 0)
            throw default_exception("failed to initialize timer thread attributes");
        if (pthread_cond_init(&m_condition_var, NULL) != 0)
            throw default_exception("failed to initialize timer condition variable");
        if (pthread_mutex_init(&m_mutex, NULL) != 0)
            throw default_exception("failed to initialize timer mutex");

        clock_serv_t host_clock;
        mach_timespec_t now;
        unsigned long long nano = static_cast<unsigned long long>(m_interval) * 1000000ull;
        
        host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock);
        m_end_time.tv_sec  = nano / 1000000000ull;
        m_end_time.tv_nsec = nano % 1000000000ull;
        clock_get_time(host_clock, &now);
        ADD_MACH_TIMESPEC(&m_end_time, &now);


        if (pthread_create(&m_thread_id, &m_attributes, &thread_func, this) != 0)
            throw default_exception("failed to start timer thread");
#elif defined(_LINUX_) || defined(_FREEBSD_)
        // Linux & FreeBSD
        struct sigevent sev;
        memset(&sev, 0, sizeof(sigevent));
        sev.sigev_notify = SIGEV_THREAD;
        sev.sigev_value.sival_ptr = this;
        sev.sigev_notify_function = sig_handler;
        if (timer_create(CLOCKID, &sev, &m_timerid) == -1)
            throw default_exception("failed to create timer");

        unsigned long long nano = static_cast<unsigned long long>(ms) * 1000000ull;
        struct itimerspec its;
        its.it_value.tv_sec  = nano / 1000000000ull;
        its.it_value.tv_nsec = nano % 1000000000ull;
        its.it_interval.tv_sec  = 0; // timer experies once
        its.it_interval.tv_nsec = 0;
        
        if (timer_settime(m_timerid, 0, &its, NULL) == -1)
            throw default_exception("failed to set timer");
#else
    // Other platforms
#endif
    }
Example #23
0
 virtual solver* translate(ast_manager& dst_m, params_ref const& p) {
     ast_translation tr(m, dst_m);
     if (m_num_scopes > 0) {
         throw default_exception("Cannot translate sat solver at non-base level");
     }
     inc_sat_solver* result = alloc(inc_sat_solver, dst_m, p);
     expr_ref fml(dst_m);
     for (unsigned i = 0; i < m_fmls.size(); ++i) {
         fml = tr(m_fmls[i].get());
         result->m_fmls.push_back(fml);
     }
     for (unsigned i = 0; i < m_asmsf.size(); ++i) {
         fml = tr(m_asmsf[i].get());
         result->m_asmsf.push_back(fml);
     }
     return result;
 }
Example #24
0
 Z3_solver Z3_API Z3_mk_solver_for_logic(Z3_context c, Z3_symbol logic) {
     Z3_TRY;
     LOG_Z3_mk_solver_for_logic(c, logic);
     RESET_ERROR_CODE();
     if (!smt_logics::supported_logic(to_symbol(logic))) {
         std::ostringstream strm;
         strm << "logic '" << to_symbol(logic) << "' is not recognized";
         throw default_exception(strm.str());
         RETURN_Z3(nullptr);
     }
     else {
         Z3_solver_ref * s = alloc(Z3_solver_ref, *mk_c(c), mk_smt_strategic_solver_factory(to_symbol(logic)));
         mk_c(c)->save_object(s);
         Z3_solver r = of_solver(s);
         RETURN_Z3(r);
     }
     Z3_CATCH_RETURN(nullptr);
 }
Example #25
0
 solver* translate(ast_manager& dst_m, params_ref const& p) override {
     if (m_num_scopes > 0) {
         throw default_exception("Cannot translate sat solver at non-base level");
     }
     ast_translation tr(m, dst_m);
     m_solver.pop_to_base_level();
     inc_sat_solver* result = alloc(inc_sat_solver, dst_m, p, is_incremental());
     result->m_solver.copy(m_solver);
     result->m_fmls_head = m_fmls_head;
     for (expr* f : m_fmls) result->m_fmls.push_back(tr(f));
     for (expr* f : m_asmsf) result->m_asmsf.push_back(tr(f));
     for (auto & kv : m_map) result->m_map.insert(tr(kv.m_key), kv.m_value);
     for (unsigned l : m_fmls_lim) result->m_fmls_lim.push_back(l);
     for (unsigned a : m_asms_lim) result->m_asms_lim.push_back(a);
     for (unsigned h : m_fmls_head_lim) result->m_fmls_head_lim.push_back(h);
     for (expr* f : m_internalized_fmls) result->m_internalized_fmls.push_back(tr(f));
     if (m_mcs.back()) result->m_mcs.push_back(m_mcs.back()->translate(tr));
     if (m_sat_mc) result->m_sat_mc = dynamic_cast<sat2goal::mc*>(m_sat_mc->translate(tr));
     // copy m_bb_rewriter?
     result->m_internalized_converted = m_internalized_converted;
     return result;
 }
Example #26
0
 void found_non_simplified() {
     throw default_exception("you must apply simplifier before internalizing expressions into the subpaving module.");
 }
Example #27
0
 void checkpoint() {
     if (m_cancel)
         throw default_exception("canceled");
     cooperate("expr2subpaving");
 }