示例#1
0
static void tst17() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m);
    d1 = m.mk_empty(3);
    add_triple(m, d1, 5, 15, 10, 10, 50, 500);
    std::cout << mk_ll_pp(d1, m) << "\n";
    m.mk_filter_disequal(d1, d2, 1, 10);
    std::cout << "filter_disequal(var1,10):\n";
    std::cout << mk_ll_pp(d2, m) << "\n";
}
示例#2
0
static void tst15() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m);
    d1 = m.mk_empty(3);
    add_triple(m, d1, 5, 5, 1, 10, 5, 5);
    std::cout << mk_ll_pp(d1, m) << "\n";
    m.mk_filter_distinct(d1, d2, 0, 2);
    std::cout << "filter_distinct(0,2):\n";
    std::cout << mk_ll_pp(d2, m) << "\n";
}
示例#3
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst10() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m);
    d1 = m.mk_empty(3);
    add_triple(m, d1, 5, 100, 10, 20, 3, 10);
    add_triple(m, d1, 5, 100, 34, 50, 98, 110);
    m.add_bounded_var(d1, d2, 0, 66, 72);
    std::cout << mk_ll_pp(d1, m) << "\n";
    std::cout << mk_ll_pp(d2, m) << "\n";
    m.add_bounded_var(d1, d3, 1, 64, 73);
    std::cout << mk_ll_pp(d3, m) << "\n";
}
示例#4
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst11() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m);
    d1 = m.mk_empty(3);
    add_triple(m, d1, 5, 100, 10, 20, 3, 10);
    add_triple(m, d1, 5, 100, 34, 50, 98, 110);
    add_triple(m, d1, 20, 30, 5, 25, 11, 13);
    m.mk_filter_distinct(d1, d2, 1, 2);
    std::cout << mk_ll_pp(d1, m) << "\n";
    std::cout << "filter_distinct(1,2):\n";
    std::cout << mk_ll_pp(d2, m) << "\n";
}
示例#5
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst14() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m);
    d1 = m.mk_empty(3);
    add_triple(m, d1, 5, 25, 1, 10, 10, 13);
    add_triple(m, d1, 5, 25, 20, 30, 15, 18);
    std::cout << "destructive version\n";
    std::cout << mk_ll_pp(d1, m) << "\n";
    m.mk_filter_distinct_dupdt(d1, 0, 2);
    std::cout << "filter_distinct(0,2):\n";
    std::cout << mk_ll_pp(d1, m) << "\n";
}
示例#6
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst7() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d2(m), d3(m);
    d2 = m.mk_empty(3);
    add_triple(m, d2, 15, 22, 15, 23, 7, 18);
    add_triple(m, d2, 28, 42, 29, 39, 34, 46);
    add_triple(m, d2, 28, 42, 29, 39, 100, 200);
    add_triple(m, d2, 28, 42, 50, 60, 100, 200);
    std::cout << "mk_project\n";
    std::cout << mk_ll_pp(d2, m) << "\n";
    unsigned vars[1] = {1};
    m.mk_project(d2, d3, 1, vars);
    std::cout << mk_ll_pp(d3, m) << "\n";
}
示例#7
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst9() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d2(m), d3(m);
    d2 = m.mk_empty(5);
    add_5tuple(m, d2, 2,2, 3,3, 1, 1,  5, 10, 100, 200);
    std::cout << mk_ll_pp(d2, m) << "\n";
    add_5tuple(m, d2, 2,2, 3,3, 1, 1, 15, 20, 100, 200);
    std::cout << mk_ll_pp(d2, m) << "\n";
    add_5tuple(m, d2, 4,4, 5,5, 1, 1,  5, 10, 100, 200);
    std::cout << mk_ll_pp(d2, m) << "\n";
    add_5tuple(m, d2, 4,4, 5,5, 1, 1, 15, 20, 100, 200);
    std::cout << mk_ll_pp(d2, m) << "\n";
    m.mk_swap(d2, d3, 2);
    std::cout << "after swap 2<->3\n";    
    std::cout << mk_ll_pp(d3, m) << "\n";
}
示例#8
0
void distribute_forall::operator()(expr * f, expr_ref & result) {
    m_todo.reset();
    flush_cache();

    m_todo.push_back(f);

    while (!m_todo.empty()) {
        expr * e = m_todo.back();
        if (visit_children(e)) {	        
            m_todo.pop_back();
            reduce1(e);
        }                
    }

    result = get_cached(f);
    SASSERT(result!=0);
    TRACE("distribute_forall", tout << mk_ll_pp(f, m_manager) << "======>\n" 
          << mk_ll_pp(result, m_manager););
示例#9
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst8() {
    std::cout << "--------------------------------\n";    
    // enable_trace("mk_swap_bug");
    imdd_manager m;
    imdd_ref d2(m), d3(m);
    d2 = m.mk_empty(3);
    add_triple(m, d2, 15, 22, 15, 23, 7, 18);
    add_triple(m, d2, 28, 42, 29, 39, 34, 46);
    add_triple(m, d2, 28, 42, 29, 39, 100, 200);
    add_triple(m, d2, 28, 42, 50, 60, 100, 200);
    std::cout << mk_ll_pp(d2, m) << "\n";
    m.mk_swap(d2, d3, 0);
    std::cout << "after swap 0<->1\n";    
    std::cout << mk_ll_pp(d3, m) << "\n";
    m.mk_swap(d2, d3, 1);
    std::cout << "after swap 1<->2\n";    
    std::cout << mk_ll_pp(d3, m) << "\n";
}
示例#10
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst0() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m), d4(m);
    d1 = m.mk_empty(1);
    d2 = m.mk_empty(1);
    m.insert_dupdt(d1, 10, 20);
    m.insert_dupdt(d1, 31, 50);
    m.insert_dupdt(d2, 1,  5);
    m.insert_dupdt(d2, 11,  13);
    m.mk_product(d1, d2, d4);
    m.mk_product(d4, d2, d4);
    m.mk_product_dupdt(d1, d2);
    std::cout << "d1:\n" << mk_ll_pp(d1, m) << "\n-------\n";
    m.mk_product_dupdt(d1, d2);
    std::cout << "d4:\n" << mk_ll_pp(d4, m) << "\nd1:\n" << mk_ll_pp(d1, m) << "\nd2:\n" << mk_ll_pp(d2, m) << "\n";
    std::cout << d1 << "\n" << d2 << "\n";
    m.mk_product_dupdt(d1, d1);
    std::cout << "d1 X d1:\n" << mk_ll_pp(d1, m) << "\n";
}
示例#11
0
/**
   \brief Little HACK for simplifying injectivity axioms
   
   \remark It is not covering all possible cases.
*/
bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) {
    expr * n = q->get_expr();
    if (q->is_forall() && m.is_or(n) && to_app(n)->get_num_args() == 2) {
        expr * arg1 = to_app(n)->get_arg(0);
        expr * arg2 = to_app(n)->get_arg(1);
        if (m.is_not(arg2)) 
            std::swap(arg1, arg2);
        if (m.is_not(arg1) && 
            m.is_eq(to_app(arg1)->get_arg(0)) && 
            m.is_eq(arg2)) {
            expr * app1 = to_app(to_app(arg1)->get_arg(0))->get_arg(0);
            expr * app2 = to_app(to_app(arg1)->get_arg(0))->get_arg(1);
            expr * var1 = to_app(arg2)->get_arg(0);
            expr * var2 = to_app(arg2)->get_arg(1);
            if (is_app(app1) &&
                is_app(app2) && 
                to_app(app1)->get_decl() == to_app(app2)->get_decl() &&
                to_app(app1)->get_num_args() == to_app(app2)->get_num_args() &&
                to_app(app1)->get_family_id() == null_family_id &&
                to_app(app1)->get_num_args() > 0 &&
                is_var(var1) && 
                is_var(var2) && 
                var1 != var2) {
                app * f1          = to_app(app1);
                app * f2          = to_app(app2);
                bool found_vars   = false;
                unsigned num      = f1->get_num_args();
                unsigned idx      = UINT_MAX;
                unsigned num_vars = 1;
                for (unsigned i = 0; i < num; i++) {
                    expr  * c1 = f1->get_arg(i);
                    expr  * c2 = f2->get_arg(i);
                    if (!is_var(c1) && !is_uninterp_const(c1))
                        return false;
                    if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) {
                        if (found_vars)
                            return false;
                        found_vars = true;
                        idx = i;
                    }
                    else if (c1 == c2 && c1 != var1 && c1 != var2) {
                        if (is_var(c1)) {
                            ++num_vars;
                        }
                    }
                    else {
                        return false;
                    }
                }
                if (found_vars && !has_free_vars(q)) {
                    TRACE("inj_axiom", 
                          tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" <<
                          mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";);
示例#12
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst5() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m), d2(m), d3(m);
    std::cout.flush();
    d1 = m.mk_empty(3);
    add_triple(m, d1, 5, 100, 10, 20, 3, 10);
    std::cout << mk_ll_pp(d1,m) << std::endl;
    add_triple(m, d1, 5, 100, 34, 50, 98, 110);
    std::cout << mk_ll_pp(d1,m) << std::endl;
    unsigned vals[3] = {6, 8, 3};
    SASSERT(!m.contains(d1, 3, vals));
    add_triple(m, d1, 6, 25, 8, 30, 14, 50);
    std::cout << mk_ll_pp(d1,m) << std::endl;
    SASSERT(!m.contains(d1, 3, vals));
    unsigned vars[2] = {0, 2};
    d2 = d1;
    d3 = d1;
    m.mk_filter_identical(d1, d1, 2, vars);
    vars[1] = 1;
    std::cout << "d1:\n" << mk_ll_pp(d1,m) << "\n";
    m.mk_filter_identical(d2, d2, 2, vars);
    std::cout << "d2:\n" << mk_ll_pp(d2,m) << "\n";
    vars[0] = 1;
    vars[1] = 2;
    m.mk_filter_identical(d3, d3, 2, vars);
    std::cout << "d3:\n" << mk_ll_pp(d3,m) << "\n";
}
示例#13
0
文件: imdd.cpp 项目: Moondee/Artemis
static void add_some_facts(imdd_manager & m, imdd_ref & d, bool destructive = false, bool memoize = true) {
    std::cout << "destructive: " << destructive << ", memoize: " << memoize << std::endl;
    add_triple(m, d, 1, 10,  3, 3,  0, 100, destructive, memoize);
    std::cout << mk_ll_pp(d, m) << std::endl;
    SASSERT(m.contains(d, 2, 3, 20));
    SASSERT(!m.contains(d, 2, 4, 20));
    SASSERT(!m.contains(d, 2, 3, 200));
    SASSERT(!m.contains(d, 0, 3, 200));
    SASSERT(m.contains(d,1,3,0));
    add_triple(m, d, 3, 6,   3, 4,  7, 101, destructive, memoize);
    std::cout << mk_ll_pp(d, m) << std::endl;
    add_triple(m, d, 3, 6,   2, 2,  7, 101, destructive, memoize);
    std::cout << mk_ll_pp(d, m) << std::endl;
    add_triple(m, d, 3, 6,   5, 6,  7, 101, destructive, memoize);
    SASSERT(m.contains(d, 2, 3, 20));
    std::cout << mk_ll_pp(d, m) << std::endl;
    SASSERT(!m.contains(d, 2, 4, 20));
    SASSERT(m.contains(d, 3, 4, 20));
    SASSERT(!m.contains(d, 2, 3, 200));
    SASSERT(!m.contains(d, 0, 3, 200));
    SASSERT(m.contains(d,1,3,0));
}
示例#14
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst3() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    imdd_ref d1(m);
    d1 = m.mk_empty(3);
    unsigned mins[3] = {0,0,0};
    unsigned maxs[3] = {127, 511, 255};
    
    m.mk_complement(d1, d1, 3, mins, maxs);
    std::cout << d1 << "\n";
    m.mk_complement(d1, d1, 3, mins, maxs);
    std::cout << d1 << "\n";
    SASSERT(d1->empty());

    d1 = m.mk_empty(3);
    add_triple(m, d1, 10, 20, 11, 21, 12, 22);
    add_triple(m, d1, 30, 40, 31, 41, 32, 42);
    std::cout << d1 << "\n";
    m.mk_complement(d1, d1, 3, mins, maxs);
    std::cout << mk_ll_pp(d1,m) << "\n";
    m.mk_filter_equal(d1, d1, 1, 15);
    std::cout << "after selecting second column = 15\n" << mk_ll_pp(d1,m) << "\n";
}
示例#15
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst1() {
    std::cout << "--------------------------------\n";    
    imdd_manager m;
    {
        imdd_ref d(m);
        d = m.mk_empty(3);
        add_some_facts(m, d);
    }
    {
        imdd_ref d(m);
        d = m.mk_empty(3);
        add_some_facts(m, d, true, false);
        m.defrag(d);
        std::cout << mk_ll_pp(d, m) << "\n";
    }
}
示例#16
0
/**
   \brief External interface for the simplifier. 
   A client will invoke operator()(s, r, p) to simplify s.
   The result is stored in r.
   When proof generation is enabled, a proof for the equivalence (or equisatisfiability)
   of s and r is stored in p.
   When proof generation is disabled, this method stores the "undefined proof" object in p.
*/
void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) {
    m_need_reset = true;
    reinitialize();
    expr  * s_orig = s;
    expr  * old_s;
    expr  * result;
    proof * result_proof;
    switch (m.proof_mode()) {
    case PGM_DISABLED: // proof generation is disabled.
        reduce_core(s); 
        // after executing reduce_core, the result of the simplification is in the cache
        get_cached(s, result, result_proof);
        r = result;
        p = m.mk_undef_proof();
        break;
    case PGM_COARSE: // coarse proofs... in this case, we do not produce a step by step (fine grain) proof to show the equivalence (or equisatisfiability) of s an r.
        m_subst_proofs.reset(); // m_subst_proofs is an auxiliary vector that is used to justify substitutions. See comment on method get_subst. 
        reduce_core(s);
        get_cached(s, result, result_proof);
        r = result;
        if (result == s)
            p = m.mk_reflexivity(s);
        else {
            remove_duplicates(m_subst_proofs);
            p = m.mk_rewrite_star(s, result, m_subst_proofs.size(), m_subst_proofs.c_ptr());
        }
        break;
    case PGM_FINE: // fine grain proofs... in this mode, every proof step (or most of them) is described.
        m_proofs.reset();
        old_s = 0;
        // keep simplyfing until no further simplifications are possible.
        while (s != old_s) {
            TRACE("simplifier", tout << "simplification pass... " << s->get_id() << "\n";);
            TRACE("simplifier_loop", tout << mk_ll_pp(s, m) << "\n";);
            reduce_core(s);
            get_cached(s, result, result_proof);
            SASSERT(is_rewrite_proof(s, result, result_proof));
            if (result_proof != 0) {
                m_proofs.push_back(result_proof);
            }
            old_s = s;
            s     = result;
        }
示例#17
0
 literal theory::mk_eq(expr * a, expr * b, bool gate_ctx) {
     context & ctx = get_context();
     app * eq = ctx.mk_eq_atom(a, b);
     TRACE("mk_var_bug", tout << "mk_eq: " << eq->get_id() << " " << a->get_id() << " " << b->get_id() << "\n";
           tout << mk_ll_pp(a, get_manager()) << "\n" << mk_ll_pp(b, get_manager()););		
示例#18
0
void goal::display_ll(std::ostream & out) const {
    unsigned sz = size();
    for (unsigned i = 0; i < sz; i++) {
        out << mk_ll_pp(form(i), m()) << "\n";
    }
}
示例#19
0
文件: imdd.cpp 项目: Moondee/Artemis
static void tst21() {
    std::cout << "--------------------------------\n";
    std::cout << "remove_facts\n";
    imdd_manager m;
    imdd_ref d2(m), d3(m);
    d2 = m.mk_empty(3);
    add_triple(m, d2, 15, 22, 15, 23, 7, 18);
    add_triple(m, d2, 28, 42, 29, 39, 34, 46);
    add_triple(m, d2, 28, 42, 29, 39, 100, 200);
    add_triple(m, d2, 28, 42, 50, 60, 100, 200);
    std::cout << mk_ll_pp(d2, m) << "\n";
    //
    // [15, 22] -> #1:{
    //     [15, 23] -> {[7, 18]}*$80}*$80
    // [28, 42] -> #2:{
    //     [29, 39] -> {[34, 46], [100, 200]}*$160
    //     [50, 60] -> {[100, 200]}*$80}*$80}$80
    //
    unsigned lowers[3] = {23,1,1};
    unsigned uppers[3] = {24,1,1};

    d3 = d2;
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (no change)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";
    d2 = d3;

    lowers[0] = 22;
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (no change)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";

    init(lowers, 22, 15, 0);
    init(uppers, 24, 23, 0);
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (no change)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";

    init(lowers, 22, 15, 7);
    init(uppers, 24, 23, 18);
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (narrow first interval)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";

    init(lowers, 22, 15, 8);
    init(uppers, 24, 23, 18);
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (split first interval)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";

    init(lowers, 22, 15, 8);
    init(uppers, 24, 23, 17);
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (split first interval)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";

    init(lowers, 22, 15, 8);
    init(uppers, 24, 23, 19);
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (split first interval)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";

    init(lowers, 30, 20, 120);
    init(uppers, 40, 60, 140);
    m.remove_facts_dupdt(d2, 3, lowers, uppers);
    std::cout << "new table (split second interval)\n";
    std::cout << mk_ll_pp(d2, m) << "\n";       
}
示例#20
0
/**
   \brief Little HACK for simplifying injectivity axioms
   
   \remark It is not covering all possible cases.
*/
bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) {
    expr * n = q->get_expr();
    expr* arg1 = nullptr, * arg2 = nullptr, *narg = nullptr;
    expr* app1 = nullptr, * app2 = nullptr;
    expr* var1 = nullptr, * var2 = nullptr;
    if (is_forall(q) && m.is_or(n, arg1, arg2)) {
        if (m.is_not(arg2)) 
            std::swap(arg1, arg2);
        if (m.is_not(arg1, narg) && 
            m.is_eq(narg, app1, app2) && 
            m.is_eq(arg2, var1, var2)) {
            if (is_app(app1) &&
                is_app(app2) && 
                to_app(app1)->get_decl() == to_app(app2)->get_decl() &&
                to_app(app1)->get_num_args() == to_app(app2)->get_num_args() &&
                to_app(app1)->get_family_id() == null_family_id &&
                to_app(app1)->get_num_args() > 0 &&
                is_var(var1) && 
                is_var(var2) && 
                var1 != var2) {
                app * f1          = to_app(app1);
                app * f2          = to_app(app2);
                bool found_vars   = false;
                unsigned num      = f1->get_num_args();
                unsigned idx      = UINT_MAX;
                unsigned num_vars = 1;
                for (unsigned i = 0; i < num; i++) {
                    expr  * c1 = f1->get_arg(i);
                    expr  * c2 = f2->get_arg(i);
                    if (!is_var(c1) && !is_uninterp_const(c1))
                        return false;
                    if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) {
                        if (found_vars)
                            return false;
                        found_vars = true;
                        idx = i;
                    }
                    else if (c1 == c2 && c1 != var1 && c1 != var2) {
                        if (is_var(c1)) {
                            ++num_vars;
                        }
                    }
                    else {
                        return false;
                    }
                }
                if (found_vars && !has_free_vars(q)) {
                    TRACE("inj_axiom", 
                          tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" <<
                          mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";);
                    // Building new (optimized) axiom
                    func_decl * decl      = f1->get_decl();
                    unsigned var_idx      = 0;
                    ptr_buffer<expr> f_args, inv_vars;
                    ptr_buffer<sort> decls;
                    buffer<symbol>   names;
                    
                    expr * var            = nullptr;
                    for (unsigned i = 0; i < num; i++) {
                        expr * c = f1->get_arg(i);
                        if (is_var(c)) {
                            names.push_back(symbol(i));
                            sort * s = decl->get_domain(i);
                            decls.push_back(s);
                            expr * new_c = m.mk_var(var_idx, s);
                            var_idx++;
                            f_args.push_back(new_c);
                            if (i == idx) {
                                var = new_c;
                            }
                            else {
                                inv_vars.push_back(new_c);
                            }
                        }
                        else {
                            SASSERT(is_uninterp_const(c));
                            f_args.push_back(c);
                        }
                    }
                    SASSERT(var != 0);
                    app * f    = m.mk_app(decl, f_args.size(), f_args.c_ptr());

                    ptr_vector<sort>  domain;
                    inv_vars.push_back(f);
                    for (unsigned i = 0; i < inv_vars.size(); ++i) {
                        domain.push_back(m.get_sort(inv_vars[i]));
                    }
                    sort * d              = decl->get_domain(idx);
                    func_decl * inv_decl  = m.mk_fresh_func_decl("inj", domain.size(), domain.c_ptr(), d);
                    
                    expr * proj = m.mk_app(inv_decl, inv_vars.size(), inv_vars.c_ptr());
                    expr * eq   = m.mk_eq(proj, var);
                    expr * p    = m.mk_pattern(f);
                    
                    // decls are in the wrong order...
                    // Remark: the sort of the var 0 must be in the last position.
                    std::reverse(decls.begin(), decls.end());
                    
                    result = m.mk_forall(decls.size(), decls.c_ptr(), names.c_ptr(), eq,
                                         0, symbol(), symbol(), 1, &p);
                    TRACE("inj_axiom", tout << "new axiom:\n" << mk_pp(result, m) << "\n";);
                    SASSERT(is_well_sorted(m, result));
                    return true;
                }